]> Git Repo - qemu.git/blame - target-sparc/translate.c
Fix crash due to invalid env->current_tb (Adam Lackorzynski, Paul Brook, me)
[qemu.git] / target-sparc / translate.c
CommitLineData
7a3f1944
FB
1/*
2 SPARC translation
3
4 Copyright (C) 2003 Thomas M. Ogrisegg <[email protected]>
3475187d 5 Copyright (C) 2003-2005 Fabrice Bellard
7a3f1944
FB
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22/*
7a3f1944
FB
23 TODO-list:
24
3475187d 25 Rest of V9 instructions, VIS instructions
bd497938 26 NPC/PC static optimisations (use JUMP_TB when possible)
7a3f1944 27 Optimize synthetic instructions
bd497938 28*/
7a3f1944
FB
29
30#include <stdarg.h>
31#include <stdlib.h>
32#include <stdio.h>
33#include <string.h>
34#include <inttypes.h>
35
36#include "cpu.h"
37#include "exec-all.h"
38#include "disas.h"
1a2fb1c0 39#include "helper.h"
57fec1fe 40#include "tcg-op.h"
7a3f1944
FB
41
42#define DEBUG_DISAS
43
72cbca10
FB
44#define DYNAMIC_PC 1 /* dynamic pc value */
45#define JUMP_PC 2 /* dynamic pc value which takes only two values
46 according to jump_pc[T2] */
47
1a2fb1c0 48/* global register indexes */
d9bdab86 49static TCGv cpu_env, cpu_T[3], cpu_regwptr, cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
48d5c82b 50static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
6ae20372 51static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
dc99a3f2
BS
52#ifdef TARGET_SPARC64
53static TCGv cpu_xcc;
54#endif
1a2fb1c0 55/* local register indexes (only used inside old micro ops) */
8911f501 56static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
1a2fb1c0 57
7a3f1944 58typedef struct DisasContext {
0f8a249a
BS
59 target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */
60 target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */
72cbca10 61 target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
cf495bcf 62 int is_br;
e8af50a3 63 int mem_idx;
a80dde08 64 int fpu_enabled;
cf495bcf 65 struct TranslationBlock *tb;
7a3f1944
FB
66} DisasContext;
67
7a3f1944
FB
68extern FILE *logfile;
69extern int loglevel;
70
3475187d 71// This function uses non-native bit order
7a3f1944
FB
72#define GET_FIELD(X, FROM, TO) \
73 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
74
3475187d
FB
75// This function uses the order in the manuals, i.e. bit 0 is 2^0
76#define GET_FIELD_SP(X, FROM, TO) \
77 GET_FIELD(X, 31 - (TO), 31 - (FROM))
78
79#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
46d38ba8 80#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
3475187d
FB
81
82#ifdef TARGET_SPARC64
19f329ad 83#define FFPREG(r) (r)
0387d928 84#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
1f587329 85#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
3475187d 86#else
19f329ad 87#define FFPREG(r) (r)
c185970a 88#define DFPREG(r) (r & 0x1e)
1f587329 89#define QFPREG(r) (r & 0x1c)
3475187d
FB
90#endif
91
92static int sign_extend(int x, int len)
93{
94 len = 32 - len;
95 return (x << len) >> len;
96}
97
7a3f1944
FB
98#define IS_IMM (insn & (1<<13))
99
ff07ec83
BS
100/* floating point registers moves */
101static void gen_op_load_fpr_FT0(unsigned int src)
102{
8911f501
BS
103 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
104 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
3475187d 105}
ff07ec83
BS
106
107static void gen_op_load_fpr_FT1(unsigned int src)
108{
8911f501
BS
109 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
110 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1));
e8af50a3
FB
111}
112
ff07ec83
BS
113static void gen_op_store_FT0_fpr(unsigned int dst)
114{
8911f501
BS
115 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
116 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
ff07ec83
BS
117}
118
119static void gen_op_load_fpr_DT0(unsigned int src)
120{
8911f501
BS
121 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
122 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper));
123 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
124 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower));
ff07ec83
BS
125}
126
127static void gen_op_load_fpr_DT1(unsigned int src)
128{
8911f501
BS
129 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
130 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.upper));
131 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
132 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.lower));
ff07ec83
BS
133}
134
135static void gen_op_store_DT0_fpr(unsigned int dst)
136{
8911f501
BS
137 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper));
138 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
139 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower));
140 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
ff07ec83
BS
141}
142
143#ifdef CONFIG_USER_ONLY
144static void gen_op_load_fpr_QT0(unsigned int src)
145{
8911f501
BS
146 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
147 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
148 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
149 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
150 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
151 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
152 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
153 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
ff07ec83
BS
154}
155
156static void gen_op_load_fpr_QT1(unsigned int src)
157{
8911f501
BS
158 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
159 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upmost));
160 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
161 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upper));
162 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
163 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lower));
164 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
165 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lowest));
ff07ec83
BS
166}
167
168static void gen_op_store_QT0_fpr(unsigned int dst)
169{
8911f501
BS
170 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
171 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
172 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
173 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
174 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
175 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2]));
176 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
177 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
ff07ec83 178}
1f587329
BS
179#endif
180
81ad8ba2
BS
181/* moves */
182#ifdef CONFIG_USER_ONLY
3475187d 183#define supervisor(dc) 0
81ad8ba2 184#ifdef TARGET_SPARC64
e9ebed4d 185#define hypervisor(dc) 0
81ad8ba2 186#endif
3475187d 187#define gen_op_ldst(name) gen_op_##name##_raw()
3475187d 188#else
6f27aba6 189#define supervisor(dc) (dc->mem_idx >= 1)
81ad8ba2
BS
190#ifdef TARGET_SPARC64
191#define hypervisor(dc) (dc->mem_idx == 2)
6f27aba6
BS
192#define OP_LD_TABLE(width) \
193 static GenOpFunc * const gen_op_##width[] = { \
194 &gen_op_##width##_user, \
195 &gen_op_##width##_kernel, \
196 &gen_op_##width##_hypv, \
197 };
198#else
0f8a249a 199#define OP_LD_TABLE(width) \
a68156d0 200 static GenOpFunc * const gen_op_##width[] = { \
0f8a249a
BS
201 &gen_op_##width##_user, \
202 &gen_op_##width##_kernel, \
81ad8ba2 203 };
3475187d 204#endif
6f27aba6
BS
205#define gen_op_ldst(name) (*gen_op_##name[dc->mem_idx])()
206#endif
e8af50a3 207
81ad8ba2 208#ifndef CONFIG_USER_ONLY
b25deda7
BS
209#ifdef __i386__
210OP_LD_TABLE(std);
211#endif /* __i386__ */
e8af50a3 212OP_LD_TABLE(stdf);
e8af50a3 213OP_LD_TABLE(lddf);
81ad8ba2
BS
214#endif
215
1a2fb1c0 216#ifdef TARGET_ABI32
8911f501 217#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
1a2fb1c0
BS
218#else
219#define ABI32_MASK(addr)
220#endif
3391c818 221
1a2fb1c0 222static inline void gen_movl_reg_TN(int reg, TCGv tn)
81ad8ba2 223{
1a2fb1c0
BS
224 if (reg == 0)
225 tcg_gen_movi_tl(tn, 0);
226 else if (reg < 8)
f5069b26 227 tcg_gen_mov_tl(tn, cpu_gregs[reg]);
1a2fb1c0 228 else {
1a2fb1c0 229 tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
81ad8ba2
BS
230 }
231}
232
1a2fb1c0 233static inline void gen_movl_TN_reg(int reg, TCGv tn)
81ad8ba2 234{
1a2fb1c0
BS
235 if (reg == 0)
236 return;
237 else if (reg < 8)
f5069b26 238 tcg_gen_mov_tl(cpu_gregs[reg], tn);
1a2fb1c0 239 else {
1a2fb1c0 240 tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
81ad8ba2
BS
241 }
242}
243
5fafdf24 244static inline void gen_goto_tb(DisasContext *s, int tb_num,
6e256c93
FB
245 target_ulong pc, target_ulong npc)
246{
247 TranslationBlock *tb;
248
249 tb = s->tb;
250 if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
251 (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK)) {
252 /* jump to same page: we can use a direct jump */
57fec1fe 253 tcg_gen_goto_tb(tb_num);
2f5680ee
BS
254 tcg_gen_movi_tl(cpu_pc, pc);
255 tcg_gen_movi_tl(cpu_npc, npc);
57fec1fe 256 tcg_gen_exit_tb((long)tb + tb_num);
6e256c93
FB
257 } else {
258 /* jump to another page: currently not optimized */
2f5680ee
BS
259 tcg_gen_movi_tl(cpu_pc, pc);
260 tcg_gen_movi_tl(cpu_npc, npc);
57fec1fe 261 tcg_gen_exit_tb(0);
6e256c93
FB
262 }
263}
264
19f329ad
BS
265// XXX suboptimal
266static inline void gen_mov_reg_N(TCGv reg, TCGv src)
267{
8911f501 268 tcg_gen_extu_i32_tl(reg, src);
4b8b8b76 269 tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
19f329ad
BS
270 tcg_gen_andi_tl(reg, reg, 0x1);
271}
272
273static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
274{
8911f501 275 tcg_gen_extu_i32_tl(reg, src);
4b8b8b76 276 tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
19f329ad
BS
277 tcg_gen_andi_tl(reg, reg, 0x1);
278}
279
280static inline void gen_mov_reg_V(TCGv reg, TCGv src)
281{
8911f501 282 tcg_gen_extu_i32_tl(reg, src);
4b8b8b76 283 tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
19f329ad
BS
284 tcg_gen_andi_tl(reg, reg, 0x1);
285}
286
287static inline void gen_mov_reg_C(TCGv reg, TCGv src)
288{
8911f501 289 tcg_gen_extu_i32_tl(reg, src);
4b8b8b76 290 tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
19f329ad
BS
291 tcg_gen_andi_tl(reg, reg, 0x1);
292}
293
ce5b3c3d 294static inline void gen_cc_clear_icc(void)
dc99a3f2
BS
295{
296 tcg_gen_movi_i32(cpu_psr, 0);
ce5b3c3d
BS
297}
298
dc99a3f2 299#ifdef TARGET_SPARC64
ce5b3c3d
BS
300static inline void gen_cc_clear_xcc(void)
301{
dc99a3f2 302 tcg_gen_movi_i32(cpu_xcc, 0);
dc99a3f2 303}
ce5b3c3d 304#endif
dc99a3f2
BS
305
306/* old op:
307 if (!T0)
308 env->psr |= PSR_ZERO;
309 if ((int32_t) T0 < 0)
310 env->psr |= PSR_NEG;
311*/
ce5b3c3d 312static inline void gen_cc_NZ_icc(TCGv dst)
dc99a3f2 313{
8911f501 314 TCGv r_temp;
dc99a3f2 315 int l1, l2;
dc99a3f2
BS
316
317 l1 = gen_new_label();
318 l2 = gen_new_label();
8911f501
BS
319 r_temp = tcg_temp_new(TCG_TYPE_TL);
320 tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
321 tcg_gen_brcond_tl(TCG_COND_NE, r_temp, tcg_const_tl(0), l1);
dc99a3f2
BS
322 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
323 gen_set_label(l1);
bdf46ea2 324 tcg_gen_ext_i32_tl(r_temp, dst);
8911f501 325 tcg_gen_brcond_tl(TCG_COND_GE, r_temp, tcg_const_tl(0), l2);
dc99a3f2
BS
326 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
327 gen_set_label(l2);
ce5b3c3d
BS
328}
329
dc99a3f2 330#ifdef TARGET_SPARC64
ce5b3c3d
BS
331static inline void gen_cc_NZ_xcc(TCGv dst)
332{
333 int l1, l2;
334
335 l1 = gen_new_label();
336 l2 = gen_new_label();
337 tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l1);
338 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
339 gen_set_label(l1);
340 tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l2);
341 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
342 gen_set_label(l2);
dc99a3f2 343}
ce5b3c3d 344#endif
dc99a3f2
BS
345
346/* old op:
347 if (T0 < src1)
348 env->psr |= PSR_CARRY;
349*/
ce5b3c3d 350static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
dc99a3f2 351{
8911f501 352 TCGv r_temp;
dc99a3f2
BS
353 int l1;
354
355 l1 = gen_new_label();
8911f501
BS
356 r_temp = tcg_temp_new(TCG_TYPE_TL);
357 tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
358 tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
dc99a3f2
BS
359 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
360 gen_set_label(l1);
ce5b3c3d
BS
361}
362
dc99a3f2 363#ifdef TARGET_SPARC64
ce5b3c3d
BS
364static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
365{
366 int l1;
dc99a3f2 367
ce5b3c3d
BS
368 l1 = gen_new_label();
369 tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
370 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
371 gen_set_label(l1);
dc99a3f2 372}
ce5b3c3d 373#endif
dc99a3f2
BS
374
375/* old op:
376 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
377 env->psr |= PSR_OVF;
378*/
ce5b3c3d 379static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 380{
0425bee5 381 TCGv r_temp;
dc99a3f2
BS
382 int l1;
383
384 l1 = gen_new_label();
385
386 r_temp = tcg_temp_new(TCG_TYPE_TL);
dc99a3f2
BS
387 tcg_gen_xor_tl(r_temp, src1, src2);
388 tcg_gen_xori_tl(r_temp, r_temp, -1);
0425bee5
BS
389 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
390 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
391 tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
8911f501 392 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
dc99a3f2
BS
393 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
394 gen_set_label(l1);
ce5b3c3d
BS
395}
396
dc99a3f2 397#ifdef TARGET_SPARC64
ce5b3c3d
BS
398static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
399{
400 TCGv r_temp;
401 int l1;
402
403 l1 = gen_new_label();
404
405 r_temp = tcg_temp_new(TCG_TYPE_TL);
406 tcg_gen_xor_tl(r_temp, src1, src2);
407 tcg_gen_xori_tl(r_temp, r_temp, -1);
408 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
409 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
410 tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
411 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
412 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
413 gen_set_label(l1);
dc99a3f2 414}
ce5b3c3d 415#endif
dc99a3f2
BS
416
417static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
418{
0425bee5 419 TCGv r_temp;
dc99a3f2
BS
420 int l1;
421
422 l1 = gen_new_label();
423
424 r_temp = tcg_temp_new(TCG_TYPE_TL);
dc99a3f2
BS
425 tcg_gen_xor_tl(r_temp, src1, src2);
426 tcg_gen_xori_tl(r_temp, r_temp, -1);
0425bee5
BS
427 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
428 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
429 tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
8911f501 430 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
2f5680ee 431 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
dc99a3f2 432 gen_set_label(l1);
dc99a3f2
BS
433}
434
435static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
436{
437 int l1;
dc99a3f2
BS
438
439 l1 = gen_new_label();
0425bee5
BS
440 tcg_gen_or_tl(cpu_tmp0, src1, src2);
441 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
442 tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
dc99a3f2
BS
443 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
444 gen_set_label(l1);
445}
446
447static inline void gen_tag_tv(TCGv src1, TCGv src2)
448{
449 int l1;
dc99a3f2
BS
450
451 l1 = gen_new_label();
0425bee5
BS
452 tcg_gen_or_tl(cpu_tmp0, src1, src2);
453 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
454 tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
2f5680ee 455 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
dc99a3f2
BS
456 gen_set_label(l1);
457}
458
4af984a7 459static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 460{
4af984a7 461 tcg_gen_mov_tl(cpu_cc_src, src1);
6f551262 462 tcg_gen_mov_tl(cpu_cc_src2, src2);
4af984a7 463 tcg_gen_add_tl(dst, src1, src2);
ce5b3c3d 464 gen_cc_clear_icc();
4af984a7
BS
465 gen_cc_NZ_icc(dst);
466 gen_cc_C_add_icc(dst, cpu_cc_src);
6f551262 467 gen_cc_V_add_icc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d
BS
468#ifdef TARGET_SPARC64
469 gen_cc_clear_xcc();
4af984a7
BS
470 gen_cc_NZ_xcc(dst);
471 gen_cc_C_add_xcc(dst, cpu_cc_src);
6f551262 472 gen_cc_V_add_xcc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 473#endif
dc99a3f2
BS
474}
475
4af984a7 476static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 477{
4af984a7 478 tcg_gen_mov_tl(cpu_cc_src, src1);
6f551262 479 tcg_gen_mov_tl(cpu_cc_src2, src2);
dc99a3f2 480 gen_mov_reg_C(cpu_tmp0, cpu_psr);
4af984a7 481 tcg_gen_add_tl(dst, src1, cpu_tmp0);
ce5b3c3d 482 gen_cc_clear_icc();
4af984a7 483 gen_cc_C_add_icc(dst, cpu_cc_src);
ce5b3c3d
BS
484#ifdef TARGET_SPARC64
485 gen_cc_clear_xcc();
4af984a7 486 gen_cc_C_add_xcc(dst, cpu_cc_src);
ce5b3c3d 487#endif
6f551262 488 tcg_gen_add_tl(dst, dst, cpu_cc_src2);
4af984a7
BS
489 gen_cc_NZ_icc(dst);
490 gen_cc_C_add_icc(dst, cpu_cc_src);
6f551262 491 gen_cc_V_add_icc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 492#ifdef TARGET_SPARC64
4af984a7
BS
493 gen_cc_NZ_xcc(dst);
494 gen_cc_C_add_xcc(dst, cpu_cc_src);
6f551262 495 gen_cc_V_add_xcc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 496#endif
dc99a3f2
BS
497}
498
4af984a7 499static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 500{
4af984a7 501 tcg_gen_mov_tl(cpu_cc_src, src1);
6f551262 502 tcg_gen_mov_tl(cpu_cc_src2, src2);
4af984a7 503 tcg_gen_add_tl(dst, src1, src2);
ce5b3c3d 504 gen_cc_clear_icc();
4af984a7
BS
505 gen_cc_NZ_icc(dst);
506 gen_cc_C_add_icc(dst, cpu_cc_src);
6f551262
BS
507 gen_cc_V_add_icc(dst, cpu_cc_src, cpu_cc_src2);
508 gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
ce5b3c3d
BS
509#ifdef TARGET_SPARC64
510 gen_cc_clear_xcc();
4af984a7
BS
511 gen_cc_NZ_xcc(dst);
512 gen_cc_C_add_xcc(dst, cpu_cc_src);
6f551262 513 gen_cc_V_add_xcc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 514#endif
dc99a3f2
BS
515}
516
4af984a7 517static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 518{
4af984a7 519 tcg_gen_mov_tl(cpu_cc_src, src1);
6f551262
BS
520 tcg_gen_mov_tl(cpu_cc_src2, src2);
521 gen_tag_tv(cpu_cc_src, cpu_cc_src2);
4af984a7 522 tcg_gen_add_tl(dst, src1, src2);
6f551262 523 gen_add_tv(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 524 gen_cc_clear_icc();
4af984a7
BS
525 gen_cc_NZ_icc(dst);
526 gen_cc_C_add_icc(dst, cpu_cc_src);
ce5b3c3d
BS
527#ifdef TARGET_SPARC64
528 gen_cc_clear_xcc();
4af984a7
BS
529 gen_cc_NZ_xcc(dst);
530 gen_cc_C_add_xcc(dst, cpu_cc_src);
6f551262 531 gen_cc_V_add_xcc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 532#endif
dc99a3f2
BS
533}
534
535/* old op:
536 if (src1 < T1)
537 env->psr |= PSR_CARRY;
538*/
ce5b3c3d 539static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
dc99a3f2 540{
8911f501 541 TCGv r_temp1, r_temp2;
dc99a3f2
BS
542 int l1;
543
544 l1 = gen_new_label();
8911f501
BS
545 r_temp1 = tcg_temp_new(TCG_TYPE_TL);
546 r_temp2 = tcg_temp_new(TCG_TYPE_TL);
547 tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
548 tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
549 tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
dc99a3f2
BS
550 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
551 gen_set_label(l1);
ce5b3c3d
BS
552}
553
dc99a3f2 554#ifdef TARGET_SPARC64
ce5b3c3d
BS
555static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
556{
557 int l1;
dc99a3f2 558
ce5b3c3d
BS
559 l1 = gen_new_label();
560 tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
561 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
562 gen_set_label(l1);
dc99a3f2 563}
ce5b3c3d 564#endif
dc99a3f2
BS
565
566/* old op:
567 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
568 env->psr |= PSR_OVF;
569*/
ce5b3c3d 570static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 571{
0425bee5 572 TCGv r_temp;
dc99a3f2
BS
573 int l1;
574
575 l1 = gen_new_label();
576
577 r_temp = tcg_temp_new(TCG_TYPE_TL);
dc99a3f2 578 tcg_gen_xor_tl(r_temp, src1, src2);
0425bee5
BS
579 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
580 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
581 tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
8911f501 582 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
dc99a3f2
BS
583 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
584 gen_set_label(l1);
ce5b3c3d
BS
585}
586
dc99a3f2 587#ifdef TARGET_SPARC64
ce5b3c3d
BS
588static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
589{
590 TCGv r_temp;
591 int l1;
592
593 l1 = gen_new_label();
594
595 r_temp = tcg_temp_new(TCG_TYPE_TL);
596 tcg_gen_xor_tl(r_temp, src1, src2);
597 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
598 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
599 tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
600 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
601 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
602 gen_set_label(l1);
dc99a3f2 603}
ce5b3c3d 604#endif
dc99a3f2
BS
605
606static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
607{
0425bee5 608 TCGv r_temp;
dc99a3f2
BS
609 int l1;
610
611 l1 = gen_new_label();
612
613 r_temp = tcg_temp_new(TCG_TYPE_TL);
dc99a3f2 614 tcg_gen_xor_tl(r_temp, src1, src2);
0425bee5
BS
615 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
616 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
617 tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
8911f501 618 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
2f5680ee 619 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
dc99a3f2 620 gen_set_label(l1);
dc99a3f2
BS
621}
622
4af984a7 623static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 624{
4af984a7 625 tcg_gen_mov_tl(cpu_cc_src, src1);
6f551262 626 tcg_gen_mov_tl(cpu_cc_src2, src2);
4af984a7 627 tcg_gen_sub_tl(dst, src1, src2);
ce5b3c3d 628 gen_cc_clear_icc();
4af984a7 629 gen_cc_NZ_icc(dst);
6f551262
BS
630 gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
631 gen_cc_V_sub_icc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d
BS
632#ifdef TARGET_SPARC64
633 gen_cc_clear_xcc();
4af984a7 634 gen_cc_NZ_xcc(dst);
6f551262
BS
635 gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
636 gen_cc_V_sub_xcc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 637#endif
dc99a3f2
BS
638}
639
4af984a7 640static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 641{
4af984a7 642 tcg_gen_mov_tl(cpu_cc_src, src1);
6f551262 643 tcg_gen_mov_tl(cpu_cc_src2, src2);
dc99a3f2 644 gen_mov_reg_C(cpu_tmp0, cpu_psr);
4af984a7 645 tcg_gen_sub_tl(dst, src1, cpu_tmp0);
ce5b3c3d 646 gen_cc_clear_icc();
4af984a7 647 gen_cc_C_sub_icc(dst, cpu_cc_src);
ce5b3c3d
BS
648#ifdef TARGET_SPARC64
649 gen_cc_clear_xcc();
4af984a7 650 gen_cc_C_sub_xcc(dst, cpu_cc_src);
ce5b3c3d 651#endif
6f551262 652 tcg_gen_sub_tl(dst, dst, cpu_cc_src2);
4af984a7
BS
653 gen_cc_NZ_icc(dst);
654 gen_cc_C_sub_icc(dst, cpu_cc_src);
6f551262 655 gen_cc_V_sub_icc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 656#ifdef TARGET_SPARC64
4af984a7
BS
657 gen_cc_NZ_xcc(dst);
658 gen_cc_C_sub_xcc(dst, cpu_cc_src);
6f551262 659 gen_cc_V_sub_xcc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 660#endif
dc99a3f2
BS
661}
662
4af984a7 663static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 664{
4af984a7 665 tcg_gen_mov_tl(cpu_cc_src, src1);
6f551262 666 tcg_gen_mov_tl(cpu_cc_src2, src2);
4af984a7 667 tcg_gen_sub_tl(dst, src1, src2);
ce5b3c3d 668 gen_cc_clear_icc();
4af984a7 669 gen_cc_NZ_icc(dst);
6f551262
BS
670 gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
671 gen_cc_V_sub_icc(dst, cpu_cc_src, cpu_cc_src2);
672 gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
ce5b3c3d
BS
673#ifdef TARGET_SPARC64
674 gen_cc_clear_xcc();
4af984a7 675 gen_cc_NZ_xcc(dst);
6f551262
BS
676 gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
677 gen_cc_V_sub_xcc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 678#endif
dc99a3f2
BS
679}
680
4af984a7 681static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
dc99a3f2 682{
4af984a7 683 tcg_gen_mov_tl(cpu_cc_src, src1);
6f551262
BS
684 tcg_gen_mov_tl(cpu_cc_src2, src2);
685 gen_tag_tv(cpu_cc_src, cpu_cc_src2);
4af984a7 686 tcg_gen_sub_tl(dst, src1, src2);
6f551262 687 gen_sub_tv(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 688 gen_cc_clear_icc();
4af984a7 689 gen_cc_NZ_icc(dst);
6f551262 690 gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
ce5b3c3d
BS
691#ifdef TARGET_SPARC64
692 gen_cc_clear_xcc();
4af984a7 693 gen_cc_NZ_xcc(dst);
6f551262
BS
694 gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
695 gen_cc_V_sub_xcc(dst, cpu_cc_src, cpu_cc_src2);
ce5b3c3d 696#endif
dc99a3f2
BS
697}
698
4af984a7 699static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
d9bdab86 700{
7127fe84 701 TCGv r_temp, r_temp2;
6f551262 702 int l1;
d9bdab86
BS
703
704 l1 = gen_new_label();
d9bdab86 705 r_temp = tcg_temp_new(TCG_TYPE_TL);
7127fe84 706 r_temp2 = tcg_temp_new(TCG_TYPE_I32);
d9bdab86
BS
707
708 /* old op:
709 if (!(env->y & 1))
710 T1 = 0;
711 */
6f551262 712 tcg_gen_mov_tl(cpu_cc_src, src1);
7127fe84
BS
713 tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
714 tcg_gen_trunc_tl_i32(r_temp2, r_temp);
715 tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
4af984a7 716 tcg_gen_mov_tl(cpu_cc_src2, src2);
6f551262 717 tcg_gen_brcond_i32(TCG_COND_NE, r_temp2, tcg_const_i32(0), l1);
d9bdab86 718 tcg_gen_movi_tl(cpu_cc_src2, 0);
6f551262 719 gen_set_label(l1);
d9bdab86
BS
720
721 // b2 = T0 & 1;
722 // env->y = (b2 << 31) | (env->y >> 1);
6f551262 723 tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
7127fe84
BS
724 tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
725 tcg_gen_shli_i32(r_temp2, r_temp2, 31);
8911f501
BS
726 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
727 tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
7127fe84 728 tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
8911f501 729 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
d9bdab86
BS
730
731 // b1 = N ^ V;
732 gen_mov_reg_N(cpu_tmp0, cpu_psr);
733 gen_mov_reg_V(r_temp, cpu_psr);
734 tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
735
736 // T0 = (b1 << 31) | (T0 >> 1);
737 // src1 = T0;
738 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
6f551262 739 tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
d9bdab86
BS
740 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
741
742 /* do addition and update flags */
4af984a7 743 tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
d9bdab86 744
ce5b3c3d 745 gen_cc_clear_icc();
4af984a7
BS
746 gen_cc_NZ_icc(dst);
747 gen_cc_V_add_icc(dst, cpu_cc_src, cpu_cc_src2);
748 gen_cc_C_add_icc(dst, cpu_cc_src);
d9bdab86
BS
749}
750
4af984a7 751static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
8879d139
BS
752{
753 TCGv r_temp, r_temp2;
754
755 r_temp = tcg_temp_new(TCG_TYPE_I64);
756 r_temp2 = tcg_temp_new(TCG_TYPE_I64);
757
4af984a7
BS
758 tcg_gen_extu_tl_i64(r_temp, src2);
759 tcg_gen_extu_tl_i64(r_temp2, src1);
8879d139
BS
760 tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
761
762 tcg_gen_shri_i64(r_temp, r_temp2, 32);
763 tcg_gen_trunc_i64_i32(r_temp, r_temp);
764 tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
765#ifdef TARGET_SPARC64
4af984a7 766 tcg_gen_mov_i64(dst, r_temp2);
8879d139 767#else
4af984a7 768 tcg_gen_trunc_i64_tl(dst, r_temp2);
8879d139 769#endif
8879d139
BS
770}
771
4af984a7 772static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
8879d139
BS
773{
774 TCGv r_temp, r_temp2;
775
776 r_temp = tcg_temp_new(TCG_TYPE_I64);
777 r_temp2 = tcg_temp_new(TCG_TYPE_I64);
778
4af984a7
BS
779 tcg_gen_ext_tl_i64(r_temp, src2);
780 tcg_gen_ext_tl_i64(r_temp2, src1);
8879d139
BS
781 tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
782
783 tcg_gen_shri_i64(r_temp, r_temp2, 32);
784 tcg_gen_trunc_i64_i32(r_temp, r_temp);
785 tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
786#ifdef TARGET_SPARC64
4af984a7 787 tcg_gen_mov_i64(dst, r_temp2);
8879d139 788#else
4af984a7 789 tcg_gen_trunc_i64_tl(dst, r_temp2);
8879d139 790#endif
8879d139
BS
791}
792
1a7b60e7 793#ifdef TARGET_SPARC64
8911f501 794static inline void gen_trap_ifdivzero_tl(TCGv divisor)
1a7b60e7
BS
795{
796 int l1;
797
798 l1 = gen_new_label();
8911f501 799 tcg_gen_brcond_tl(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
2f5680ee 800 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
1a7b60e7
BS
801 gen_set_label(l1);
802}
803
4af984a7 804static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
1a7b60e7
BS
805{
806 int l1, l2;
807
808 l1 = gen_new_label();
809 l2 = gen_new_label();
6f551262
BS
810 tcg_gen_mov_tl(cpu_cc_src, src1);
811 tcg_gen_mov_tl(cpu_cc_src2, src2);
4af984a7 812 gen_trap_ifdivzero_tl(src2);
6f551262
BS
813 tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src, tcg_const_tl(INT64_MIN), l1);
814 tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src2, tcg_const_tl(-1), l1);
4af984a7 815 tcg_gen_movi_i64(dst, INT64_MIN);
06b3e1b3 816 tcg_gen_br(l2);
1a7b60e7 817 gen_set_label(l1);
6f551262 818 tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
1a7b60e7
BS
819 gen_set_label(l2);
820}
821#endif
822
4af984a7 823static inline void gen_op_div_cc(TCGv dst)
dc99a3f2
BS
824{
825 int l1;
dc99a3f2 826
ce5b3c3d 827 gen_cc_clear_icc();
4af984a7 828 gen_cc_NZ_icc(dst);
dc99a3f2 829 l1 = gen_new_label();
3b89f26c
BS
830 tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
831 tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
dc99a3f2
BS
832 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
833 gen_set_label(l1);
834}
835
4af984a7 836static inline void gen_op_logic_cc(TCGv dst)
dc99a3f2 837{
ce5b3c3d 838 gen_cc_clear_icc();
4af984a7 839 gen_cc_NZ_icc(dst);
ce5b3c3d
BS
840#ifdef TARGET_SPARC64
841 gen_cc_clear_xcc();
4af984a7 842 gen_cc_NZ_xcc(dst);
ce5b3c3d 843#endif
dc99a3f2
BS
844}
845
19f329ad
BS
846// 1
847static inline void gen_op_eval_ba(TCGv dst)
848{
849 tcg_gen_movi_tl(dst, 1);
850}
851
852// Z
853static inline void gen_op_eval_be(TCGv dst, TCGv src)
854{
855 gen_mov_reg_Z(dst, src);
856}
857
858// Z | (N ^ V)
859static inline void gen_op_eval_ble(TCGv dst, TCGv src)
860{
0425bee5 861 gen_mov_reg_N(cpu_tmp0, src);
19f329ad 862 gen_mov_reg_V(dst, src);
0425bee5
BS
863 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
864 gen_mov_reg_Z(cpu_tmp0, src);
865 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
866}
867
868// N ^ V
869static inline void gen_op_eval_bl(TCGv dst, TCGv src)
870{
0425bee5 871 gen_mov_reg_V(cpu_tmp0, src);
19f329ad 872 gen_mov_reg_N(dst, src);
0425bee5 873 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
19f329ad
BS
874}
875
876// C | Z
877static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
878{
0425bee5 879 gen_mov_reg_Z(cpu_tmp0, src);
19f329ad 880 gen_mov_reg_C(dst, src);
0425bee5 881 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
882}
883
884// C
885static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
886{
887 gen_mov_reg_C(dst, src);
888}
889
890// V
891static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
892{
893 gen_mov_reg_V(dst, src);
894}
895
896// 0
897static inline void gen_op_eval_bn(TCGv dst)
898{
899 tcg_gen_movi_tl(dst, 0);
900}
901
902// N
903static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
904{
905 gen_mov_reg_N(dst, src);
906}
907
908// !Z
909static inline void gen_op_eval_bne(TCGv dst, TCGv src)
910{
911 gen_mov_reg_Z(dst, src);
912 tcg_gen_xori_tl(dst, dst, 0x1);
913}
914
915// !(Z | (N ^ V))
916static inline void gen_op_eval_bg(TCGv dst, TCGv src)
917{
0425bee5 918 gen_mov_reg_N(cpu_tmp0, src);
19f329ad 919 gen_mov_reg_V(dst, src);
0425bee5
BS
920 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
921 gen_mov_reg_Z(cpu_tmp0, src);
922 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
923 tcg_gen_xori_tl(dst, dst, 0x1);
924}
925
926// !(N ^ V)
927static inline void gen_op_eval_bge(TCGv dst, TCGv src)
928{
0425bee5 929 gen_mov_reg_V(cpu_tmp0, src);
19f329ad 930 gen_mov_reg_N(dst, src);
0425bee5 931 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
19f329ad
BS
932 tcg_gen_xori_tl(dst, dst, 0x1);
933}
934
935// !(C | Z)
936static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
937{
0425bee5 938 gen_mov_reg_Z(cpu_tmp0, src);
19f329ad 939 gen_mov_reg_C(dst, src);
0425bee5 940 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
941 tcg_gen_xori_tl(dst, dst, 0x1);
942}
943
944// !C
945static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
946{
947 gen_mov_reg_C(dst, src);
948 tcg_gen_xori_tl(dst, dst, 0x1);
949}
950
951// !N
952static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
953{
954 gen_mov_reg_N(dst, src);
955 tcg_gen_xori_tl(dst, dst, 0x1);
956}
957
958// !V
959static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
960{
961 gen_mov_reg_V(dst, src);
962 tcg_gen_xori_tl(dst, dst, 0x1);
963}
964
965/*
966 FPSR bit field FCC1 | FCC0:
967 0 =
968 1 <
969 2 >
970 3 unordered
971*/
972static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
973 unsigned int fcc_offset)
974{
8911f501 975 tcg_gen_extu_i32_tl(reg, src);
4b8b8b76 976 tcg_gen_shri_tl(reg, reg, FSR_FCC0_SHIFT + fcc_offset);
19f329ad
BS
977 tcg_gen_andi_tl(reg, reg, 0x1);
978}
979
980static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
981 unsigned int fcc_offset)
982{
8911f501 983 tcg_gen_extu_i32_tl(reg, src);
4b8b8b76 984 tcg_gen_shri_tl(reg, reg, FSR_FCC1_SHIFT + fcc_offset);
19f329ad
BS
985 tcg_gen_andi_tl(reg, reg, 0x1);
986}
987
988// !0: FCC0 | FCC1
989static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
990 unsigned int fcc_offset)
991{
19f329ad 992 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
993 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
994 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
995}
996
997// 1 or 2: FCC0 ^ FCC1
998static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
999 unsigned int fcc_offset)
1000{
19f329ad 1001 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1002 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1003 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1004}
1005
1006// 1 or 3: FCC0
1007static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1008 unsigned int fcc_offset)
1009{
1010 gen_mov_reg_FCC0(dst, src, fcc_offset);
1011}
1012
1013// 1: FCC0 & !FCC1
1014static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
1015 unsigned int fcc_offset)
1016{
19f329ad 1017 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1018 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1019 tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1020 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1021}
1022
1023// 2 or 3: FCC1
1024static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1025 unsigned int fcc_offset)
1026{
1027 gen_mov_reg_FCC1(dst, src, fcc_offset);
1028}
1029
1030// 2: !FCC0 & FCC1
1031static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
1032 unsigned int fcc_offset)
1033{
19f329ad
BS
1034 gen_mov_reg_FCC0(dst, src, fcc_offset);
1035 tcg_gen_xori_tl(dst, dst, 0x1);
0425bee5
BS
1036 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1037 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1038}
1039
1040// 3: FCC0 & FCC1
1041static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1042 unsigned int fcc_offset)
1043{
19f329ad 1044 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1045 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1046 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1047}
1048
1049// 0: !(FCC0 | FCC1)
1050static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1051 unsigned int fcc_offset)
1052{
19f329ad 1053 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1054 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1055 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1056 tcg_gen_xori_tl(dst, dst, 0x1);
1057}
1058
1059// 0 or 3: !(FCC0 ^ FCC1)
1060static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1061 unsigned int fcc_offset)
1062{
19f329ad 1063 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1064 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1065 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1066 tcg_gen_xori_tl(dst, dst, 0x1);
1067}
1068
1069// 0 or 2: !FCC0
1070static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1071 unsigned int fcc_offset)
1072{
1073 gen_mov_reg_FCC0(dst, src, fcc_offset);
1074 tcg_gen_xori_tl(dst, dst, 0x1);
1075}
1076
1077// !1: !(FCC0 & !FCC1)
1078static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1079 unsigned int fcc_offset)
1080{
19f329ad 1081 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1082 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1083 tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1084 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1085 tcg_gen_xori_tl(dst, dst, 0x1);
1086}
1087
1088// 0 or 1: !FCC1
1089static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1090 unsigned int fcc_offset)
1091{
1092 gen_mov_reg_FCC1(dst, src, fcc_offset);
1093 tcg_gen_xori_tl(dst, dst, 0x1);
1094}
1095
1096// !2: !(!FCC0 & FCC1)
1097static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1098 unsigned int fcc_offset)
1099{
19f329ad
BS
1100 gen_mov_reg_FCC0(dst, src, fcc_offset);
1101 tcg_gen_xori_tl(dst, dst, 0x1);
0425bee5
BS
1102 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1103 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1104 tcg_gen_xori_tl(dst, dst, 0x1);
1105}
1106
1107// !3: !(FCC0 & FCC1)
1108static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1109 unsigned int fcc_offset)
1110{
19f329ad 1111 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1112 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1113 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1114 tcg_gen_xori_tl(dst, dst, 0x1);
1115}
1116
46525e1f 1117static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
19f329ad 1118 target_ulong pc2, TCGv r_cond)
83469015
FB
1119{
1120 int l1;
1121
1122 l1 = gen_new_label();
1123
0425bee5 1124 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
83469015 1125
6e256c93 1126 gen_goto_tb(dc, 0, pc1, pc1 + 4);
83469015
FB
1127
1128 gen_set_label(l1);
6e256c93 1129 gen_goto_tb(dc, 1, pc2, pc2 + 4);
83469015
FB
1130}
1131
46525e1f 1132static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
19f329ad 1133 target_ulong pc2, TCGv r_cond)
83469015
FB
1134{
1135 int l1;
1136
1137 l1 = gen_new_label();
1138
0425bee5 1139 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
83469015 1140
6e256c93 1141 gen_goto_tb(dc, 0, pc2, pc1);
83469015
FB
1142
1143 gen_set_label(l1);
6e256c93 1144 gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
83469015
FB
1145}
1146
19f329ad
BS
1147static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1148 TCGv r_cond)
83469015
FB
1149{
1150 int l1, l2;
1151
1152 l1 = gen_new_label();
1153 l2 = gen_new_label();
19f329ad 1154
0425bee5 1155 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
83469015 1156
2f5680ee 1157 tcg_gen_movi_tl(cpu_npc, npc1);
06b3e1b3 1158 tcg_gen_br(l2);
83469015
FB
1159
1160 gen_set_label(l1);
2f5680ee 1161 tcg_gen_movi_tl(cpu_npc, npc2);
83469015
FB
1162 gen_set_label(l2);
1163}
1164
4af984a7
BS
1165/* call this function before using the condition register as it may
1166 have been set for a jump */
1167static inline void flush_cond(DisasContext *dc, TCGv cond)
83469015
FB
1168{
1169 if (dc->npc == JUMP_PC) {
4af984a7 1170 gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
83469015
FB
1171 dc->npc = DYNAMIC_PC;
1172 }
1173}
1174
4af984a7 1175static inline void save_npc(DisasContext *dc, TCGv cond)
72cbca10
FB
1176{
1177 if (dc->npc == JUMP_PC) {
4af984a7 1178 gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
72cbca10
FB
1179 dc->npc = DYNAMIC_PC;
1180 } else if (dc->npc != DYNAMIC_PC) {
2f5680ee 1181 tcg_gen_movi_tl(cpu_npc, dc->npc);
72cbca10
FB
1182 }
1183}
1184
4af984a7 1185static inline void save_state(DisasContext *dc, TCGv cond)
72cbca10 1186{
2f5680ee 1187 tcg_gen_movi_tl(cpu_pc, dc->pc);
4af984a7 1188 save_npc(dc, cond);
72cbca10
FB
1189}
1190
4af984a7 1191static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
0bee699e
FB
1192{
1193 if (dc->npc == JUMP_PC) {
4af984a7 1194 gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
48d5c82b 1195 tcg_gen_mov_tl(cpu_pc, cpu_npc);
0bee699e
FB
1196 dc->pc = DYNAMIC_PC;
1197 } else if (dc->npc == DYNAMIC_PC) {
48d5c82b 1198 tcg_gen_mov_tl(cpu_pc, cpu_npc);
0bee699e
FB
1199 dc->pc = DYNAMIC_PC;
1200 } else {
1201 dc->pc = dc->npc;
1202 }
1203}
1204
38bc628b
BS
1205static inline void gen_op_next_insn(void)
1206{
48d5c82b
BS
1207 tcg_gen_mov_tl(cpu_pc, cpu_npc);
1208 tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
38bc628b
BS
1209}
1210
19f329ad
BS
1211static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1212{
1213 TCGv r_src;
3475187d 1214
3475187d 1215#ifdef TARGET_SPARC64
19f329ad 1216 if (cc)
dc99a3f2 1217 r_src = cpu_xcc;
19f329ad 1218 else
dc99a3f2 1219 r_src = cpu_psr;
3475187d 1220#else
dc99a3f2 1221 r_src = cpu_psr;
3475187d 1222#endif
19f329ad
BS
1223 switch (cond) {
1224 case 0x0:
1225 gen_op_eval_bn(r_dst);
1226 break;
1227 case 0x1:
1228 gen_op_eval_be(r_dst, r_src);
1229 break;
1230 case 0x2:
1231 gen_op_eval_ble(r_dst, r_src);
1232 break;
1233 case 0x3:
1234 gen_op_eval_bl(r_dst, r_src);
1235 break;
1236 case 0x4:
1237 gen_op_eval_bleu(r_dst, r_src);
1238 break;
1239 case 0x5:
1240 gen_op_eval_bcs(r_dst, r_src);
1241 break;
1242 case 0x6:
1243 gen_op_eval_bneg(r_dst, r_src);
1244 break;
1245 case 0x7:
1246 gen_op_eval_bvs(r_dst, r_src);
1247 break;
1248 case 0x8:
1249 gen_op_eval_ba(r_dst);
1250 break;
1251 case 0x9:
1252 gen_op_eval_bne(r_dst, r_src);
1253 break;
1254 case 0xa:
1255 gen_op_eval_bg(r_dst, r_src);
1256 break;
1257 case 0xb:
1258 gen_op_eval_bge(r_dst, r_src);
1259 break;
1260 case 0xc:
1261 gen_op_eval_bgu(r_dst, r_src);
1262 break;
1263 case 0xd:
1264 gen_op_eval_bcc(r_dst, r_src);
1265 break;
1266 case 0xe:
1267 gen_op_eval_bpos(r_dst, r_src);
1268 break;
1269 case 0xf:
1270 gen_op_eval_bvc(r_dst, r_src);
1271 break;
1272 }
1273}
7a3f1944 1274
19f329ad 1275static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
e8af50a3 1276{
19f329ad
BS
1277 unsigned int offset;
1278
19f329ad
BS
1279 switch (cc) {
1280 default:
1281 case 0x0:
1282 offset = 0;
1283 break;
1284 case 0x1:
1285 offset = 32 - 10;
1286 break;
1287 case 0x2:
1288 offset = 34 - 10;
1289 break;
1290 case 0x3:
1291 offset = 36 - 10;
1292 break;
1293 }
1294
1295 switch (cond) {
1296 case 0x0:
1297 gen_op_eval_bn(r_dst);
1298 break;
1299 case 0x1:
87e92502 1300 gen_op_eval_fbne(r_dst, cpu_fsr, offset);
19f329ad
BS
1301 break;
1302 case 0x2:
87e92502 1303 gen_op_eval_fblg(r_dst, cpu_fsr, offset);
19f329ad
BS
1304 break;
1305 case 0x3:
87e92502 1306 gen_op_eval_fbul(r_dst, cpu_fsr, offset);
19f329ad
BS
1307 break;
1308 case 0x4:
87e92502 1309 gen_op_eval_fbl(r_dst, cpu_fsr, offset);
19f329ad
BS
1310 break;
1311 case 0x5:
87e92502 1312 gen_op_eval_fbug(r_dst, cpu_fsr, offset);
19f329ad
BS
1313 break;
1314 case 0x6:
87e92502 1315 gen_op_eval_fbg(r_dst, cpu_fsr, offset);
19f329ad
BS
1316 break;
1317 case 0x7:
87e92502 1318 gen_op_eval_fbu(r_dst, cpu_fsr, offset);
19f329ad
BS
1319 break;
1320 case 0x8:
1321 gen_op_eval_ba(r_dst);
1322 break;
1323 case 0x9:
87e92502 1324 gen_op_eval_fbe(r_dst, cpu_fsr, offset);
19f329ad
BS
1325 break;
1326 case 0xa:
87e92502 1327 gen_op_eval_fbue(r_dst, cpu_fsr, offset);
19f329ad
BS
1328 break;
1329 case 0xb:
87e92502 1330 gen_op_eval_fbge(r_dst, cpu_fsr, offset);
19f329ad
BS
1331 break;
1332 case 0xc:
87e92502 1333 gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
19f329ad
BS
1334 break;
1335 case 0xd:
87e92502 1336 gen_op_eval_fble(r_dst, cpu_fsr, offset);
19f329ad
BS
1337 break;
1338 case 0xe:
87e92502 1339 gen_op_eval_fbule(r_dst, cpu_fsr, offset);
19f329ad
BS
1340 break;
1341 case 0xf:
87e92502 1342 gen_op_eval_fbo(r_dst, cpu_fsr, offset);
19f329ad
BS
1343 break;
1344 }
e8af50a3 1345}
00f219bf 1346
19f329ad 1347#ifdef TARGET_SPARC64
00f219bf
BS
1348// Inverted logic
1349static const int gen_tcg_cond_reg[8] = {
1350 -1,
1351 TCG_COND_NE,
1352 TCG_COND_GT,
1353 TCG_COND_GE,
1354 -1,
1355 TCG_COND_EQ,
1356 TCG_COND_LE,
1357 TCG_COND_LT,
1358};
19f329ad 1359
4af984a7 1360static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
19f329ad 1361{
19f329ad
BS
1362 int l1;
1363
1364 l1 = gen_new_label();
0425bee5 1365 tcg_gen_movi_tl(r_dst, 0);
4af984a7 1366 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], r_src, tcg_const_tl(0), l1);
19f329ad
BS
1367 tcg_gen_movi_tl(r_dst, 1);
1368 gen_set_label(l1);
1369}
3475187d 1370#endif
cf495bcf 1371
0bee699e 1372/* XXX: potentially incorrect if dynamic npc */
4af984a7
BS
1373static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1374 TCGv r_cond)
7a3f1944 1375{
cf495bcf 1376 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
af7bf89b 1377 target_ulong target = dc->pc + offset;
5fafdf24 1378
cf495bcf 1379 if (cond == 0x0) {
0f8a249a
BS
1380 /* unconditional not taken */
1381 if (a) {
1382 dc->pc = dc->npc + 4;
1383 dc->npc = dc->pc + 4;
1384 } else {
1385 dc->pc = dc->npc;
1386 dc->npc = dc->pc + 4;
1387 }
cf495bcf 1388 } else if (cond == 0x8) {
0f8a249a
BS
1389 /* unconditional taken */
1390 if (a) {
1391 dc->pc = target;
1392 dc->npc = dc->pc + 4;
1393 } else {
1394 dc->pc = dc->npc;
1395 dc->npc = target;
1396 }
cf495bcf 1397 } else {
4af984a7
BS
1398 flush_cond(dc, r_cond);
1399 gen_cond(r_cond, cc, cond);
0f8a249a 1400 if (a) {
4af984a7 1401 gen_branch_a(dc, target, dc->npc, r_cond);
cf495bcf 1402 dc->is_br = 1;
0f8a249a 1403 } else {
cf495bcf 1404 dc->pc = dc->npc;
72cbca10
FB
1405 dc->jump_pc[0] = target;
1406 dc->jump_pc[1] = dc->npc + 4;
1407 dc->npc = JUMP_PC;
0f8a249a 1408 }
cf495bcf 1409 }
7a3f1944
FB
1410}
1411
0bee699e 1412/* XXX: potentially incorrect if dynamic npc */
4af984a7
BS
1413static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1414 TCGv r_cond)
e8af50a3
FB
1415{
1416 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
af7bf89b
FB
1417 target_ulong target = dc->pc + offset;
1418
e8af50a3 1419 if (cond == 0x0) {
0f8a249a
BS
1420 /* unconditional not taken */
1421 if (a) {
1422 dc->pc = dc->npc + 4;
1423 dc->npc = dc->pc + 4;
1424 } else {
1425 dc->pc = dc->npc;
1426 dc->npc = dc->pc + 4;
1427 }
e8af50a3 1428 } else if (cond == 0x8) {
0f8a249a
BS
1429 /* unconditional taken */
1430 if (a) {
1431 dc->pc = target;
1432 dc->npc = dc->pc + 4;
1433 } else {
1434 dc->pc = dc->npc;
1435 dc->npc = target;
1436 }
e8af50a3 1437 } else {
4af984a7
BS
1438 flush_cond(dc, r_cond);
1439 gen_fcond(r_cond, cc, cond);
0f8a249a 1440 if (a) {
4af984a7 1441 gen_branch_a(dc, target, dc->npc, r_cond);
e8af50a3 1442 dc->is_br = 1;
0f8a249a 1443 } else {
e8af50a3
FB
1444 dc->pc = dc->npc;
1445 dc->jump_pc[0] = target;
1446 dc->jump_pc[1] = dc->npc + 4;
1447 dc->npc = JUMP_PC;
0f8a249a 1448 }
e8af50a3
FB
1449 }
1450}
1451
3475187d
FB
1452#ifdef TARGET_SPARC64
1453/* XXX: potentially incorrect if dynamic npc */
4af984a7
BS
1454static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1455 TCGv r_cond, TCGv r_reg)
7a3f1944 1456{
3475187d
FB
1457 unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1458 target_ulong target = dc->pc + offset;
1459
4af984a7
BS
1460 flush_cond(dc, r_cond);
1461 gen_cond_reg(r_cond, cond, r_reg);
3475187d 1462 if (a) {
4af984a7 1463 gen_branch_a(dc, target, dc->npc, r_cond);
0f8a249a 1464 dc->is_br = 1;
3475187d 1465 } else {
0f8a249a
BS
1466 dc->pc = dc->npc;
1467 dc->jump_pc[0] = target;
1468 dc->jump_pc[1] = dc->npc + 4;
1469 dc->npc = JUMP_PC;
3475187d 1470 }
7a3f1944
FB
1471}
1472
3475187d 1473static GenOpFunc * const gen_fcmps[4] = {
7e8c2b6c
BS
1474 helper_fcmps,
1475 helper_fcmps_fcc1,
1476 helper_fcmps_fcc2,
1477 helper_fcmps_fcc3,
3475187d
FB
1478};
1479
1480static GenOpFunc * const gen_fcmpd[4] = {
7e8c2b6c
BS
1481 helper_fcmpd,
1482 helper_fcmpd_fcc1,
1483 helper_fcmpd_fcc2,
1484 helper_fcmpd_fcc3,
3475187d 1485};
417454b0 1486
1f587329
BS
1487#if defined(CONFIG_USER_ONLY)
1488static GenOpFunc * const gen_fcmpq[4] = {
7e8c2b6c
BS
1489 helper_fcmpq,
1490 helper_fcmpq_fcc1,
1491 helper_fcmpq_fcc2,
1492 helper_fcmpq_fcc3,
1f587329
BS
1493};
1494#endif
1495
417454b0 1496static GenOpFunc * const gen_fcmpes[4] = {
7e8c2b6c
BS
1497 helper_fcmpes,
1498 helper_fcmpes_fcc1,
1499 helper_fcmpes_fcc2,
1500 helper_fcmpes_fcc3,
417454b0
BS
1501};
1502
1503static GenOpFunc * const gen_fcmped[4] = {
7e8c2b6c
BS
1504 helper_fcmped,
1505 helper_fcmped_fcc1,
1506 helper_fcmped_fcc2,
1507 helper_fcmped_fcc3,
417454b0
BS
1508};
1509
1f587329
BS
1510#if defined(CONFIG_USER_ONLY)
1511static GenOpFunc * const gen_fcmpeq[4] = {
7e8c2b6c
BS
1512 helper_fcmpeq,
1513 helper_fcmpeq_fcc1,
1514 helper_fcmpeq_fcc2,
1515 helper_fcmpeq_fcc3,
1f587329
BS
1516};
1517#endif
7e8c2b6c
BS
1518
1519static inline void gen_op_fcmps(int fccno)
1520{
1521 tcg_gen_helper_0_0(gen_fcmps[fccno]);
1522}
1523
1524static inline void gen_op_fcmpd(int fccno)
1525{
1526 tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1527}
1528
1529#if defined(CONFIG_USER_ONLY)
1530static inline void gen_op_fcmpq(int fccno)
1531{
1532 tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1533}
1534#endif
1535
1536static inline void gen_op_fcmpes(int fccno)
1537{
1538 tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1539}
1540
1541static inline void gen_op_fcmped(int fccno)
1542{
1543 tcg_gen_helper_0_0(gen_fcmped[fccno]);
1544}
1545
1546#if defined(CONFIG_USER_ONLY)
1547static inline void gen_op_fcmpeq(int fccno)
1548{
1549 tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1550}
1551#endif
1552
1553#else
1554
1555static inline void gen_op_fcmps(int fccno)
1556{
1557 tcg_gen_helper_0_0(helper_fcmps);
1558}
1559
1560static inline void gen_op_fcmpd(int fccno)
1561{
1562 tcg_gen_helper_0_0(helper_fcmpd);
1563}
1564
1565#if defined(CONFIG_USER_ONLY)
1566static inline void gen_op_fcmpq(int fccno)
1567{
1568 tcg_gen_helper_0_0(helper_fcmpq);
1569}
1570#endif
1571
1572static inline void gen_op_fcmpes(int fccno)
1573{
1574 tcg_gen_helper_0_0(helper_fcmpes);
1575}
1576
1577static inline void gen_op_fcmped(int fccno)
1578{
1579 tcg_gen_helper_0_0(helper_fcmped);
1580}
1581
1582#if defined(CONFIG_USER_ONLY)
1583static inline void gen_op_fcmpeq(int fccno)
1584{
1585 tcg_gen_helper_0_0(helper_fcmpeq);
1586}
1587#endif
1588
3475187d
FB
1589#endif
1590
134d77a1
BS
1591static inline void gen_op_fpexception_im(int fsr_flags)
1592{
87e92502
BS
1593 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1594 tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
2f5680ee 1595 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
134d77a1
BS
1596}
1597
4af984a7 1598static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
a80dde08
FB
1599{
1600#if !defined(CONFIG_USER_ONLY)
1601 if (!dc->fpu_enabled) {
4af984a7 1602 save_state(dc, r_cond);
2f5680ee 1603 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
a80dde08
FB
1604 dc->is_br = 1;
1605 return 1;
1606 }
1607#endif
1608 return 0;
1609}
1610
7e8c2b6c
BS
1611static inline void gen_op_clear_ieee_excp_and_FTT(void)
1612{
87e92502 1613 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
7e8c2b6c
BS
1614}
1615
1616static inline void gen_clear_float_exceptions(void)
1617{
1618 tcg_gen_helper_0_0(helper_clear_float_exceptions);
1619}
1620
1a2fb1c0
BS
1621/* asi moves */
1622#ifdef TARGET_SPARC64
0425bee5 1623static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1a2fb1c0
BS
1624{
1625 int asi, offset;
0425bee5 1626 TCGv r_asi;
1a2fb1c0 1627
1a2fb1c0 1628 if (IS_IMM) {
0425bee5 1629 r_asi = tcg_temp_new(TCG_TYPE_I32);
1a2fb1c0 1630 offset = GET_FIELD(insn, 25, 31);
0425bee5
BS
1631 tcg_gen_addi_tl(r_addr, r_addr, offset);
1632 tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1a2fb1c0
BS
1633 } else {
1634 asi = GET_FIELD(insn, 19, 26);
0425bee5 1635 r_asi = tcg_const_i32(asi);
1a2fb1c0 1636 }
0425bee5
BS
1637 return r_asi;
1638}
1639
4af984a7 1640static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
0425bee5
BS
1641{
1642 TCGv r_asi;
1643
4af984a7
BS
1644 r_asi = gen_get_asi(insn, addr);
1645 tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi,
0425bee5 1646 tcg_const_i32(size), tcg_const_i32(sign));
1a2fb1c0
BS
1647}
1648
4af984a7 1649static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1a2fb1c0 1650{
0425bee5 1651 TCGv r_asi;
1a2fb1c0 1652
4af984a7
BS
1653 r_asi = gen_get_asi(insn, addr);
1654 tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, tcg_const_i32(size));
1a2fb1c0
BS
1655}
1656
4af984a7 1657static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1a2fb1c0 1658{
0425bee5 1659 TCGv r_asi;
1a2fb1c0 1660
4af984a7
BS
1661 r_asi = gen_get_asi(insn, addr);
1662 tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, tcg_const_i32(size),
0425bee5 1663 tcg_const_i32(rd));
1a2fb1c0
BS
1664}
1665
4af984a7 1666static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1a2fb1c0 1667{
0425bee5 1668 TCGv r_asi;
1a2fb1c0 1669
31741a27
BS
1670 r_asi = gen_get_asi(insn, addr);
1671 tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, tcg_const_i32(size),
0425bee5 1672 tcg_const_i32(rd));
1a2fb1c0
BS
1673}
1674
4af984a7 1675static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1a2fb1c0 1676{
0425bee5 1677 TCGv r_temp, r_asi;
1a2fb1c0 1678
1a2fb1c0 1679 r_temp = tcg_temp_new(TCG_TYPE_I32);
4af984a7
BS
1680 r_asi = gen_get_asi(insn, addr);
1681 tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, r_asi,
0425bee5 1682 tcg_const_i32(4), tcg_const_i32(0));
4af984a7 1683 tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi,
0425bee5 1684 tcg_const_i32(4));
4af984a7 1685 tcg_gen_extu_i32_tl(dst, r_temp);
1a2fb1c0
BS
1686}
1687
4af984a7 1688static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1a2fb1c0 1689{
8911f501 1690 TCGv r_asi;
1a2fb1c0 1691
4af984a7
BS
1692 r_asi = gen_get_asi(insn, addr);
1693 tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi,
0425bee5 1694 tcg_const_i32(8), tcg_const_i32(0));
4af984a7 1695 tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
8911f501 1696 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4af984a7 1697 tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
0425bee5
BS
1698}
1699
4af984a7 1700static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
0425bee5 1701{
8911f501 1702 TCGv r_temp, r_asi;
0425bee5 1703
0425bee5
BS
1704 r_temp = tcg_temp_new(TCG_TYPE_I32);
1705 gen_movl_reg_TN(rd + 1, r_temp);
4af984a7 1706 tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
0425bee5 1707 r_temp);
4af984a7
BS
1708 r_asi = gen_get_asi(insn, addr);
1709 tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi,
0425bee5 1710 tcg_const_i32(8));
1a2fb1c0
BS
1711}
1712
4af984a7 1713static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1a2fb1c0 1714{
1a2fb1c0
BS
1715 TCGv r_val1, r_asi;
1716
1717 r_val1 = tcg_temp_new(TCG_TYPE_I32);
1a2fb1c0 1718 gen_movl_reg_TN(rd, r_val1);
4af984a7
BS
1719 r_asi = gen_get_asi(insn, addr);
1720 tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1a2fb1c0
BS
1721}
1722
4af984a7 1723static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1a2fb1c0 1724{
8911f501 1725 TCGv r_asi;
1a2fb1c0 1726
8911f501 1727 gen_movl_reg_TN(rd, cpu_tmp64);
4af984a7
BS
1728 r_asi = gen_get_asi(insn, addr);
1729 tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1a2fb1c0
BS
1730}
1731
1732#elif !defined(CONFIG_USER_ONLY)
1733
4af984a7 1734static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1a2fb1c0
BS
1735{
1736 int asi;
1a2fb1c0 1737
1a2fb1c0 1738 asi = GET_FIELD(insn, 19, 26);
4af984a7 1739 tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
0425bee5 1740 tcg_const_i32(size), tcg_const_i32(sign));
4af984a7 1741 tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1a2fb1c0
BS
1742}
1743
4af984a7 1744static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1a2fb1c0
BS
1745{
1746 int asi;
1a2fb1c0 1747
4af984a7 1748 tcg_gen_extu_tl_i64(cpu_tmp64, src);
1a2fb1c0 1749 asi = GET_FIELD(insn, 19, 26);
4af984a7 1750 tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
0425bee5 1751 tcg_const_i32(size));
1a2fb1c0
BS
1752}
1753
4af984a7 1754static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1a2fb1c0
BS
1755{
1756 int asi;
0425bee5 1757 TCGv r_temp;
1a2fb1c0 1758
1a2fb1c0 1759 r_temp = tcg_temp_new(TCG_TYPE_I32);
1a2fb1c0 1760 asi = GET_FIELD(insn, 19, 26);
4af984a7 1761 tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, tcg_const_i32(asi),
0425bee5 1762 tcg_const_i32(4), tcg_const_i32(0));
4af984a7 1763 tcg_gen_helper_0_4(helper_st_asi, addr, dst, tcg_const_i32(asi),
0425bee5 1764 tcg_const_i32(4));
4af984a7 1765 tcg_gen_extu_i32_tl(dst, r_temp);
1a2fb1c0
BS
1766}
1767
4af984a7 1768static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1a2fb1c0
BS
1769{
1770 int asi;
1a2fb1c0 1771
1a2fb1c0 1772 asi = GET_FIELD(insn, 19, 26);
4af984a7 1773 tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
0425bee5 1774 tcg_const_i32(8), tcg_const_i32(0));
4af984a7 1775 tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
8911f501 1776 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4af984a7 1777 tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
0425bee5
BS
1778}
1779
4af984a7 1780static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
0425bee5
BS
1781{
1782 int asi;
8911f501 1783 TCGv r_temp;
0425bee5 1784
0425bee5
BS
1785 r_temp = tcg_temp_new(TCG_TYPE_I32);
1786 gen_movl_reg_TN(rd + 1, r_temp);
4af984a7 1787 tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
0425bee5 1788 asi = GET_FIELD(insn, 19, 26);
4af984a7 1789 tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
0425bee5 1790 tcg_const_i32(8));
1a2fb1c0
BS
1791}
1792#endif
1793
1794#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4af984a7 1795static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1a2fb1c0
BS
1796{
1797 int asi;
1a2fb1c0 1798
4af984a7 1799 gen_ld_asi(dst, addr, insn, 1, 0);
1a2fb1c0 1800
1a2fb1c0 1801 asi = GET_FIELD(insn, 19, 26);
4af984a7 1802 tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL),
0425bee5 1803 tcg_const_i32(asi), tcg_const_i32(1));
1a2fb1c0
BS
1804}
1805#endif
1806
9322a4bf
BS
1807static inline TCGv get_src1(unsigned int insn, TCGv def)
1808{
1809 TCGv r_rs1 = def;
1810 unsigned int rs1;
1811
1812 rs1 = GET_FIELD(insn, 13, 17);
1813 if (rs1 == 0)
1814 //r_rs1 = tcg_const_tl(0);
1815 tcg_gen_movi_tl(def, 0);
1816 else if (rs1 < 8)
1817 //r_rs1 = cpu_gregs[rs1];
1818 tcg_gen_mov_tl(def, cpu_gregs[rs1]);
1819 else
1820 tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1821 return r_rs1;
1822}
1823
a49d9390
BS
1824static inline TCGv get_src2(unsigned int insn, TCGv def)
1825{
1826 TCGv r_rs2 = def;
1827 unsigned int rs2;
1828
1829 if (IS_IMM) { /* immediate */
1830 rs2 = GET_FIELDs(insn, 19, 31);
1831 r_rs2 = tcg_const_tl((int)rs2);
1832 } else { /* register */
1833 rs2 = GET_FIELD(insn, 27, 31);
1834 if (rs2 == 0)
1835 r_rs2 = tcg_const_tl(0);
1836 else if (rs2 < 8)
1837 r_rs2 = cpu_gregs[rs2];
1838 else
1839 tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1840 }
1841 return r_rs2;
1842}
1843
0bee699e 1844/* before an instruction, dc->pc must be static */
cf495bcf
FB
1845static void disas_sparc_insn(DisasContext * dc)
1846{
1847 unsigned int insn, opc, rs1, rs2, rd;
7a3f1944 1848
0fa85d43 1849 insn = ldl_code(dc->pc);
cf495bcf 1850 opc = GET_FIELD(insn, 0, 1);
7a3f1944 1851
cf495bcf 1852 rd = GET_FIELD(insn, 2, 6);
6ae20372
BS
1853
1854 cpu_dst = cpu_T[0];
1855 cpu_src1 = cpu_T[0]; // const
1856 cpu_src2 = cpu_T[1]; // const
1857
1858 // loads and stores
1859 cpu_addr = cpu_T[0];
1860 cpu_val = cpu_T[1];
1861
cf495bcf 1862 switch (opc) {
0f8a249a
BS
1863 case 0: /* branches/sethi */
1864 {
1865 unsigned int xop = GET_FIELD(insn, 7, 9);
1866 int32_t target;
1867 switch (xop) {
3475187d 1868#ifdef TARGET_SPARC64
0f8a249a
BS
1869 case 0x1: /* V9 BPcc */
1870 {
1871 int cc;
1872
1873 target = GET_FIELD_SP(insn, 0, 18);
1874 target = sign_extend(target, 18);
1875 target <<= 2;
1876 cc = GET_FIELD_SP(insn, 20, 21);
1877 if (cc == 0)
6ae20372 1878 do_branch(dc, target, insn, 0, cpu_cond);
0f8a249a 1879 else if (cc == 2)
6ae20372 1880 do_branch(dc, target, insn, 1, cpu_cond);
0f8a249a
BS
1881 else
1882 goto illegal_insn;
1883 goto jmp_insn;
1884 }
1885 case 0x3: /* V9 BPr */
1886 {
1887 target = GET_FIELD_SP(insn, 0, 13) |
13846e70 1888 (GET_FIELD_SP(insn, 20, 21) << 14);
0f8a249a
BS
1889 target = sign_extend(target, 16);
1890 target <<= 2;
9322a4bf 1891 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 1892 do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
0f8a249a
BS
1893 goto jmp_insn;
1894 }
1895 case 0x5: /* V9 FBPcc */
1896 {
1897 int cc = GET_FIELD_SP(insn, 20, 21);
6ae20372 1898 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 1899 goto jmp_insn;
0f8a249a
BS
1900 target = GET_FIELD_SP(insn, 0, 18);
1901 target = sign_extend(target, 19);
1902 target <<= 2;
6ae20372 1903 do_fbranch(dc, target, insn, cc, cpu_cond);
0f8a249a
BS
1904 goto jmp_insn;
1905 }
a4d17f19 1906#else
0f8a249a
BS
1907 case 0x7: /* CBN+x */
1908 {
1909 goto ncp_insn;
1910 }
1911#endif
1912 case 0x2: /* BN+x */
1913 {
1914 target = GET_FIELD(insn, 10, 31);
1915 target = sign_extend(target, 22);
1916 target <<= 2;
6ae20372 1917 do_branch(dc, target, insn, 0, cpu_cond);
0f8a249a
BS
1918 goto jmp_insn;
1919 }
1920 case 0x6: /* FBN+x */
1921 {
6ae20372 1922 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 1923 goto jmp_insn;
0f8a249a
BS
1924 target = GET_FIELD(insn, 10, 31);
1925 target = sign_extend(target, 22);
1926 target <<= 2;
6ae20372 1927 do_fbranch(dc, target, insn, 0, cpu_cond);
0f8a249a
BS
1928 goto jmp_insn;
1929 }
1930 case 0x4: /* SETHI */
0f8a249a 1931 if (rd) { // nop
0f8a249a 1932 uint32_t value = GET_FIELD(insn, 10, 31);
6ae20372
BS
1933 tcg_gen_movi_tl(cpu_dst, value << 10);
1934 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 1935 }
0f8a249a
BS
1936 break;
1937 case 0x0: /* UNIMPL */
1938 default:
3475187d 1939 goto illegal_insn;
0f8a249a
BS
1940 }
1941 break;
1942 }
1943 break;
cf495bcf 1944 case 1:
0f8a249a
BS
1945 /*CALL*/ {
1946 target_long target = GET_FIELDs(insn, 2, 31) << 2;
cf495bcf 1947
48d5c82b 1948 gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
0f8a249a 1949 target += dc->pc;
6ae20372 1950 gen_mov_pc_npc(dc, cpu_cond);
0f8a249a
BS
1951 dc->npc = target;
1952 }
1953 goto jmp_insn;
1954 case 2: /* FPU & Logical Operations */
1955 {
1956 unsigned int xop = GET_FIELD(insn, 7, 12);
1957 if (xop == 0x3a) { /* generate trap */
cf495bcf 1958 int cond;
3475187d 1959
9322a4bf 1960 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a
BS
1961 if (IS_IMM) {
1962 rs2 = GET_FIELD(insn, 25, 31);
6ae20372 1963 tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
cf495bcf
FB
1964 } else {
1965 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 1966 if (rs2 != 0) {
6ae20372
BS
1967 gen_movl_reg_TN(rs2, cpu_src2);
1968 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
1969 } else
1970 tcg_gen_mov_tl(cpu_dst, cpu_src1);
cf495bcf 1971 }
cf495bcf
FB
1972 cond = GET_FIELD(insn, 3, 6);
1973 if (cond == 0x8) {
6ae20372
BS
1974 save_state(dc, cpu_cond);
1975 tcg_gen_helper_0_1(helper_trap, cpu_dst);
af7bf89b 1976 } else if (cond != 0) {
748b9d8e 1977 TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
3475187d 1978#ifdef TARGET_SPARC64
0f8a249a
BS
1979 /* V9 icc/xcc */
1980 int cc = GET_FIELD_SP(insn, 11, 12);
748b9d8e 1981
6ae20372 1982 save_state(dc, cpu_cond);
0f8a249a 1983 if (cc == 0)
748b9d8e 1984 gen_cond(r_cond, 0, cond);
0f8a249a 1985 else if (cc == 2)
748b9d8e 1986 gen_cond(r_cond, 1, cond);
0f8a249a
BS
1987 else
1988 goto illegal_insn;
3475187d 1989#else
6ae20372 1990 save_state(dc, cpu_cond);
748b9d8e 1991 gen_cond(r_cond, 0, cond);
3475187d 1992#endif
6ae20372 1993 tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
cf495bcf 1994 }
a80dde08 1995 gen_op_next_insn();
57fec1fe 1996 tcg_gen_exit_tb(0);
a80dde08
FB
1997 dc->is_br = 1;
1998 goto jmp_insn;
cf495bcf
FB
1999 } else if (xop == 0x28) {
2000 rs1 = GET_FIELD(insn, 13, 17);
2001 switch(rs1) {
2002 case 0: /* rdy */
65fe7b09
BS
2003#ifndef TARGET_SPARC64
2004 case 0x01 ... 0x0e: /* undefined in the SPARCv8
2005 manual, rdy on the microSPARC
2006 II */
2007 case 0x0f: /* stbar in the SPARCv8 manual,
2008 rdy on the microSPARC II */
2009 case 0x10 ... 0x1f: /* implementation-dependent in the
2010 SPARCv8 manual, rdy on the
2011 microSPARC II */
2012#endif
6ae20372
BS
2013 tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, y));
2014 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 2015 break;
3475187d 2016#ifdef TARGET_SPARC64
0f8a249a 2017 case 0x2: /* V9 rdccr */
6ae20372
BS
2018 tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
2019 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2020 break;
0f8a249a 2021 case 0x3: /* V9 rdasi */
2f5680ee 2022 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi));
6ae20372
BS
2023 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2024 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2025 break;
0f8a249a 2026 case 0x4: /* V9 rdtick */
ccd4a219
BS
2027 {
2028 TCGv r_tickptr;
2029
2030 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2031 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2032 offsetof(CPUState, tick));
6ae20372 2033 tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
ccd4a219 2034 r_tickptr);
6ae20372 2035 gen_movl_TN_reg(rd, cpu_dst);
ccd4a219 2036 }
3475187d 2037 break;
0f8a249a 2038 case 0x5: /* V9 rdpc */
6ae20372
BS
2039 tcg_gen_movi_tl(cpu_dst, dc->pc);
2040 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
2041 break;
2042 case 0x6: /* V9 rdfprs */
2f5680ee 2043 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
6ae20372
BS
2044 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2045 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2046 break;
65fe7b09
BS
2047 case 0xf: /* V9 membar */
2048 break; /* no effect */
0f8a249a 2049 case 0x13: /* Graphics Status */
6ae20372 2050 if (gen_trap_ifnofpu(dc, cpu_cond))
725cb90b 2051 goto jmp_insn;
6ae20372
BS
2052 tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr));
2053 gen_movl_TN_reg(rd, cpu_dst);
725cb90b 2054 break;
0f8a249a 2055 case 0x17: /* Tick compare */
6ae20372
BS
2056 tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tick_cmpr));
2057 gen_movl_TN_reg(rd, cpu_dst);
83469015 2058 break;
0f8a249a 2059 case 0x18: /* System tick */
ccd4a219
BS
2060 {
2061 TCGv r_tickptr;
2062
2063 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2064 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2065 offsetof(CPUState, stick));
6ae20372 2066 tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
ccd4a219 2067 r_tickptr);
6ae20372 2068 gen_movl_TN_reg(rd, cpu_dst);
ccd4a219 2069 }
83469015 2070 break;
0f8a249a 2071 case 0x19: /* System tick compare */
6ae20372
BS
2072 tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, stick_cmpr));
2073 gen_movl_TN_reg(rd, cpu_dst);
83469015 2074 break;
0f8a249a
BS
2075 case 0x10: /* Performance Control */
2076 case 0x11: /* Performance Instrumentation Counter */
2077 case 0x12: /* Dispatch Control */
2078 case 0x14: /* Softint set, WO */
2079 case 0x15: /* Softint clear, WO */
2080 case 0x16: /* Softint write */
3475187d
FB
2081#endif
2082 default:
cf495bcf
FB
2083 goto illegal_insn;
2084 }
e8af50a3 2085#if !defined(CONFIG_USER_ONLY)
e9ebed4d 2086 } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
3475187d 2087#ifndef TARGET_SPARC64
0f8a249a
BS
2088 if (!supervisor(dc))
2089 goto priv_insn;
6ae20372 2090 tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
e9ebed4d
BS
2091#else
2092 if (!hypervisor(dc))
2093 goto priv_insn;
2094 rs1 = GET_FIELD(insn, 13, 17);
2095 switch (rs1) {
2096 case 0: // hpstate
2097 // gen_op_rdhpstate();
2098 break;
2099 case 1: // htstate
2100 // gen_op_rdhtstate();
2101 break;
2102 case 3: // hintp
2f5680ee 2103 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
6ae20372 2104 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
e9ebed4d
BS
2105 break;
2106 case 5: // htba
2f5680ee 2107 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
6ae20372 2108 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
e9ebed4d
BS
2109 break;
2110 case 6: // hver
2f5680ee 2111 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hver));
6ae20372 2112 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
e9ebed4d
BS
2113 break;
2114 case 31: // hstick_cmpr
6ae20372 2115 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 2116 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hstick_cmpr));
e9ebed4d
BS
2117 break;
2118 default:
2119 goto illegal_insn;
2120 }
2121#endif
6ae20372 2122 gen_movl_TN_reg(rd, cpu_dst);
e8af50a3 2123 break;
3475187d 2124 } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
0f8a249a
BS
2125 if (!supervisor(dc))
2126 goto priv_insn;
3475187d
FB
2127#ifdef TARGET_SPARC64
2128 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2129 switch (rs1) {
2130 case 0: // tpc
375ee38b
BS
2131 {
2132 TCGv r_tsptr;
2133
2134 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2135 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2136 offsetof(CPUState, tsptr));
6ae20372 2137 tcg_gen_ld_tl(cpu_dst, r_tsptr,
375ee38b
BS
2138 offsetof(trap_state, tpc));
2139 }
0f8a249a
BS
2140 break;
2141 case 1: // tnpc
375ee38b
BS
2142 {
2143 TCGv r_tsptr;
2144
2145 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2146 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2147 offsetof(CPUState, tsptr));
6ae20372 2148 tcg_gen_ld_tl(cpu_dst, r_tsptr,
375ee38b
BS
2149 offsetof(trap_state, tnpc));
2150 }
0f8a249a
BS
2151 break;
2152 case 2: // tstate
375ee38b
BS
2153 {
2154 TCGv r_tsptr;
2155
2156 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2157 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2158 offsetof(CPUState, tsptr));
6ae20372 2159 tcg_gen_ld_tl(cpu_dst, r_tsptr,
375ee38b
BS
2160 offsetof(trap_state, tstate));
2161 }
0f8a249a
BS
2162 break;
2163 case 3: // tt
375ee38b
BS
2164 {
2165 TCGv r_tsptr;
2166
2167 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2168 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2169 offsetof(CPUState, tsptr));
6ae20372 2170 tcg_gen_ld_i32(cpu_dst, r_tsptr,
375ee38b
BS
2171 offsetof(trap_state, tt));
2172 }
0f8a249a
BS
2173 break;
2174 case 4: // tick
ccd4a219
BS
2175 {
2176 TCGv r_tickptr;
2177
2178 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2179 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2180 offsetof(CPUState, tick));
6ae20372 2181 tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
ccd4a219 2182 r_tickptr);
6ae20372 2183 gen_movl_TN_reg(rd, cpu_dst);
ccd4a219 2184 }
0f8a249a
BS
2185 break;
2186 case 5: // tba
6ae20372 2187 tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
0f8a249a
BS
2188 break;
2189 case 6: // pstate
2f5680ee 2190 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, pstate));
6ae20372 2191 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
0f8a249a
BS
2192 break;
2193 case 7: // tl
2f5680ee 2194 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl));
6ae20372 2195 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
0f8a249a
BS
2196 break;
2197 case 8: // pil
2f5680ee 2198 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil));
6ae20372 2199 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
0f8a249a
BS
2200 break;
2201 case 9: // cwp
6ae20372 2202 tcg_gen_helper_1_0(helper_rdcwp, cpu_dst);
0f8a249a
BS
2203 break;
2204 case 10: // cansave
2f5680ee 2205 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave));
6ae20372 2206 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
0f8a249a
BS
2207 break;
2208 case 11: // canrestore
2f5680ee 2209 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore));
6ae20372 2210 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
0f8a249a
BS
2211 break;
2212 case 12: // cleanwin
2f5680ee 2213 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin));
6ae20372 2214 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
0f8a249a
BS
2215 break;
2216 case 13: // otherwin
2f5680ee 2217 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin));
6ae20372 2218 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
0f8a249a
BS
2219 break;
2220 case 14: // wstate
2f5680ee 2221 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate));
6ae20372 2222 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
0f8a249a 2223 break;
e9ebed4d 2224 case 16: // UA2005 gl
2f5680ee 2225 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl));
6ae20372 2226 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
e9ebed4d
BS
2227 break;
2228 case 26: // UA2005 strand status
2229 if (!hypervisor(dc))
2230 goto priv_insn;
2f5680ee 2231 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr));
6ae20372 2232 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
e9ebed4d 2233 break;
0f8a249a 2234 case 31: // ver
6ae20372 2235 tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, version));
0f8a249a
BS
2236 break;
2237 case 15: // fq
2238 default:
2239 goto illegal_insn;
2240 }
3475187d 2241#else
2f5680ee 2242 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim));
6ae20372 2243 tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
3475187d 2244#endif
6ae20372 2245 gen_movl_TN_reg(rd, cpu_dst);
e8af50a3 2246 break;
3475187d
FB
2247 } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2248#ifdef TARGET_SPARC64
72a9747b 2249 tcg_gen_helper_0_0(helper_flushw);
3475187d 2250#else
0f8a249a
BS
2251 if (!supervisor(dc))
2252 goto priv_insn;
6ae20372
BS
2253 tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
2254 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2255#endif
e8af50a3
FB
2256 break;
2257#endif
0f8a249a 2258 } else if (xop == 0x34) { /* FPU Operations */
6ae20372 2259 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 2260 goto jmp_insn;
0f8a249a 2261 gen_op_clear_ieee_excp_and_FTT();
e8af50a3 2262 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2263 rs2 = GET_FIELD(insn, 27, 31);
2264 xop = GET_FIELD(insn, 18, 26);
2265 switch (xop) {
2266 case 0x1: /* fmovs */
2267 gen_op_load_fpr_FT0(rs2);
2268 gen_op_store_FT0_fpr(rd);
2269 break;
2270 case 0x5: /* fnegs */
2271 gen_op_load_fpr_FT1(rs2);
44e7757c 2272 tcg_gen_helper_0_0(helper_fnegs);
0f8a249a
BS
2273 gen_op_store_FT0_fpr(rd);
2274 break;
2275 case 0x9: /* fabss */
2276 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2277 tcg_gen_helper_0_0(helper_fabss);
0f8a249a
BS
2278 gen_op_store_FT0_fpr(rd);
2279 break;
2280 case 0x29: /* fsqrts */
2281 gen_op_load_fpr_FT1(rs2);
7e8c2b6c
BS
2282 gen_clear_float_exceptions();
2283 tcg_gen_helper_0_0(helper_fsqrts);
2284 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2285 gen_op_store_FT0_fpr(rd);
2286 break;
2287 case 0x2a: /* fsqrtd */
2288 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c
BS
2289 gen_clear_float_exceptions();
2290 tcg_gen_helper_0_0(helper_fsqrtd);
2291 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2292 gen_op_store_DT0_fpr(DFPREG(rd));
2293 break;
2294 case 0x2b: /* fsqrtq */
1f587329
BS
2295#if defined(CONFIG_USER_ONLY)
2296 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c
BS
2297 gen_clear_float_exceptions();
2298 tcg_gen_helper_0_0(helper_fsqrtq);
2299 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2300 gen_op_store_QT0_fpr(QFPREG(rd));
2301 break;
2302#else
0f8a249a 2303 goto nfpu_insn;
1f587329 2304#endif
0f8a249a
BS
2305 case 0x41:
2306 gen_op_load_fpr_FT0(rs1);
2307 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2308 gen_clear_float_exceptions();
44e7757c 2309 tcg_gen_helper_0_0(helper_fadds);
7e8c2b6c 2310 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2311 gen_op_store_FT0_fpr(rd);
2312 break;
2313 case 0x42:
2314 gen_op_load_fpr_DT0(DFPREG(rs1));
2315 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2316 gen_clear_float_exceptions();
44e7757c 2317 tcg_gen_helper_0_0(helper_faddd);
7e8c2b6c 2318 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2319 gen_op_store_DT0_fpr(DFPREG(rd));
2320 break;
2321 case 0x43: /* faddq */
1f587329
BS
2322#if defined(CONFIG_USER_ONLY)
2323 gen_op_load_fpr_QT0(QFPREG(rs1));
2324 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2325 gen_clear_float_exceptions();
44e7757c 2326 tcg_gen_helper_0_0(helper_faddq);
7e8c2b6c 2327 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2328 gen_op_store_QT0_fpr(QFPREG(rd));
2329 break;
2330#else
0f8a249a 2331 goto nfpu_insn;
1f587329 2332#endif
0f8a249a
BS
2333 case 0x45:
2334 gen_op_load_fpr_FT0(rs1);
2335 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2336 gen_clear_float_exceptions();
44e7757c 2337 tcg_gen_helper_0_0(helper_fsubs);
7e8c2b6c 2338 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2339 gen_op_store_FT0_fpr(rd);
2340 break;
2341 case 0x46:
2342 gen_op_load_fpr_DT0(DFPREG(rs1));
2343 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2344 gen_clear_float_exceptions();
44e7757c 2345 tcg_gen_helper_0_0(helper_fsubd);
7e8c2b6c 2346 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2347 gen_op_store_DT0_fpr(DFPREG(rd));
2348 break;
2349 case 0x47: /* fsubq */
1f587329
BS
2350#if defined(CONFIG_USER_ONLY)
2351 gen_op_load_fpr_QT0(QFPREG(rs1));
2352 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2353 gen_clear_float_exceptions();
44e7757c 2354 tcg_gen_helper_0_0(helper_fsubq);
7e8c2b6c 2355 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2356 gen_op_store_QT0_fpr(QFPREG(rd));
2357 break;
2358#else
0f8a249a 2359 goto nfpu_insn;
1f587329 2360#endif
0f8a249a
BS
2361 case 0x49:
2362 gen_op_load_fpr_FT0(rs1);
2363 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2364 gen_clear_float_exceptions();
44e7757c 2365 tcg_gen_helper_0_0(helper_fmuls);
7e8c2b6c 2366 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2367 gen_op_store_FT0_fpr(rd);
2368 break;
2369 case 0x4a:
2370 gen_op_load_fpr_DT0(DFPREG(rs1));
2371 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2372 gen_clear_float_exceptions();
44e7757c 2373 tcg_gen_helper_0_0(helper_fmuld);
7e8c2b6c 2374 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2382dc6b 2375 gen_op_store_DT0_fpr(DFPREG(rd));
0f8a249a
BS
2376 break;
2377 case 0x4b: /* fmulq */
1f587329
BS
2378#if defined(CONFIG_USER_ONLY)
2379 gen_op_load_fpr_QT0(QFPREG(rs1));
2380 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2381 gen_clear_float_exceptions();
44e7757c 2382 tcg_gen_helper_0_0(helper_fmulq);
7e8c2b6c 2383 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2384 gen_op_store_QT0_fpr(QFPREG(rd));
2385 break;
2386#else
0f8a249a 2387 goto nfpu_insn;
1f587329 2388#endif
0f8a249a
BS
2389 case 0x4d:
2390 gen_op_load_fpr_FT0(rs1);
2391 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2392 gen_clear_float_exceptions();
44e7757c 2393 tcg_gen_helper_0_0(helper_fdivs);
7e8c2b6c 2394 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2395 gen_op_store_FT0_fpr(rd);
2396 break;
2397 case 0x4e:
2398 gen_op_load_fpr_DT0(DFPREG(rs1));
2399 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2400 gen_clear_float_exceptions();
44e7757c 2401 tcg_gen_helper_0_0(helper_fdivd);
7e8c2b6c 2402 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2403 gen_op_store_DT0_fpr(DFPREG(rd));
2404 break;
2405 case 0x4f: /* fdivq */
1f587329
BS
2406#if defined(CONFIG_USER_ONLY)
2407 gen_op_load_fpr_QT0(QFPREG(rs1));
2408 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2409 gen_clear_float_exceptions();
44e7757c 2410 tcg_gen_helper_0_0(helper_fdivq);
7e8c2b6c 2411 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2412 gen_op_store_QT0_fpr(QFPREG(rd));
2413 break;
2414#else
0f8a249a 2415 goto nfpu_insn;
1f587329 2416#endif
0f8a249a
BS
2417 case 0x69:
2418 gen_op_load_fpr_FT0(rs1);
2419 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2420 gen_clear_float_exceptions();
44e7757c 2421 tcg_gen_helper_0_0(helper_fsmuld);
7e8c2b6c 2422 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2423 gen_op_store_DT0_fpr(DFPREG(rd));
2424 break;
2425 case 0x6e: /* fdmulq */
1f587329
BS
2426#if defined(CONFIG_USER_ONLY)
2427 gen_op_load_fpr_DT0(DFPREG(rs1));
2428 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2429 gen_clear_float_exceptions();
44e7757c 2430 tcg_gen_helper_0_0(helper_fdmulq);
7e8c2b6c 2431 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2432 gen_op_store_QT0_fpr(QFPREG(rd));
2433 break;
2434#else
0f8a249a 2435 goto nfpu_insn;
1f587329 2436#endif
0f8a249a
BS
2437 case 0xc4:
2438 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2439 gen_clear_float_exceptions();
44e7757c 2440 tcg_gen_helper_0_0(helper_fitos);
7e8c2b6c 2441 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2442 gen_op_store_FT0_fpr(rd);
2443 break;
2444 case 0xc6:
2445 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2446 gen_clear_float_exceptions();
44e7757c 2447 tcg_gen_helper_0_0(helper_fdtos);
7e8c2b6c 2448 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2449 gen_op_store_FT0_fpr(rd);
2450 break;
2451 case 0xc7: /* fqtos */
1f587329
BS
2452#if defined(CONFIG_USER_ONLY)
2453 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2454 gen_clear_float_exceptions();
44e7757c 2455 tcg_gen_helper_0_0(helper_fqtos);
7e8c2b6c 2456 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2457 gen_op_store_FT0_fpr(rd);
2458 break;
2459#else
0f8a249a 2460 goto nfpu_insn;
1f587329 2461#endif
0f8a249a
BS
2462 case 0xc8:
2463 gen_op_load_fpr_FT1(rs2);
44e7757c 2464 tcg_gen_helper_0_0(helper_fitod);
0f8a249a
BS
2465 gen_op_store_DT0_fpr(DFPREG(rd));
2466 break;
2467 case 0xc9:
2468 gen_op_load_fpr_FT1(rs2);
44e7757c 2469 tcg_gen_helper_0_0(helper_fstod);
0f8a249a
BS
2470 gen_op_store_DT0_fpr(DFPREG(rd));
2471 break;
2472 case 0xcb: /* fqtod */
1f587329
BS
2473#if defined(CONFIG_USER_ONLY)
2474 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2475 gen_clear_float_exceptions();
44e7757c 2476 tcg_gen_helper_0_0(helper_fqtod);
7e8c2b6c 2477 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2478 gen_op_store_DT0_fpr(DFPREG(rd));
2479 break;
2480#else
0f8a249a 2481 goto nfpu_insn;
1f587329 2482#endif
0f8a249a 2483 case 0xcc: /* fitoq */
1f587329
BS
2484#if defined(CONFIG_USER_ONLY)
2485 gen_op_load_fpr_FT1(rs2);
44e7757c 2486 tcg_gen_helper_0_0(helper_fitoq);
1f587329
BS
2487 gen_op_store_QT0_fpr(QFPREG(rd));
2488 break;
2489#else
0f8a249a 2490 goto nfpu_insn;
1f587329 2491#endif
0f8a249a 2492 case 0xcd: /* fstoq */
1f587329
BS
2493#if defined(CONFIG_USER_ONLY)
2494 gen_op_load_fpr_FT1(rs2);
44e7757c 2495 tcg_gen_helper_0_0(helper_fstoq);
1f587329
BS
2496 gen_op_store_QT0_fpr(QFPREG(rd));
2497 break;
2498#else
0f8a249a 2499 goto nfpu_insn;
1f587329 2500#endif
0f8a249a 2501 case 0xce: /* fdtoq */
1f587329
BS
2502#if defined(CONFIG_USER_ONLY)
2503 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 2504 tcg_gen_helper_0_0(helper_fdtoq);
1f587329
BS
2505 gen_op_store_QT0_fpr(QFPREG(rd));
2506 break;
2507#else
0f8a249a 2508 goto nfpu_insn;
1f587329 2509#endif
0f8a249a
BS
2510 case 0xd1:
2511 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2512 gen_clear_float_exceptions();
44e7757c 2513 tcg_gen_helper_0_0(helper_fstoi);
7e8c2b6c 2514 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2515 gen_op_store_FT0_fpr(rd);
2516 break;
2517 case 0xd2:
2382dc6b 2518 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2519 gen_clear_float_exceptions();
44e7757c 2520 tcg_gen_helper_0_0(helper_fdtoi);
7e8c2b6c 2521 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2522 gen_op_store_FT0_fpr(rd);
2523 break;
2524 case 0xd3: /* fqtoi */
1f587329
BS
2525#if defined(CONFIG_USER_ONLY)
2526 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2527 gen_clear_float_exceptions();
44e7757c 2528 tcg_gen_helper_0_0(helper_fqtoi);
7e8c2b6c 2529 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2530 gen_op_store_FT0_fpr(rd);
2531 break;
2532#else
0f8a249a 2533 goto nfpu_insn;
1f587329 2534#endif
3475187d 2535#ifdef TARGET_SPARC64
0f8a249a
BS
2536 case 0x2: /* V9 fmovd */
2537 gen_op_load_fpr_DT0(DFPREG(rs2));
2538 gen_op_store_DT0_fpr(DFPREG(rd));
2539 break;
1f587329
BS
2540 case 0x3: /* V9 fmovq */
2541#if defined(CONFIG_USER_ONLY)
2542 gen_op_load_fpr_QT0(QFPREG(rs2));
2543 gen_op_store_QT0_fpr(QFPREG(rd));
2544 break;
2545#else
2546 goto nfpu_insn;
2547#endif
0f8a249a
BS
2548 case 0x6: /* V9 fnegd */
2549 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 2550 tcg_gen_helper_0_0(helper_fnegd);
0f8a249a
BS
2551 gen_op_store_DT0_fpr(DFPREG(rd));
2552 break;
1f587329
BS
2553 case 0x7: /* V9 fnegq */
2554#if defined(CONFIG_USER_ONLY)
2555 gen_op_load_fpr_QT1(QFPREG(rs2));
44e7757c 2556 tcg_gen_helper_0_0(helper_fnegq);
1f587329
BS
2557 gen_op_store_QT0_fpr(QFPREG(rd));
2558 break;
2559#else
2560 goto nfpu_insn;
2561#endif
0f8a249a
BS
2562 case 0xa: /* V9 fabsd */
2563 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2564 tcg_gen_helper_0_0(helper_fabsd);
0f8a249a
BS
2565 gen_op_store_DT0_fpr(DFPREG(rd));
2566 break;
1f587329
BS
2567 case 0xb: /* V9 fabsq */
2568#if defined(CONFIG_USER_ONLY)
2569 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2570 tcg_gen_helper_0_0(helper_fabsq);
1f587329
BS
2571 gen_op_store_QT0_fpr(QFPREG(rd));
2572 break;
2573#else
2574 goto nfpu_insn;
2575#endif
0f8a249a
BS
2576 case 0x81: /* V9 fstox */
2577 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2578 gen_clear_float_exceptions();
44e7757c 2579 tcg_gen_helper_0_0(helper_fstox);
7e8c2b6c 2580 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2581 gen_op_store_DT0_fpr(DFPREG(rd));
2582 break;
2583 case 0x82: /* V9 fdtox */
2584 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2585 gen_clear_float_exceptions();
44e7757c 2586 tcg_gen_helper_0_0(helper_fdtox);
7e8c2b6c 2587 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2588 gen_op_store_DT0_fpr(DFPREG(rd));
2589 break;
1f587329
BS
2590 case 0x83: /* V9 fqtox */
2591#if defined(CONFIG_USER_ONLY)
2592 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2593 gen_clear_float_exceptions();
44e7757c 2594 tcg_gen_helper_0_0(helper_fqtox);
7e8c2b6c 2595 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2596 gen_op_store_DT0_fpr(DFPREG(rd));
2597 break;
2598#else
2599 goto nfpu_insn;
2600#endif
0f8a249a
BS
2601 case 0x84: /* V9 fxtos */
2602 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2603 gen_clear_float_exceptions();
44e7757c 2604 tcg_gen_helper_0_0(helper_fxtos);
7e8c2b6c 2605 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2606 gen_op_store_FT0_fpr(rd);
2607 break;
2608 case 0x88: /* V9 fxtod */
2609 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2610 gen_clear_float_exceptions();
44e7757c 2611 tcg_gen_helper_0_0(helper_fxtod);
7e8c2b6c 2612 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2613 gen_op_store_DT0_fpr(DFPREG(rd));
2614 break;
0f8a249a 2615 case 0x8c: /* V9 fxtoq */
1f587329
BS
2616#if defined(CONFIG_USER_ONLY)
2617 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2618 gen_clear_float_exceptions();
44e7757c 2619 tcg_gen_helper_0_0(helper_fxtoq);
7e8c2b6c 2620 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2621 gen_op_store_QT0_fpr(QFPREG(rd));
2622 break;
2623#else
0f8a249a 2624 goto nfpu_insn;
1f587329 2625#endif
0f8a249a
BS
2626#endif
2627 default:
2628 goto illegal_insn;
2629 }
2630 } else if (xop == 0x35) { /* FPU Operations */
3475187d 2631#ifdef TARGET_SPARC64
0f8a249a 2632 int cond;
3475187d 2633#endif
6ae20372 2634 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 2635 goto jmp_insn;
0f8a249a 2636 gen_op_clear_ieee_excp_and_FTT();
cf495bcf 2637 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2638 rs2 = GET_FIELD(insn, 27, 31);
2639 xop = GET_FIELD(insn, 18, 26);
3475187d 2640#ifdef TARGET_SPARC64
0f8a249a 2641 if ((xop & 0x11f) == 0x005) { // V9 fmovsr
dcf24905
BS
2642 int l1;
2643
2644 l1 = gen_new_label();
0f8a249a 2645 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2646 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 2647 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
0425bee5 2648 tcg_const_tl(0), l1);
19f329ad 2649 gen_op_load_fpr_FT0(rs2);
0f8a249a 2650 gen_op_store_FT0_fpr(rd);
dcf24905 2651 gen_set_label(l1);
0f8a249a
BS
2652 break;
2653 } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
dcf24905
BS
2654 int l1;
2655
2656 l1 = gen_new_label();
0f8a249a 2657 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2658 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 2659 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
0425bee5 2660 tcg_const_tl(0), l1);
19f329ad 2661 gen_op_load_fpr_DT0(DFPREG(rs2));
2382dc6b 2662 gen_op_store_DT0_fpr(DFPREG(rd));
dcf24905 2663 gen_set_label(l1);
0f8a249a
BS
2664 break;
2665 } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
1f587329 2666#if defined(CONFIG_USER_ONLY)
dcf24905
BS
2667 int l1;
2668
2669 l1 = gen_new_label();
1f587329 2670 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2671 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 2672 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
0425bee5 2673 tcg_const_tl(0), l1);
19f329ad 2674 gen_op_load_fpr_QT0(QFPREG(rs2));
1f587329 2675 gen_op_store_QT0_fpr(QFPREG(rd));
dcf24905 2676 gen_set_label(l1);
1f587329
BS
2677 break;
2678#else
0f8a249a 2679 goto nfpu_insn;
1f587329 2680#endif
0f8a249a
BS
2681 }
2682#endif
2683 switch (xop) {
3475187d 2684#ifdef TARGET_SPARC64
19f329ad
BS
2685#define FMOVCC(size_FDQ, fcc) \
2686 { \
0425bee5 2687 TCGv r_cond; \
19f329ad
BS
2688 int l1; \
2689 \
2690 l1 = gen_new_label(); \
19f329ad 2691 r_cond = tcg_temp_new(TCG_TYPE_TL); \
19f329ad
BS
2692 cond = GET_FIELD_SP(insn, 14, 17); \
2693 gen_fcond(r_cond, fcc, cond); \
0425bee5
BS
2694 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, \
2695 tcg_const_tl(0), l1); \
19f329ad
BS
2696 glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2697 glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2698 gen_set_label(l1); \
2699 }
0f8a249a 2700 case 0x001: /* V9 fmovscc %fcc0 */
19f329ad 2701 FMOVCC(F, 0);
0f8a249a
BS
2702 break;
2703 case 0x002: /* V9 fmovdcc %fcc0 */
19f329ad 2704 FMOVCC(D, 0);
0f8a249a
BS
2705 break;
2706 case 0x003: /* V9 fmovqcc %fcc0 */
1f587329 2707#if defined(CONFIG_USER_ONLY)
19f329ad 2708 FMOVCC(Q, 0);
1f587329
BS
2709 break;
2710#else
0f8a249a 2711 goto nfpu_insn;
1f587329 2712#endif
0f8a249a 2713 case 0x041: /* V9 fmovscc %fcc1 */
19f329ad 2714 FMOVCC(F, 1);
0f8a249a
BS
2715 break;
2716 case 0x042: /* V9 fmovdcc %fcc1 */
19f329ad 2717 FMOVCC(D, 1);
0f8a249a
BS
2718 break;
2719 case 0x043: /* V9 fmovqcc %fcc1 */
1f587329 2720#if defined(CONFIG_USER_ONLY)
19f329ad 2721 FMOVCC(Q, 1);
1f587329
BS
2722 break;
2723#else
0f8a249a 2724 goto nfpu_insn;
1f587329 2725#endif
0f8a249a 2726 case 0x081: /* V9 fmovscc %fcc2 */
19f329ad 2727 FMOVCC(F, 2);
0f8a249a
BS
2728 break;
2729 case 0x082: /* V9 fmovdcc %fcc2 */
19f329ad 2730 FMOVCC(D, 2);
0f8a249a
BS
2731 break;
2732 case 0x083: /* V9 fmovqcc %fcc2 */
1f587329 2733#if defined(CONFIG_USER_ONLY)
19f329ad 2734 FMOVCC(Q, 2);
1f587329
BS
2735 break;
2736#else
0f8a249a 2737 goto nfpu_insn;
1f587329 2738#endif
0f8a249a 2739 case 0x0c1: /* V9 fmovscc %fcc3 */
19f329ad 2740 FMOVCC(F, 3);
0f8a249a
BS
2741 break;
2742 case 0x0c2: /* V9 fmovdcc %fcc3 */
19f329ad 2743 FMOVCC(D, 3);
0f8a249a
BS
2744 break;
2745 case 0x0c3: /* V9 fmovqcc %fcc3 */
1f587329 2746#if defined(CONFIG_USER_ONLY)
19f329ad 2747 FMOVCC(Q, 3);
1f587329
BS
2748 break;
2749#else
0f8a249a 2750 goto nfpu_insn;
1f587329 2751#endif
19f329ad
BS
2752#undef FMOVCC
2753#define FMOVCC(size_FDQ, icc) \
2754 { \
0425bee5 2755 TCGv r_cond; \
19f329ad
BS
2756 int l1; \
2757 \
2758 l1 = gen_new_label(); \
19f329ad 2759 r_cond = tcg_temp_new(TCG_TYPE_TL); \
19f329ad
BS
2760 cond = GET_FIELD_SP(insn, 14, 17); \
2761 gen_cond(r_cond, icc, cond); \
0425bee5
BS
2762 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, \
2763 tcg_const_tl(0), l1); \
19f329ad
BS
2764 glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2765 glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2766 gen_set_label(l1); \
2767 }
2768
0f8a249a 2769 case 0x101: /* V9 fmovscc %icc */
19f329ad 2770 FMOVCC(F, 0);
0f8a249a
BS
2771 break;
2772 case 0x102: /* V9 fmovdcc %icc */
19f329ad 2773 FMOVCC(D, 0);
0f8a249a 2774 case 0x103: /* V9 fmovqcc %icc */
1f587329 2775#if defined(CONFIG_USER_ONLY)
19f329ad 2776 FMOVCC(D, 0);
1f587329
BS
2777 break;
2778#else
0f8a249a 2779 goto nfpu_insn;
1f587329 2780#endif
0f8a249a 2781 case 0x181: /* V9 fmovscc %xcc */
19f329ad 2782 FMOVCC(F, 1);
0f8a249a
BS
2783 break;
2784 case 0x182: /* V9 fmovdcc %xcc */
19f329ad 2785 FMOVCC(D, 1);
0f8a249a
BS
2786 break;
2787 case 0x183: /* V9 fmovqcc %xcc */
1f587329 2788#if defined(CONFIG_USER_ONLY)
19f329ad 2789 FMOVCC(Q, 1);
1f587329
BS
2790 break;
2791#else
0f8a249a
BS
2792 goto nfpu_insn;
2793#endif
19f329ad 2794#undef FMOVCC
1f587329
BS
2795#endif
2796 case 0x51: /* fcmps, V9 %fcc */
0f8a249a
BS
2797 gen_op_load_fpr_FT0(rs1);
2798 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2799 gen_op_fcmps(rd & 3);
0f8a249a 2800 break;
1f587329 2801 case 0x52: /* fcmpd, V9 %fcc */
0f8a249a
BS
2802 gen_op_load_fpr_DT0(DFPREG(rs1));
2803 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2804 gen_op_fcmpd(rd & 3);
0f8a249a 2805 break;
1f587329
BS
2806 case 0x53: /* fcmpq, V9 %fcc */
2807#if defined(CONFIG_USER_ONLY)
2808 gen_op_load_fpr_QT0(QFPREG(rs1));
2809 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2810 gen_op_fcmpq(rd & 3);
1f587329
BS
2811 break;
2812#else /* !defined(CONFIG_USER_ONLY) */
0f8a249a 2813 goto nfpu_insn;
1f587329 2814#endif
0f8a249a
BS
2815 case 0x55: /* fcmpes, V9 %fcc */
2816 gen_op_load_fpr_FT0(rs1);
2817 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2818 gen_op_fcmpes(rd & 3);
0f8a249a
BS
2819 break;
2820 case 0x56: /* fcmped, V9 %fcc */
2821 gen_op_load_fpr_DT0(DFPREG(rs1));
2822 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2823 gen_op_fcmped(rd & 3);
0f8a249a 2824 break;
1f587329
BS
2825 case 0x57: /* fcmpeq, V9 %fcc */
2826#if defined(CONFIG_USER_ONLY)
2827 gen_op_load_fpr_QT0(QFPREG(rs1));
2828 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2829 gen_op_fcmpeq(rd & 3);
1f587329
BS
2830 break;
2831#else/* !defined(CONFIG_USER_ONLY) */
0f8a249a 2832 goto nfpu_insn;
1f587329 2833#endif
0f8a249a
BS
2834 default:
2835 goto illegal_insn;
2836 }
0f8a249a
BS
2837 } else if (xop == 0x2) {
2838 // clr/mov shortcut
e80cfcfc
FB
2839
2840 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a 2841 if (rs1 == 0) {
1a2fb1c0 2842 // or %g0, x, y -> mov T0, x; mov y, T0
0f8a249a
BS
2843 if (IS_IMM) { /* immediate */
2844 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 2845 tcg_gen_movi_tl(cpu_dst, (int)rs2);
0f8a249a
BS
2846 } else { /* register */
2847 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2848 gen_movl_reg_TN(rs2, cpu_dst);
0f8a249a 2849 }
0f8a249a 2850 } else {
9322a4bf 2851 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2852 if (IS_IMM) { /* immediate */
0f8a249a 2853 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 2854 tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
0f8a249a
BS
2855 } else { /* register */
2856 // or x, %g0, y -> mov T1, x; mov y, T1
2857 rs2 = GET_FIELD(insn, 27, 31);
2858 if (rs2 != 0) {
6ae20372
BS
2859 gen_movl_reg_TN(rs2, cpu_src2);
2860 tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
2861 } else
2862 tcg_gen_mov_tl(cpu_dst, cpu_src1);
0f8a249a 2863 }
0f8a249a 2864 }
6ae20372 2865 gen_movl_TN_reg(rd, cpu_dst);
83469015 2866#ifdef TARGET_SPARC64
0f8a249a 2867 } else if (xop == 0x25) { /* sll, V9 sllx */
9322a4bf 2868 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2869 if (IS_IMM) { /* immediate */
83469015 2870 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0 2871 if (insn & (1 << 12)) {
6ae20372 2872 tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
1a2fb1c0 2873 } else {
6ae20372
BS
2874 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2875 tcg_gen_shli_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
1a2fb1c0 2876 }
0f8a249a 2877 } else { /* register */
83469015 2878 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2879 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 2880 if (insn & (1 << 12)) {
6ae20372
BS
2881 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2882 tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
1a2fb1c0 2883 } else {
6ae20372
BS
2884 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2885 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2886 tcg_gen_shl_i64(cpu_dst, cpu_dst, cpu_tmp0);
1a2fb1c0 2887 }
83469015 2888 }
6ae20372 2889 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 2890 } else if (xop == 0x26) { /* srl, V9 srlx */
9322a4bf 2891 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2892 if (IS_IMM) { /* immediate */
83469015 2893 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0 2894 if (insn & (1 << 12)) {
6ae20372 2895 tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
1a2fb1c0 2896 } else {
6ae20372
BS
2897 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2898 tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
1a2fb1c0 2899 }
0f8a249a 2900 } else { /* register */
83469015 2901 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2902 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 2903 if (insn & (1 << 12)) {
6ae20372
BS
2904 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2905 tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
1a2fb1c0 2906 } else {
6ae20372
BS
2907 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2908 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2909 tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
1a2fb1c0 2910 }
83469015 2911 }
6ae20372 2912 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 2913 } else if (xop == 0x27) { /* sra, V9 srax */
9322a4bf 2914 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2915 if (IS_IMM) { /* immediate */
83469015 2916 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0 2917 if (insn & (1 << 12)) {
6ae20372 2918 tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
1a2fb1c0 2919 } else {
6ae20372
BS
2920 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2921 tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
2922 tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
1a2fb1c0 2923 }
0f8a249a 2924 } else { /* register */
83469015 2925 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2926 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 2927 if (insn & (1 << 12)) {
6ae20372
BS
2928 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2929 tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
1a2fb1c0 2930 } else {
6ae20372
BS
2931 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2932 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2933 tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
1a2fb1c0 2934 }
83469015 2935 }
6ae20372 2936 gen_movl_TN_reg(rd, cpu_dst);
e80cfcfc 2937#endif
fcc72045 2938 } else if (xop < 0x36) {
9322a4bf 2939 cpu_src1 = get_src1(insn, cpu_src1);
a49d9390 2940 cpu_src2 = get_src2(insn, cpu_src2);
cf495bcf
FB
2941 if (xop < 0x20) {
2942 switch (xop & ~0x10) {
2943 case 0x0:
2944 if (xop & 0x10)
6ae20372 2945 gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 2946 else
6ae20372 2947 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
cf495bcf
FB
2948 break;
2949 case 0x1:
6ae20372 2950 tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 2951 if (xop & 0x10)
6ae20372 2952 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
2953 break;
2954 case 0x2:
6ae20372 2955 tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
0f8a249a 2956 if (xop & 0x10)
6ae20372 2957 gen_op_logic_cc(cpu_dst);
0f8a249a 2958 break;
cf495bcf 2959 case 0x3:
6ae20372 2960 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 2961 if (xop & 0x10)
6ae20372 2962 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
2963 break;
2964 case 0x4:
2965 if (xop & 0x10)
6ae20372 2966 gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 2967 else
6ae20372 2968 tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
cf495bcf
FB
2969 break;
2970 case 0x5:
6ae20372
BS
2971 tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2972 tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_tmp0);
cf495bcf 2973 if (xop & 0x10)
6ae20372 2974 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
2975 break;
2976 case 0x6:
6ae20372
BS
2977 tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2978 tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_tmp0);
cf495bcf 2979 if (xop & 0x10)
6ae20372 2980 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
2981 break;
2982 case 0x7:
6ae20372
BS
2983 tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2984 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
cf495bcf 2985 if (xop & 0x10)
6ae20372 2986 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
2987 break;
2988 case 0x8:
cf495bcf 2989 if (xop & 0x10)
6ae20372 2990 gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
38bc628b 2991 else {
dc99a3f2 2992 gen_mov_reg_C(cpu_tmp0, cpu_psr);
6ae20372
BS
2993 tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2994 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
38bc628b 2995 }
cf495bcf 2996 break;
ded3ab80 2997#ifdef TARGET_SPARC64
0f8a249a 2998 case 0x9: /* V9 mulx */
6ae20372 2999 tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
ded3ab80
PB
3000 break;
3001#endif
cf495bcf 3002 case 0xa:
6ae20372 3003 gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3004 if (xop & 0x10)
6ae20372 3005 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3006 break;
3007 case 0xb:
6ae20372 3008 gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3009 if (xop & 0x10)
6ae20372 3010 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3011 break;
3012 case 0xc:
cf495bcf 3013 if (xop & 0x10)
6ae20372 3014 gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
38bc628b 3015 else {
dc99a3f2 3016 gen_mov_reg_C(cpu_tmp0, cpu_psr);
6ae20372
BS
3017 tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
3018 tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
38bc628b 3019 }
cf495bcf 3020 break;
ded3ab80 3021#ifdef TARGET_SPARC64
0f8a249a 3022 case 0xd: /* V9 udivx */
6ae20372
BS
3023 gen_trap_ifdivzero_tl(cpu_src2);
3024 tcg_gen_divu_i64(cpu_dst, cpu_src1, cpu_src2);
ded3ab80
PB
3025 break;
3026#endif
cf495bcf 3027 case 0xe:
6ae20372 3028 tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3029 if (xop & 0x10)
6ae20372 3030 gen_op_div_cc(cpu_dst);
cf495bcf
FB
3031 break;
3032 case 0xf:
6ae20372 3033 tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3034 if (xop & 0x10)
6ae20372 3035 gen_op_div_cc(cpu_dst);
cf495bcf
FB
3036 break;
3037 default:
3038 goto illegal_insn;
3039 }
6ae20372 3040 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf
FB
3041 } else {
3042 switch (xop) {
0f8a249a 3043 case 0x20: /* taddcc */
6ae20372
BS
3044 gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
3045 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3046 break;
3047 case 0x21: /* tsubcc */
6ae20372
BS
3048 gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
3049 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3050 break;
3051 case 0x22: /* taddcctv */
6ae20372
BS
3052 save_state(dc, cpu_cond);
3053 gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
3054 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3055 break;
3056 case 0x23: /* tsubcctv */
6ae20372
BS
3057 save_state(dc, cpu_cond);
3058 gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3059 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 3060 break;
cf495bcf 3061 case 0x24: /* mulscc */
6ae20372
BS
3062 gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3063 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3064 break;
83469015 3065#ifndef TARGET_SPARC64
0f8a249a 3066 case 0x25: /* sll */
6ae20372
BS
3067 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3068 tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3069 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3070 break;
83469015 3071 case 0x26: /* srl */
6ae20372
BS
3072 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3073 tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3074 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3075 break;
83469015 3076 case 0x27: /* sra */
6ae20372
BS
3077 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3078 tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3079 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3080 break;
83469015 3081#endif
cf495bcf
FB
3082 case 0x30:
3083 {
cf495bcf 3084 switch(rd) {
3475187d 3085 case 0: /* wry */
6ae20372
BS
3086 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3087 tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, y));
cf495bcf 3088 break;
65fe7b09
BS
3089#ifndef TARGET_SPARC64
3090 case 0x01 ... 0x0f: /* undefined in the
3091 SPARCv8 manual, nop
3092 on the microSPARC
3093 II */
3094 case 0x10 ... 0x1f: /* implementation-dependent
3095 in the SPARCv8
3096 manual, nop on the
3097 microSPARC II */
3098 break;
3099#else
0f8a249a 3100 case 0x2: /* V9 wrccr */
6ae20372
BS
3101 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3102 tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
0f8a249a
BS
3103 break;
3104 case 0x3: /* V9 wrasi */
6ae20372
BS
3105 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3106 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3107 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi));
0f8a249a
BS
3108 break;
3109 case 0x6: /* V9 wrfprs */
6ae20372
BS
3110 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3111 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3112 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
6ae20372 3113 save_state(dc, cpu_cond);
3299908c 3114 gen_op_next_insn();
57fec1fe 3115 tcg_gen_exit_tb(0);
3299908c 3116 dc->is_br = 1;
0f8a249a
BS
3117 break;
3118 case 0xf: /* V9 sir, nop if user */
3475187d 3119#if !defined(CONFIG_USER_ONLY)
0f8a249a 3120 if (supervisor(dc))
1a2fb1c0 3121 ; // XXX
3475187d 3122#endif
0f8a249a
BS
3123 break;
3124 case 0x13: /* Graphics Status */
6ae20372 3125 if (gen_trap_ifnofpu(dc, cpu_cond))
725cb90b 3126 goto jmp_insn;
6ae20372
BS
3127 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3128 tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr));
0f8a249a
BS
3129 break;
3130 case 0x17: /* Tick compare */
83469015 3131#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3132 if (!supervisor(dc))
3133 goto illegal_insn;
83469015 3134#endif
ccd4a219
BS
3135 {
3136 TCGv r_tickptr;
3137
6ae20372
BS
3138 tcg_gen_xor_tl(cpu_dst, cpu_src1,
3139 cpu_src2);
3140 tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
ccd4a219
BS
3141 tick_cmpr));
3142 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3143 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3144 offsetof(CPUState, tick));
3145 tcg_gen_helper_0_2(helper_tick_set_limit,
6ae20372 3146 r_tickptr, cpu_dst);
ccd4a219 3147 }
0f8a249a
BS
3148 break;
3149 case 0x18: /* System tick */
83469015 3150#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3151 if (!supervisor(dc))
3152 goto illegal_insn;
83469015 3153#endif
ccd4a219
BS
3154 {
3155 TCGv r_tickptr;
3156
6ae20372
BS
3157 tcg_gen_xor_tl(cpu_dst, cpu_src1,
3158 cpu_src2);
ccd4a219
BS
3159 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3160 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3161 offsetof(CPUState, stick));
3162 tcg_gen_helper_0_2(helper_tick_set_count,
6ae20372 3163 r_tickptr, cpu_dst);
ccd4a219 3164 }
0f8a249a
BS
3165 break;
3166 case 0x19: /* System tick compare */
83469015 3167#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3168 if (!supervisor(dc))
3169 goto illegal_insn;
3475187d 3170#endif
ccd4a219
BS
3171 {
3172 TCGv r_tickptr;
3173
6ae20372
BS
3174 tcg_gen_xor_tl(cpu_dst, cpu_src1,
3175 cpu_src2);
3176 tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
ccd4a219
BS
3177 stick_cmpr));
3178 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3179 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3180 offsetof(CPUState, stick));
3181 tcg_gen_helper_0_2(helper_tick_set_limit,
6ae20372 3182 r_tickptr, cpu_dst);
ccd4a219 3183 }
0f8a249a 3184 break;
83469015 3185
0f8a249a
BS
3186 case 0x10: /* Performance Control */
3187 case 0x11: /* Performance Instrumentation Counter */
3188 case 0x12: /* Dispatch Control */
3189 case 0x14: /* Softint set */
3190 case 0x15: /* Softint clear */
3191 case 0x16: /* Softint write */
83469015 3192#endif
3475187d 3193 default:
cf495bcf
FB
3194 goto illegal_insn;
3195 }
3196 }
3197 break;
e8af50a3 3198#if !defined(CONFIG_USER_ONLY)
af7bf89b 3199 case 0x31: /* wrpsr, V9 saved, restored */
e8af50a3 3200 {
0f8a249a
BS
3201 if (!supervisor(dc))
3202 goto priv_insn;
3475187d 3203#ifdef TARGET_SPARC64
0f8a249a
BS
3204 switch (rd) {
3205 case 0:
72a9747b 3206 tcg_gen_helper_0_0(helper_saved);
0f8a249a
BS
3207 break;
3208 case 1:
72a9747b 3209 tcg_gen_helper_0_0(helper_restored);
0f8a249a 3210 break;
e9ebed4d
BS
3211 case 2: /* UA2005 allclean */
3212 case 3: /* UA2005 otherw */
3213 case 4: /* UA2005 normalw */
3214 case 5: /* UA2005 invalw */
3215 // XXX
0f8a249a 3216 default:
3475187d
FB
3217 goto illegal_insn;
3218 }
3219#else
6ae20372
BS
3220 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3221 tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
3222 save_state(dc, cpu_cond);
9e61bde5 3223 gen_op_next_insn();
57fec1fe 3224 tcg_gen_exit_tb(0);
0f8a249a 3225 dc->is_br = 1;
3475187d 3226#endif
e8af50a3
FB
3227 }
3228 break;
af7bf89b 3229 case 0x32: /* wrwim, V9 wrpr */
e8af50a3 3230 {
0f8a249a
BS
3231 if (!supervisor(dc))
3232 goto priv_insn;
6ae20372 3233 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3475187d 3234#ifdef TARGET_SPARC64
0f8a249a
BS
3235 switch (rd) {
3236 case 0: // tpc
375ee38b
BS
3237 {
3238 TCGv r_tsptr;
3239
3240 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3241 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3242 offsetof(CPUState, tsptr));
6ae20372 3243 tcg_gen_st_tl(cpu_dst, r_tsptr,
375ee38b
BS
3244 offsetof(trap_state, tpc));
3245 }
0f8a249a
BS
3246 break;
3247 case 1: // tnpc
375ee38b
BS
3248 {
3249 TCGv r_tsptr;
3250
3251 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3252 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3253 offsetof(CPUState, tsptr));
6ae20372 3254 tcg_gen_st_tl(cpu_dst, r_tsptr,
375ee38b
BS
3255 offsetof(trap_state, tnpc));
3256 }
0f8a249a
BS
3257 break;
3258 case 2: // tstate
375ee38b
BS
3259 {
3260 TCGv r_tsptr;
3261
3262 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3263 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3264 offsetof(CPUState, tsptr));
6ae20372 3265 tcg_gen_st_tl(cpu_dst, r_tsptr,
375ee38b
BS
3266 offsetof(trap_state, tstate));
3267 }
0f8a249a
BS
3268 break;
3269 case 3: // tt
375ee38b
BS
3270 {
3271 TCGv r_tsptr;
3272
3273 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3274 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3275 offsetof(CPUState, tsptr));
6ae20372 3276 tcg_gen_st_i32(cpu_dst, r_tsptr,
375ee38b
BS
3277 offsetof(trap_state, tt));
3278 }
0f8a249a
BS
3279 break;
3280 case 4: // tick
ccd4a219
BS
3281 {
3282 TCGv r_tickptr;
3283
3284 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3285 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3286 offsetof(CPUState, tick));
3287 tcg_gen_helper_0_2(helper_tick_set_count,
6ae20372 3288 r_tickptr, cpu_dst);
ccd4a219 3289 }
0f8a249a
BS
3290 break;
3291 case 5: // tba
6ae20372 3292 tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
0f8a249a
BS
3293 break;
3294 case 6: // pstate
6ae20372
BS
3295 save_state(dc, cpu_cond);
3296 tcg_gen_helper_0_1(helper_wrpstate, cpu_dst);
ded3ab80 3297 gen_op_next_insn();
57fec1fe 3298 tcg_gen_exit_tb(0);
ded3ab80 3299 dc->is_br = 1;
0f8a249a
BS
3300 break;
3301 case 7: // tl
6ae20372 3302 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3303 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl));
0f8a249a
BS
3304 break;
3305 case 8: // pil
6ae20372 3306 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3307 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil));
0f8a249a
BS
3308 break;
3309 case 9: // cwp
6ae20372 3310 tcg_gen_helper_0_1(helper_wrcwp, cpu_dst);
0f8a249a
BS
3311 break;
3312 case 10: // cansave
6ae20372 3313 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3314 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave));
0f8a249a
BS
3315 break;
3316 case 11: // canrestore
6ae20372 3317 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3318 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore));
0f8a249a
BS
3319 break;
3320 case 12: // cleanwin
6ae20372 3321 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3322 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin));
0f8a249a
BS
3323 break;
3324 case 13: // otherwin
6ae20372 3325 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3326 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin));
0f8a249a
BS
3327 break;
3328 case 14: // wstate
6ae20372 3329 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3330 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate));
0f8a249a 3331 break;
e9ebed4d 3332 case 16: // UA2005 gl
6ae20372 3333 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3334 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl));
e9ebed4d
BS
3335 break;
3336 case 26: // UA2005 strand status
3337 if (!hypervisor(dc))
3338 goto priv_insn;
6ae20372 3339 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3340 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr));
e9ebed4d 3341 break;
0f8a249a
BS
3342 default:
3343 goto illegal_insn;
3344 }
3475187d 3345#else
6ae20372
BS
3346 tcg_gen_andi_tl(cpu_dst, cpu_dst, ((1 << NWINDOWS) - 1));
3347 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3348 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim));
3475187d 3349#endif
e8af50a3
FB
3350 }
3351 break;
e9ebed4d 3352 case 0x33: /* wrtbr, UA2005 wrhpr */
e8af50a3 3353 {
e9ebed4d 3354#ifndef TARGET_SPARC64
0f8a249a
BS
3355 if (!supervisor(dc))
3356 goto priv_insn;
6ae20372
BS
3357 tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2);
3358 tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
e9ebed4d
BS
3359#else
3360 if (!hypervisor(dc))
3361 goto priv_insn;
6ae20372 3362 tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2);
e9ebed4d
BS
3363 switch (rd) {
3364 case 0: // hpstate
3365 // XXX gen_op_wrhpstate();
6ae20372 3366 save_state(dc, cpu_cond);
e9ebed4d 3367 gen_op_next_insn();
57fec1fe 3368 tcg_gen_exit_tb(0);
e9ebed4d
BS
3369 dc->is_br = 1;
3370 break;
3371 case 1: // htstate
3372 // XXX gen_op_wrhtstate();
3373 break;
3374 case 3: // hintp
6ae20372 3375 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3376 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
e9ebed4d
BS
3377 break;
3378 case 5: // htba
6ae20372 3379 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2f5680ee 3380 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
e9ebed4d
BS
3381 break;
3382 case 31: // hstick_cmpr
ccd4a219
BS
3383 {
3384 TCGv r_tickptr;
3385
6ae20372 3386 tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
ccd4a219
BS
3387 hstick_cmpr));
3388 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3389 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3390 offsetof(CPUState, hstick));
3391 tcg_gen_helper_0_2(helper_tick_set_limit,
6ae20372 3392 r_tickptr, cpu_dst);
ccd4a219 3393 }
e9ebed4d
BS
3394 break;
3395 case 6: // hver readonly
3396 default:
3397 goto illegal_insn;
3398 }
3399#endif
e8af50a3
FB
3400 }
3401 break;
3402#endif
3475187d 3403#ifdef TARGET_SPARC64
0f8a249a
BS
3404 case 0x2c: /* V9 movcc */
3405 {
3406 int cc = GET_FIELD_SP(insn, 11, 12);
3407 int cond = GET_FIELD_SP(insn, 14, 17);
748b9d8e 3408 TCGv r_cond;
00f219bf
BS
3409 int l1;
3410
748b9d8e 3411 r_cond = tcg_temp_new(TCG_TYPE_TL);
0f8a249a
BS
3412 if (insn & (1 << 18)) {
3413 if (cc == 0)
748b9d8e 3414 gen_cond(r_cond, 0, cond);
0f8a249a 3415 else if (cc == 2)
748b9d8e 3416 gen_cond(r_cond, 1, cond);
0f8a249a
BS
3417 else
3418 goto illegal_insn;
3419 } else {
748b9d8e 3420 gen_fcond(r_cond, cc, cond);
0f8a249a 3421 }
00f219bf
BS
3422
3423 l1 = gen_new_label();
3424
748b9d8e
BS
3425 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3426 tcg_const_tl(0), l1);
00f219bf
BS
3427 if (IS_IMM) { /* immediate */
3428 rs2 = GET_FIELD_SPs(insn, 0, 10);
6ae20372 3429 tcg_gen_movi_tl(cpu_dst, (int)rs2);
00f219bf
BS
3430 } else {
3431 rs2 = GET_FIELD_SP(insn, 0, 4);
6ae20372 3432 gen_movl_reg_TN(rs2, cpu_dst);
00f219bf 3433 }
6ae20372 3434 gen_movl_TN_reg(rd, cpu_dst);
00f219bf 3435 gen_set_label(l1);
0f8a249a
BS
3436 break;
3437 }
3438 case 0x2d: /* V9 sdivx */
6ae20372
BS
3439 gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3440 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3441 break;
3442 case 0x2e: /* V9 popc */
3443 {
a49d9390 3444 cpu_src2 = get_src2(insn, cpu_src2);
6ae20372
BS
3445 tcg_gen_helper_1_1(helper_popc, cpu_dst,
3446 cpu_src2);
3447 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3448 }
3449 case 0x2f: /* V9 movr */
3450 {
3451 int cond = GET_FIELD_SP(insn, 10, 12);
00f219bf
BS
3452 int l1;
3453
9322a4bf 3454 cpu_src1 = get_src1(insn, cpu_src1);
00f219bf
BS
3455
3456 l1 = gen_new_label();
3457
6ae20372 3458 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
0425bee5 3459 tcg_const_tl(0), l1);
0f8a249a
BS
3460 if (IS_IMM) { /* immediate */
3461 rs2 = GET_FIELD_SPs(insn, 0, 9);
6ae20372 3462 tcg_gen_movi_tl(cpu_dst, (int)rs2);
00f219bf 3463 } else {
0f8a249a 3464 rs2 = GET_FIELD_SP(insn, 0, 4);
6ae20372 3465 gen_movl_reg_TN(rs2, cpu_dst);
0f8a249a 3466 }
6ae20372 3467 gen_movl_TN_reg(rd, cpu_dst);
00f219bf 3468 gen_set_label(l1);
0f8a249a
BS
3469 break;
3470 }
3471#endif
3472 default:
3473 goto illegal_insn;
3474 }
3475 }
3299908c
BS
3476 } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3477#ifdef TARGET_SPARC64
3478 int opf = GET_FIELD_SP(insn, 5, 13);
3479 rs1 = GET_FIELD(insn, 13, 17);
3480 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 3481 if (gen_trap_ifnofpu(dc, cpu_cond))
e9ebed4d 3482 goto jmp_insn;
3299908c
BS
3483
3484 switch (opf) {
e9ebed4d
BS
3485 case 0x000: /* VIS I edge8cc */
3486 case 0x001: /* VIS II edge8n */
3487 case 0x002: /* VIS I edge8lcc */
3488 case 0x003: /* VIS II edge8ln */
3489 case 0x004: /* VIS I edge16cc */
3490 case 0x005: /* VIS II edge16n */
3491 case 0x006: /* VIS I edge16lcc */
3492 case 0x007: /* VIS II edge16ln */
3493 case 0x008: /* VIS I edge32cc */
3494 case 0x009: /* VIS II edge32n */
3495 case 0x00a: /* VIS I edge32lcc */
3496 case 0x00b: /* VIS II edge32ln */
3497 // XXX
3498 goto illegal_insn;
3499 case 0x010: /* VIS I array8 */
9322a4bf 3500 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372
BS
3501 gen_movl_reg_TN(rs2, cpu_src2);
3502 tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3503 cpu_src2);
3504 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d
BS
3505 break;
3506 case 0x012: /* VIS I array16 */
9322a4bf 3507 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372
BS
3508 gen_movl_reg_TN(rs2, cpu_src2);
3509 tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3510 cpu_src2);
3511 tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3512 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d
BS
3513 break;
3514 case 0x014: /* VIS I array32 */
9322a4bf 3515 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372
BS
3516 gen_movl_reg_TN(rs2, cpu_src2);
3517 tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3518 cpu_src2);
3519 tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3520 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d 3521 break;
3299908c 3522 case 0x018: /* VIS I alignaddr */
9322a4bf 3523 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372
BS
3524 gen_movl_reg_TN(rs2, cpu_src2);
3525 tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
3526 cpu_src2);
3527 gen_movl_TN_reg(rd, cpu_dst);
3299908c 3528 break;
e9ebed4d 3529 case 0x019: /* VIS II bmask */
3299908c 3530 case 0x01a: /* VIS I alignaddrl */
3299908c 3531 // XXX
e9ebed4d
BS
3532 goto illegal_insn;
3533 case 0x020: /* VIS I fcmple16 */
2382dc6b
BS
3534 gen_op_load_fpr_DT0(DFPREG(rs1));
3535 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3536 tcg_gen_helper_0_0(helper_fcmple16);
2382dc6b 3537 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3538 break;
3539 case 0x022: /* VIS I fcmpne16 */
2382dc6b
BS
3540 gen_op_load_fpr_DT0(DFPREG(rs1));
3541 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3542 tcg_gen_helper_0_0(helper_fcmpne16);
2382dc6b 3543 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c 3544 break;
e9ebed4d 3545 case 0x024: /* VIS I fcmple32 */
2382dc6b
BS
3546 gen_op_load_fpr_DT0(DFPREG(rs1));
3547 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3548 tcg_gen_helper_0_0(helper_fcmple32);
2382dc6b 3549 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3550 break;
3551 case 0x026: /* VIS I fcmpne32 */
2382dc6b
BS
3552 gen_op_load_fpr_DT0(DFPREG(rs1));
3553 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3554 tcg_gen_helper_0_0(helper_fcmpne32);
2382dc6b 3555 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3556 break;
3557 case 0x028: /* VIS I fcmpgt16 */
2382dc6b
BS
3558 gen_op_load_fpr_DT0(DFPREG(rs1));
3559 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3560 tcg_gen_helper_0_0(helper_fcmpgt16);
2382dc6b 3561 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3562 break;
3563 case 0x02a: /* VIS I fcmpeq16 */
2382dc6b
BS
3564 gen_op_load_fpr_DT0(DFPREG(rs1));
3565 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3566 tcg_gen_helper_0_0(helper_fcmpeq16);
2382dc6b 3567 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3568 break;
3569 case 0x02c: /* VIS I fcmpgt32 */
2382dc6b
BS
3570 gen_op_load_fpr_DT0(DFPREG(rs1));
3571 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3572 tcg_gen_helper_0_0(helper_fcmpgt32);
2382dc6b 3573 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3574 break;
3575 case 0x02e: /* VIS I fcmpeq32 */
2382dc6b
BS
3576 gen_op_load_fpr_DT0(DFPREG(rs1));
3577 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3578 tcg_gen_helper_0_0(helper_fcmpeq32);
2382dc6b 3579 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3580 break;
3581 case 0x031: /* VIS I fmul8x16 */
2382dc6b
BS
3582 gen_op_load_fpr_DT0(DFPREG(rs1));
3583 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3584 tcg_gen_helper_0_0(helper_fmul8x16);
2382dc6b 3585 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3586 break;
3587 case 0x033: /* VIS I fmul8x16au */
2382dc6b
BS
3588 gen_op_load_fpr_DT0(DFPREG(rs1));
3589 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3590 tcg_gen_helper_0_0(helper_fmul8x16au);
2382dc6b 3591 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3592 break;
3593 case 0x035: /* VIS I fmul8x16al */
2382dc6b
BS
3594 gen_op_load_fpr_DT0(DFPREG(rs1));
3595 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3596 tcg_gen_helper_0_0(helper_fmul8x16al);
2382dc6b 3597 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3598 break;
3599 case 0x036: /* VIS I fmul8sux16 */
2382dc6b
BS
3600 gen_op_load_fpr_DT0(DFPREG(rs1));
3601 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3602 tcg_gen_helper_0_0(helper_fmul8sux16);
2382dc6b 3603 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3604 break;
3605 case 0x037: /* VIS I fmul8ulx16 */
2382dc6b
BS
3606 gen_op_load_fpr_DT0(DFPREG(rs1));
3607 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3608 tcg_gen_helper_0_0(helper_fmul8ulx16);
2382dc6b 3609 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3610 break;
3611 case 0x038: /* VIS I fmuld8sux16 */
2382dc6b
BS
3612 gen_op_load_fpr_DT0(DFPREG(rs1));
3613 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3614 tcg_gen_helper_0_0(helper_fmuld8sux16);
2382dc6b 3615 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3616 break;
3617 case 0x039: /* VIS I fmuld8ulx16 */
2382dc6b
BS
3618 gen_op_load_fpr_DT0(DFPREG(rs1));
3619 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3620 tcg_gen_helper_0_0(helper_fmuld8ulx16);
2382dc6b 3621 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3622 break;
3623 case 0x03a: /* VIS I fpack32 */
3624 case 0x03b: /* VIS I fpack16 */
3625 case 0x03d: /* VIS I fpackfix */
3626 case 0x03e: /* VIS I pdist */
3627 // XXX
3628 goto illegal_insn;
3299908c 3629 case 0x048: /* VIS I faligndata */
2382dc6b
BS
3630 gen_op_load_fpr_DT0(DFPREG(rs1));
3631 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3632 tcg_gen_helper_0_0(helper_faligndata);
2382dc6b 3633 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c 3634 break;
e9ebed4d 3635 case 0x04b: /* VIS I fpmerge */
2382dc6b
BS
3636 gen_op_load_fpr_DT0(DFPREG(rs1));
3637 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3638 tcg_gen_helper_0_0(helper_fpmerge);
2382dc6b 3639 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3640 break;
3641 case 0x04c: /* VIS II bshuffle */
3642 // XXX
3643 goto illegal_insn;
3644 case 0x04d: /* VIS I fexpand */
2382dc6b
BS
3645 gen_op_load_fpr_DT0(DFPREG(rs1));
3646 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3647 tcg_gen_helper_0_0(helper_fexpand);
2382dc6b 3648 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3649 break;
3650 case 0x050: /* VIS I fpadd16 */
2382dc6b
BS
3651 gen_op_load_fpr_DT0(DFPREG(rs1));
3652 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3653 tcg_gen_helper_0_0(helper_fpadd16);
2382dc6b 3654 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3655 break;
3656 case 0x051: /* VIS I fpadd16s */
3657 gen_op_load_fpr_FT0(rs1);
3658 gen_op_load_fpr_FT1(rs2);
44e7757c 3659 tcg_gen_helper_0_0(helper_fpadd16s);
e9ebed4d
BS
3660 gen_op_store_FT0_fpr(rd);
3661 break;
3662 case 0x052: /* VIS I fpadd32 */
2382dc6b
BS
3663 gen_op_load_fpr_DT0(DFPREG(rs1));
3664 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3665 tcg_gen_helper_0_0(helper_fpadd32);
2382dc6b 3666 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3667 break;
3668 case 0x053: /* VIS I fpadd32s */
3669 gen_op_load_fpr_FT0(rs1);
3670 gen_op_load_fpr_FT1(rs2);
44e7757c 3671 tcg_gen_helper_0_0(helper_fpadd32s);
e9ebed4d
BS
3672 gen_op_store_FT0_fpr(rd);
3673 break;
3674 case 0x054: /* VIS I fpsub16 */
2382dc6b
BS
3675 gen_op_load_fpr_DT0(DFPREG(rs1));
3676 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3677 tcg_gen_helper_0_0(helper_fpsub16);
2382dc6b 3678 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3679 break;
3680 case 0x055: /* VIS I fpsub16s */
3681 gen_op_load_fpr_FT0(rs1);
3682 gen_op_load_fpr_FT1(rs2);
44e7757c 3683 tcg_gen_helper_0_0(helper_fpsub16s);
e9ebed4d
BS
3684 gen_op_store_FT0_fpr(rd);
3685 break;
3686 case 0x056: /* VIS I fpsub32 */
2382dc6b
BS
3687 gen_op_load_fpr_DT0(DFPREG(rs1));
3688 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3689 tcg_gen_helper_0_0(helper_fpadd32);
2382dc6b 3690 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3691 break;
3692 case 0x057: /* VIS I fpsub32s */
3693 gen_op_load_fpr_FT0(rs1);
3694 gen_op_load_fpr_FT1(rs2);
44e7757c 3695 tcg_gen_helper_0_0(helper_fpsub32s);
e9ebed4d
BS
3696 gen_op_store_FT0_fpr(rd);
3697 break;
3299908c 3698 case 0x060: /* VIS I fzero */
44e7757c 3699 tcg_gen_helper_0_0(helper_movl_DT0_0);
2382dc6b 3700 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
3701 break;
3702 case 0x061: /* VIS I fzeros */
44e7757c 3703 tcg_gen_helper_0_0(helper_movl_FT0_0);
3299908c
BS
3704 gen_op_store_FT0_fpr(rd);
3705 break;
e9ebed4d 3706 case 0x062: /* VIS I fnor */
2382dc6b
BS
3707 gen_op_load_fpr_DT0(DFPREG(rs1));
3708 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3709 tcg_gen_helper_0_0(helper_fnor);
2382dc6b 3710 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3711 break;
3712 case 0x063: /* VIS I fnors */
3713 gen_op_load_fpr_FT0(rs1);
3714 gen_op_load_fpr_FT1(rs2);
44e7757c 3715 tcg_gen_helper_0_0(helper_fnors);
e9ebed4d
BS
3716 gen_op_store_FT0_fpr(rd);
3717 break;
3718 case 0x064: /* VIS I fandnot2 */
2382dc6b
BS
3719 gen_op_load_fpr_DT1(DFPREG(rs1));
3720 gen_op_load_fpr_DT0(DFPREG(rs2));
44e7757c 3721 tcg_gen_helper_0_0(helper_fandnot);
2382dc6b 3722 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3723 break;
3724 case 0x065: /* VIS I fandnot2s */
3725 gen_op_load_fpr_FT1(rs1);
3726 gen_op_load_fpr_FT0(rs2);
44e7757c 3727 tcg_gen_helper_0_0(helper_fandnots);
e9ebed4d
BS
3728 gen_op_store_FT0_fpr(rd);
3729 break;
3730 case 0x066: /* VIS I fnot2 */
2382dc6b 3731 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3732 tcg_gen_helper_0_0(helper_fnot);
2382dc6b 3733 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3734 break;
3735 case 0x067: /* VIS I fnot2s */
3736 gen_op_load_fpr_FT1(rs2);
44e7757c 3737 tcg_gen_helper_0_0(helper_fnot);
e9ebed4d
BS
3738 gen_op_store_FT0_fpr(rd);
3739 break;
3740 case 0x068: /* VIS I fandnot1 */
2382dc6b
BS
3741 gen_op_load_fpr_DT0(DFPREG(rs1));
3742 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3743 tcg_gen_helper_0_0(helper_fandnot);
2382dc6b 3744 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3745 break;
3746 case 0x069: /* VIS I fandnot1s */
3747 gen_op_load_fpr_FT0(rs1);
3748 gen_op_load_fpr_FT1(rs2);
44e7757c 3749 tcg_gen_helper_0_0(helper_fandnots);
e9ebed4d
BS
3750 gen_op_store_FT0_fpr(rd);
3751 break;
3752 case 0x06a: /* VIS I fnot1 */
2382dc6b 3753 gen_op_load_fpr_DT1(DFPREG(rs1));
44e7757c 3754 tcg_gen_helper_0_0(helper_fnot);
2382dc6b 3755 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3756 break;
3757 case 0x06b: /* VIS I fnot1s */
3758 gen_op_load_fpr_FT1(rs1);
44e7757c 3759 tcg_gen_helper_0_0(helper_fnot);
e9ebed4d
BS
3760 gen_op_store_FT0_fpr(rd);
3761 break;
3762 case 0x06c: /* VIS I fxor */
2382dc6b
BS
3763 gen_op_load_fpr_DT0(DFPREG(rs1));
3764 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3765 tcg_gen_helper_0_0(helper_fxor);
2382dc6b 3766 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3767 break;
3768 case 0x06d: /* VIS I fxors */
3769 gen_op_load_fpr_FT0(rs1);
3770 gen_op_load_fpr_FT1(rs2);
44e7757c 3771 tcg_gen_helper_0_0(helper_fxors);
e9ebed4d
BS
3772 gen_op_store_FT0_fpr(rd);
3773 break;
3774 case 0x06e: /* VIS I fnand */
2382dc6b
BS
3775 gen_op_load_fpr_DT0(DFPREG(rs1));
3776 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3777 tcg_gen_helper_0_0(helper_fnand);
2382dc6b 3778 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3779 break;
3780 case 0x06f: /* VIS I fnands */
3781 gen_op_load_fpr_FT0(rs1);
3782 gen_op_load_fpr_FT1(rs2);
44e7757c 3783 tcg_gen_helper_0_0(helper_fnands);
e9ebed4d
BS
3784 gen_op_store_FT0_fpr(rd);
3785 break;
3786 case 0x070: /* VIS I fand */
2382dc6b
BS
3787 gen_op_load_fpr_DT0(DFPREG(rs1));
3788 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3789 tcg_gen_helper_0_0(helper_fand);
2382dc6b 3790 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3791 break;
3792 case 0x071: /* VIS I fands */
3793 gen_op_load_fpr_FT0(rs1);
3794 gen_op_load_fpr_FT1(rs2);
44e7757c 3795 tcg_gen_helper_0_0(helper_fands);
e9ebed4d
BS
3796 gen_op_store_FT0_fpr(rd);
3797 break;
3798 case 0x072: /* VIS I fxnor */
2382dc6b
BS
3799 gen_op_load_fpr_DT0(DFPREG(rs1));
3800 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3801 tcg_gen_helper_0_0(helper_fxnor);
2382dc6b 3802 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3803 break;
3804 case 0x073: /* VIS I fxnors */
3805 gen_op_load_fpr_FT0(rs1);
3806 gen_op_load_fpr_FT1(rs2);
44e7757c 3807 tcg_gen_helper_0_0(helper_fxnors);
e9ebed4d
BS
3808 gen_op_store_FT0_fpr(rd);
3809 break;
3299908c 3810 case 0x074: /* VIS I fsrc1 */
2382dc6b
BS
3811 gen_op_load_fpr_DT0(DFPREG(rs1));
3812 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
3813 break;
3814 case 0x075: /* VIS I fsrc1s */
3299908c
BS
3815 gen_op_load_fpr_FT0(rs1);
3816 gen_op_store_FT0_fpr(rd);
3817 break;
e9ebed4d 3818 case 0x076: /* VIS I fornot2 */
2382dc6b
BS
3819 gen_op_load_fpr_DT1(DFPREG(rs1));
3820 gen_op_load_fpr_DT0(DFPREG(rs2));
44e7757c 3821 tcg_gen_helper_0_0(helper_fornot);
2382dc6b 3822 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3823 break;
3824 case 0x077: /* VIS I fornot2s */
3825 gen_op_load_fpr_FT1(rs1);
3826 gen_op_load_fpr_FT0(rs2);
44e7757c 3827 tcg_gen_helper_0_0(helper_fornots);
e9ebed4d
BS
3828 gen_op_store_FT0_fpr(rd);
3829 break;
3299908c 3830 case 0x078: /* VIS I fsrc2 */
2382dc6b
BS
3831 gen_op_load_fpr_DT0(DFPREG(rs2));
3832 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
3833 break;
3834 case 0x079: /* VIS I fsrc2s */
3299908c
BS
3835 gen_op_load_fpr_FT0(rs2);
3836 gen_op_store_FT0_fpr(rd);
3837 break;
e9ebed4d 3838 case 0x07a: /* VIS I fornot1 */
2382dc6b
BS
3839 gen_op_load_fpr_DT0(DFPREG(rs1));
3840 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3841 tcg_gen_helper_0_0(helper_fornot);
2382dc6b 3842 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3843 break;
3844 case 0x07b: /* VIS I fornot1s */
3845 gen_op_load_fpr_FT0(rs1);
3846 gen_op_load_fpr_FT1(rs2);
44e7757c 3847 tcg_gen_helper_0_0(helper_fornots);
e9ebed4d
BS
3848 gen_op_store_FT0_fpr(rd);
3849 break;
3850 case 0x07c: /* VIS I for */
2382dc6b
BS
3851 gen_op_load_fpr_DT0(DFPREG(rs1));
3852 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3853 tcg_gen_helper_0_0(helper_for);
2382dc6b 3854 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3855 break;
3856 case 0x07d: /* VIS I fors */
3857 gen_op_load_fpr_FT0(rs1);
3858 gen_op_load_fpr_FT1(rs2);
44e7757c 3859 tcg_gen_helper_0_0(helper_fors);
e9ebed4d
BS
3860 gen_op_store_FT0_fpr(rd);
3861 break;
3299908c 3862 case 0x07e: /* VIS I fone */
44e7757c 3863 tcg_gen_helper_0_0(helper_movl_DT0_1);
2382dc6b 3864 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
3865 break;
3866 case 0x07f: /* VIS I fones */
44e7757c 3867 tcg_gen_helper_0_0(helper_movl_FT0_1);
3299908c
BS
3868 gen_op_store_FT0_fpr(rd);
3869 break;
e9ebed4d
BS
3870 case 0x080: /* VIS I shutdown */
3871 case 0x081: /* VIS II siam */
3872 // XXX
3873 goto illegal_insn;
3299908c
BS
3874 default:
3875 goto illegal_insn;
3876 }
3877#else
0f8a249a 3878 goto ncp_insn;
3299908c
BS
3879#endif
3880 } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
fcc72045 3881#ifdef TARGET_SPARC64
0f8a249a 3882 goto illegal_insn;
fcc72045 3883#else
0f8a249a 3884 goto ncp_insn;
fcc72045 3885#endif
3475187d 3886#ifdef TARGET_SPARC64
0f8a249a 3887 } else if (xop == 0x39) { /* V9 return */
6ae20372 3888 save_state(dc, cpu_cond);
9322a4bf 3889 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a
BS
3890 if (IS_IMM) { /* immediate */
3891 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 3892 tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
0f8a249a 3893 } else { /* register */
3475187d 3894 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 3895 if (rs2) {
6ae20372
BS
3896 gen_movl_reg_TN(rs2, cpu_src2);
3897 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
3898 } else
3899 tcg_gen_mov_tl(cpu_dst, cpu_src1);
3475187d 3900 }
72a9747b 3901 tcg_gen_helper_0_0(helper_restore);
6ae20372
BS
3902 gen_mov_pc_npc(dc, cpu_cond);
3903 tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3904 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a
BS
3905 dc->npc = DYNAMIC_PC;
3906 goto jmp_insn;
3475187d 3907#endif
0f8a249a 3908 } else {
9322a4bf 3909 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a
BS
3910 if (IS_IMM) { /* immediate */
3911 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 3912 tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
0f8a249a 3913 } else { /* register */
e80cfcfc 3914 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 3915 if (rs2) {
6ae20372
BS
3916 gen_movl_reg_TN(rs2, cpu_src2);
3917 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
3918 } else
3919 tcg_gen_mov_tl(cpu_dst, cpu_src1);
cf495bcf 3920 }
0f8a249a
BS
3921 switch (xop) {
3922 case 0x38: /* jmpl */
3923 {
3924 if (rd != 0) {
32b6c812
BS
3925 tcg_gen_movi_tl(cpu_tmp0, dc->pc);
3926 gen_movl_TN_reg(rd, cpu_tmp0);
0f8a249a 3927 }
6ae20372
BS
3928 gen_mov_pc_npc(dc, cpu_cond);
3929 tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3930 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a
BS
3931 dc->npc = DYNAMIC_PC;
3932 }
3933 goto jmp_insn;
3475187d 3934#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
0f8a249a
BS
3935 case 0x39: /* rett, V9 return */
3936 {
3937 if (!supervisor(dc))
3938 goto priv_insn;
6ae20372
BS
3939 gen_mov_pc_npc(dc, cpu_cond);
3940 tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3941 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a 3942 dc->npc = DYNAMIC_PC;
1a2fb1c0 3943 tcg_gen_helper_0_0(helper_rett);
0f8a249a
BS
3944 }
3945 goto jmp_insn;
3946#endif
3947 case 0x3b: /* flush */
6ae20372 3948 tcg_gen_helper_0_1(helper_flush, cpu_dst);
0f8a249a
BS
3949 break;
3950 case 0x3c: /* save */
6ae20372 3951 save_state(dc, cpu_cond);
72a9747b 3952 tcg_gen_helper_0_0(helper_save);
6ae20372 3953 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3954 break;
3955 case 0x3d: /* restore */
6ae20372 3956 save_state(dc, cpu_cond);
72a9747b 3957 tcg_gen_helper_0_0(helper_restore);
6ae20372 3958 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 3959 break;
3475187d 3960#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
0f8a249a
BS
3961 case 0x3e: /* V9 done/retry */
3962 {
3963 switch (rd) {
3964 case 0:
3965 if (!supervisor(dc))
3966 goto priv_insn;
3967 dc->npc = DYNAMIC_PC;
3968 dc->pc = DYNAMIC_PC;
1a2fb1c0 3969 tcg_gen_helper_0_0(helper_done);
0f8a249a
BS
3970 goto jmp_insn;
3971 case 1:
3972 if (!supervisor(dc))
3973 goto priv_insn;
3974 dc->npc = DYNAMIC_PC;
3975 dc->pc = DYNAMIC_PC;
1a2fb1c0 3976 tcg_gen_helper_0_0(helper_retry);
0f8a249a
BS
3977 goto jmp_insn;
3978 default:
3979 goto illegal_insn;
3980 }
3981 }
3982 break;
3983#endif
3984 default:
3985 goto illegal_insn;
3986 }
cf495bcf 3987 }
0f8a249a
BS
3988 break;
3989 }
3990 break;
3991 case 3: /* load/store instructions */
3992 {
3993 unsigned int xop = GET_FIELD(insn, 7, 12);
9322a4bf 3994
6ae20372 3995 save_state(dc, cpu_cond);
9322a4bf 3996 cpu_src1 = get_src1(insn, cpu_src1);
81ad8ba2
BS
3997 if (xop == 0x3c || xop == 0x3e)
3998 {
3999 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 4000 gen_movl_reg_TN(rs2, cpu_src2);
81ad8ba2
BS
4001 }
4002 else if (IS_IMM) { /* immediate */
0f8a249a 4003 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 4004 tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
0f8a249a
BS
4005 } else { /* register */
4006 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 4007 if (rs2 != 0) {
6ae20372
BS
4008 gen_movl_reg_TN(rs2, cpu_src2);
4009 tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
6f551262
BS
4010 } else
4011 tcg_gen_mov_tl(cpu_addr, cpu_src1);
0f8a249a 4012 }
2f2ecb83
BS
4013 if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4014 (xop > 0x17 && xop <= 0x1d ) ||
4015 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
0f8a249a 4016 switch (xop) {
1a2fb1c0 4017 case 0x0: /* load unsigned word */
6ae20372
BS
4018 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4019 ABI32_MASK(cpu_addr);
4020 tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4021 break;
4022 case 0x1: /* load unsigned byte */
6ae20372
BS
4023 ABI32_MASK(cpu_addr);
4024 tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4025 break;
4026 case 0x2: /* load unsigned halfword */
6ae20372
BS
4027 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4028 ABI32_MASK(cpu_addr);
4029 tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4030 break;
4031 case 0x3: /* load double word */
0f8a249a 4032 if (rd & 1)
d4218d99 4033 goto illegal_insn;
1a2fb1c0 4034 else {
6ae20372
BS
4035 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4036 ABI32_MASK(cpu_addr);
4037 tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
32b6c812
BS
4038 tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4039 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4040 gen_movl_TN_reg(rd + 1, cpu_tmp0);
8911f501 4041 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
6ae20372
BS
4042 tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4043 tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
1a2fb1c0 4044 }
0f8a249a
BS
4045 break;
4046 case 0x9: /* load signed byte */
6ae20372
BS
4047 ABI32_MASK(cpu_addr);
4048 tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4049 break;
4050 case 0xa: /* load signed halfword */
6ae20372
BS
4051 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4052 ABI32_MASK(cpu_addr);
4053 tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4054 break;
4055 case 0xd: /* ldstub -- XXX: should be atomically */
6ae20372
BS
4056 ABI32_MASK(cpu_addr);
4057 tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4058 tcg_gen_qemu_st8(tcg_const_tl(0xff), cpu_addr, dc->mem_idx);
0f8a249a
BS
4059 break;
4060 case 0x0f: /* swap register with memory. Also atomically */
6ae20372
BS
4061 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4062 gen_movl_reg_TN(rd, cpu_val);
4063 ABI32_MASK(cpu_addr);
4064 tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4065 tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4066 tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
0f8a249a 4067 break;
3475187d 4068#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
0f8a249a 4069 case 0x10: /* load word alternate */
3475187d 4070#ifndef TARGET_SPARC64
0f8a249a
BS
4071 if (IS_IMM)
4072 goto illegal_insn;
4073 if (!supervisor(dc))
4074 goto priv_insn;
6ea4a6c8 4075#endif
6ae20372
BS
4076 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4077 gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
0f8a249a
BS
4078 break;
4079 case 0x11: /* load unsigned byte alternate */
3475187d 4080#ifndef TARGET_SPARC64
0f8a249a
BS
4081 if (IS_IMM)
4082 goto illegal_insn;
4083 if (!supervisor(dc))
4084 goto priv_insn;
4085#endif
6ae20372 4086 gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
0f8a249a
BS
4087 break;
4088 case 0x12: /* load unsigned halfword alternate */
3475187d 4089#ifndef TARGET_SPARC64
0f8a249a
BS
4090 if (IS_IMM)
4091 goto illegal_insn;
4092 if (!supervisor(dc))
4093 goto priv_insn;
3475187d 4094#endif
6ae20372
BS
4095 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4096 gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
0f8a249a
BS
4097 break;
4098 case 0x13: /* load double word alternate */
3475187d 4099#ifndef TARGET_SPARC64
0f8a249a
BS
4100 if (IS_IMM)
4101 goto illegal_insn;
4102 if (!supervisor(dc))
4103 goto priv_insn;
3475187d 4104#endif
0f8a249a 4105 if (rd & 1)
d4218d99 4106 goto illegal_insn;
6ae20372
BS
4107 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4108 gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn);
32b6c812 4109 gen_movl_TN_reg(rd + 1, cpu_tmp0);
0f8a249a
BS
4110 break;
4111 case 0x19: /* load signed byte alternate */
3475187d 4112#ifndef TARGET_SPARC64
0f8a249a
BS
4113 if (IS_IMM)
4114 goto illegal_insn;
4115 if (!supervisor(dc))
4116 goto priv_insn;
4117#endif
6ae20372 4118 gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
0f8a249a
BS
4119 break;
4120 case 0x1a: /* load signed halfword alternate */
3475187d 4121#ifndef TARGET_SPARC64
0f8a249a
BS
4122 if (IS_IMM)
4123 goto illegal_insn;
4124 if (!supervisor(dc))
4125 goto priv_insn;
3475187d 4126#endif
6ae20372
BS
4127 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4128 gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
0f8a249a
BS
4129 break;
4130 case 0x1d: /* ldstuba -- XXX: should be atomically */
3475187d 4131#ifndef TARGET_SPARC64
0f8a249a
BS
4132 if (IS_IMM)
4133 goto illegal_insn;
4134 if (!supervisor(dc))
4135 goto priv_insn;
4136#endif
6ae20372 4137 gen_ldstub_asi(cpu_val, cpu_addr, insn);
0f8a249a
BS
4138 break;
4139 case 0x1f: /* swap reg with alt. memory. Also atomically */
3475187d 4140#ifndef TARGET_SPARC64
0f8a249a
BS
4141 if (IS_IMM)
4142 goto illegal_insn;
4143 if (!supervisor(dc))
4144 goto priv_insn;
6ea4a6c8 4145#endif
6ae20372
BS
4146 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4147 gen_movl_reg_TN(rd, cpu_val);
4148 gen_swap_asi(cpu_val, cpu_addr, insn);
0f8a249a 4149 break;
3475187d
FB
4150
4151#ifndef TARGET_SPARC64
0f8a249a
BS
4152 case 0x30: /* ldc */
4153 case 0x31: /* ldcsr */
4154 case 0x33: /* lddc */
4155 goto ncp_insn;
3475187d
FB
4156#endif
4157#endif
4158#ifdef TARGET_SPARC64
0f8a249a 4159 case 0x08: /* V9 ldsw */
6ae20372
BS
4160 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4161 ABI32_MASK(cpu_addr);
4162 tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4163 break;
4164 case 0x0b: /* V9 ldx */
6ae20372
BS
4165 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4166 ABI32_MASK(cpu_addr);
4167 tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4168 break;
4169 case 0x18: /* V9 ldswa */
6ae20372
BS
4170 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4171 gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
0f8a249a
BS
4172 break;
4173 case 0x1b: /* V9 ldxa */
6ae20372
BS
4174 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4175 gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
0f8a249a
BS
4176 break;
4177 case 0x2d: /* V9 prefetch, no effect */
4178 goto skip_move;
4179 case 0x30: /* V9 ldfa */
6ae20372
BS
4180 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4181 gen_ldf_asi(cpu_addr, insn, 4, rd);
81ad8ba2 4182 goto skip_move;
0f8a249a 4183 case 0x33: /* V9 lddfa */
6ae20372
BS
4184 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4185 gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
81ad8ba2 4186 goto skip_move;
0f8a249a
BS
4187 case 0x3d: /* V9 prefetcha, no effect */
4188 goto skip_move;
4189 case 0x32: /* V9 ldqfa */
1f587329 4190#if defined(CONFIG_USER_ONLY)
6ae20372
BS
4191 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4192 gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
1f587329
BS
4193 goto skip_move;
4194#else
0f8a249a 4195 goto nfpu_insn;
1f587329 4196#endif
0f8a249a
BS
4197#endif
4198 default:
4199 goto illegal_insn;
4200 }
6ae20372 4201 gen_movl_TN_reg(rd, cpu_val);
3475187d 4202#ifdef TARGET_SPARC64
0f8a249a 4203 skip_move: ;
3475187d 4204#endif
0f8a249a 4205 } else if (xop >= 0x20 && xop < 0x24) {
6ae20372 4206 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 4207 goto jmp_insn;
0f8a249a
BS
4208 switch (xop) {
4209 case 0x20: /* load fpreg */
6ae20372
BS
4210 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4211 tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
ce8536e2
BS
4212 tcg_gen_st_i32(cpu_tmp32, cpu_env,
4213 offsetof(CPUState, fpr[rd]));
0f8a249a
BS
4214 break;
4215 case 0x21: /* load fsr */
6ae20372
BS
4216 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4217 tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
ce8536e2
BS
4218 tcg_gen_st_i32(cpu_tmp32, cpu_env,
4219 offsetof(CPUState, ft0));
7e8c2b6c 4220 tcg_gen_helper_0_0(helper_ldfsr);
0f8a249a
BS
4221 break;
4222 case 0x22: /* load quad fpreg */
1f587329 4223#if defined(CONFIG_USER_ONLY)
6ae20372 4224 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
1f587329
BS
4225 gen_op_ldst(ldqf);
4226 gen_op_store_QT0_fpr(QFPREG(rd));
4227 break;
4228#else
0f8a249a 4229 goto nfpu_insn;
1f587329 4230#endif
0f8a249a 4231 case 0x23: /* load double fpreg */
6ae20372 4232 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
0f8a249a
BS
4233 gen_op_ldst(lddf);
4234 gen_op_store_DT0_fpr(DFPREG(rd));
4235 break;
4236 default:
4237 goto illegal_insn;
4238 }
4239 } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4240 xop == 0xe || xop == 0x1e) {
6ae20372 4241 gen_movl_reg_TN(rd, cpu_val);
0f8a249a 4242 switch (xop) {
1a2fb1c0 4243 case 0x4: /* store word */
6ae20372
BS
4244 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4245 ABI32_MASK(cpu_addr);
4246 tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4247 break;
1a2fb1c0 4248 case 0x5: /* store byte */
6ae20372
BS
4249 ABI32_MASK(cpu_addr);
4250 tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4251 break;
1a2fb1c0 4252 case 0x6: /* store halfword */
6ae20372
BS
4253 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4254 ABI32_MASK(cpu_addr);
4255 tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4256 break;
1a2fb1c0 4257 case 0x7: /* store double word */
0f8a249a 4258 if (rd & 1)
d4218d99 4259 goto illegal_insn;
b25deda7 4260#ifndef __i386__
1a2fb1c0 4261 else {
8911f501 4262 TCGv r_low;
1a2fb1c0 4263
6ae20372 4264 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
1a2fb1c0
BS
4265 r_low = tcg_temp_new(TCG_TYPE_I32);
4266 gen_movl_reg_TN(rd + 1, r_low);
6ae20372 4267 tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val,
1a2fb1c0 4268 r_low);
6ae20372 4269 tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
1a2fb1c0 4270 }
b25deda7 4271#else /* __i386__ */
6ae20372
BS
4272 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4273 flush_cond(dc, cpu_cond);
4274 gen_movl_reg_TN(rd + 1, cpu_cond);
b25deda7
BS
4275 gen_op_ldst(std);
4276#endif /* __i386__ */
0f8a249a 4277 break;
3475187d 4278#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1a2fb1c0 4279 case 0x14: /* store word alternate */
3475187d 4280#ifndef TARGET_SPARC64
0f8a249a
BS
4281 if (IS_IMM)
4282 goto illegal_insn;
4283 if (!supervisor(dc))
4284 goto priv_insn;
6ea4a6c8 4285#endif
6ae20372
BS
4286 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4287 gen_st_asi(cpu_val, cpu_addr, insn, 4);
d39c0b99 4288 break;
1a2fb1c0 4289 case 0x15: /* store byte alternate */
3475187d 4290#ifndef TARGET_SPARC64
0f8a249a
BS
4291 if (IS_IMM)
4292 goto illegal_insn;
4293 if (!supervisor(dc))
4294 goto priv_insn;
3475187d 4295#endif
6ae20372 4296 gen_st_asi(cpu_val, cpu_addr, insn, 1);
d39c0b99 4297 break;
1a2fb1c0 4298 case 0x16: /* store halfword alternate */
3475187d 4299#ifndef TARGET_SPARC64
0f8a249a
BS
4300 if (IS_IMM)
4301 goto illegal_insn;
4302 if (!supervisor(dc))
4303 goto priv_insn;
6ea4a6c8 4304#endif
6ae20372
BS
4305 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4306 gen_st_asi(cpu_val, cpu_addr, insn, 2);
d39c0b99 4307 break;
1a2fb1c0 4308 case 0x17: /* store double word alternate */
3475187d 4309#ifndef TARGET_SPARC64
0f8a249a
BS
4310 if (IS_IMM)
4311 goto illegal_insn;
4312 if (!supervisor(dc))
4313 goto priv_insn;
3475187d 4314#endif
0f8a249a 4315 if (rd & 1)
d4218d99 4316 goto illegal_insn;
1a2fb1c0 4317 else {
6ae20372
BS
4318 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4319 gen_stda_asi(cpu_val, cpu_addr, insn, rd);
1a2fb1c0 4320 }
d39c0b99 4321 break;
e80cfcfc 4322#endif
3475187d 4323#ifdef TARGET_SPARC64
0f8a249a 4324 case 0x0e: /* V9 stx */
6ae20372
BS
4325 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4326 ABI32_MASK(cpu_addr);
4327 tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4328 break;
4329 case 0x1e: /* V9 stxa */
6ae20372
BS
4330 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4331 gen_st_asi(cpu_val, cpu_addr, insn, 8);
0f8a249a 4332 break;
3475187d 4333#endif
0f8a249a
BS
4334 default:
4335 goto illegal_insn;
4336 }
4337 } else if (xop > 0x23 && xop < 0x28) {
6ae20372 4338 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 4339 goto jmp_insn;
0f8a249a 4340 switch (xop) {
ce8536e2 4341 case 0x24: /* store fpreg */
6ae20372 4342 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
ce8536e2
BS
4343 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4344 offsetof(CPUState, fpr[rd]));
6ae20372 4345 tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
0f8a249a
BS
4346 break;
4347 case 0x25: /* stfsr, V9 stxfsr */
6ea4a6c8 4348#ifdef CONFIG_USER_ONLY
6ae20372 4349 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
6ea4a6c8 4350#endif
bb5529bb 4351 tcg_gen_helper_0_0(helper_stfsr);
ce8536e2
BS
4352 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4353 offsetof(CPUState, ft0));
6ae20372 4354 tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
0f8a249a 4355 break;
1f587329
BS
4356 case 0x26:
4357#ifdef TARGET_SPARC64
4358#if defined(CONFIG_USER_ONLY)
4359 /* V9 stqf, store quad fpreg */
6ae20372 4360 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
1f587329
BS
4361 gen_op_load_fpr_QT0(QFPREG(rd));
4362 gen_op_ldst(stqf);
4363 break;
4364#else
4365 goto nfpu_insn;
4366#endif
4367#else /* !TARGET_SPARC64 */
4368 /* stdfq, store floating point queue */
4369#if defined(CONFIG_USER_ONLY)
4370 goto illegal_insn;
4371#else
0f8a249a
BS
4372 if (!supervisor(dc))
4373 goto priv_insn;
6ae20372 4374 if (gen_trap_ifnofpu(dc, cpu_cond))
0f8a249a
BS
4375 goto jmp_insn;
4376 goto nfq_insn;
1f587329 4377#endif
0f8a249a
BS
4378#endif
4379 case 0x27:
6ae20372 4380 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
3475187d 4381 gen_op_load_fpr_DT0(DFPREG(rd));
0f8a249a
BS
4382 gen_op_ldst(stdf);
4383 break;
4384 default:
4385 goto illegal_insn;
4386 }
4387 } else if (xop > 0x33 && xop < 0x3f) {
4388 switch (xop) {
a4d17f19 4389#ifdef TARGET_SPARC64
0f8a249a 4390 case 0x34: /* V9 stfa */
6ae20372 4391 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
3391c818 4392 gen_op_load_fpr_FT0(rd);
6ae20372 4393 gen_stf_asi(cpu_addr, insn, 4, rd);
0f8a249a 4394 break;
1f587329
BS
4395 case 0x36: /* V9 stqfa */
4396#if defined(CONFIG_USER_ONLY)
6ae20372 4397 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
1f587329 4398 gen_op_load_fpr_QT0(QFPREG(rd));
6ae20372 4399 gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
1f587329
BS
4400 break;
4401#else
4402 goto nfpu_insn;
4403#endif
0f8a249a 4404 case 0x37: /* V9 stdfa */
6ae20372 4405 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
3391c818 4406 gen_op_load_fpr_DT0(DFPREG(rd));
6ae20372 4407 gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
0f8a249a
BS
4408 break;
4409 case 0x3c: /* V9 casa */
6ae20372
BS
4410 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4411 gen_cas_asi(cpu_val, cpu_addr, cpu_val, insn, rd);
4412 gen_movl_TN_reg(rd, cpu_val);
0f8a249a
BS
4413 break;
4414 case 0x3e: /* V9 casxa */
6ae20372
BS
4415 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4416 gen_casx_asi(cpu_val, cpu_addr, cpu_val, insn, rd);
4417 gen_movl_TN_reg(rd, cpu_val);
0f8a249a 4418 break;
a4d17f19 4419#else
0f8a249a
BS
4420 case 0x34: /* stc */
4421 case 0x35: /* stcsr */
4422 case 0x36: /* stdcq */
4423 case 0x37: /* stdc */
4424 goto ncp_insn;
4425#endif
4426 default:
4427 goto illegal_insn;
4428 }
e8af50a3 4429 }
0f8a249a
BS
4430 else
4431 goto illegal_insn;
4432 }
4433 break;
cf495bcf
FB
4434 }
4435 /* default case for non jump instructions */
72cbca10 4436 if (dc->npc == DYNAMIC_PC) {
0f8a249a
BS
4437 dc->pc = DYNAMIC_PC;
4438 gen_op_next_insn();
72cbca10
FB
4439 } else if (dc->npc == JUMP_PC) {
4440 /* we can do a static jump */
6ae20372 4441 gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
72cbca10
FB
4442 dc->is_br = 1;
4443 } else {
0f8a249a
BS
4444 dc->pc = dc->npc;
4445 dc->npc = dc->npc + 4;
cf495bcf 4446 }
e80cfcfc 4447 jmp_insn:
cf495bcf
FB
4448 return;
4449 illegal_insn:
6ae20372 4450 save_state(dc, cpu_cond);
2f5680ee 4451 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_ILL_INSN));
cf495bcf 4452 dc->is_br = 1;
e8af50a3 4453 return;
e80cfcfc 4454#if !defined(CONFIG_USER_ONLY)
e8af50a3 4455 priv_insn:
6ae20372 4456 save_state(dc, cpu_cond);
2f5680ee 4457 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_PRIV_INSN));
e8af50a3 4458 dc->is_br = 1;
e80cfcfc 4459 return;
e80cfcfc 4460 nfpu_insn:
6ae20372 4461 save_state(dc, cpu_cond);
e80cfcfc
FB
4462 gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4463 dc->is_br = 1;
fcc72045 4464 return;
1f587329 4465#ifndef TARGET_SPARC64
9143e598 4466 nfq_insn:
6ae20372 4467 save_state(dc, cpu_cond);
9143e598
BS
4468 gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4469 dc->is_br = 1;
4470 return;
4471#endif
1f587329 4472#endif
fcc72045
BS
4473#ifndef TARGET_SPARC64
4474 ncp_insn:
6ae20372 4475 save_state(dc, cpu_cond);
2f5680ee 4476 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NCP_INSN));
fcc72045
BS
4477 dc->is_br = 1;
4478 return;
4479#endif
7a3f1944
FB
4480}
4481
1a2fb1c0
BS
4482static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4483{
4484}
4485
cf495bcf 4486static inline int gen_intermediate_code_internal(TranslationBlock * tb,
0f8a249a 4487 int spc, CPUSPARCState *env)
7a3f1944 4488{
72cbca10 4489 target_ulong pc_start, last_pc;
cf495bcf
FB
4490 uint16_t *gen_opc_end;
4491 DisasContext dc1, *dc = &dc1;
e8af50a3 4492 int j, lj = -1;
cf495bcf
FB
4493
4494 memset(dc, 0, sizeof(DisasContext));
cf495bcf 4495 dc->tb = tb;
72cbca10 4496 pc_start = tb->pc;
cf495bcf 4497 dc->pc = pc_start;
e80cfcfc 4498 last_pc = dc->pc;
72cbca10 4499 dc->npc = (target_ulong) tb->cs_base;
6f27aba6
BS
4500 dc->mem_idx = cpu_mmu_index(env);
4501 dc->fpu_enabled = cpu_fpu_enabled(env);
cf495bcf 4502 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
cf495bcf 4503
1a2fb1c0 4504 cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
8911f501
BS
4505 cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4506 cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
1a2fb1c0 4507
6ae20372
BS
4508 cpu_cond = cpu_T[2];
4509
cf495bcf 4510 do {
e8af50a3
FB
4511 if (env->nb_breakpoints > 0) {
4512 for(j = 0; j < env->nb_breakpoints; j++) {
4513 if (env->breakpoints[j] == dc->pc) {
0f8a249a 4514 if (dc->pc != pc_start)
6ae20372 4515 save_state(dc, cpu_cond);
1a2fb1c0 4516 tcg_gen_helper_0_0(helper_debug);
57fec1fe 4517 tcg_gen_exit_tb(0);
0f8a249a 4518 dc->is_br = 1;
e80cfcfc 4519 goto exit_gen_loop;
e8af50a3
FB
4520 }
4521 }
4522 }
4523 if (spc) {
4524 if (loglevel > 0)
4525 fprintf(logfile, "Search PC...\n");
4526 j = gen_opc_ptr - gen_opc_buf;
4527 if (lj < j) {
4528 lj++;
4529 while (lj < j)
4530 gen_opc_instr_start[lj++] = 0;
4531 gen_opc_pc[lj] = dc->pc;
4532 gen_opc_npc[lj] = dc->npc;
4533 gen_opc_instr_start[lj] = 1;
4534 }
4535 }
0f8a249a
BS
4536 last_pc = dc->pc;
4537 disas_sparc_insn(dc);
4538
4539 if (dc->is_br)
4540 break;
4541 /* if the next PC is different, we abort now */
4542 if (dc->pc != (last_pc + 4))
4543 break;
d39c0b99
FB
4544 /* if we reach a page boundary, we stop generation so that the
4545 PC of a TT_TFAULT exception is always in the right page */
4546 if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4547 break;
e80cfcfc
FB
4548 /* if single step mode, we generate only one instruction and
4549 generate an exception */
4550 if (env->singlestep_enabled) {
2f5680ee 4551 tcg_gen_movi_tl(cpu_pc, dc->pc);
57fec1fe 4552 tcg_gen_exit_tb(0);
e80cfcfc
FB
4553 break;
4554 }
cf495bcf 4555 } while ((gen_opc_ptr < gen_opc_end) &&
0f8a249a 4556 (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
e80cfcfc
FB
4557
4558 exit_gen_loop:
72cbca10 4559 if (!dc->is_br) {
5fafdf24 4560 if (dc->pc != DYNAMIC_PC &&
72cbca10
FB
4561 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4562 /* static PC and NPC: we can use direct chaining */
2f5680ee 4563 gen_goto_tb(dc, 0, dc->pc, dc->npc);
72cbca10
FB
4564 } else {
4565 if (dc->pc != DYNAMIC_PC)
2f5680ee 4566 tcg_gen_movi_tl(cpu_pc, dc->pc);
6ae20372 4567 save_npc(dc, cpu_cond);
57fec1fe 4568 tcg_gen_exit_tb(0);
72cbca10
FB
4569 }
4570 }
cf495bcf 4571 *gen_opc_ptr = INDEX_op_end;
e8af50a3
FB
4572 if (spc) {
4573 j = gen_opc_ptr - gen_opc_buf;
4574 lj++;
4575 while (lj <= j)
4576 gen_opc_instr_start[lj++] = 0;
e8af50a3
FB
4577#if 0
4578 if (loglevel > 0) {
4579 page_dump(logfile);
4580 }
4581#endif
c3278b7b
FB
4582 gen_opc_jump_pc[0] = dc->jump_pc[0];
4583 gen_opc_jump_pc[1] = dc->jump_pc[1];
e8af50a3 4584 } else {
e80cfcfc 4585 tb->size = last_pc + 4 - pc_start;
e8af50a3 4586 }
7a3f1944 4587#ifdef DEBUG_DISAS
e19e89a5 4588 if (loglevel & CPU_LOG_TB_IN_ASM) {
0f8a249a
BS
4589 fprintf(logfile, "--------------\n");
4590 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4591 target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4592 fprintf(logfile, "\n");
cf495bcf 4593 }
7a3f1944 4594#endif
cf495bcf 4595 return 0;
7a3f1944
FB
4596}
4597
cf495bcf 4598int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
7a3f1944 4599{
e8af50a3 4600 return gen_intermediate_code_internal(tb, 0, env);
7a3f1944
FB
4601}
4602
cf495bcf 4603int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
7a3f1944 4604{
e8af50a3 4605 return gen_intermediate_code_internal(tb, 1, env);
7a3f1944
FB
4606}
4607
c48fcb47 4608void gen_intermediate_code_init(CPUSPARCState *env)
e80cfcfc 4609{
f5069b26 4610 unsigned int i;
c48fcb47 4611 static int inited;
f5069b26
BS
4612 static const char * const gregnames[8] = {
4613 NULL, // g0 not used
4614 "g1",
4615 "g2",
4616 "g3",
4617 "g4",
4618 "g5",
4619 "g6",
4620 "g7",
4621 };
aaed909a 4622
1a2fb1c0
BS
4623 /* init various static tables */
4624 if (!inited) {
4625 inited = 1;
4626
4627 tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4628 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
db4a4ea4
BS
4629 cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4630 offsetof(CPUState, regwptr),
4631 "regwptr");
1a2fb1c0
BS
4632 //#if TARGET_LONG_BITS > HOST_LONG_BITS
4633#ifdef TARGET_SPARC64
4634 cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4635 TCG_AREG0, offsetof(CPUState, t0), "T0");
4636 cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4637 TCG_AREG0, offsetof(CPUState, t1), "T1");
4638 cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
4639 TCG_AREG0, offsetof(CPUState, t2), "T2");
dc99a3f2
BS
4640 cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4641 TCG_AREG0, offsetof(CPUState, xcc),
4642 "xcc");
1a2fb1c0
BS
4643#else
4644 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
4645 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
4646 cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
4647#endif
dc99a3f2
BS
4648 cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4649 TCG_AREG0, offsetof(CPUState, cc_src),
4650 "cc_src");
d9bdab86
BS
4651 cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4652 offsetof(CPUState, cc_src2),
4653 "cc_src2");
dc99a3f2
BS
4654 cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4655 TCG_AREG0, offsetof(CPUState, cc_dst),
4656 "cc_dst");
4657 cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4658 TCG_AREG0, offsetof(CPUState, psr),
4659 "psr");
87e92502
BS
4660 cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4661 TCG_AREG0, offsetof(CPUState, fsr),
4662 "fsr");
48d5c82b
BS
4663 cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4664 TCG_AREG0, offsetof(CPUState, pc),
4665 "pc");
4666 cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4667 TCG_AREG0, offsetof(CPUState, npc),
4668 "npc");
f5069b26
BS
4669 for (i = 1; i < 8; i++)
4670 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4671 offsetof(CPUState, gregs[i]),
4672 gregnames[i]);
1a2fb1c0 4673 }
658138bc 4674}
d2856f1a
AJ
4675
4676void gen_pc_load(CPUState *env, TranslationBlock *tb,
4677 unsigned long searched_pc, int pc_pos, void *puc)
4678{
4679 target_ulong npc;
4680 env->pc = gen_opc_pc[pc_pos];
4681 npc = gen_opc_npc[pc_pos];
4682 if (npc == 1) {
4683 /* dynamic NPC: already stored */
4684 } else if (npc == 2) {
4685 target_ulong t2 = (target_ulong)(unsigned long)puc;
4686 /* jump PC: use T2 and the jump targets of the translation */
4687 if (t2)
4688 env->npc = gen_opc_jump_pc[0];
4689 else
4690 env->npc = gen_opc_jump_pc[1];
4691 } else {
4692 env->npc = npc;
4693 }
4694}
This page took 0.963336 seconds and 4 git commands to generate.