xref: /openbmc/qemu/target/sparc/translate.c (revision 0b29090a)
1 /*
2    SPARC translation
3 
4    Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5    Copyright (C) 2003-2005 Fabrice Bellard
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.1 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, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "qemu/osdep.h"
22 
23 #include "cpu.h"
24 #include "disas/disas.h"
25 #include "exec/helper-proto.h"
26 #include "exec/exec-all.h"
27 #include "tcg/tcg-op.h"
28 #include "exec/cpu_ldst.h"
29 
30 #include "exec/helper-gen.h"
31 
32 #include "exec/translator.h"
33 #include "exec/log.h"
34 #include "asi.h"
35 
36 
37 #define DEBUG_DISAS
38 
39 #define DYNAMIC_PC  1 /* dynamic pc value */
40 #define JUMP_PC     2 /* dynamic pc value which takes only two values
41                          according to jump_pc[T2] */
42 
43 #define DISAS_EXIT  DISAS_TARGET_0
44 
45 /* global register indexes */
46 static TCGv_ptr cpu_regwptr;
47 static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
48 static TCGv_i32 cpu_cc_op;
49 static TCGv_i32 cpu_psr;
50 static TCGv cpu_fsr, cpu_pc, cpu_npc;
51 static TCGv cpu_regs[32];
52 static TCGv cpu_y;
53 #ifndef CONFIG_USER_ONLY
54 static TCGv cpu_tbr;
55 #endif
56 static TCGv cpu_cond;
57 #ifdef TARGET_SPARC64
58 static TCGv_i32 cpu_xcc, cpu_fprs;
59 static TCGv cpu_gsr;
60 static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
61 static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
62 #else
63 static TCGv cpu_wim;
64 #endif
65 /* Floating point registers */
66 static TCGv_i64 cpu_fpr[TARGET_DPREGS];
67 
68 #include "exec/gen-icount.h"
69 
70 typedef struct DisasContext {
71     DisasContextBase base;
72     target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
73     target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
74     target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
75     int mem_idx;
76     bool fpu_enabled;
77     bool address_mask_32bit;
78 #ifndef CONFIG_USER_ONLY
79     bool supervisor;
80 #ifdef TARGET_SPARC64
81     bool hypervisor;
82 #endif
83 #endif
84 
85     uint32_t cc_op;  /* current CC operation */
86     sparc_def_t *def;
87 #ifdef TARGET_SPARC64
88     int fprs_dirty;
89     int asi;
90 #endif
91 } DisasContext;
92 
93 typedef struct {
94     TCGCond cond;
95     bool is_bool;
96     TCGv c1, c2;
97 } DisasCompare;
98 
99 // This function uses non-native bit order
100 #define GET_FIELD(X, FROM, TO)                                  \
101     ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
102 
103 // This function uses the order in the manuals, i.e. bit 0 is 2^0
104 #define GET_FIELD_SP(X, FROM, TO)               \
105     GET_FIELD(X, 31 - (TO), 31 - (FROM))
106 
107 #define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
108 #define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
109 
110 #ifdef TARGET_SPARC64
111 #define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
112 #define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
113 #else
114 #define DFPREG(r) (r & 0x1e)
115 #define QFPREG(r) (r & 0x1c)
116 #endif
117 
118 #define UA2005_HTRAP_MASK 0xff
119 #define V8_TRAP_MASK 0x7f
120 
121 static int sign_extend(int x, int len)
122 {
123     len = 32 - len;
124     return (x << len) >> len;
125 }
126 
127 #define IS_IMM (insn & (1<<13))
128 
129 static inline void gen_update_fprs_dirty(DisasContext *dc, int rd)
130 {
131 #if defined(TARGET_SPARC64)
132     int bit = (rd < 32) ? 1 : 2;
133     /* If we know we've already set this bit within the TB,
134        we can avoid setting it again.  */
135     if (!(dc->fprs_dirty & bit)) {
136         dc->fprs_dirty |= bit;
137         tcg_gen_ori_i32(cpu_fprs, cpu_fprs, bit);
138     }
139 #endif
140 }
141 
142 /* floating point registers moves */
143 static TCGv_i32 gen_load_fpr_F(DisasContext *dc, unsigned int src)
144 {
145     TCGv_i32 ret = tcg_temp_new_i32();
146     if (src & 1) {
147         tcg_gen_extrl_i64_i32(ret, cpu_fpr[src / 2]);
148     } else {
149         tcg_gen_extrh_i64_i32(ret, cpu_fpr[src / 2]);
150     }
151     return ret;
152 }
153 
154 static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v)
155 {
156     TCGv_i64 t = tcg_temp_new_i64();
157 
158     tcg_gen_extu_i32_i64(t, v);
159     tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t,
160                         (dst & 1 ? 0 : 32), 32);
161     gen_update_fprs_dirty(dc, dst);
162 }
163 
164 static TCGv_i32 gen_dest_fpr_F(DisasContext *dc)
165 {
166     return tcg_temp_new_i32();
167 }
168 
169 static TCGv_i64 gen_load_fpr_D(DisasContext *dc, unsigned int src)
170 {
171     src = DFPREG(src);
172     return cpu_fpr[src / 2];
173 }
174 
175 static void gen_store_fpr_D(DisasContext *dc, unsigned int dst, TCGv_i64 v)
176 {
177     dst = DFPREG(dst);
178     tcg_gen_mov_i64(cpu_fpr[dst / 2], v);
179     gen_update_fprs_dirty(dc, dst);
180 }
181 
182 static TCGv_i64 gen_dest_fpr_D(DisasContext *dc, unsigned int dst)
183 {
184     return cpu_fpr[DFPREG(dst) / 2];
185 }
186 
187 static void gen_op_load_fpr_QT0(unsigned int src)
188 {
189     tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt0) +
190                    offsetof(CPU_QuadU, ll.upper));
191     tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
192                    offsetof(CPU_QuadU, ll.lower));
193 }
194 
195 static void gen_op_load_fpr_QT1(unsigned int src)
196 {
197     tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt1) +
198                    offsetof(CPU_QuadU, ll.upper));
199     tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt1) +
200                    offsetof(CPU_QuadU, ll.lower));
201 }
202 
203 static void gen_op_store_QT0_fpr(unsigned int dst)
204 {
205     tcg_gen_ld_i64(cpu_fpr[dst / 2], cpu_env, offsetof(CPUSPARCState, qt0) +
206                    offsetof(CPU_QuadU, ll.upper));
207     tcg_gen_ld_i64(cpu_fpr[dst/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
208                    offsetof(CPU_QuadU, ll.lower));
209 }
210 
211 static void gen_store_fpr_Q(DisasContext *dc, unsigned int dst,
212                             TCGv_i64 v1, TCGv_i64 v2)
213 {
214     dst = QFPREG(dst);
215 
216     tcg_gen_mov_i64(cpu_fpr[dst / 2], v1);
217     tcg_gen_mov_i64(cpu_fpr[dst / 2 + 1], v2);
218     gen_update_fprs_dirty(dc, dst);
219 }
220 
221 #ifdef TARGET_SPARC64
222 static TCGv_i64 gen_load_fpr_Q0(DisasContext *dc, unsigned int src)
223 {
224     src = QFPREG(src);
225     return cpu_fpr[src / 2];
226 }
227 
228 static TCGv_i64 gen_load_fpr_Q1(DisasContext *dc, unsigned int src)
229 {
230     src = QFPREG(src);
231     return cpu_fpr[src / 2 + 1];
232 }
233 
234 static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
235 {
236     rd = QFPREG(rd);
237     rs = QFPREG(rs);
238 
239     tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]);
240     tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]);
241     gen_update_fprs_dirty(dc, rd);
242 }
243 #endif
244 
245 /* moves */
246 #ifdef CONFIG_USER_ONLY
247 #define supervisor(dc) 0
248 #ifdef TARGET_SPARC64
249 #define hypervisor(dc) 0
250 #endif
251 #else
252 #ifdef TARGET_SPARC64
253 #define hypervisor(dc) (dc->hypervisor)
254 #define supervisor(dc) (dc->supervisor | dc->hypervisor)
255 #else
256 #define supervisor(dc) (dc->supervisor)
257 #endif
258 #endif
259 
260 #ifdef TARGET_SPARC64
261 #ifndef TARGET_ABI32
262 #define AM_CHECK(dc) ((dc)->address_mask_32bit)
263 #else
264 #define AM_CHECK(dc) (1)
265 #endif
266 #endif
267 
268 static inline void gen_address_mask(DisasContext *dc, TCGv addr)
269 {
270 #ifdef TARGET_SPARC64
271     if (AM_CHECK(dc))
272         tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
273 #endif
274 }
275 
276 static inline TCGv gen_load_gpr(DisasContext *dc, int reg)
277 {
278     if (reg > 0) {
279         assert(reg < 32);
280         return cpu_regs[reg];
281     } else {
282         TCGv t = tcg_temp_new();
283         tcg_gen_movi_tl(t, 0);
284         return t;
285     }
286 }
287 
288 static inline void gen_store_gpr(DisasContext *dc, int reg, TCGv v)
289 {
290     if (reg > 0) {
291         assert(reg < 32);
292         tcg_gen_mov_tl(cpu_regs[reg], v);
293     }
294 }
295 
296 static inline TCGv gen_dest_gpr(DisasContext *dc, int reg)
297 {
298     if (reg > 0) {
299         assert(reg < 32);
300         return cpu_regs[reg];
301     } else {
302         return tcg_temp_new();
303     }
304 }
305 
306 static bool use_goto_tb(DisasContext *s, target_ulong pc, target_ulong npc)
307 {
308     return translator_use_goto_tb(&s->base, pc) &&
309            translator_use_goto_tb(&s->base, npc);
310 }
311 
312 static void gen_goto_tb(DisasContext *s, int tb_num,
313                         target_ulong pc, target_ulong npc)
314 {
315     if (use_goto_tb(s, pc, npc))  {
316         /* jump to same page: we can use a direct jump */
317         tcg_gen_goto_tb(tb_num);
318         tcg_gen_movi_tl(cpu_pc, pc);
319         tcg_gen_movi_tl(cpu_npc, npc);
320         tcg_gen_exit_tb(s->base.tb, tb_num);
321     } else {
322         /* jump to another page: currently not optimized */
323         tcg_gen_movi_tl(cpu_pc, pc);
324         tcg_gen_movi_tl(cpu_npc, npc);
325         tcg_gen_exit_tb(NULL, 0);
326     }
327 }
328 
329 // XXX suboptimal
330 static inline void gen_mov_reg_N(TCGv reg, TCGv_i32 src)
331 {
332     tcg_gen_extu_i32_tl(reg, src);
333     tcg_gen_extract_tl(reg, reg, PSR_NEG_SHIFT, 1);
334 }
335 
336 static inline void gen_mov_reg_Z(TCGv reg, TCGv_i32 src)
337 {
338     tcg_gen_extu_i32_tl(reg, src);
339     tcg_gen_extract_tl(reg, reg, PSR_ZERO_SHIFT, 1);
340 }
341 
342 static inline void gen_mov_reg_V(TCGv reg, TCGv_i32 src)
343 {
344     tcg_gen_extu_i32_tl(reg, src);
345     tcg_gen_extract_tl(reg, reg, PSR_OVF_SHIFT, 1);
346 }
347 
348 static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
349 {
350     tcg_gen_extu_i32_tl(reg, src);
351     tcg_gen_extract_tl(reg, reg, PSR_CARRY_SHIFT, 1);
352 }
353 
354 static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
355 {
356     tcg_gen_mov_tl(cpu_cc_src, src1);
357     tcg_gen_mov_tl(cpu_cc_src2, src2);
358     tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
359     tcg_gen_mov_tl(dst, cpu_cc_dst);
360 }
361 
362 static TCGv_i32 gen_add32_carry32(void)
363 {
364     TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
365 
366     /* Carry is computed from a previous add: (dst < src)  */
367 #if TARGET_LONG_BITS == 64
368     cc_src1_32 = tcg_temp_new_i32();
369     cc_src2_32 = tcg_temp_new_i32();
370     tcg_gen_extrl_i64_i32(cc_src1_32, cpu_cc_dst);
371     tcg_gen_extrl_i64_i32(cc_src2_32, cpu_cc_src);
372 #else
373     cc_src1_32 = cpu_cc_dst;
374     cc_src2_32 = cpu_cc_src;
375 #endif
376 
377     carry_32 = tcg_temp_new_i32();
378     tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
379 
380     return carry_32;
381 }
382 
383 static TCGv_i32 gen_sub32_carry32(void)
384 {
385     TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
386 
387     /* Carry is computed from a previous borrow: (src1 < src2)  */
388 #if TARGET_LONG_BITS == 64
389     cc_src1_32 = tcg_temp_new_i32();
390     cc_src2_32 = tcg_temp_new_i32();
391     tcg_gen_extrl_i64_i32(cc_src1_32, cpu_cc_src);
392     tcg_gen_extrl_i64_i32(cc_src2_32, cpu_cc_src2);
393 #else
394     cc_src1_32 = cpu_cc_src;
395     cc_src2_32 = cpu_cc_src2;
396 #endif
397 
398     carry_32 = tcg_temp_new_i32();
399     tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
400 
401     return carry_32;
402 }
403 
404 static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
405                             TCGv src2, int update_cc)
406 {
407     TCGv_i32 carry_32;
408     TCGv carry;
409 
410     switch (dc->cc_op) {
411     case CC_OP_DIV:
412     case CC_OP_LOGIC:
413         /* Carry is known to be zero.  Fall back to plain ADD.  */
414         if (update_cc) {
415             gen_op_add_cc(dst, src1, src2);
416         } else {
417             tcg_gen_add_tl(dst, src1, src2);
418         }
419         return;
420 
421     case CC_OP_ADD:
422     case CC_OP_TADD:
423     case CC_OP_TADDTV:
424         if (TARGET_LONG_BITS == 32) {
425             /* We can re-use the host's hardware carry generation by using
426                an ADD2 opcode.  We discard the low part of the output.
427                Ideally we'd combine this operation with the add that
428                generated the carry in the first place.  */
429             carry = tcg_temp_new();
430             tcg_gen_add2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
431             goto add_done;
432         }
433         carry_32 = gen_add32_carry32();
434         break;
435 
436     case CC_OP_SUB:
437     case CC_OP_TSUB:
438     case CC_OP_TSUBTV:
439         carry_32 = gen_sub32_carry32();
440         break;
441 
442     default:
443         /* We need external help to produce the carry.  */
444         carry_32 = tcg_temp_new_i32();
445         gen_helper_compute_C_icc(carry_32, cpu_env);
446         break;
447     }
448 
449 #if TARGET_LONG_BITS == 64
450     carry = tcg_temp_new();
451     tcg_gen_extu_i32_i64(carry, carry_32);
452 #else
453     carry = carry_32;
454 #endif
455 
456     tcg_gen_add_tl(dst, src1, src2);
457     tcg_gen_add_tl(dst, dst, carry);
458 
459  add_done:
460     if (update_cc) {
461         tcg_gen_mov_tl(cpu_cc_src, src1);
462         tcg_gen_mov_tl(cpu_cc_src2, src2);
463         tcg_gen_mov_tl(cpu_cc_dst, dst);
464         tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADDX);
465         dc->cc_op = CC_OP_ADDX;
466     }
467 }
468 
469 static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
470 {
471     tcg_gen_mov_tl(cpu_cc_src, src1);
472     tcg_gen_mov_tl(cpu_cc_src2, src2);
473     tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
474     tcg_gen_mov_tl(dst, cpu_cc_dst);
475 }
476 
477 static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
478                             TCGv src2, int update_cc)
479 {
480     TCGv_i32 carry_32;
481     TCGv carry;
482 
483     switch (dc->cc_op) {
484     case CC_OP_DIV:
485     case CC_OP_LOGIC:
486         /* Carry is known to be zero.  Fall back to plain SUB.  */
487         if (update_cc) {
488             gen_op_sub_cc(dst, src1, src2);
489         } else {
490             tcg_gen_sub_tl(dst, src1, src2);
491         }
492         return;
493 
494     case CC_OP_ADD:
495     case CC_OP_TADD:
496     case CC_OP_TADDTV:
497         carry_32 = gen_add32_carry32();
498         break;
499 
500     case CC_OP_SUB:
501     case CC_OP_TSUB:
502     case CC_OP_TSUBTV:
503         if (TARGET_LONG_BITS == 32) {
504             /* We can re-use the host's hardware carry generation by using
505                a SUB2 opcode.  We discard the low part of the output.
506                Ideally we'd combine this operation with the add that
507                generated the carry in the first place.  */
508             carry = tcg_temp_new();
509             tcg_gen_sub2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
510             goto sub_done;
511         }
512         carry_32 = gen_sub32_carry32();
513         break;
514 
515     default:
516         /* We need external help to produce the carry.  */
517         carry_32 = tcg_temp_new_i32();
518         gen_helper_compute_C_icc(carry_32, cpu_env);
519         break;
520     }
521 
522 #if TARGET_LONG_BITS == 64
523     carry = tcg_temp_new();
524     tcg_gen_extu_i32_i64(carry, carry_32);
525 #else
526     carry = carry_32;
527 #endif
528 
529     tcg_gen_sub_tl(dst, src1, src2);
530     tcg_gen_sub_tl(dst, dst, carry);
531 
532  sub_done:
533     if (update_cc) {
534         tcg_gen_mov_tl(cpu_cc_src, src1);
535         tcg_gen_mov_tl(cpu_cc_src2, src2);
536         tcg_gen_mov_tl(cpu_cc_dst, dst);
537         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUBX);
538         dc->cc_op = CC_OP_SUBX;
539     }
540 }
541 
542 static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
543 {
544     TCGv r_temp, zero, t0;
545 
546     r_temp = tcg_temp_new();
547     t0 = tcg_temp_new();
548 
549     /* old op:
550     if (!(env->y & 1))
551         T1 = 0;
552     */
553     zero = tcg_constant_tl(0);
554     tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
555     tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
556     tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
557     tcg_gen_movcond_tl(TCG_COND_EQ, cpu_cc_src2, r_temp, zero,
558                        zero, cpu_cc_src2);
559 
560     // b2 = T0 & 1;
561     // env->y = (b2 << 31) | (env->y >> 1);
562     tcg_gen_extract_tl(t0, cpu_y, 1, 31);
563     tcg_gen_deposit_tl(cpu_y, t0, cpu_cc_src, 31, 1);
564 
565     // b1 = N ^ V;
566     gen_mov_reg_N(t0, cpu_psr);
567     gen_mov_reg_V(r_temp, cpu_psr);
568     tcg_gen_xor_tl(t0, t0, r_temp);
569 
570     // T0 = (b1 << 31) | (T0 >> 1);
571     // src1 = T0;
572     tcg_gen_shli_tl(t0, t0, 31);
573     tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
574     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
575 
576     tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
577 
578     tcg_gen_mov_tl(dst, cpu_cc_dst);
579 }
580 
581 static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)
582 {
583 #if TARGET_LONG_BITS == 32
584     if (sign_ext) {
585         tcg_gen_muls2_tl(dst, cpu_y, src1, src2);
586     } else {
587         tcg_gen_mulu2_tl(dst, cpu_y, src1, src2);
588     }
589 #else
590     TCGv t0 = tcg_temp_new_i64();
591     TCGv t1 = tcg_temp_new_i64();
592 
593     if (sign_ext) {
594         tcg_gen_ext32s_i64(t0, src1);
595         tcg_gen_ext32s_i64(t1, src2);
596     } else {
597         tcg_gen_ext32u_i64(t0, src1);
598         tcg_gen_ext32u_i64(t1, src2);
599     }
600 
601     tcg_gen_mul_i64(dst, t0, t1);
602     tcg_gen_shri_i64(cpu_y, dst, 32);
603 #endif
604 }
605 
606 static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
607 {
608     /* zero-extend truncated operands before multiplication */
609     gen_op_multiply(dst, src1, src2, 0);
610 }
611 
612 static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
613 {
614     /* sign-extend truncated operands before multiplication */
615     gen_op_multiply(dst, src1, src2, 1);
616 }
617 
618 // 1
619 static inline void gen_op_eval_ba(TCGv dst)
620 {
621     tcg_gen_movi_tl(dst, 1);
622 }
623 
624 // Z
625 static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
626 {
627     gen_mov_reg_Z(dst, src);
628 }
629 
630 // Z | (N ^ V)
631 static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
632 {
633     TCGv t0 = tcg_temp_new();
634     gen_mov_reg_N(t0, src);
635     gen_mov_reg_V(dst, src);
636     tcg_gen_xor_tl(dst, dst, t0);
637     gen_mov_reg_Z(t0, src);
638     tcg_gen_or_tl(dst, dst, t0);
639 }
640 
641 // N ^ V
642 static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
643 {
644     TCGv t0 = tcg_temp_new();
645     gen_mov_reg_V(t0, src);
646     gen_mov_reg_N(dst, src);
647     tcg_gen_xor_tl(dst, dst, t0);
648 }
649 
650 // C | Z
651 static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
652 {
653     TCGv t0 = tcg_temp_new();
654     gen_mov_reg_Z(t0, src);
655     gen_mov_reg_C(dst, src);
656     tcg_gen_or_tl(dst, dst, t0);
657 }
658 
659 // C
660 static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
661 {
662     gen_mov_reg_C(dst, src);
663 }
664 
665 // V
666 static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
667 {
668     gen_mov_reg_V(dst, src);
669 }
670 
671 // 0
672 static inline void gen_op_eval_bn(TCGv dst)
673 {
674     tcg_gen_movi_tl(dst, 0);
675 }
676 
677 // N
678 static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
679 {
680     gen_mov_reg_N(dst, src);
681 }
682 
683 // !Z
684 static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
685 {
686     gen_mov_reg_Z(dst, src);
687     tcg_gen_xori_tl(dst, dst, 0x1);
688 }
689 
690 // !(Z | (N ^ V))
691 static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
692 {
693     gen_op_eval_ble(dst, src);
694     tcg_gen_xori_tl(dst, dst, 0x1);
695 }
696 
697 // !(N ^ V)
698 static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
699 {
700     gen_op_eval_bl(dst, src);
701     tcg_gen_xori_tl(dst, dst, 0x1);
702 }
703 
704 // !(C | Z)
705 static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
706 {
707     gen_op_eval_bleu(dst, src);
708     tcg_gen_xori_tl(dst, dst, 0x1);
709 }
710 
711 // !C
712 static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
713 {
714     gen_mov_reg_C(dst, src);
715     tcg_gen_xori_tl(dst, dst, 0x1);
716 }
717 
718 // !N
719 static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
720 {
721     gen_mov_reg_N(dst, src);
722     tcg_gen_xori_tl(dst, dst, 0x1);
723 }
724 
725 // !V
726 static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
727 {
728     gen_mov_reg_V(dst, src);
729     tcg_gen_xori_tl(dst, dst, 0x1);
730 }
731 
732 /*
733   FPSR bit field FCC1 | FCC0:
734    0 =
735    1 <
736    2 >
737    3 unordered
738 */
739 static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
740                                     unsigned int fcc_offset)
741 {
742     tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
743     tcg_gen_andi_tl(reg, reg, 0x1);
744 }
745 
746 static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
747                                     unsigned int fcc_offset)
748 {
749     tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
750     tcg_gen_andi_tl(reg, reg, 0x1);
751 }
752 
753 // !0: FCC0 | FCC1
754 static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
755                                     unsigned int fcc_offset)
756 {
757     TCGv t0 = tcg_temp_new();
758     gen_mov_reg_FCC0(dst, src, fcc_offset);
759     gen_mov_reg_FCC1(t0, src, fcc_offset);
760     tcg_gen_or_tl(dst, dst, t0);
761 }
762 
763 // 1 or 2: FCC0 ^ FCC1
764 static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
765                                     unsigned int fcc_offset)
766 {
767     TCGv t0 = tcg_temp_new();
768     gen_mov_reg_FCC0(dst, src, fcc_offset);
769     gen_mov_reg_FCC1(t0, src, fcc_offset);
770     tcg_gen_xor_tl(dst, dst, t0);
771 }
772 
773 // 1 or 3: FCC0
774 static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
775                                     unsigned int fcc_offset)
776 {
777     gen_mov_reg_FCC0(dst, src, fcc_offset);
778 }
779 
780 // 1: FCC0 & !FCC1
781 static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
782                                     unsigned int fcc_offset)
783 {
784     TCGv t0 = tcg_temp_new();
785     gen_mov_reg_FCC0(dst, src, fcc_offset);
786     gen_mov_reg_FCC1(t0, src, fcc_offset);
787     tcg_gen_andc_tl(dst, dst, t0);
788 }
789 
790 // 2 or 3: FCC1
791 static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
792                                     unsigned int fcc_offset)
793 {
794     gen_mov_reg_FCC1(dst, src, fcc_offset);
795 }
796 
797 // 2: !FCC0 & FCC1
798 static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
799                                     unsigned int fcc_offset)
800 {
801     TCGv t0 = tcg_temp_new();
802     gen_mov_reg_FCC0(dst, src, fcc_offset);
803     gen_mov_reg_FCC1(t0, src, fcc_offset);
804     tcg_gen_andc_tl(dst, t0, dst);
805 }
806 
807 // 3: FCC0 & FCC1
808 static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
809                                     unsigned int fcc_offset)
810 {
811     TCGv t0 = tcg_temp_new();
812     gen_mov_reg_FCC0(dst, src, fcc_offset);
813     gen_mov_reg_FCC1(t0, src, fcc_offset);
814     tcg_gen_and_tl(dst, dst, t0);
815 }
816 
817 // 0: !(FCC0 | FCC1)
818 static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
819                                     unsigned int fcc_offset)
820 {
821     TCGv t0 = tcg_temp_new();
822     gen_mov_reg_FCC0(dst, src, fcc_offset);
823     gen_mov_reg_FCC1(t0, src, fcc_offset);
824     tcg_gen_or_tl(dst, dst, t0);
825     tcg_gen_xori_tl(dst, dst, 0x1);
826 }
827 
828 // 0 or 3: !(FCC0 ^ FCC1)
829 static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
830                                     unsigned int fcc_offset)
831 {
832     TCGv t0 = tcg_temp_new();
833     gen_mov_reg_FCC0(dst, src, fcc_offset);
834     gen_mov_reg_FCC1(t0, src, fcc_offset);
835     tcg_gen_xor_tl(dst, dst, t0);
836     tcg_gen_xori_tl(dst, dst, 0x1);
837 }
838 
839 // 0 or 2: !FCC0
840 static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
841                                     unsigned int fcc_offset)
842 {
843     gen_mov_reg_FCC0(dst, src, fcc_offset);
844     tcg_gen_xori_tl(dst, dst, 0x1);
845 }
846 
847 // !1: !(FCC0 & !FCC1)
848 static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
849                                     unsigned int fcc_offset)
850 {
851     TCGv t0 = tcg_temp_new();
852     gen_mov_reg_FCC0(dst, src, fcc_offset);
853     gen_mov_reg_FCC1(t0, src, fcc_offset);
854     tcg_gen_andc_tl(dst, dst, t0);
855     tcg_gen_xori_tl(dst, dst, 0x1);
856 }
857 
858 // 0 or 1: !FCC1
859 static inline void gen_op_eval_fble(TCGv dst, TCGv src,
860                                     unsigned int fcc_offset)
861 {
862     gen_mov_reg_FCC1(dst, src, fcc_offset);
863     tcg_gen_xori_tl(dst, dst, 0x1);
864 }
865 
866 // !2: !(!FCC0 & FCC1)
867 static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
868                                     unsigned int fcc_offset)
869 {
870     TCGv t0 = tcg_temp_new();
871     gen_mov_reg_FCC0(dst, src, fcc_offset);
872     gen_mov_reg_FCC1(t0, src, fcc_offset);
873     tcg_gen_andc_tl(dst, t0, dst);
874     tcg_gen_xori_tl(dst, dst, 0x1);
875 }
876 
877 // !3: !(FCC0 & FCC1)
878 static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
879                                     unsigned int fcc_offset)
880 {
881     TCGv t0 = tcg_temp_new();
882     gen_mov_reg_FCC0(dst, src, fcc_offset);
883     gen_mov_reg_FCC1(t0, src, fcc_offset);
884     tcg_gen_and_tl(dst, dst, t0);
885     tcg_gen_xori_tl(dst, dst, 0x1);
886 }
887 
888 static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
889                                target_ulong pc2, TCGv r_cond)
890 {
891     TCGLabel *l1 = gen_new_label();
892 
893     tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
894 
895     gen_goto_tb(dc, 0, pc1, pc1 + 4);
896 
897     gen_set_label(l1);
898     gen_goto_tb(dc, 1, pc2, pc2 + 4);
899 }
900 
901 static void gen_branch_a(DisasContext *dc, target_ulong pc1)
902 {
903     TCGLabel *l1 = gen_new_label();
904     target_ulong npc = dc->npc;
905 
906     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cond, 0, l1);
907 
908     gen_goto_tb(dc, 0, npc, pc1);
909 
910     gen_set_label(l1);
911     gen_goto_tb(dc, 1, npc + 4, npc + 8);
912 
913     dc->base.is_jmp = DISAS_NORETURN;
914 }
915 
916 static void gen_branch_n(DisasContext *dc, target_ulong pc1)
917 {
918     target_ulong npc = dc->npc;
919 
920     if (likely(npc != DYNAMIC_PC)) {
921         dc->pc = npc;
922         dc->jump_pc[0] = pc1;
923         dc->jump_pc[1] = npc + 4;
924         dc->npc = JUMP_PC;
925     } else {
926         TCGv t, z;
927 
928         tcg_gen_mov_tl(cpu_pc, cpu_npc);
929 
930         tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
931         t = tcg_constant_tl(pc1);
932         z = tcg_constant_tl(0);
933         tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, z, t, cpu_npc);
934 
935         dc->pc = DYNAMIC_PC;
936     }
937 }
938 
939 static inline void gen_generic_branch(DisasContext *dc)
940 {
941     TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
942     TCGv npc1 = tcg_constant_tl(dc->jump_pc[1]);
943     TCGv zero = tcg_constant_tl(0);
944 
945     tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, zero, npc0, npc1);
946 }
947 
948 /* call this function before using the condition register as it may
949    have been set for a jump */
950 static inline void flush_cond(DisasContext *dc)
951 {
952     if (dc->npc == JUMP_PC) {
953         gen_generic_branch(dc);
954         dc->npc = DYNAMIC_PC;
955     }
956 }
957 
958 static inline void save_npc(DisasContext *dc)
959 {
960     if (dc->npc == JUMP_PC) {
961         gen_generic_branch(dc);
962         dc->npc = DYNAMIC_PC;
963     } else if (dc->npc != DYNAMIC_PC) {
964         tcg_gen_movi_tl(cpu_npc, dc->npc);
965     }
966 }
967 
968 static inline void update_psr(DisasContext *dc)
969 {
970     if (dc->cc_op != CC_OP_FLAGS) {
971         dc->cc_op = CC_OP_FLAGS;
972         gen_helper_compute_psr(cpu_env);
973     }
974 }
975 
976 static inline void save_state(DisasContext *dc)
977 {
978     tcg_gen_movi_tl(cpu_pc, dc->pc);
979     save_npc(dc);
980 }
981 
982 static void gen_exception(DisasContext *dc, int which)
983 {
984     save_state(dc);
985     gen_helper_raise_exception(cpu_env, tcg_constant_i32(which));
986     dc->base.is_jmp = DISAS_NORETURN;
987 }
988 
989 static void gen_check_align(TCGv addr, int mask)
990 {
991     gen_helper_check_align(cpu_env, addr, tcg_constant_i32(mask));
992 }
993 
994 static inline void gen_mov_pc_npc(DisasContext *dc)
995 {
996     if (dc->npc == JUMP_PC) {
997         gen_generic_branch(dc);
998         tcg_gen_mov_tl(cpu_pc, cpu_npc);
999         dc->pc = DYNAMIC_PC;
1000     } else if (dc->npc == DYNAMIC_PC) {
1001         tcg_gen_mov_tl(cpu_pc, cpu_npc);
1002         dc->pc = DYNAMIC_PC;
1003     } else {
1004         dc->pc = dc->npc;
1005     }
1006 }
1007 
1008 static inline void gen_op_next_insn(void)
1009 {
1010     tcg_gen_mov_tl(cpu_pc, cpu_npc);
1011     tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1012 }
1013 
1014 static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
1015                         DisasContext *dc)
1016 {
1017     static int subcc_cond[16] = {
1018         TCG_COND_NEVER,
1019         TCG_COND_EQ,
1020         TCG_COND_LE,
1021         TCG_COND_LT,
1022         TCG_COND_LEU,
1023         TCG_COND_LTU,
1024         -1, /* neg */
1025         -1, /* overflow */
1026         TCG_COND_ALWAYS,
1027         TCG_COND_NE,
1028         TCG_COND_GT,
1029         TCG_COND_GE,
1030         TCG_COND_GTU,
1031         TCG_COND_GEU,
1032         -1, /* pos */
1033         -1, /* no overflow */
1034     };
1035 
1036     static int logic_cond[16] = {
1037         TCG_COND_NEVER,
1038         TCG_COND_EQ,     /* eq:  Z */
1039         TCG_COND_LE,     /* le:  Z | (N ^ V) -> Z | N */
1040         TCG_COND_LT,     /* lt:  N ^ V -> N */
1041         TCG_COND_EQ,     /* leu: C | Z -> Z */
1042         TCG_COND_NEVER,  /* ltu: C -> 0 */
1043         TCG_COND_LT,     /* neg: N */
1044         TCG_COND_NEVER,  /* vs:  V -> 0 */
1045         TCG_COND_ALWAYS,
1046         TCG_COND_NE,     /* ne:  !Z */
1047         TCG_COND_GT,     /* gt:  !(Z | (N ^ V)) -> !(Z | N) */
1048         TCG_COND_GE,     /* ge:  !(N ^ V) -> !N */
1049         TCG_COND_NE,     /* gtu: !(C | Z) -> !Z */
1050         TCG_COND_ALWAYS, /* geu: !C -> 1 */
1051         TCG_COND_GE,     /* pos: !N */
1052         TCG_COND_ALWAYS, /* vc:  !V -> 1 */
1053     };
1054 
1055     TCGv_i32 r_src;
1056     TCGv r_dst;
1057 
1058 #ifdef TARGET_SPARC64
1059     if (xcc) {
1060         r_src = cpu_xcc;
1061     } else {
1062         r_src = cpu_psr;
1063     }
1064 #else
1065     r_src = cpu_psr;
1066 #endif
1067 
1068     switch (dc->cc_op) {
1069     case CC_OP_LOGIC:
1070         cmp->cond = logic_cond[cond];
1071     do_compare_dst_0:
1072         cmp->is_bool = false;
1073         cmp->c2 = tcg_constant_tl(0);
1074 #ifdef TARGET_SPARC64
1075         if (!xcc) {
1076             cmp->c1 = tcg_temp_new();
1077             tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
1078             break;
1079         }
1080 #endif
1081         cmp->c1 = cpu_cc_dst;
1082         break;
1083 
1084     case CC_OP_SUB:
1085         switch (cond) {
1086         case 6:  /* neg */
1087         case 14: /* pos */
1088             cmp->cond = (cond == 6 ? TCG_COND_LT : TCG_COND_GE);
1089             goto do_compare_dst_0;
1090 
1091         case 7: /* overflow */
1092         case 15: /* !overflow */
1093             goto do_dynamic;
1094 
1095         default:
1096             cmp->cond = subcc_cond[cond];
1097             cmp->is_bool = false;
1098 #ifdef TARGET_SPARC64
1099             if (!xcc) {
1100                 /* Note that sign-extension works for unsigned compares as
1101                    long as both operands are sign-extended.  */
1102                 cmp->c1 = tcg_temp_new();
1103                 cmp->c2 = tcg_temp_new();
1104                 tcg_gen_ext32s_tl(cmp->c1, cpu_cc_src);
1105                 tcg_gen_ext32s_tl(cmp->c2, cpu_cc_src2);
1106                 break;
1107             }
1108 #endif
1109             cmp->c1 = cpu_cc_src;
1110             cmp->c2 = cpu_cc_src2;
1111             break;
1112         }
1113         break;
1114 
1115     default:
1116     do_dynamic:
1117         gen_helper_compute_psr(cpu_env);
1118         dc->cc_op = CC_OP_FLAGS;
1119         /* FALLTHRU */
1120 
1121     case CC_OP_FLAGS:
1122         /* We're going to generate a boolean result.  */
1123         cmp->cond = TCG_COND_NE;
1124         cmp->is_bool = true;
1125         cmp->c1 = r_dst = tcg_temp_new();
1126         cmp->c2 = tcg_constant_tl(0);
1127 
1128         switch (cond) {
1129         case 0x0:
1130             gen_op_eval_bn(r_dst);
1131             break;
1132         case 0x1:
1133             gen_op_eval_be(r_dst, r_src);
1134             break;
1135         case 0x2:
1136             gen_op_eval_ble(r_dst, r_src);
1137             break;
1138         case 0x3:
1139             gen_op_eval_bl(r_dst, r_src);
1140             break;
1141         case 0x4:
1142             gen_op_eval_bleu(r_dst, r_src);
1143             break;
1144         case 0x5:
1145             gen_op_eval_bcs(r_dst, r_src);
1146             break;
1147         case 0x6:
1148             gen_op_eval_bneg(r_dst, r_src);
1149             break;
1150         case 0x7:
1151             gen_op_eval_bvs(r_dst, r_src);
1152             break;
1153         case 0x8:
1154             gen_op_eval_ba(r_dst);
1155             break;
1156         case 0x9:
1157             gen_op_eval_bne(r_dst, r_src);
1158             break;
1159         case 0xa:
1160             gen_op_eval_bg(r_dst, r_src);
1161             break;
1162         case 0xb:
1163             gen_op_eval_bge(r_dst, r_src);
1164             break;
1165         case 0xc:
1166             gen_op_eval_bgu(r_dst, r_src);
1167             break;
1168         case 0xd:
1169             gen_op_eval_bcc(r_dst, r_src);
1170             break;
1171         case 0xe:
1172             gen_op_eval_bpos(r_dst, r_src);
1173             break;
1174         case 0xf:
1175             gen_op_eval_bvc(r_dst, r_src);
1176             break;
1177         }
1178         break;
1179     }
1180 }
1181 
1182 static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
1183 {
1184     unsigned int offset;
1185     TCGv r_dst;
1186 
1187     /* For now we still generate a straight boolean result.  */
1188     cmp->cond = TCG_COND_NE;
1189     cmp->is_bool = true;
1190     cmp->c1 = r_dst = tcg_temp_new();
1191     cmp->c2 = tcg_constant_tl(0);
1192 
1193     switch (cc) {
1194     default:
1195     case 0x0:
1196         offset = 0;
1197         break;
1198     case 0x1:
1199         offset = 32 - 10;
1200         break;
1201     case 0x2:
1202         offset = 34 - 10;
1203         break;
1204     case 0x3:
1205         offset = 36 - 10;
1206         break;
1207     }
1208 
1209     switch (cond) {
1210     case 0x0:
1211         gen_op_eval_bn(r_dst);
1212         break;
1213     case 0x1:
1214         gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1215         break;
1216     case 0x2:
1217         gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1218         break;
1219     case 0x3:
1220         gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1221         break;
1222     case 0x4:
1223         gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1224         break;
1225     case 0x5:
1226         gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1227         break;
1228     case 0x6:
1229         gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1230         break;
1231     case 0x7:
1232         gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1233         break;
1234     case 0x8:
1235         gen_op_eval_ba(r_dst);
1236         break;
1237     case 0x9:
1238         gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1239         break;
1240     case 0xa:
1241         gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1242         break;
1243     case 0xb:
1244         gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1245         break;
1246     case 0xc:
1247         gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1248         break;
1249     case 0xd:
1250         gen_op_eval_fble(r_dst, cpu_fsr, offset);
1251         break;
1252     case 0xe:
1253         gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1254         break;
1255     case 0xf:
1256         gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1257         break;
1258     }
1259 }
1260 
1261 static void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
1262                      DisasContext *dc)
1263 {
1264     DisasCompare cmp;
1265     gen_compare(&cmp, cc, cond, dc);
1266 
1267     /* The interface is to return a boolean in r_dst.  */
1268     if (cmp.is_bool) {
1269         tcg_gen_mov_tl(r_dst, cmp.c1);
1270     } else {
1271         tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
1272     }
1273 }
1274 
1275 static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1276 {
1277     DisasCompare cmp;
1278     gen_fcompare(&cmp, cc, cond);
1279 
1280     /* The interface is to return a boolean in r_dst.  */
1281     if (cmp.is_bool) {
1282         tcg_gen_mov_tl(r_dst, cmp.c1);
1283     } else {
1284         tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
1285     }
1286 }
1287 
1288 #ifdef TARGET_SPARC64
1289 // Inverted logic
1290 static const int gen_tcg_cond_reg[8] = {
1291     -1,
1292     TCG_COND_NE,
1293     TCG_COND_GT,
1294     TCG_COND_GE,
1295     -1,
1296     TCG_COND_EQ,
1297     TCG_COND_LE,
1298     TCG_COND_LT,
1299 };
1300 
1301 static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
1302 {
1303     cmp->cond = tcg_invert_cond(gen_tcg_cond_reg[cond]);
1304     cmp->is_bool = false;
1305     cmp->c1 = r_src;
1306     cmp->c2 = tcg_constant_tl(0);
1307 }
1308 
1309 static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1310 {
1311     DisasCompare cmp;
1312     gen_compare_reg(&cmp, cond, r_src);
1313 
1314     /* The interface is to return a boolean in r_dst.  */
1315     tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
1316 }
1317 #endif
1318 
1319 static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
1320 {
1321     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1322     target_ulong target = dc->pc + offset;
1323 
1324 #ifdef TARGET_SPARC64
1325     if (unlikely(AM_CHECK(dc))) {
1326         target &= 0xffffffffULL;
1327     }
1328 #endif
1329     if (cond == 0x0) {
1330         /* unconditional not taken */
1331         if (a) {
1332             dc->pc = dc->npc + 4;
1333             dc->npc = dc->pc + 4;
1334         } else {
1335             dc->pc = dc->npc;
1336             dc->npc = dc->pc + 4;
1337         }
1338     } else if (cond == 0x8) {
1339         /* unconditional taken */
1340         if (a) {
1341             dc->pc = target;
1342             dc->npc = dc->pc + 4;
1343         } else {
1344             dc->pc = dc->npc;
1345             dc->npc = target;
1346             tcg_gen_mov_tl(cpu_pc, cpu_npc);
1347         }
1348     } else {
1349         flush_cond(dc);
1350         gen_cond(cpu_cond, cc, cond, dc);
1351         if (a) {
1352             gen_branch_a(dc, target);
1353         } else {
1354             gen_branch_n(dc, target);
1355         }
1356     }
1357 }
1358 
1359 static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
1360 {
1361     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1362     target_ulong target = dc->pc + offset;
1363 
1364 #ifdef TARGET_SPARC64
1365     if (unlikely(AM_CHECK(dc))) {
1366         target &= 0xffffffffULL;
1367     }
1368 #endif
1369     if (cond == 0x0) {
1370         /* unconditional not taken */
1371         if (a) {
1372             dc->pc = dc->npc + 4;
1373             dc->npc = dc->pc + 4;
1374         } else {
1375             dc->pc = dc->npc;
1376             dc->npc = dc->pc + 4;
1377         }
1378     } else if (cond == 0x8) {
1379         /* unconditional taken */
1380         if (a) {
1381             dc->pc = target;
1382             dc->npc = dc->pc + 4;
1383         } else {
1384             dc->pc = dc->npc;
1385             dc->npc = target;
1386             tcg_gen_mov_tl(cpu_pc, cpu_npc);
1387         }
1388     } else {
1389         flush_cond(dc);
1390         gen_fcond(cpu_cond, cc, cond);
1391         if (a) {
1392             gen_branch_a(dc, target);
1393         } else {
1394             gen_branch_n(dc, target);
1395         }
1396     }
1397 }
1398 
1399 #ifdef TARGET_SPARC64
1400 static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1401                           TCGv r_reg)
1402 {
1403     unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1404     target_ulong target = dc->pc + offset;
1405 
1406     if (unlikely(AM_CHECK(dc))) {
1407         target &= 0xffffffffULL;
1408     }
1409     flush_cond(dc);
1410     gen_cond_reg(cpu_cond, cond, r_reg);
1411     if (a) {
1412         gen_branch_a(dc, target);
1413     } else {
1414         gen_branch_n(dc, target);
1415     }
1416 }
1417 
1418 static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1419 {
1420     switch (fccno) {
1421     case 0:
1422         gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2);
1423         break;
1424     case 1:
1425         gen_helper_fcmps_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
1426         break;
1427     case 2:
1428         gen_helper_fcmps_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
1429         break;
1430     case 3:
1431         gen_helper_fcmps_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
1432         break;
1433     }
1434 }
1435 
1436 static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1437 {
1438     switch (fccno) {
1439     case 0:
1440         gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2);
1441         break;
1442     case 1:
1443         gen_helper_fcmpd_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
1444         break;
1445     case 2:
1446         gen_helper_fcmpd_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
1447         break;
1448     case 3:
1449         gen_helper_fcmpd_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
1450         break;
1451     }
1452 }
1453 
1454 static inline void gen_op_fcmpq(int fccno)
1455 {
1456     switch (fccno) {
1457     case 0:
1458         gen_helper_fcmpq(cpu_fsr, cpu_env);
1459         break;
1460     case 1:
1461         gen_helper_fcmpq_fcc1(cpu_fsr, cpu_env);
1462         break;
1463     case 2:
1464         gen_helper_fcmpq_fcc2(cpu_fsr, cpu_env);
1465         break;
1466     case 3:
1467         gen_helper_fcmpq_fcc3(cpu_fsr, cpu_env);
1468         break;
1469     }
1470 }
1471 
1472 static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1473 {
1474     switch (fccno) {
1475     case 0:
1476         gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2);
1477         break;
1478     case 1:
1479         gen_helper_fcmpes_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
1480         break;
1481     case 2:
1482         gen_helper_fcmpes_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
1483         break;
1484     case 3:
1485         gen_helper_fcmpes_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
1486         break;
1487     }
1488 }
1489 
1490 static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1491 {
1492     switch (fccno) {
1493     case 0:
1494         gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2);
1495         break;
1496     case 1:
1497         gen_helper_fcmped_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
1498         break;
1499     case 2:
1500         gen_helper_fcmped_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
1501         break;
1502     case 3:
1503         gen_helper_fcmped_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
1504         break;
1505     }
1506 }
1507 
1508 static inline void gen_op_fcmpeq(int fccno)
1509 {
1510     switch (fccno) {
1511     case 0:
1512         gen_helper_fcmpeq(cpu_fsr, cpu_env);
1513         break;
1514     case 1:
1515         gen_helper_fcmpeq_fcc1(cpu_fsr, cpu_env);
1516         break;
1517     case 2:
1518         gen_helper_fcmpeq_fcc2(cpu_fsr, cpu_env);
1519         break;
1520     case 3:
1521         gen_helper_fcmpeq_fcc3(cpu_fsr, cpu_env);
1522         break;
1523     }
1524 }
1525 
1526 #else
1527 
1528 static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1529 {
1530     gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2);
1531 }
1532 
1533 static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1534 {
1535     gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2);
1536 }
1537 
1538 static inline void gen_op_fcmpq(int fccno)
1539 {
1540     gen_helper_fcmpq(cpu_fsr, cpu_env);
1541 }
1542 
1543 static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1544 {
1545     gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2);
1546 }
1547 
1548 static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1549 {
1550     gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2);
1551 }
1552 
1553 static inline void gen_op_fcmpeq(int fccno)
1554 {
1555     gen_helper_fcmpeq(cpu_fsr, cpu_env);
1556 }
1557 #endif
1558 
1559 static void gen_op_fpexception_im(DisasContext *dc, int fsr_flags)
1560 {
1561     tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
1562     tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1563     gen_exception(dc, TT_FP_EXCP);
1564 }
1565 
1566 static int gen_trap_ifnofpu(DisasContext *dc)
1567 {
1568 #if !defined(CONFIG_USER_ONLY)
1569     if (!dc->fpu_enabled) {
1570         gen_exception(dc, TT_NFPU_INSN);
1571         return 1;
1572     }
1573 #endif
1574     return 0;
1575 }
1576 
1577 static inline void gen_op_clear_ieee_excp_and_FTT(void)
1578 {
1579     tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1580 }
1581 
1582 static inline void gen_fop_FF(DisasContext *dc, int rd, int rs,
1583                               void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32))
1584 {
1585     TCGv_i32 dst, src;
1586 
1587     src = gen_load_fpr_F(dc, rs);
1588     dst = gen_dest_fpr_F(dc);
1589 
1590     gen(dst, cpu_env, src);
1591     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1592 
1593     gen_store_fpr_F(dc, rd, dst);
1594 }
1595 
1596 static inline void gen_ne_fop_FF(DisasContext *dc, int rd, int rs,
1597                                  void (*gen)(TCGv_i32, TCGv_i32))
1598 {
1599     TCGv_i32 dst, src;
1600 
1601     src = gen_load_fpr_F(dc, rs);
1602     dst = gen_dest_fpr_F(dc);
1603 
1604     gen(dst, src);
1605 
1606     gen_store_fpr_F(dc, rd, dst);
1607 }
1608 
1609 static inline void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
1610                         void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32))
1611 {
1612     TCGv_i32 dst, src1, src2;
1613 
1614     src1 = gen_load_fpr_F(dc, rs1);
1615     src2 = gen_load_fpr_F(dc, rs2);
1616     dst = gen_dest_fpr_F(dc);
1617 
1618     gen(dst, cpu_env, src1, src2);
1619     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1620 
1621     gen_store_fpr_F(dc, rd, dst);
1622 }
1623 
1624 #ifdef TARGET_SPARC64
1625 static inline void gen_ne_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
1626                                   void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
1627 {
1628     TCGv_i32 dst, src1, src2;
1629 
1630     src1 = gen_load_fpr_F(dc, rs1);
1631     src2 = gen_load_fpr_F(dc, rs2);
1632     dst = gen_dest_fpr_F(dc);
1633 
1634     gen(dst, src1, src2);
1635 
1636     gen_store_fpr_F(dc, rd, dst);
1637 }
1638 #endif
1639 
1640 static inline void gen_fop_DD(DisasContext *dc, int rd, int rs,
1641                               void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64))
1642 {
1643     TCGv_i64 dst, src;
1644 
1645     src = gen_load_fpr_D(dc, rs);
1646     dst = gen_dest_fpr_D(dc, rd);
1647 
1648     gen(dst, cpu_env, src);
1649     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1650 
1651     gen_store_fpr_D(dc, rd, dst);
1652 }
1653 
1654 #ifdef TARGET_SPARC64
1655 static inline void gen_ne_fop_DD(DisasContext *dc, int rd, int rs,
1656                                  void (*gen)(TCGv_i64, TCGv_i64))
1657 {
1658     TCGv_i64 dst, src;
1659 
1660     src = gen_load_fpr_D(dc, rs);
1661     dst = gen_dest_fpr_D(dc, rd);
1662 
1663     gen(dst, src);
1664 
1665     gen_store_fpr_D(dc, rd, dst);
1666 }
1667 #endif
1668 
1669 static inline void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
1670                         void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64))
1671 {
1672     TCGv_i64 dst, src1, src2;
1673 
1674     src1 = gen_load_fpr_D(dc, rs1);
1675     src2 = gen_load_fpr_D(dc, rs2);
1676     dst = gen_dest_fpr_D(dc, rd);
1677 
1678     gen(dst, cpu_env, src1, src2);
1679     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1680 
1681     gen_store_fpr_D(dc, rd, dst);
1682 }
1683 
1684 #ifdef TARGET_SPARC64
1685 static inline void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
1686                                   void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
1687 {
1688     TCGv_i64 dst, src1, src2;
1689 
1690     src1 = gen_load_fpr_D(dc, rs1);
1691     src2 = gen_load_fpr_D(dc, rs2);
1692     dst = gen_dest_fpr_D(dc, rd);
1693 
1694     gen(dst, src1, src2);
1695 
1696     gen_store_fpr_D(dc, rd, dst);
1697 }
1698 
1699 static inline void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
1700                            void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
1701 {
1702     TCGv_i64 dst, src1, src2;
1703 
1704     src1 = gen_load_fpr_D(dc, rs1);
1705     src2 = gen_load_fpr_D(dc, rs2);
1706     dst = gen_dest_fpr_D(dc, rd);
1707 
1708     gen(dst, cpu_gsr, src1, src2);
1709 
1710     gen_store_fpr_D(dc, rd, dst);
1711 }
1712 
1713 static inline void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2,
1714                            void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
1715 {
1716     TCGv_i64 dst, src0, src1, src2;
1717 
1718     src1 = gen_load_fpr_D(dc, rs1);
1719     src2 = gen_load_fpr_D(dc, rs2);
1720     src0 = gen_load_fpr_D(dc, rd);
1721     dst = gen_dest_fpr_D(dc, rd);
1722 
1723     gen(dst, src0, src1, src2);
1724 
1725     gen_store_fpr_D(dc, rd, dst);
1726 }
1727 #endif
1728 
1729 static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs,
1730                               void (*gen)(TCGv_ptr))
1731 {
1732     gen_op_load_fpr_QT1(QFPREG(rs));
1733 
1734     gen(cpu_env);
1735     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1736 
1737     gen_op_store_QT0_fpr(QFPREG(rd));
1738     gen_update_fprs_dirty(dc, QFPREG(rd));
1739 }
1740 
1741 #ifdef TARGET_SPARC64
1742 static inline void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
1743                                  void (*gen)(TCGv_ptr))
1744 {
1745     gen_op_load_fpr_QT1(QFPREG(rs));
1746 
1747     gen(cpu_env);
1748 
1749     gen_op_store_QT0_fpr(QFPREG(rd));
1750     gen_update_fprs_dirty(dc, QFPREG(rd));
1751 }
1752 #endif
1753 
1754 static inline void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2,
1755                                void (*gen)(TCGv_ptr))
1756 {
1757     gen_op_load_fpr_QT0(QFPREG(rs1));
1758     gen_op_load_fpr_QT1(QFPREG(rs2));
1759 
1760     gen(cpu_env);
1761     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1762 
1763     gen_op_store_QT0_fpr(QFPREG(rd));
1764     gen_update_fprs_dirty(dc, QFPREG(rd));
1765 }
1766 
1767 static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2,
1768                         void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32, TCGv_i32))
1769 {
1770     TCGv_i64 dst;
1771     TCGv_i32 src1, src2;
1772 
1773     src1 = gen_load_fpr_F(dc, rs1);
1774     src2 = gen_load_fpr_F(dc, rs2);
1775     dst = gen_dest_fpr_D(dc, rd);
1776 
1777     gen(dst, cpu_env, src1, src2);
1778     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1779 
1780     gen_store_fpr_D(dc, rd, dst);
1781 }
1782 
1783 static inline void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2,
1784                                void (*gen)(TCGv_ptr, TCGv_i64, TCGv_i64))
1785 {
1786     TCGv_i64 src1, src2;
1787 
1788     src1 = gen_load_fpr_D(dc, rs1);
1789     src2 = gen_load_fpr_D(dc, rs2);
1790 
1791     gen(cpu_env, src1, src2);
1792     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1793 
1794     gen_op_store_QT0_fpr(QFPREG(rd));
1795     gen_update_fprs_dirty(dc, QFPREG(rd));
1796 }
1797 
1798 #ifdef TARGET_SPARC64
1799 static inline void gen_fop_DF(DisasContext *dc, int rd, int rs,
1800                               void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
1801 {
1802     TCGv_i64 dst;
1803     TCGv_i32 src;
1804 
1805     src = gen_load_fpr_F(dc, rs);
1806     dst = gen_dest_fpr_D(dc, rd);
1807 
1808     gen(dst, cpu_env, src);
1809     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1810 
1811     gen_store_fpr_D(dc, rd, dst);
1812 }
1813 #endif
1814 
1815 static inline void gen_ne_fop_DF(DisasContext *dc, int rd, int rs,
1816                                  void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
1817 {
1818     TCGv_i64 dst;
1819     TCGv_i32 src;
1820 
1821     src = gen_load_fpr_F(dc, rs);
1822     dst = gen_dest_fpr_D(dc, rd);
1823 
1824     gen(dst, cpu_env, src);
1825 
1826     gen_store_fpr_D(dc, rd, dst);
1827 }
1828 
1829 static inline void gen_fop_FD(DisasContext *dc, int rd, int rs,
1830                               void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i64))
1831 {
1832     TCGv_i32 dst;
1833     TCGv_i64 src;
1834 
1835     src = gen_load_fpr_D(dc, rs);
1836     dst = gen_dest_fpr_F(dc);
1837 
1838     gen(dst, cpu_env, src);
1839     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1840 
1841     gen_store_fpr_F(dc, rd, dst);
1842 }
1843 
1844 static inline void gen_fop_FQ(DisasContext *dc, int rd, int rs,
1845                               void (*gen)(TCGv_i32, TCGv_ptr))
1846 {
1847     TCGv_i32 dst;
1848 
1849     gen_op_load_fpr_QT1(QFPREG(rs));
1850     dst = gen_dest_fpr_F(dc);
1851 
1852     gen(dst, cpu_env);
1853     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1854 
1855     gen_store_fpr_F(dc, rd, dst);
1856 }
1857 
1858 static inline void gen_fop_DQ(DisasContext *dc, int rd, int rs,
1859                               void (*gen)(TCGv_i64, TCGv_ptr))
1860 {
1861     TCGv_i64 dst;
1862 
1863     gen_op_load_fpr_QT1(QFPREG(rs));
1864     dst = gen_dest_fpr_D(dc, rd);
1865 
1866     gen(dst, cpu_env);
1867     gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
1868 
1869     gen_store_fpr_D(dc, rd, dst);
1870 }
1871 
1872 static inline void gen_ne_fop_QF(DisasContext *dc, int rd, int rs,
1873                                  void (*gen)(TCGv_ptr, TCGv_i32))
1874 {
1875     TCGv_i32 src;
1876 
1877     src = gen_load_fpr_F(dc, rs);
1878 
1879     gen(cpu_env, src);
1880 
1881     gen_op_store_QT0_fpr(QFPREG(rd));
1882     gen_update_fprs_dirty(dc, QFPREG(rd));
1883 }
1884 
1885 static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
1886                                  void (*gen)(TCGv_ptr, TCGv_i64))
1887 {
1888     TCGv_i64 src;
1889 
1890     src = gen_load_fpr_D(dc, rs);
1891 
1892     gen(cpu_env, src);
1893 
1894     gen_op_store_QT0_fpr(QFPREG(rd));
1895     gen_update_fprs_dirty(dc, QFPREG(rd));
1896 }
1897 
1898 static void gen_swap(DisasContext *dc, TCGv dst, TCGv src,
1899                      TCGv addr, int mmu_idx, MemOp memop)
1900 {
1901     gen_address_mask(dc, addr);
1902     tcg_gen_atomic_xchg_tl(dst, addr, src, mmu_idx, memop);
1903 }
1904 
1905 static void gen_ldstub(DisasContext *dc, TCGv dst, TCGv addr, int mmu_idx)
1906 {
1907     TCGv m1 = tcg_constant_tl(0xff);
1908     gen_address_mask(dc, addr);
1909     tcg_gen_atomic_xchg_tl(dst, addr, m1, mmu_idx, MO_UB);
1910 }
1911 
1912 /* asi moves */
1913 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1914 typedef enum {
1915     GET_ASI_HELPER,
1916     GET_ASI_EXCP,
1917     GET_ASI_DIRECT,
1918     GET_ASI_DTWINX,
1919     GET_ASI_BLOCK,
1920     GET_ASI_SHORT,
1921     GET_ASI_BCOPY,
1922     GET_ASI_BFILL,
1923 } ASIType;
1924 
1925 typedef struct {
1926     ASIType type;
1927     int asi;
1928     int mem_idx;
1929     MemOp memop;
1930 } DisasASI;
1931 
1932 static DisasASI get_asi(DisasContext *dc, int insn, MemOp memop)
1933 {
1934     int asi = GET_FIELD(insn, 19, 26);
1935     ASIType type = GET_ASI_HELPER;
1936     int mem_idx = dc->mem_idx;
1937 
1938 #ifndef TARGET_SPARC64
1939     /* Before v9, all asis are immediate and privileged.  */
1940     if (IS_IMM) {
1941         gen_exception(dc, TT_ILL_INSN);
1942         type = GET_ASI_EXCP;
1943     } else if (supervisor(dc)
1944                /* Note that LEON accepts ASI_USERDATA in user mode, for
1945                   use with CASA.  Also note that previous versions of
1946                   QEMU allowed (and old versions of gcc emitted) ASI_P
1947                   for LEON, which is incorrect.  */
1948                || (asi == ASI_USERDATA
1949                    && (dc->def->features & CPU_FEATURE_CASA))) {
1950         switch (asi) {
1951         case ASI_USERDATA:   /* User data access */
1952             mem_idx = MMU_USER_IDX;
1953             type = GET_ASI_DIRECT;
1954             break;
1955         case ASI_KERNELDATA: /* Supervisor data access */
1956             mem_idx = MMU_KERNEL_IDX;
1957             type = GET_ASI_DIRECT;
1958             break;
1959         case ASI_M_BYPASS:    /* MMU passthrough */
1960         case ASI_LEON_BYPASS: /* LEON MMU passthrough */
1961             mem_idx = MMU_PHYS_IDX;
1962             type = GET_ASI_DIRECT;
1963             break;
1964         case ASI_M_BCOPY: /* Block copy, sta access */
1965             mem_idx = MMU_KERNEL_IDX;
1966             type = GET_ASI_BCOPY;
1967             break;
1968         case ASI_M_BFILL: /* Block fill, stda access */
1969             mem_idx = MMU_KERNEL_IDX;
1970             type = GET_ASI_BFILL;
1971             break;
1972         }
1973 
1974         /* MMU_PHYS_IDX is used when the MMU is disabled to passthrough the
1975          * permissions check in get_physical_address(..).
1976          */
1977         mem_idx = (dc->mem_idx == MMU_PHYS_IDX) ? MMU_PHYS_IDX : mem_idx;
1978     } else {
1979         gen_exception(dc, TT_PRIV_INSN);
1980         type = GET_ASI_EXCP;
1981     }
1982 #else
1983     if (IS_IMM) {
1984         asi = dc->asi;
1985     }
1986     /* With v9, all asis below 0x80 are privileged.  */
1987     /* ??? We ought to check cpu_has_hypervisor, but we didn't copy
1988        down that bit into DisasContext.  For the moment that's ok,
1989        since the direct implementations below doesn't have any ASIs
1990        in the restricted [0x30, 0x7f] range, and the check will be
1991        done properly in the helper.  */
1992     if (!supervisor(dc) && asi < 0x80) {
1993         gen_exception(dc, TT_PRIV_ACT);
1994         type = GET_ASI_EXCP;
1995     } else {
1996         switch (asi) {
1997         case ASI_REAL:      /* Bypass */
1998         case ASI_REAL_IO:   /* Bypass, non-cacheable */
1999         case ASI_REAL_L:    /* Bypass LE */
2000         case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
2001         case ASI_TWINX_REAL:   /* Real address, twinx */
2002         case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
2003         case ASI_QUAD_LDD_PHYS:
2004         case ASI_QUAD_LDD_PHYS_L:
2005             mem_idx = MMU_PHYS_IDX;
2006             break;
2007         case ASI_N:  /* Nucleus */
2008         case ASI_NL: /* Nucleus LE */
2009         case ASI_TWINX_N:
2010         case ASI_TWINX_NL:
2011         case ASI_NUCLEUS_QUAD_LDD:
2012         case ASI_NUCLEUS_QUAD_LDD_L:
2013             if (hypervisor(dc)) {
2014                 mem_idx = MMU_PHYS_IDX;
2015             } else {
2016                 mem_idx = MMU_NUCLEUS_IDX;
2017             }
2018             break;
2019         case ASI_AIUP:  /* As if user primary */
2020         case ASI_AIUPL: /* As if user primary LE */
2021         case ASI_TWINX_AIUP:
2022         case ASI_TWINX_AIUP_L:
2023         case ASI_BLK_AIUP_4V:
2024         case ASI_BLK_AIUP_L_4V:
2025         case ASI_BLK_AIUP:
2026         case ASI_BLK_AIUPL:
2027             mem_idx = MMU_USER_IDX;
2028             break;
2029         case ASI_AIUS:  /* As if user secondary */
2030         case ASI_AIUSL: /* As if user secondary LE */
2031         case ASI_TWINX_AIUS:
2032         case ASI_TWINX_AIUS_L:
2033         case ASI_BLK_AIUS_4V:
2034         case ASI_BLK_AIUS_L_4V:
2035         case ASI_BLK_AIUS:
2036         case ASI_BLK_AIUSL:
2037             mem_idx = MMU_USER_SECONDARY_IDX;
2038             break;
2039         case ASI_S:  /* Secondary */
2040         case ASI_SL: /* Secondary LE */
2041         case ASI_TWINX_S:
2042         case ASI_TWINX_SL:
2043         case ASI_BLK_COMMIT_S:
2044         case ASI_BLK_S:
2045         case ASI_BLK_SL:
2046         case ASI_FL8_S:
2047         case ASI_FL8_SL:
2048         case ASI_FL16_S:
2049         case ASI_FL16_SL:
2050             if (mem_idx == MMU_USER_IDX) {
2051                 mem_idx = MMU_USER_SECONDARY_IDX;
2052             } else if (mem_idx == MMU_KERNEL_IDX) {
2053                 mem_idx = MMU_KERNEL_SECONDARY_IDX;
2054             }
2055             break;
2056         case ASI_P:  /* Primary */
2057         case ASI_PL: /* Primary LE */
2058         case ASI_TWINX_P:
2059         case ASI_TWINX_PL:
2060         case ASI_BLK_COMMIT_P:
2061         case ASI_BLK_P:
2062         case ASI_BLK_PL:
2063         case ASI_FL8_P:
2064         case ASI_FL8_PL:
2065         case ASI_FL16_P:
2066         case ASI_FL16_PL:
2067             break;
2068         }
2069         switch (asi) {
2070         case ASI_REAL:
2071         case ASI_REAL_IO:
2072         case ASI_REAL_L:
2073         case ASI_REAL_IO_L:
2074         case ASI_N:
2075         case ASI_NL:
2076         case ASI_AIUP:
2077         case ASI_AIUPL:
2078         case ASI_AIUS:
2079         case ASI_AIUSL:
2080         case ASI_S:
2081         case ASI_SL:
2082         case ASI_P:
2083         case ASI_PL:
2084             type = GET_ASI_DIRECT;
2085             break;
2086         case ASI_TWINX_REAL:
2087         case ASI_TWINX_REAL_L:
2088         case ASI_TWINX_N:
2089         case ASI_TWINX_NL:
2090         case ASI_TWINX_AIUP:
2091         case ASI_TWINX_AIUP_L:
2092         case ASI_TWINX_AIUS:
2093         case ASI_TWINX_AIUS_L:
2094         case ASI_TWINX_P:
2095         case ASI_TWINX_PL:
2096         case ASI_TWINX_S:
2097         case ASI_TWINX_SL:
2098         case ASI_QUAD_LDD_PHYS:
2099         case ASI_QUAD_LDD_PHYS_L:
2100         case ASI_NUCLEUS_QUAD_LDD:
2101         case ASI_NUCLEUS_QUAD_LDD_L:
2102             type = GET_ASI_DTWINX;
2103             break;
2104         case ASI_BLK_COMMIT_P:
2105         case ASI_BLK_COMMIT_S:
2106         case ASI_BLK_AIUP_4V:
2107         case ASI_BLK_AIUP_L_4V:
2108         case ASI_BLK_AIUP:
2109         case ASI_BLK_AIUPL:
2110         case ASI_BLK_AIUS_4V:
2111         case ASI_BLK_AIUS_L_4V:
2112         case ASI_BLK_AIUS:
2113         case ASI_BLK_AIUSL:
2114         case ASI_BLK_S:
2115         case ASI_BLK_SL:
2116         case ASI_BLK_P:
2117         case ASI_BLK_PL:
2118             type = GET_ASI_BLOCK;
2119             break;
2120         case ASI_FL8_S:
2121         case ASI_FL8_SL:
2122         case ASI_FL8_P:
2123         case ASI_FL8_PL:
2124             memop = MO_UB;
2125             type = GET_ASI_SHORT;
2126             break;
2127         case ASI_FL16_S:
2128         case ASI_FL16_SL:
2129         case ASI_FL16_P:
2130         case ASI_FL16_PL:
2131             memop = MO_TEUW;
2132             type = GET_ASI_SHORT;
2133             break;
2134         }
2135         /* The little-endian asis all have bit 3 set.  */
2136         if (asi & 8) {
2137             memop ^= MO_BSWAP;
2138         }
2139     }
2140 #endif
2141 
2142     return (DisasASI){ type, asi, mem_idx, memop };
2143 }
2144 
2145 static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
2146                        int insn, MemOp memop)
2147 {
2148     DisasASI da = get_asi(dc, insn, memop);
2149 
2150     switch (da.type) {
2151     case GET_ASI_EXCP:
2152         break;
2153     case GET_ASI_DTWINX: /* Reserved for ldda.  */
2154         gen_exception(dc, TT_ILL_INSN);
2155         break;
2156     case GET_ASI_DIRECT:
2157         gen_address_mask(dc, addr);
2158         tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop);
2159         break;
2160     default:
2161         {
2162             TCGv_i32 r_asi = tcg_constant_i32(da.asi);
2163             TCGv_i32 r_mop = tcg_constant_i32(memop);
2164 
2165             save_state(dc);
2166 #ifdef TARGET_SPARC64
2167             gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_mop);
2168 #else
2169             {
2170                 TCGv_i64 t64 = tcg_temp_new_i64();
2171                 gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
2172                 tcg_gen_trunc_i64_tl(dst, t64);
2173             }
2174 #endif
2175         }
2176         break;
2177     }
2178 }
2179 
2180 static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
2181                        int insn, MemOp memop)
2182 {
2183     DisasASI da = get_asi(dc, insn, memop);
2184 
2185     switch (da.type) {
2186     case GET_ASI_EXCP:
2187         break;
2188     case GET_ASI_DTWINX: /* Reserved for stda.  */
2189 #ifndef TARGET_SPARC64
2190         gen_exception(dc, TT_ILL_INSN);
2191         break;
2192 #else
2193         if (!(dc->def->features & CPU_FEATURE_HYPV)) {
2194             /* Pre OpenSPARC CPUs don't have these */
2195             gen_exception(dc, TT_ILL_INSN);
2196             return;
2197         }
2198         /* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions
2199          * are ST_BLKINIT_ ASIs */
2200 #endif
2201         /* fall through */
2202     case GET_ASI_DIRECT:
2203         gen_address_mask(dc, addr);
2204         tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
2205         break;
2206 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
2207     case GET_ASI_BCOPY:
2208         /* Copy 32 bytes from the address in SRC to ADDR.  */
2209         /* ??? The original qemu code suggests 4-byte alignment, dropping
2210            the low bits, but the only place I can see this used is in the
2211            Linux kernel with 32 byte alignment, which would make more sense
2212            as a cacheline-style operation.  */
2213         {
2214             TCGv saddr = tcg_temp_new();
2215             TCGv daddr = tcg_temp_new();
2216             TCGv four = tcg_constant_tl(4);
2217             TCGv_i32 tmp = tcg_temp_new_i32();
2218             int i;
2219 
2220             tcg_gen_andi_tl(saddr, src, -4);
2221             tcg_gen_andi_tl(daddr, addr, -4);
2222             for (i = 0; i < 32; i += 4) {
2223                 /* Since the loads and stores are paired, allow the
2224                    copy to happen in the host endianness.  */
2225                 tcg_gen_qemu_ld_i32(tmp, saddr, da.mem_idx, MO_UL);
2226                 tcg_gen_qemu_st_i32(tmp, daddr, da.mem_idx, MO_UL);
2227                 tcg_gen_add_tl(saddr, saddr, four);
2228                 tcg_gen_add_tl(daddr, daddr, four);
2229             }
2230         }
2231         break;
2232 #endif
2233     default:
2234         {
2235             TCGv_i32 r_asi = tcg_constant_i32(da.asi);
2236             TCGv_i32 r_mop = tcg_constant_i32(memop & MO_SIZE);
2237 
2238             save_state(dc);
2239 #ifdef TARGET_SPARC64
2240             gen_helper_st_asi(cpu_env, addr, src, r_asi, r_mop);
2241 #else
2242             {
2243                 TCGv_i64 t64 = tcg_temp_new_i64();
2244                 tcg_gen_extu_tl_i64(t64, src);
2245                 gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
2246             }
2247 #endif
2248 
2249             /* A write to a TLB register may alter page maps.  End the TB. */
2250             dc->npc = DYNAMIC_PC;
2251         }
2252         break;
2253     }
2254 }
2255 
2256 static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
2257                          TCGv addr, int insn)
2258 {
2259     DisasASI da = get_asi(dc, insn, MO_TEUL);
2260 
2261     switch (da.type) {
2262     case GET_ASI_EXCP:
2263         break;
2264     case GET_ASI_DIRECT:
2265         gen_swap(dc, dst, src, addr, da.mem_idx, da.memop);
2266         break;
2267     default:
2268         /* ??? Should be DAE_invalid_asi.  */
2269         gen_exception(dc, TT_DATA_ACCESS);
2270         break;
2271     }
2272 }
2273 
2274 static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
2275                         int insn, int rd)
2276 {
2277     DisasASI da = get_asi(dc, insn, MO_TEUL);
2278     TCGv oldv;
2279 
2280     switch (da.type) {
2281     case GET_ASI_EXCP:
2282         return;
2283     case GET_ASI_DIRECT:
2284         oldv = tcg_temp_new();
2285         tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
2286                                   da.mem_idx, da.memop);
2287         gen_store_gpr(dc, rd, oldv);
2288         break;
2289     default:
2290         /* ??? Should be DAE_invalid_asi.  */
2291         gen_exception(dc, TT_DATA_ACCESS);
2292         break;
2293     }
2294 }
2295 
2296 static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
2297 {
2298     DisasASI da = get_asi(dc, insn, MO_UB);
2299 
2300     switch (da.type) {
2301     case GET_ASI_EXCP:
2302         break;
2303     case GET_ASI_DIRECT:
2304         gen_ldstub(dc, dst, addr, da.mem_idx);
2305         break;
2306     default:
2307         /* ??? In theory, this should be raise DAE_invalid_asi.
2308            But the SS-20 roms do ldstuba [%l0] #ASI_M_CTL, %o1.  */
2309         if (tb_cflags(dc->base.tb) & CF_PARALLEL) {
2310             gen_helper_exit_atomic(cpu_env);
2311         } else {
2312             TCGv_i32 r_asi = tcg_constant_i32(da.asi);
2313             TCGv_i32 r_mop = tcg_constant_i32(MO_UB);
2314             TCGv_i64 s64, t64;
2315 
2316             save_state(dc);
2317             t64 = tcg_temp_new_i64();
2318             gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
2319 
2320             s64 = tcg_constant_i64(0xff);
2321             gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_mop);
2322 
2323             tcg_gen_trunc_i64_tl(dst, t64);
2324 
2325             /* End the TB.  */
2326             dc->npc = DYNAMIC_PC;
2327         }
2328         break;
2329     }
2330 }
2331 #endif
2332 
2333 #ifdef TARGET_SPARC64
2334 static void gen_ldf_asi(DisasContext *dc, TCGv addr,
2335                         int insn, int size, int rd)
2336 {
2337     DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEUQ));
2338     TCGv_i32 d32;
2339     TCGv_i64 d64;
2340 
2341     switch (da.type) {
2342     case GET_ASI_EXCP:
2343         break;
2344 
2345     case GET_ASI_DIRECT:
2346         gen_address_mask(dc, addr);
2347         switch (size) {
2348         case 4:
2349             d32 = gen_dest_fpr_F(dc);
2350             tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop);
2351             gen_store_fpr_F(dc, rd, d32);
2352             break;
2353         case 8:
2354             tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
2355                                 da.memop | MO_ALIGN_4);
2356             break;
2357         case 16:
2358             d64 = tcg_temp_new_i64();
2359             tcg_gen_qemu_ld_i64(d64, addr, da.mem_idx, da.memop | MO_ALIGN_4);
2360             tcg_gen_addi_tl(addr, addr, 8);
2361             tcg_gen_qemu_ld_i64(cpu_fpr[rd/2+1], addr, da.mem_idx,
2362                                 da.memop | MO_ALIGN_4);
2363             tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
2364             break;
2365         default:
2366             g_assert_not_reached();
2367         }
2368         break;
2369 
2370     case GET_ASI_BLOCK:
2371         /* Valid for lddfa on aligned registers only.  */
2372         if (size == 8 && (rd & 7) == 0) {
2373             MemOp memop;
2374             TCGv eight;
2375             int i;
2376 
2377             gen_address_mask(dc, addr);
2378 
2379             /* The first operation checks required alignment.  */
2380             memop = da.memop | MO_ALIGN_64;
2381             eight = tcg_constant_tl(8);
2382             for (i = 0; ; ++i) {
2383                 tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr,
2384                                     da.mem_idx, memop);
2385                 if (i == 7) {
2386                     break;
2387                 }
2388                 tcg_gen_add_tl(addr, addr, eight);
2389                 memop = da.memop;
2390             }
2391         } else {
2392             gen_exception(dc, TT_ILL_INSN);
2393         }
2394         break;
2395 
2396     case GET_ASI_SHORT:
2397         /* Valid for lddfa only.  */
2398         if (size == 8) {
2399             gen_address_mask(dc, addr);
2400             tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
2401         } else {
2402             gen_exception(dc, TT_ILL_INSN);
2403         }
2404         break;
2405 
2406     default:
2407         {
2408             TCGv_i32 r_asi = tcg_constant_i32(da.asi);
2409             TCGv_i32 r_mop = tcg_constant_i32(da.memop);
2410 
2411             save_state(dc);
2412             /* According to the table in the UA2011 manual, the only
2413                other asis that are valid for ldfa/lddfa/ldqfa are
2414                the NO_FAULT asis.  We still need a helper for these,
2415                but we can just use the integer asi helper for them.  */
2416             switch (size) {
2417             case 4:
2418                 d64 = tcg_temp_new_i64();
2419                 gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_mop);
2420                 d32 = gen_dest_fpr_F(dc);
2421                 tcg_gen_extrl_i64_i32(d32, d64);
2422                 gen_store_fpr_F(dc, rd, d32);
2423                 break;
2424             case 8:
2425                 gen_helper_ld_asi(cpu_fpr[rd / 2], cpu_env, addr, r_asi, r_mop);
2426                 break;
2427             case 16:
2428                 d64 = tcg_temp_new_i64();
2429                 gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_mop);
2430                 tcg_gen_addi_tl(addr, addr, 8);
2431                 gen_helper_ld_asi(cpu_fpr[rd/2+1], cpu_env, addr, r_asi, r_mop);
2432                 tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
2433                 break;
2434             default:
2435                 g_assert_not_reached();
2436             }
2437         }
2438         break;
2439     }
2440 }
2441 
2442 static void gen_stf_asi(DisasContext *dc, TCGv addr,
2443                         int insn, int size, int rd)
2444 {
2445     DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEUQ));
2446     TCGv_i32 d32;
2447 
2448     switch (da.type) {
2449     case GET_ASI_EXCP:
2450         break;
2451 
2452     case GET_ASI_DIRECT:
2453         gen_address_mask(dc, addr);
2454         switch (size) {
2455         case 4:
2456             d32 = gen_load_fpr_F(dc, rd);
2457             tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop);
2458             break;
2459         case 8:
2460             tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
2461                                 da.memop | MO_ALIGN_4);
2462             break;
2463         case 16:
2464             /* Only 4-byte alignment required.  However, it is legal for the
2465                cpu to signal the alignment fault, and the OS trap handler is
2466                required to fix it up.  Requiring 16-byte alignment here avoids
2467                having to probe the second page before performing the first
2468                write.  */
2469             tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
2470                                 da.memop | MO_ALIGN_16);
2471             tcg_gen_addi_tl(addr, addr, 8);
2472             tcg_gen_qemu_st_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
2473             break;
2474         default:
2475             g_assert_not_reached();
2476         }
2477         break;
2478 
2479     case GET_ASI_BLOCK:
2480         /* Valid for stdfa on aligned registers only.  */
2481         if (size == 8 && (rd & 7) == 0) {
2482             MemOp memop;
2483             TCGv eight;
2484             int i;
2485 
2486             gen_address_mask(dc, addr);
2487 
2488             /* The first operation checks required alignment.  */
2489             memop = da.memop | MO_ALIGN_64;
2490             eight = tcg_constant_tl(8);
2491             for (i = 0; ; ++i) {
2492                 tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr,
2493                                     da.mem_idx, memop);
2494                 if (i == 7) {
2495                     break;
2496                 }
2497                 tcg_gen_add_tl(addr, addr, eight);
2498                 memop = da.memop;
2499             }
2500         } else {
2501             gen_exception(dc, TT_ILL_INSN);
2502         }
2503         break;
2504 
2505     case GET_ASI_SHORT:
2506         /* Valid for stdfa only.  */
2507         if (size == 8) {
2508             gen_address_mask(dc, addr);
2509             tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
2510         } else {
2511             gen_exception(dc, TT_ILL_INSN);
2512         }
2513         break;
2514 
2515     default:
2516         /* According to the table in the UA2011 manual, the only
2517            other asis that are valid for ldfa/lddfa/ldqfa are
2518            the PST* asis, which aren't currently handled.  */
2519         gen_exception(dc, TT_ILL_INSN);
2520         break;
2521     }
2522 }
2523 
2524 static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
2525 {
2526     DisasASI da = get_asi(dc, insn, MO_TEUQ);
2527     TCGv_i64 hi = gen_dest_gpr(dc, rd);
2528     TCGv_i64 lo = gen_dest_gpr(dc, rd + 1);
2529 
2530     switch (da.type) {
2531     case GET_ASI_EXCP:
2532         return;
2533 
2534     case GET_ASI_DTWINX:
2535         gen_address_mask(dc, addr);
2536         tcg_gen_qemu_ld_i64(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
2537         tcg_gen_addi_tl(addr, addr, 8);
2538         tcg_gen_qemu_ld_i64(lo, addr, da.mem_idx, da.memop);
2539         break;
2540 
2541     case GET_ASI_DIRECT:
2542         {
2543             TCGv_i64 tmp = tcg_temp_new_i64();
2544 
2545             gen_address_mask(dc, addr);
2546             tcg_gen_qemu_ld_i64(tmp, addr, da.mem_idx, da.memop);
2547 
2548             /* Note that LE ldda acts as if each 32-bit register
2549                result is byte swapped.  Having just performed one
2550                64-bit bswap, we need now to swap the writebacks.  */
2551             if ((da.memop & MO_BSWAP) == MO_TE) {
2552                 tcg_gen_extr32_i64(lo, hi, tmp);
2553             } else {
2554                 tcg_gen_extr32_i64(hi, lo, tmp);
2555             }
2556         }
2557         break;
2558 
2559     default:
2560         /* ??? In theory we've handled all of the ASIs that are valid
2561            for ldda, and this should raise DAE_invalid_asi.  However,
2562            real hardware allows others.  This can be seen with e.g.
2563            FreeBSD 10.3 wrt ASI_IC_TAG.  */
2564         {
2565             TCGv_i32 r_asi = tcg_constant_i32(da.asi);
2566             TCGv_i32 r_mop = tcg_constant_i32(da.memop);
2567             TCGv_i64 tmp = tcg_temp_new_i64();
2568 
2569             save_state(dc);
2570             gen_helper_ld_asi(tmp, cpu_env, addr, r_asi, r_mop);
2571 
2572             /* See above.  */
2573             if ((da.memop & MO_BSWAP) == MO_TE) {
2574                 tcg_gen_extr32_i64(lo, hi, tmp);
2575             } else {
2576                 tcg_gen_extr32_i64(hi, lo, tmp);
2577             }
2578         }
2579         break;
2580     }
2581 
2582     gen_store_gpr(dc, rd, hi);
2583     gen_store_gpr(dc, rd + 1, lo);
2584 }
2585 
2586 static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
2587                          int insn, int rd)
2588 {
2589     DisasASI da = get_asi(dc, insn, MO_TEUQ);
2590     TCGv lo = gen_load_gpr(dc, rd + 1);
2591 
2592     switch (da.type) {
2593     case GET_ASI_EXCP:
2594         break;
2595 
2596     case GET_ASI_DTWINX:
2597         gen_address_mask(dc, addr);
2598         tcg_gen_qemu_st_i64(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
2599         tcg_gen_addi_tl(addr, addr, 8);
2600         tcg_gen_qemu_st_i64(lo, addr, da.mem_idx, da.memop);
2601         break;
2602 
2603     case GET_ASI_DIRECT:
2604         {
2605             TCGv_i64 t64 = tcg_temp_new_i64();
2606 
2607             /* Note that LE stda acts as if each 32-bit register result is
2608                byte swapped.  We will perform one 64-bit LE store, so now
2609                we must swap the order of the construction.  */
2610             if ((da.memop & MO_BSWAP) == MO_TE) {
2611                 tcg_gen_concat32_i64(t64, lo, hi);
2612             } else {
2613                 tcg_gen_concat32_i64(t64, hi, lo);
2614             }
2615             gen_address_mask(dc, addr);
2616             tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
2617         }
2618         break;
2619 
2620     default:
2621         /* ??? In theory we've handled all of the ASIs that are valid
2622            for stda, and this should raise DAE_invalid_asi.  */
2623         {
2624             TCGv_i32 r_asi = tcg_constant_i32(da.asi);
2625             TCGv_i32 r_mop = tcg_constant_i32(da.memop);
2626             TCGv_i64 t64 = tcg_temp_new_i64();
2627 
2628             /* See above.  */
2629             if ((da.memop & MO_BSWAP) == MO_TE) {
2630                 tcg_gen_concat32_i64(t64, lo, hi);
2631             } else {
2632                 tcg_gen_concat32_i64(t64, hi, lo);
2633             }
2634 
2635             save_state(dc);
2636             gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
2637         }
2638         break;
2639     }
2640 }
2641 
2642 static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
2643                          int insn, int rd)
2644 {
2645     DisasASI da = get_asi(dc, insn, MO_TEUQ);
2646     TCGv oldv;
2647 
2648     switch (da.type) {
2649     case GET_ASI_EXCP:
2650         return;
2651     case GET_ASI_DIRECT:
2652         oldv = tcg_temp_new();
2653         tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
2654                                   da.mem_idx, da.memop);
2655         gen_store_gpr(dc, rd, oldv);
2656         break;
2657     default:
2658         /* ??? Should be DAE_invalid_asi.  */
2659         gen_exception(dc, TT_DATA_ACCESS);
2660         break;
2661     }
2662 }
2663 
2664 #elif !defined(CONFIG_USER_ONLY)
2665 static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
2666 {
2667     /* ??? Work around an apparent bug in Ubuntu gcc 4.8.2-10ubuntu2+12,
2668        whereby "rd + 1" elicits "error: array subscript is above array".
2669        Since we have already asserted that rd is even, the semantics
2670        are unchanged.  */
2671     TCGv lo = gen_dest_gpr(dc, rd | 1);
2672     TCGv hi = gen_dest_gpr(dc, rd);
2673     TCGv_i64 t64 = tcg_temp_new_i64();
2674     DisasASI da = get_asi(dc, insn, MO_TEUQ);
2675 
2676     switch (da.type) {
2677     case GET_ASI_EXCP:
2678         return;
2679     case GET_ASI_DIRECT:
2680         gen_address_mask(dc, addr);
2681         tcg_gen_qemu_ld_i64(t64, addr, da.mem_idx, da.memop);
2682         break;
2683     default:
2684         {
2685             TCGv_i32 r_asi = tcg_constant_i32(da.asi);
2686             TCGv_i32 r_mop = tcg_constant_i32(MO_UQ);
2687 
2688             save_state(dc);
2689             gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
2690         }
2691         break;
2692     }
2693 
2694     tcg_gen_extr_i64_i32(lo, hi, t64);
2695     gen_store_gpr(dc, rd | 1, lo);
2696     gen_store_gpr(dc, rd, hi);
2697 }
2698 
2699 static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
2700                          int insn, int rd)
2701 {
2702     DisasASI da = get_asi(dc, insn, MO_TEUQ);
2703     TCGv lo = gen_load_gpr(dc, rd + 1);
2704     TCGv_i64 t64 = tcg_temp_new_i64();
2705 
2706     tcg_gen_concat_tl_i64(t64, lo, hi);
2707 
2708     switch (da.type) {
2709     case GET_ASI_EXCP:
2710         break;
2711     case GET_ASI_DIRECT:
2712         gen_address_mask(dc, addr);
2713         tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
2714         break;
2715     case GET_ASI_BFILL:
2716         /* Store 32 bytes of T64 to ADDR.  */
2717         /* ??? The original qemu code suggests 8-byte alignment, dropping
2718            the low bits, but the only place I can see this used is in the
2719            Linux kernel with 32 byte alignment, which would make more sense
2720            as a cacheline-style operation.  */
2721         {
2722             TCGv d_addr = tcg_temp_new();
2723             TCGv eight = tcg_constant_tl(8);
2724             int i;
2725 
2726             tcg_gen_andi_tl(d_addr, addr, -8);
2727             for (i = 0; i < 32; i += 8) {
2728                 tcg_gen_qemu_st_i64(t64, d_addr, da.mem_idx, da.memop);
2729                 tcg_gen_add_tl(d_addr, d_addr, eight);
2730             }
2731         }
2732         break;
2733     default:
2734         {
2735             TCGv_i32 r_asi = tcg_constant_i32(da.asi);
2736             TCGv_i32 r_mop = tcg_constant_i32(MO_UQ);
2737 
2738             save_state(dc);
2739             gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
2740         }
2741         break;
2742     }
2743 }
2744 #endif
2745 
2746 static TCGv get_src1(DisasContext *dc, unsigned int insn)
2747 {
2748     unsigned int rs1 = GET_FIELD(insn, 13, 17);
2749     return gen_load_gpr(dc, rs1);
2750 }
2751 
2752 static TCGv get_src2(DisasContext *dc, unsigned int insn)
2753 {
2754     if (IS_IMM) { /* immediate */
2755         target_long simm = GET_FIELDs(insn, 19, 31);
2756         TCGv t = tcg_temp_new();
2757         tcg_gen_movi_tl(t, simm);
2758         return t;
2759     } else {      /* register */
2760         unsigned int rs2 = GET_FIELD(insn, 27, 31);
2761         return gen_load_gpr(dc, rs2);
2762     }
2763 }
2764 
2765 #ifdef TARGET_SPARC64
2766 static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2767 {
2768     TCGv_i32 c32, zero, dst, s1, s2;
2769 
2770     /* We have two choices here: extend the 32 bit data and use movcond_i64,
2771        or fold the comparison down to 32 bits and use movcond_i32.  Choose
2772        the later.  */
2773     c32 = tcg_temp_new_i32();
2774     if (cmp->is_bool) {
2775         tcg_gen_extrl_i64_i32(c32, cmp->c1);
2776     } else {
2777         TCGv_i64 c64 = tcg_temp_new_i64();
2778         tcg_gen_setcond_i64(cmp->cond, c64, cmp->c1, cmp->c2);
2779         tcg_gen_extrl_i64_i32(c32, c64);
2780     }
2781 
2782     s1 = gen_load_fpr_F(dc, rs);
2783     s2 = gen_load_fpr_F(dc, rd);
2784     dst = gen_dest_fpr_F(dc);
2785     zero = tcg_constant_i32(0);
2786 
2787     tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
2788 
2789     gen_store_fpr_F(dc, rd, dst);
2790 }
2791 
2792 static void gen_fmovd(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2793 {
2794     TCGv_i64 dst = gen_dest_fpr_D(dc, rd);
2795     tcg_gen_movcond_i64(cmp->cond, dst, cmp->c1, cmp->c2,
2796                         gen_load_fpr_D(dc, rs),
2797                         gen_load_fpr_D(dc, rd));
2798     gen_store_fpr_D(dc, rd, dst);
2799 }
2800 
2801 static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2802 {
2803     int qd = QFPREG(rd);
2804     int qs = QFPREG(rs);
2805 
2806     tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2], cmp->c1, cmp->c2,
2807                         cpu_fpr[qs / 2], cpu_fpr[qd / 2]);
2808     tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, cmp->c2,
2809                         cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
2810 
2811     gen_update_fprs_dirty(dc, qd);
2812 }
2813 
2814 #ifndef CONFIG_USER_ONLY
2815 static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env cpu_env)
2816 {
2817     TCGv_i32 r_tl = tcg_temp_new_i32();
2818 
2819     /* load env->tl into r_tl */
2820     tcg_gen_ld_i32(r_tl, cpu_env, offsetof(CPUSPARCState, tl));
2821 
2822     /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
2823     tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
2824 
2825     /* calculate offset to current trap state from env->ts, reuse r_tl */
2826     tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
2827     tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUSPARCState, ts));
2828 
2829     /* tsptr = env->ts[env->tl & MAXTL_MASK] */
2830     {
2831         TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
2832         tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
2833         tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
2834     }
2835 }
2836 #endif
2837 
2838 static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
2839                      int width, bool cc, bool left)
2840 {
2841     TCGv lo1, lo2;
2842     uint64_t amask, tabl, tabr;
2843     int shift, imask, omask;
2844 
2845     if (cc) {
2846         tcg_gen_mov_tl(cpu_cc_src, s1);
2847         tcg_gen_mov_tl(cpu_cc_src2, s2);
2848         tcg_gen_sub_tl(cpu_cc_dst, s1, s2);
2849         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
2850         dc->cc_op = CC_OP_SUB;
2851     }
2852 
2853     /* Theory of operation: there are two tables, left and right (not to
2854        be confused with the left and right versions of the opcode).  These
2855        are indexed by the low 3 bits of the inputs.  To make things "easy",
2856        these tables are loaded into two constants, TABL and TABR below.
2857        The operation index = (input & imask) << shift calculates the index
2858        into the constant, while val = (table >> index) & omask calculates
2859        the value we're looking for.  */
2860     switch (width) {
2861     case 8:
2862         imask = 0x7;
2863         shift = 3;
2864         omask = 0xff;
2865         if (left) {
2866             tabl = 0x80c0e0f0f8fcfeffULL;
2867             tabr = 0xff7f3f1f0f070301ULL;
2868         } else {
2869             tabl = 0x0103070f1f3f7fffULL;
2870             tabr = 0xfffefcf8f0e0c080ULL;
2871         }
2872         break;
2873     case 16:
2874         imask = 0x6;
2875         shift = 1;
2876         omask = 0xf;
2877         if (left) {
2878             tabl = 0x8cef;
2879             tabr = 0xf731;
2880         } else {
2881             tabl = 0x137f;
2882             tabr = 0xfec8;
2883         }
2884         break;
2885     case 32:
2886         imask = 0x4;
2887         shift = 0;
2888         omask = 0x3;
2889         if (left) {
2890             tabl = (2 << 2) | 3;
2891             tabr = (3 << 2) | 1;
2892         } else {
2893             tabl = (1 << 2) | 3;
2894             tabr = (3 << 2) | 2;
2895         }
2896         break;
2897     default:
2898         abort();
2899     }
2900 
2901     lo1 = tcg_temp_new();
2902     lo2 = tcg_temp_new();
2903     tcg_gen_andi_tl(lo1, s1, imask);
2904     tcg_gen_andi_tl(lo2, s2, imask);
2905     tcg_gen_shli_tl(lo1, lo1, shift);
2906     tcg_gen_shli_tl(lo2, lo2, shift);
2907 
2908     tcg_gen_shr_tl(lo1, tcg_constant_tl(tabl), lo1);
2909     tcg_gen_shr_tl(lo2, tcg_constant_tl(tabr), lo2);
2910     tcg_gen_andi_tl(dst, lo1, omask);
2911     tcg_gen_andi_tl(lo2, lo2, omask);
2912 
2913     amask = -8;
2914     if (AM_CHECK(dc)) {
2915         amask &= 0xffffffffULL;
2916     }
2917     tcg_gen_andi_tl(s1, s1, amask);
2918     tcg_gen_andi_tl(s2, s2, amask);
2919 
2920     /* We want to compute
2921         dst = (s1 == s2 ? lo1 : lo1 & lo2).
2922        We've already done dst = lo1, so this reduces to
2923         dst &= (s1 == s2 ? -1 : lo2)
2924        Which we perform by
2925         lo2 |= -(s1 == s2)
2926         dst &= lo2
2927     */
2928     tcg_gen_setcond_tl(TCG_COND_EQ, lo1, s1, s2);
2929     tcg_gen_neg_tl(lo1, lo1);
2930     tcg_gen_or_tl(lo2, lo2, lo1);
2931     tcg_gen_and_tl(dst, dst, lo2);
2932 }
2933 
2934 static void gen_alignaddr(TCGv dst, TCGv s1, TCGv s2, bool left)
2935 {
2936     TCGv tmp = tcg_temp_new();
2937 
2938     tcg_gen_add_tl(tmp, s1, s2);
2939     tcg_gen_andi_tl(dst, tmp, -8);
2940     if (left) {
2941         tcg_gen_neg_tl(tmp, tmp);
2942     }
2943     tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
2944 }
2945 
2946 static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
2947 {
2948     TCGv t1, t2, shift;
2949 
2950     t1 = tcg_temp_new();
2951     t2 = tcg_temp_new();
2952     shift = tcg_temp_new();
2953 
2954     tcg_gen_andi_tl(shift, gsr, 7);
2955     tcg_gen_shli_tl(shift, shift, 3);
2956     tcg_gen_shl_tl(t1, s1, shift);
2957 
2958     /* A shift of 64 does not produce 0 in TCG.  Divide this into a
2959        shift of (up to 63) followed by a constant shift of 1.  */
2960     tcg_gen_xori_tl(shift, shift, 63);
2961     tcg_gen_shr_tl(t2, s2, shift);
2962     tcg_gen_shri_tl(t2, t2, 1);
2963 
2964     tcg_gen_or_tl(dst, t1, t2);
2965 }
2966 #endif
2967 
2968 #define CHECK_IU_FEATURE(dc, FEATURE)                      \
2969     if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
2970         goto illegal_insn;
2971 #define CHECK_FPU_FEATURE(dc, FEATURE)                     \
2972     if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
2973         goto nfpu_insn;
2974 
2975 /* before an instruction, dc->pc must be static */
2976 static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
2977 {
2978     unsigned int opc, rs1, rs2, rd;
2979     TCGv cpu_src1, cpu_src2;
2980     TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
2981     TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
2982     target_long simm;
2983 
2984     opc = GET_FIELD(insn, 0, 1);
2985     rd = GET_FIELD(insn, 2, 6);
2986 
2987     switch (opc) {
2988     case 0:                     /* branches/sethi */
2989         {
2990             unsigned int xop = GET_FIELD(insn, 7, 9);
2991             int32_t target;
2992             switch (xop) {
2993 #ifdef TARGET_SPARC64
2994             case 0x1:           /* V9 BPcc */
2995                 {
2996                     int cc;
2997 
2998                     target = GET_FIELD_SP(insn, 0, 18);
2999                     target = sign_extend(target, 19);
3000                     target <<= 2;
3001                     cc = GET_FIELD_SP(insn, 20, 21);
3002                     if (cc == 0)
3003                         do_branch(dc, target, insn, 0);
3004                     else if (cc == 2)
3005                         do_branch(dc, target, insn, 1);
3006                     else
3007                         goto illegal_insn;
3008                     goto jmp_insn;
3009                 }
3010             case 0x3:           /* V9 BPr */
3011                 {
3012                     target = GET_FIELD_SP(insn, 0, 13) |
3013                         (GET_FIELD_SP(insn, 20, 21) << 14);
3014                     target = sign_extend(target, 16);
3015                     target <<= 2;
3016                     cpu_src1 = get_src1(dc, insn);
3017                     do_branch_reg(dc, target, insn, cpu_src1);
3018                     goto jmp_insn;
3019                 }
3020             case 0x5:           /* V9 FBPcc */
3021                 {
3022                     int cc = GET_FIELD_SP(insn, 20, 21);
3023                     if (gen_trap_ifnofpu(dc)) {
3024                         goto jmp_insn;
3025                     }
3026                     target = GET_FIELD_SP(insn, 0, 18);
3027                     target = sign_extend(target, 19);
3028                     target <<= 2;
3029                     do_fbranch(dc, target, insn, cc);
3030                     goto jmp_insn;
3031                 }
3032 #else
3033             case 0x7:           /* CBN+x */
3034                 {
3035                     goto ncp_insn;
3036                 }
3037 #endif
3038             case 0x2:           /* BN+x */
3039                 {
3040                     target = GET_FIELD(insn, 10, 31);
3041                     target = sign_extend(target, 22);
3042                     target <<= 2;
3043                     do_branch(dc, target, insn, 0);
3044                     goto jmp_insn;
3045                 }
3046             case 0x6:           /* FBN+x */
3047                 {
3048                     if (gen_trap_ifnofpu(dc)) {
3049                         goto jmp_insn;
3050                     }
3051                     target = GET_FIELD(insn, 10, 31);
3052                     target = sign_extend(target, 22);
3053                     target <<= 2;
3054                     do_fbranch(dc, target, insn, 0);
3055                     goto jmp_insn;
3056                 }
3057             case 0x4:           /* SETHI */
3058                 /* Special-case %g0 because that's the canonical nop.  */
3059                 if (rd) {
3060                     uint32_t value = GET_FIELD(insn, 10, 31);
3061                     TCGv t = gen_dest_gpr(dc, rd);
3062                     tcg_gen_movi_tl(t, value << 10);
3063                     gen_store_gpr(dc, rd, t);
3064                 }
3065                 break;
3066             case 0x0:           /* UNIMPL */
3067             default:
3068                 goto illegal_insn;
3069             }
3070             break;
3071         }
3072         break;
3073     case 1:                     /*CALL*/
3074         {
3075             target_long target = GET_FIELDs(insn, 2, 31) << 2;
3076             TCGv o7 = gen_dest_gpr(dc, 15);
3077 
3078             tcg_gen_movi_tl(o7, dc->pc);
3079             gen_store_gpr(dc, 15, o7);
3080             target += dc->pc;
3081             gen_mov_pc_npc(dc);
3082 #ifdef TARGET_SPARC64
3083             if (unlikely(AM_CHECK(dc))) {
3084                 target &= 0xffffffffULL;
3085             }
3086 #endif
3087             dc->npc = target;
3088         }
3089         goto jmp_insn;
3090     case 2:                     /* FPU & Logical Operations */
3091         {
3092             unsigned int xop = GET_FIELD(insn, 7, 12);
3093             TCGv cpu_dst = tcg_temp_new();
3094             TCGv cpu_tmp0;
3095 
3096             if (xop == 0x3a) {  /* generate trap */
3097                 int cond = GET_FIELD(insn, 3, 6);
3098                 TCGv_i32 trap;
3099                 TCGLabel *l1 = NULL;
3100                 int mask;
3101 
3102                 if (cond == 0) {
3103                     /* Trap never.  */
3104                     break;
3105                 }
3106 
3107                 save_state(dc);
3108 
3109                 if (cond != 8) {
3110                     /* Conditional trap.  */
3111                     DisasCompare cmp;
3112 #ifdef TARGET_SPARC64
3113                     /* V9 icc/xcc */
3114                     int cc = GET_FIELD_SP(insn, 11, 12);
3115                     if (cc == 0) {
3116                         gen_compare(&cmp, 0, cond, dc);
3117                     } else if (cc == 2) {
3118                         gen_compare(&cmp, 1, cond, dc);
3119                     } else {
3120                         goto illegal_insn;
3121                     }
3122 #else
3123                     gen_compare(&cmp, 0, cond, dc);
3124 #endif
3125                     l1 = gen_new_label();
3126                     tcg_gen_brcond_tl(tcg_invert_cond(cmp.cond),
3127                                       cmp.c1, cmp.c2, l1);
3128                 }
3129 
3130                 mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc)
3131                         ? UA2005_HTRAP_MASK : V8_TRAP_MASK);
3132 
3133                 /* Don't use the normal temporaries, as they may well have
3134                    gone out of scope with the branch above.  While we're
3135                    doing that we might as well pre-truncate to 32-bit.  */
3136                 trap = tcg_temp_new_i32();
3137 
3138                 rs1 = GET_FIELD_SP(insn, 14, 18);
3139                 if (IS_IMM) {
3140                     rs2 = GET_FIELD_SP(insn, 0, 7);
3141                     if (rs1 == 0) {
3142                         tcg_gen_movi_i32(trap, (rs2 & mask) + TT_TRAP);
3143                         /* Signal that the trap value is fully constant.  */
3144                         mask = 0;
3145                     } else {
3146                         TCGv t1 = gen_load_gpr(dc, rs1);
3147                         tcg_gen_trunc_tl_i32(trap, t1);
3148                         tcg_gen_addi_i32(trap, trap, rs2);
3149                     }
3150                 } else {
3151                     TCGv t1, t2;
3152                     rs2 = GET_FIELD_SP(insn, 0, 4);
3153                     t1 = gen_load_gpr(dc, rs1);
3154                     t2 = gen_load_gpr(dc, rs2);
3155                     tcg_gen_add_tl(t1, t1, t2);
3156                     tcg_gen_trunc_tl_i32(trap, t1);
3157                 }
3158                 if (mask != 0) {
3159                     tcg_gen_andi_i32(trap, trap, mask);
3160                     tcg_gen_addi_i32(trap, trap, TT_TRAP);
3161                 }
3162 
3163                 gen_helper_raise_exception(cpu_env, trap);
3164 
3165                 if (cond == 8) {
3166                     /* An unconditional trap ends the TB.  */
3167                     dc->base.is_jmp = DISAS_NORETURN;
3168                     goto jmp_insn;
3169                 } else {
3170                     /* A conditional trap falls through to the next insn.  */
3171                     gen_set_label(l1);
3172                     break;
3173                 }
3174             } else if (xop == 0x28) {
3175                 rs1 = GET_FIELD(insn, 13, 17);
3176                 switch(rs1) {
3177                 case 0: /* rdy */
3178 #ifndef TARGET_SPARC64
3179                 case 0x01 ... 0x0e: /* undefined in the SPARCv8
3180                                        manual, rdy on the microSPARC
3181                                        II */
3182                 case 0x0f:          /* stbar in the SPARCv8 manual,
3183                                        rdy on the microSPARC II */
3184                 case 0x10 ... 0x1f: /* implementation-dependent in the
3185                                        SPARCv8 manual, rdy on the
3186                                        microSPARC II */
3187                     /* Read Asr17 */
3188                     if (rs1 == 0x11 && dc->def->features & CPU_FEATURE_ASR17) {
3189                         TCGv t = gen_dest_gpr(dc, rd);
3190                         /* Read Asr17 for a Leon3 monoprocessor */
3191                         tcg_gen_movi_tl(t, (1 << 8) | (dc->def->nwindows - 1));
3192                         gen_store_gpr(dc, rd, t);
3193                         break;
3194                     }
3195 #endif
3196                     gen_store_gpr(dc, rd, cpu_y);
3197                     break;
3198 #ifdef TARGET_SPARC64
3199                 case 0x2: /* V9 rdccr */
3200                     update_psr(dc);
3201                     gen_helper_rdccr(cpu_dst, cpu_env);
3202                     gen_store_gpr(dc, rd, cpu_dst);
3203                     break;
3204                 case 0x3: /* V9 rdasi */
3205                     tcg_gen_movi_tl(cpu_dst, dc->asi);
3206                     gen_store_gpr(dc, rd, cpu_dst);
3207                     break;
3208                 case 0x4: /* V9 rdtick */
3209                     {
3210                         TCGv_ptr r_tickptr;
3211                         TCGv_i32 r_const;
3212 
3213                         r_tickptr = tcg_temp_new_ptr();
3214                         r_const = tcg_constant_i32(dc->mem_idx);
3215                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
3216                                        offsetof(CPUSPARCState, tick));
3217                         if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
3218                             gen_io_start();
3219                         }
3220                         gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
3221                                                   r_const);
3222                         gen_store_gpr(dc, rd, cpu_dst);
3223                         if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
3224                             /* I/O operations in icount mode must end the TB */
3225                             dc->base.is_jmp = DISAS_EXIT;
3226                         }
3227                     }
3228                     break;
3229                 case 0x5: /* V9 rdpc */
3230                     {
3231                         TCGv t = gen_dest_gpr(dc, rd);
3232                         if (unlikely(AM_CHECK(dc))) {
3233                             tcg_gen_movi_tl(t, dc->pc & 0xffffffffULL);
3234                         } else {
3235                             tcg_gen_movi_tl(t, dc->pc);
3236                         }
3237                         gen_store_gpr(dc, rd, t);
3238                     }
3239                     break;
3240                 case 0x6: /* V9 rdfprs */
3241                     tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
3242                     gen_store_gpr(dc, rd, cpu_dst);
3243                     break;
3244                 case 0xf: /* V9 membar */
3245                     break; /* no effect */
3246                 case 0x13: /* Graphics Status */
3247                     if (gen_trap_ifnofpu(dc)) {
3248                         goto jmp_insn;
3249                     }
3250                     gen_store_gpr(dc, rd, cpu_gsr);
3251                     break;
3252                 case 0x16: /* Softint */
3253                     tcg_gen_ld32s_tl(cpu_dst, cpu_env,
3254                                      offsetof(CPUSPARCState, softint));
3255                     gen_store_gpr(dc, rd, cpu_dst);
3256                     break;
3257                 case 0x17: /* Tick compare */
3258                     gen_store_gpr(dc, rd, cpu_tick_cmpr);
3259                     break;
3260                 case 0x18: /* System tick */
3261                     {
3262                         TCGv_ptr r_tickptr;
3263                         TCGv_i32 r_const;
3264 
3265                         r_tickptr = tcg_temp_new_ptr();
3266                         r_const = tcg_constant_i32(dc->mem_idx);
3267                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
3268                                        offsetof(CPUSPARCState, stick));
3269                         if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
3270                             gen_io_start();
3271                         }
3272                         gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
3273                                                   r_const);
3274                         gen_store_gpr(dc, rd, cpu_dst);
3275                         if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
3276                             /* I/O operations in icount mode must end the TB */
3277                             dc->base.is_jmp = DISAS_EXIT;
3278                         }
3279                     }
3280                     break;
3281                 case 0x19: /* System tick compare */
3282                     gen_store_gpr(dc, rd, cpu_stick_cmpr);
3283                     break;
3284                 case 0x1a: /* UltraSPARC-T1 Strand status */
3285                     /* XXX HYPV check maybe not enough, UA2005 & UA2007 describe
3286                      * this ASR as impl. dep
3287                      */
3288                     CHECK_IU_FEATURE(dc, HYPV);
3289                     {
3290                         TCGv t = gen_dest_gpr(dc, rd);
3291                         tcg_gen_movi_tl(t, 1UL);
3292                         gen_store_gpr(dc, rd, t);
3293                     }
3294                     break;
3295                 case 0x10: /* Performance Control */
3296                 case 0x11: /* Performance Instrumentation Counter */
3297                 case 0x12: /* Dispatch Control */
3298                 case 0x14: /* Softint set, WO */
3299                 case 0x15: /* Softint clear, WO */
3300 #endif
3301                 default:
3302                     goto illegal_insn;
3303                 }
3304 #if !defined(CONFIG_USER_ONLY)
3305             } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
3306 #ifndef TARGET_SPARC64
3307                 if (!supervisor(dc)) {
3308                     goto priv_insn;
3309                 }
3310                 update_psr(dc);
3311                 gen_helper_rdpsr(cpu_dst, cpu_env);
3312 #else
3313                 CHECK_IU_FEATURE(dc, HYPV);
3314                 if (!hypervisor(dc))
3315                     goto priv_insn;
3316                 rs1 = GET_FIELD(insn, 13, 17);
3317                 switch (rs1) {
3318                 case 0: // hpstate
3319                     tcg_gen_ld_i64(cpu_dst, cpu_env,
3320                                    offsetof(CPUSPARCState, hpstate));
3321                     break;
3322                 case 1: // htstate
3323                     // gen_op_rdhtstate();
3324                     break;
3325                 case 3: // hintp
3326                     tcg_gen_mov_tl(cpu_dst, cpu_hintp);
3327                     break;
3328                 case 5: // htba
3329                     tcg_gen_mov_tl(cpu_dst, cpu_htba);
3330                     break;
3331                 case 6: // hver
3332                     tcg_gen_mov_tl(cpu_dst, cpu_hver);
3333                     break;
3334                 case 31: // hstick_cmpr
3335                     tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
3336                     break;
3337                 default:
3338                     goto illegal_insn;
3339                 }
3340 #endif
3341                 gen_store_gpr(dc, rd, cpu_dst);
3342                 break;
3343             } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
3344                 if (!supervisor(dc)) {
3345                     goto priv_insn;
3346                 }
3347                 cpu_tmp0 = tcg_temp_new();
3348 #ifdef TARGET_SPARC64
3349                 rs1 = GET_FIELD(insn, 13, 17);
3350                 switch (rs1) {
3351                 case 0: // tpc
3352                     {
3353                         TCGv_ptr r_tsptr;
3354 
3355                         r_tsptr = tcg_temp_new_ptr();
3356                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3357                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
3358                                       offsetof(trap_state, tpc));
3359                     }
3360                     break;
3361                 case 1: // tnpc
3362                     {
3363                         TCGv_ptr r_tsptr;
3364 
3365                         r_tsptr = tcg_temp_new_ptr();
3366                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3367                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
3368                                       offsetof(trap_state, tnpc));
3369                     }
3370                     break;
3371                 case 2: // tstate
3372                     {
3373                         TCGv_ptr r_tsptr;
3374 
3375                         r_tsptr = tcg_temp_new_ptr();
3376                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3377                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
3378                                       offsetof(trap_state, tstate));
3379                     }
3380                     break;
3381                 case 3: // tt
3382                     {
3383                         TCGv_ptr r_tsptr = tcg_temp_new_ptr();
3384 
3385                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3386                         tcg_gen_ld32s_tl(cpu_tmp0, r_tsptr,
3387                                          offsetof(trap_state, tt));
3388                     }
3389                     break;
3390                 case 4: // tick
3391                     {
3392                         TCGv_ptr r_tickptr;
3393                         TCGv_i32 r_const;
3394 
3395                         r_tickptr = tcg_temp_new_ptr();
3396                         r_const = tcg_constant_i32(dc->mem_idx);
3397                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
3398                                        offsetof(CPUSPARCState, tick));
3399                         if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
3400                             gen_io_start();
3401                         }
3402                         gen_helper_tick_get_count(cpu_tmp0, cpu_env,
3403                                                   r_tickptr, r_const);
3404                         if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
3405                             /* I/O operations in icount mode must end the TB */
3406                             dc->base.is_jmp = DISAS_EXIT;
3407                         }
3408                     }
3409                     break;
3410                 case 5: // tba
3411                     tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
3412                     break;
3413                 case 6: // pstate
3414                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3415                                      offsetof(CPUSPARCState, pstate));
3416                     break;
3417                 case 7: // tl
3418                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3419                                      offsetof(CPUSPARCState, tl));
3420                     break;
3421                 case 8: // pil
3422                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3423                                      offsetof(CPUSPARCState, psrpil));
3424                     break;
3425                 case 9: // cwp
3426                     gen_helper_rdcwp(cpu_tmp0, cpu_env);
3427                     break;
3428                 case 10: // cansave
3429                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3430                                      offsetof(CPUSPARCState, cansave));
3431                     break;
3432                 case 11: // canrestore
3433                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3434                                      offsetof(CPUSPARCState, canrestore));
3435                     break;
3436                 case 12: // cleanwin
3437                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3438                                      offsetof(CPUSPARCState, cleanwin));
3439                     break;
3440                 case 13: // otherwin
3441                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3442                                      offsetof(CPUSPARCState, otherwin));
3443                     break;
3444                 case 14: // wstate
3445                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3446                                      offsetof(CPUSPARCState, wstate));
3447                     break;
3448                 case 16: // UA2005 gl
3449                     CHECK_IU_FEATURE(dc, GL);
3450                     tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
3451                                      offsetof(CPUSPARCState, gl));
3452                     break;
3453                 case 26: // UA2005 strand status
3454                     CHECK_IU_FEATURE(dc, HYPV);
3455                     if (!hypervisor(dc))
3456                         goto priv_insn;
3457                     tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
3458                     break;
3459                 case 31: // ver
3460                     tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
3461                     break;
3462                 case 15: // fq
3463                 default:
3464                     goto illegal_insn;
3465                 }
3466 #else
3467                 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
3468 #endif
3469                 gen_store_gpr(dc, rd, cpu_tmp0);
3470                 break;
3471 #endif
3472 #if defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)
3473             } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
3474 #ifdef TARGET_SPARC64
3475                 gen_helper_flushw(cpu_env);
3476 #else
3477                 if (!supervisor(dc))
3478                     goto priv_insn;
3479                 gen_store_gpr(dc, rd, cpu_tbr);
3480 #endif
3481                 break;
3482 #endif
3483             } else if (xop == 0x34) {   /* FPU Operations */
3484                 if (gen_trap_ifnofpu(dc)) {
3485                     goto jmp_insn;
3486                 }
3487                 gen_op_clear_ieee_excp_and_FTT();
3488                 rs1 = GET_FIELD(insn, 13, 17);
3489                 rs2 = GET_FIELD(insn, 27, 31);
3490                 xop = GET_FIELD(insn, 18, 26);
3491 
3492                 switch (xop) {
3493                 case 0x1: /* fmovs */
3494                     cpu_src1_32 = gen_load_fpr_F(dc, rs2);
3495                     gen_store_fpr_F(dc, rd, cpu_src1_32);
3496                     break;
3497                 case 0x5: /* fnegs */
3498                     gen_ne_fop_FF(dc, rd, rs2, gen_helper_fnegs);
3499                     break;
3500                 case 0x9: /* fabss */
3501                     gen_ne_fop_FF(dc, rd, rs2, gen_helper_fabss);
3502                     break;
3503                 case 0x29: /* fsqrts */
3504                     CHECK_FPU_FEATURE(dc, FSQRT);
3505                     gen_fop_FF(dc, rd, rs2, gen_helper_fsqrts);
3506                     break;
3507                 case 0x2a: /* fsqrtd */
3508                     CHECK_FPU_FEATURE(dc, FSQRT);
3509                     gen_fop_DD(dc, rd, rs2, gen_helper_fsqrtd);
3510                     break;
3511                 case 0x2b: /* fsqrtq */
3512                     CHECK_FPU_FEATURE(dc, FLOAT128);
3513                     gen_fop_QQ(dc, rd, rs2, gen_helper_fsqrtq);
3514                     break;
3515                 case 0x41: /* fadds */
3516                     gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fadds);
3517                     break;
3518                 case 0x42: /* faddd */
3519                     gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_faddd);
3520                     break;
3521                 case 0x43: /* faddq */
3522                     CHECK_FPU_FEATURE(dc, FLOAT128);
3523                     gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_faddq);
3524                     break;
3525                 case 0x45: /* fsubs */
3526                     gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fsubs);
3527                     break;
3528                 case 0x46: /* fsubd */
3529                     gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fsubd);
3530                     break;
3531                 case 0x47: /* fsubq */
3532                     CHECK_FPU_FEATURE(dc, FLOAT128);
3533                     gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fsubq);
3534                     break;
3535                 case 0x49: /* fmuls */
3536                     CHECK_FPU_FEATURE(dc, FMUL);
3537                     gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fmuls);
3538                     break;
3539                 case 0x4a: /* fmuld */
3540                     CHECK_FPU_FEATURE(dc, FMUL);
3541                     gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld);
3542                     break;
3543                 case 0x4b: /* fmulq */
3544                     CHECK_FPU_FEATURE(dc, FLOAT128);
3545                     CHECK_FPU_FEATURE(dc, FMUL);
3546                     gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fmulq);
3547                     break;
3548                 case 0x4d: /* fdivs */
3549                     gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fdivs);
3550                     break;
3551                 case 0x4e: /* fdivd */
3552                     gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fdivd);
3553                     break;
3554                 case 0x4f: /* fdivq */
3555                     CHECK_FPU_FEATURE(dc, FLOAT128);
3556                     gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fdivq);
3557                     break;
3558                 case 0x69: /* fsmuld */
3559                     CHECK_FPU_FEATURE(dc, FSMULD);
3560                     gen_fop_DFF(dc, rd, rs1, rs2, gen_helper_fsmuld);
3561                     break;
3562                 case 0x6e: /* fdmulq */
3563                     CHECK_FPU_FEATURE(dc, FLOAT128);
3564                     gen_fop_QDD(dc, rd, rs1, rs2, gen_helper_fdmulq);
3565                     break;
3566                 case 0xc4: /* fitos */
3567                     gen_fop_FF(dc, rd, rs2, gen_helper_fitos);
3568                     break;
3569                 case 0xc6: /* fdtos */
3570                     gen_fop_FD(dc, rd, rs2, gen_helper_fdtos);
3571                     break;
3572                 case 0xc7: /* fqtos */
3573                     CHECK_FPU_FEATURE(dc, FLOAT128);
3574                     gen_fop_FQ(dc, rd, rs2, gen_helper_fqtos);
3575                     break;
3576                 case 0xc8: /* fitod */
3577                     gen_ne_fop_DF(dc, rd, rs2, gen_helper_fitod);
3578                     break;
3579                 case 0xc9: /* fstod */
3580                     gen_ne_fop_DF(dc, rd, rs2, gen_helper_fstod);
3581                     break;
3582                 case 0xcb: /* fqtod */
3583                     CHECK_FPU_FEATURE(dc, FLOAT128);
3584                     gen_fop_DQ(dc, rd, rs2, gen_helper_fqtod);
3585                     break;
3586                 case 0xcc: /* fitoq */
3587                     CHECK_FPU_FEATURE(dc, FLOAT128);
3588                     gen_ne_fop_QF(dc, rd, rs2, gen_helper_fitoq);
3589                     break;
3590                 case 0xcd: /* fstoq */
3591                     CHECK_FPU_FEATURE(dc, FLOAT128);
3592                     gen_ne_fop_QF(dc, rd, rs2, gen_helper_fstoq);
3593                     break;
3594                 case 0xce: /* fdtoq */
3595                     CHECK_FPU_FEATURE(dc, FLOAT128);
3596                     gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq);
3597                     break;
3598                 case 0xd1: /* fstoi */
3599                     gen_fop_FF(dc, rd, rs2, gen_helper_fstoi);
3600                     break;
3601                 case 0xd2: /* fdtoi */
3602                     gen_fop_FD(dc, rd, rs2, gen_helper_fdtoi);
3603                     break;
3604                 case 0xd3: /* fqtoi */
3605                     CHECK_FPU_FEATURE(dc, FLOAT128);
3606                     gen_fop_FQ(dc, rd, rs2, gen_helper_fqtoi);
3607                     break;
3608 #ifdef TARGET_SPARC64
3609                 case 0x2: /* V9 fmovd */
3610                     cpu_src1_64 = gen_load_fpr_D(dc, rs2);
3611                     gen_store_fpr_D(dc, rd, cpu_src1_64);
3612                     break;
3613                 case 0x3: /* V9 fmovq */
3614                     CHECK_FPU_FEATURE(dc, FLOAT128);
3615                     gen_move_Q(dc, rd, rs2);
3616                     break;
3617                 case 0x6: /* V9 fnegd */
3618                     gen_ne_fop_DD(dc, rd, rs2, gen_helper_fnegd);
3619                     break;
3620                 case 0x7: /* V9 fnegq */
3621                     CHECK_FPU_FEATURE(dc, FLOAT128);
3622                     gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fnegq);
3623                     break;
3624                 case 0xa: /* V9 fabsd */
3625                     gen_ne_fop_DD(dc, rd, rs2, gen_helper_fabsd);
3626                     break;
3627                 case 0xb: /* V9 fabsq */
3628                     CHECK_FPU_FEATURE(dc, FLOAT128);
3629                     gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq);
3630                     break;
3631                 case 0x81: /* V9 fstox */
3632                     gen_fop_DF(dc, rd, rs2, gen_helper_fstox);
3633                     break;
3634                 case 0x82: /* V9 fdtox */
3635                     gen_fop_DD(dc, rd, rs2, gen_helper_fdtox);
3636                     break;
3637                 case 0x83: /* V9 fqtox */
3638                     CHECK_FPU_FEATURE(dc, FLOAT128);
3639                     gen_fop_DQ(dc, rd, rs2, gen_helper_fqtox);
3640                     break;
3641                 case 0x84: /* V9 fxtos */
3642                     gen_fop_FD(dc, rd, rs2, gen_helper_fxtos);
3643                     break;
3644                 case 0x88: /* V9 fxtod */
3645                     gen_fop_DD(dc, rd, rs2, gen_helper_fxtod);
3646                     break;
3647                 case 0x8c: /* V9 fxtoq */
3648                     CHECK_FPU_FEATURE(dc, FLOAT128);
3649                     gen_ne_fop_QD(dc, rd, rs2, gen_helper_fxtoq);
3650                     break;
3651 #endif
3652                 default:
3653                     goto illegal_insn;
3654                 }
3655             } else if (xop == 0x35) {   /* FPU Operations */
3656 #ifdef TARGET_SPARC64
3657                 int cond;
3658 #endif
3659                 if (gen_trap_ifnofpu(dc)) {
3660                     goto jmp_insn;
3661                 }
3662                 gen_op_clear_ieee_excp_and_FTT();
3663                 rs1 = GET_FIELD(insn, 13, 17);
3664                 rs2 = GET_FIELD(insn, 27, 31);
3665                 xop = GET_FIELD(insn, 18, 26);
3666 
3667 #ifdef TARGET_SPARC64
3668 #define FMOVR(sz)                                                  \
3669                 do {                                               \
3670                     DisasCompare cmp;                              \
3671                     cond = GET_FIELD_SP(insn, 10, 12);             \
3672                     cpu_src1 = get_src1(dc, insn);                 \
3673                     gen_compare_reg(&cmp, cond, cpu_src1);         \
3674                     gen_fmov##sz(dc, &cmp, rd, rs2);               \
3675                 } while (0)
3676 
3677                 if ((xop & 0x11f) == 0x005) { /* V9 fmovsr */
3678                     FMOVR(s);
3679                     break;
3680                 } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
3681                     FMOVR(d);
3682                     break;
3683                 } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
3684                     CHECK_FPU_FEATURE(dc, FLOAT128);
3685                     FMOVR(q);
3686                     break;
3687                 }
3688 #undef FMOVR
3689 #endif
3690                 switch (xop) {
3691 #ifdef TARGET_SPARC64
3692 #define FMOVCC(fcc, sz)                                                 \
3693                     do {                                                \
3694                         DisasCompare cmp;                               \
3695                         cond = GET_FIELD_SP(insn, 14, 17);              \
3696                         gen_fcompare(&cmp, fcc, cond);                  \
3697                         gen_fmov##sz(dc, &cmp, rd, rs2);                \
3698                     } while (0)
3699 
3700                     case 0x001: /* V9 fmovscc %fcc0 */
3701                         FMOVCC(0, s);
3702                         break;
3703                     case 0x002: /* V9 fmovdcc %fcc0 */
3704                         FMOVCC(0, d);
3705                         break;
3706                     case 0x003: /* V9 fmovqcc %fcc0 */
3707                         CHECK_FPU_FEATURE(dc, FLOAT128);
3708                         FMOVCC(0, q);
3709                         break;
3710                     case 0x041: /* V9 fmovscc %fcc1 */
3711                         FMOVCC(1, s);
3712                         break;
3713                     case 0x042: /* V9 fmovdcc %fcc1 */
3714                         FMOVCC(1, d);
3715                         break;
3716                     case 0x043: /* V9 fmovqcc %fcc1 */
3717                         CHECK_FPU_FEATURE(dc, FLOAT128);
3718                         FMOVCC(1, q);
3719                         break;
3720                     case 0x081: /* V9 fmovscc %fcc2 */
3721                         FMOVCC(2, s);
3722                         break;
3723                     case 0x082: /* V9 fmovdcc %fcc2 */
3724                         FMOVCC(2, d);
3725                         break;
3726                     case 0x083: /* V9 fmovqcc %fcc2 */
3727                         CHECK_FPU_FEATURE(dc, FLOAT128);
3728                         FMOVCC(2, q);
3729                         break;
3730                     case 0x0c1: /* V9 fmovscc %fcc3 */
3731                         FMOVCC(3, s);
3732                         break;
3733                     case 0x0c2: /* V9 fmovdcc %fcc3 */
3734                         FMOVCC(3, d);
3735                         break;
3736                     case 0x0c3: /* V9 fmovqcc %fcc3 */
3737                         CHECK_FPU_FEATURE(dc, FLOAT128);
3738                         FMOVCC(3, q);
3739                         break;
3740 #undef FMOVCC
3741 #define FMOVCC(xcc, sz)                                                 \
3742                     do {                                                \
3743                         DisasCompare cmp;                               \
3744                         cond = GET_FIELD_SP(insn, 14, 17);              \
3745                         gen_compare(&cmp, xcc, cond, dc);               \
3746                         gen_fmov##sz(dc, &cmp, rd, rs2);                \
3747                     } while (0)
3748 
3749                     case 0x101: /* V9 fmovscc %icc */
3750                         FMOVCC(0, s);
3751                         break;
3752                     case 0x102: /* V9 fmovdcc %icc */
3753                         FMOVCC(0, d);
3754                         break;
3755                     case 0x103: /* V9 fmovqcc %icc */
3756                         CHECK_FPU_FEATURE(dc, FLOAT128);
3757                         FMOVCC(0, q);
3758                         break;
3759                     case 0x181: /* V9 fmovscc %xcc */
3760                         FMOVCC(1, s);
3761                         break;
3762                     case 0x182: /* V9 fmovdcc %xcc */
3763                         FMOVCC(1, d);
3764                         break;
3765                     case 0x183: /* V9 fmovqcc %xcc */
3766                         CHECK_FPU_FEATURE(dc, FLOAT128);
3767                         FMOVCC(1, q);
3768                         break;
3769 #undef FMOVCC
3770 #endif
3771                     case 0x51: /* fcmps, V9 %fcc */
3772                         cpu_src1_32 = gen_load_fpr_F(dc, rs1);
3773                         cpu_src2_32 = gen_load_fpr_F(dc, rs2);
3774                         gen_op_fcmps(rd & 3, cpu_src1_32, cpu_src2_32);
3775                         break;
3776                     case 0x52: /* fcmpd, V9 %fcc */
3777                         cpu_src1_64 = gen_load_fpr_D(dc, rs1);
3778                         cpu_src2_64 = gen_load_fpr_D(dc, rs2);
3779                         gen_op_fcmpd(rd & 3, cpu_src1_64, cpu_src2_64);
3780                         break;
3781                     case 0x53: /* fcmpq, V9 %fcc */
3782                         CHECK_FPU_FEATURE(dc, FLOAT128);
3783                         gen_op_load_fpr_QT0(QFPREG(rs1));
3784                         gen_op_load_fpr_QT1(QFPREG(rs2));
3785                         gen_op_fcmpq(rd & 3);
3786                         break;
3787                     case 0x55: /* fcmpes, V9 %fcc */
3788                         cpu_src1_32 = gen_load_fpr_F(dc, rs1);
3789                         cpu_src2_32 = gen_load_fpr_F(dc, rs2);
3790                         gen_op_fcmpes(rd & 3, cpu_src1_32, cpu_src2_32);
3791                         break;
3792                     case 0x56: /* fcmped, V9 %fcc */
3793                         cpu_src1_64 = gen_load_fpr_D(dc, rs1);
3794                         cpu_src2_64 = gen_load_fpr_D(dc, rs2);
3795                         gen_op_fcmped(rd & 3, cpu_src1_64, cpu_src2_64);
3796                         break;
3797                     case 0x57: /* fcmpeq, V9 %fcc */
3798                         CHECK_FPU_FEATURE(dc, FLOAT128);
3799                         gen_op_load_fpr_QT0(QFPREG(rs1));
3800                         gen_op_load_fpr_QT1(QFPREG(rs2));
3801                         gen_op_fcmpeq(rd & 3);
3802                         break;
3803                     default:
3804                         goto illegal_insn;
3805                 }
3806             } else if (xop == 0x2) {
3807                 TCGv dst = gen_dest_gpr(dc, rd);
3808                 rs1 = GET_FIELD(insn, 13, 17);
3809                 if (rs1 == 0) {
3810                     /* clr/mov shortcut : or %g0, x, y -> mov x, y */
3811                     if (IS_IMM) {       /* immediate */
3812                         simm = GET_FIELDs(insn, 19, 31);
3813                         tcg_gen_movi_tl(dst, simm);
3814                         gen_store_gpr(dc, rd, dst);
3815                     } else {            /* register */
3816                         rs2 = GET_FIELD(insn, 27, 31);
3817                         if (rs2 == 0) {
3818                             tcg_gen_movi_tl(dst, 0);
3819                             gen_store_gpr(dc, rd, dst);
3820                         } else {
3821                             cpu_src2 = gen_load_gpr(dc, rs2);
3822                             gen_store_gpr(dc, rd, cpu_src2);
3823                         }
3824                     }
3825                 } else {
3826                     cpu_src1 = get_src1(dc, insn);
3827                     if (IS_IMM) {       /* immediate */
3828                         simm = GET_FIELDs(insn, 19, 31);
3829                         tcg_gen_ori_tl(dst, cpu_src1, simm);
3830                         gen_store_gpr(dc, rd, dst);
3831                     } else {            /* register */
3832                         rs2 = GET_FIELD(insn, 27, 31);
3833                         if (rs2 == 0) {
3834                             /* mov shortcut:  or x, %g0, y -> mov x, y */
3835                             gen_store_gpr(dc, rd, cpu_src1);
3836                         } else {
3837                             cpu_src2 = gen_load_gpr(dc, rs2);
3838                             tcg_gen_or_tl(dst, cpu_src1, cpu_src2);
3839                             gen_store_gpr(dc, rd, dst);
3840                         }
3841                     }
3842                 }
3843 #ifdef TARGET_SPARC64
3844             } else if (xop == 0x25) { /* sll, V9 sllx */
3845                 cpu_src1 = get_src1(dc, insn);
3846                 if (IS_IMM) {   /* immediate */
3847                     simm = GET_FIELDs(insn, 20, 31);
3848                     if (insn & (1 << 12)) {
3849                         tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
3850                     } else {
3851                         tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
3852                     }
3853                 } else {                /* register */
3854                     rs2 = GET_FIELD(insn, 27, 31);
3855                     cpu_src2 = gen_load_gpr(dc, rs2);
3856                     cpu_tmp0 = tcg_temp_new();
3857                     if (insn & (1 << 12)) {
3858                         tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
3859                     } else {
3860                         tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
3861                     }
3862                     tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
3863                 }
3864                 gen_store_gpr(dc, rd, cpu_dst);
3865             } else if (xop == 0x26) { /* srl, V9 srlx */
3866                 cpu_src1 = get_src1(dc, insn);
3867                 if (IS_IMM) {   /* immediate */
3868                     simm = GET_FIELDs(insn, 20, 31);
3869                     if (insn & (1 << 12)) {
3870                         tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
3871                     } else {
3872                         tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
3873                         tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
3874                     }
3875                 } else {                /* register */
3876                     rs2 = GET_FIELD(insn, 27, 31);
3877                     cpu_src2 = gen_load_gpr(dc, rs2);
3878                     cpu_tmp0 = tcg_temp_new();
3879                     if (insn & (1 << 12)) {
3880                         tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
3881                         tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
3882                     } else {
3883                         tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
3884                         tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
3885                         tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
3886                     }
3887                 }
3888                 gen_store_gpr(dc, rd, cpu_dst);
3889             } else if (xop == 0x27) { /* sra, V9 srax */
3890                 cpu_src1 = get_src1(dc, insn);
3891                 if (IS_IMM) {   /* immediate */
3892                     simm = GET_FIELDs(insn, 20, 31);
3893                     if (insn & (1 << 12)) {
3894                         tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
3895                     } else {
3896                         tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
3897                         tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
3898                     }
3899                 } else {                /* register */
3900                     rs2 = GET_FIELD(insn, 27, 31);
3901                     cpu_src2 = gen_load_gpr(dc, rs2);
3902                     cpu_tmp0 = tcg_temp_new();
3903                     if (insn & (1 << 12)) {
3904                         tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
3905                         tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
3906                     } else {
3907                         tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
3908                         tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
3909                         tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
3910                     }
3911                 }
3912                 gen_store_gpr(dc, rd, cpu_dst);
3913 #endif
3914             } else if (xop < 0x36) {
3915                 if (xop < 0x20) {
3916                     cpu_src1 = get_src1(dc, insn);
3917                     cpu_src2 = get_src2(dc, insn);
3918                     switch (xop & ~0x10) {
3919                     case 0x0: /* add */
3920                         if (xop & 0x10) {
3921                             gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
3922                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
3923                             dc->cc_op = CC_OP_ADD;
3924                         } else {
3925                             tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3926                         }
3927                         break;
3928                     case 0x1: /* and */
3929                         tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
3930                         if (xop & 0x10) {
3931                             tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3932                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3933                             dc->cc_op = CC_OP_LOGIC;
3934                         }
3935                         break;
3936                     case 0x2: /* or */
3937                         tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
3938                         if (xop & 0x10) {
3939                             tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3940                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3941                             dc->cc_op = CC_OP_LOGIC;
3942                         }
3943                         break;
3944                     case 0x3: /* xor */
3945                         tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3946                         if (xop & 0x10) {
3947                             tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3948                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3949                             dc->cc_op = CC_OP_LOGIC;
3950                         }
3951                         break;
3952                     case 0x4: /* sub */
3953                         if (xop & 0x10) {
3954                             gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
3955                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
3956                             dc->cc_op = CC_OP_SUB;
3957                         } else {
3958                             tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
3959                         }
3960                         break;
3961                     case 0x5: /* andn */
3962                         tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
3963                         if (xop & 0x10) {
3964                             tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3965                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3966                             dc->cc_op = CC_OP_LOGIC;
3967                         }
3968                         break;
3969                     case 0x6: /* orn */
3970                         tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
3971                         if (xop & 0x10) {
3972                             tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3973                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3974                             dc->cc_op = CC_OP_LOGIC;
3975                         }
3976                         break;
3977                     case 0x7: /* xorn */
3978                         tcg_gen_eqv_tl(cpu_dst, cpu_src1, cpu_src2);
3979                         if (xop & 0x10) {
3980                             tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3981                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3982                             dc->cc_op = CC_OP_LOGIC;
3983                         }
3984                         break;
3985                     case 0x8: /* addx, V9 addc */
3986                         gen_op_addx_int(dc, cpu_dst, cpu_src1, cpu_src2,
3987                                         (xop & 0x10));
3988                         break;
3989 #ifdef TARGET_SPARC64
3990                     case 0x9: /* V9 mulx */
3991                         tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
3992                         break;
3993 #endif
3994                     case 0xa: /* umul */
3995                         CHECK_IU_FEATURE(dc, MUL);
3996                         gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
3997                         if (xop & 0x10) {
3998                             tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3999                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4000                             dc->cc_op = CC_OP_LOGIC;
4001                         }
4002                         break;
4003                     case 0xb: /* smul */
4004                         CHECK_IU_FEATURE(dc, MUL);
4005                         gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
4006                         if (xop & 0x10) {
4007                             tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
4008                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
4009                             dc->cc_op = CC_OP_LOGIC;
4010                         }
4011                         break;
4012                     case 0xc: /* subx, V9 subc */
4013                         gen_op_subx_int(dc, cpu_dst, cpu_src1, cpu_src2,
4014                                         (xop & 0x10));
4015                         break;
4016 #ifdef TARGET_SPARC64
4017                     case 0xd: /* V9 udivx */
4018                         gen_helper_udivx(cpu_dst, cpu_env, cpu_src1, cpu_src2);
4019                         break;
4020 #endif
4021                     case 0xe: /* udiv */
4022                         CHECK_IU_FEATURE(dc, DIV);
4023                         if (xop & 0x10) {
4024                             gen_helper_udiv_cc(cpu_dst, cpu_env, cpu_src1,
4025                                                cpu_src2);
4026                             dc->cc_op = CC_OP_DIV;
4027                         } else {
4028                             gen_helper_udiv(cpu_dst, cpu_env, cpu_src1,
4029                                             cpu_src2);
4030                         }
4031                         break;
4032                     case 0xf: /* sdiv */
4033                         CHECK_IU_FEATURE(dc, DIV);
4034                         if (xop & 0x10) {
4035                             gen_helper_sdiv_cc(cpu_dst, cpu_env, cpu_src1,
4036                                                cpu_src2);
4037                             dc->cc_op = CC_OP_DIV;
4038                         } else {
4039                             gen_helper_sdiv(cpu_dst, cpu_env, cpu_src1,
4040                                             cpu_src2);
4041                         }
4042                         break;
4043                     default:
4044                         goto illegal_insn;
4045                     }
4046                     gen_store_gpr(dc, rd, cpu_dst);
4047                 } else {
4048                     cpu_src1 = get_src1(dc, insn);
4049                     cpu_src2 = get_src2(dc, insn);
4050                     switch (xop) {
4051                     case 0x20: /* taddcc */
4052                         gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
4053                         gen_store_gpr(dc, rd, cpu_dst);
4054                         tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
4055                         dc->cc_op = CC_OP_TADD;
4056                         break;
4057                     case 0x21: /* tsubcc */
4058                         gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
4059                         gen_store_gpr(dc, rd, cpu_dst);
4060                         tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
4061                         dc->cc_op = CC_OP_TSUB;
4062                         break;
4063                     case 0x22: /* taddcctv */
4064                         gen_helper_taddcctv(cpu_dst, cpu_env,
4065                                             cpu_src1, cpu_src2);
4066                         gen_store_gpr(dc, rd, cpu_dst);
4067                         dc->cc_op = CC_OP_TADDTV;
4068                         break;
4069                     case 0x23: /* tsubcctv */
4070                         gen_helper_tsubcctv(cpu_dst, cpu_env,
4071                                             cpu_src1, cpu_src2);
4072                         gen_store_gpr(dc, rd, cpu_dst);
4073                         dc->cc_op = CC_OP_TSUBTV;
4074                         break;
4075                     case 0x24: /* mulscc */
4076                         update_psr(dc);
4077                         gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
4078                         gen_store_gpr(dc, rd, cpu_dst);
4079                         tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
4080                         dc->cc_op = CC_OP_ADD;
4081                         break;
4082 #ifndef TARGET_SPARC64
4083                     case 0x25:  /* sll */
4084                         if (IS_IMM) { /* immediate */
4085                             simm = GET_FIELDs(insn, 20, 31);
4086                             tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
4087                         } else { /* register */
4088                             cpu_tmp0 = tcg_temp_new();
4089                             tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
4090                             tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
4091                         }
4092                         gen_store_gpr(dc, rd, cpu_dst);
4093                         break;
4094                     case 0x26:  /* srl */
4095                         if (IS_IMM) { /* immediate */
4096                             simm = GET_FIELDs(insn, 20, 31);
4097                             tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
4098                         } else { /* register */
4099                             cpu_tmp0 = tcg_temp_new();
4100                             tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
4101                             tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
4102                         }
4103                         gen_store_gpr(dc, rd, cpu_dst);
4104                         break;
4105                     case 0x27:  /* sra */
4106                         if (IS_IMM) { /* immediate */
4107                             simm = GET_FIELDs(insn, 20, 31);
4108                             tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
4109                         } else { /* register */
4110                             cpu_tmp0 = tcg_temp_new();
4111                             tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
4112                             tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
4113                         }
4114                         gen_store_gpr(dc, rd, cpu_dst);
4115                         break;
4116 #endif
4117                     case 0x30:
4118                         {
4119                             cpu_tmp0 = tcg_temp_new();
4120                             switch(rd) {
4121                             case 0: /* wry */
4122                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4123                                 tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
4124                                 break;
4125 #ifndef TARGET_SPARC64
4126                             case 0x01 ... 0x0f: /* undefined in the
4127                                                    SPARCv8 manual, nop
4128                                                    on the microSPARC
4129                                                    II */
4130                             case 0x10 ... 0x1f: /* implementation-dependent
4131                                                    in the SPARCv8
4132                                                    manual, nop on the
4133                                                    microSPARC II */
4134                                 if ((rd == 0x13) && (dc->def->features &
4135                                                      CPU_FEATURE_POWERDOWN)) {
4136                                     /* LEON3 power-down */
4137                                     save_state(dc);
4138                                     gen_helper_power_down(cpu_env);
4139                                 }
4140                                 break;
4141 #else
4142                             case 0x2: /* V9 wrccr */
4143                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4144                                 gen_helper_wrccr(cpu_env, cpu_tmp0);
4145                                 tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
4146                                 dc->cc_op = CC_OP_FLAGS;
4147                                 break;
4148                             case 0x3: /* V9 wrasi */
4149                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4150                                 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff);
4151                                 tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4152                                                 offsetof(CPUSPARCState, asi));
4153                                 /* End TB to notice changed ASI.  */
4154                                 save_state(dc);
4155                                 gen_op_next_insn();
4156                                 tcg_gen_exit_tb(NULL, 0);
4157                                 dc->base.is_jmp = DISAS_NORETURN;
4158                                 break;
4159                             case 0x6: /* V9 wrfprs */
4160                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4161                                 tcg_gen_trunc_tl_i32(cpu_fprs, cpu_tmp0);
4162                                 dc->fprs_dirty = 0;
4163                                 save_state(dc);
4164                                 gen_op_next_insn();
4165                                 tcg_gen_exit_tb(NULL, 0);
4166                                 dc->base.is_jmp = DISAS_NORETURN;
4167                                 break;
4168                             case 0xf: /* V9 sir, nop if user */
4169 #if !defined(CONFIG_USER_ONLY)
4170                                 if (supervisor(dc)) {
4171                                     ; // XXX
4172                                 }
4173 #endif
4174                                 break;
4175                             case 0x13: /* Graphics Status */
4176                                 if (gen_trap_ifnofpu(dc)) {
4177                                     goto jmp_insn;
4178                                 }
4179                                 tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
4180                                 break;
4181                             case 0x14: /* Softint set */
4182                                 if (!supervisor(dc))
4183                                     goto illegal_insn;
4184                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4185                                 gen_helper_set_softint(cpu_env, cpu_tmp0);
4186                                 break;
4187                             case 0x15: /* Softint clear */
4188                                 if (!supervisor(dc))
4189                                     goto illegal_insn;
4190                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4191                                 gen_helper_clear_softint(cpu_env, cpu_tmp0);
4192                                 break;
4193                             case 0x16: /* Softint write */
4194                                 if (!supervisor(dc))
4195                                     goto illegal_insn;
4196                                 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4197                                 gen_helper_write_softint(cpu_env, cpu_tmp0);
4198                                 break;
4199                             case 0x17: /* Tick compare */
4200 #if !defined(CONFIG_USER_ONLY)
4201                                 if (!supervisor(dc))
4202                                     goto illegal_insn;
4203 #endif
4204                                 {
4205                                     TCGv_ptr r_tickptr;
4206 
4207                                     tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
4208                                                    cpu_src2);
4209                                     r_tickptr = tcg_temp_new_ptr();
4210                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
4211                                                    offsetof(CPUSPARCState, tick));
4212                                     if (tb_cflags(dc->base.tb) &
4213                                            CF_USE_ICOUNT) {
4214                                         gen_io_start();
4215                                     }
4216                                     gen_helper_tick_set_limit(r_tickptr,
4217                                                               cpu_tick_cmpr);
4218                                     /* End TB to handle timer interrupt */
4219                                     dc->base.is_jmp = DISAS_EXIT;
4220                                 }
4221                                 break;
4222                             case 0x18: /* System tick */
4223 #if !defined(CONFIG_USER_ONLY)
4224                                 if (!supervisor(dc))
4225                                     goto illegal_insn;
4226 #endif
4227                                 {
4228                                     TCGv_ptr r_tickptr;
4229 
4230                                     tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
4231                                                    cpu_src2);
4232                                     r_tickptr = tcg_temp_new_ptr();
4233                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
4234                                                    offsetof(CPUSPARCState, stick));
4235                                     if (tb_cflags(dc->base.tb) &
4236                                            CF_USE_ICOUNT) {
4237                                         gen_io_start();
4238                                     }
4239                                     gen_helper_tick_set_count(r_tickptr,
4240                                                               cpu_tmp0);
4241                                     /* End TB to handle timer interrupt */
4242                                     dc->base.is_jmp = DISAS_EXIT;
4243                                 }
4244                                 break;
4245                             case 0x19: /* System tick compare */
4246 #if !defined(CONFIG_USER_ONLY)
4247                                 if (!supervisor(dc))
4248                                     goto illegal_insn;
4249 #endif
4250                                 {
4251                                     TCGv_ptr r_tickptr;
4252 
4253                                     tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
4254                                                    cpu_src2);
4255                                     r_tickptr = tcg_temp_new_ptr();
4256                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
4257                                                    offsetof(CPUSPARCState, stick));
4258                                     if (tb_cflags(dc->base.tb) &
4259                                            CF_USE_ICOUNT) {
4260                                         gen_io_start();
4261                                     }
4262                                     gen_helper_tick_set_limit(r_tickptr,
4263                                                               cpu_stick_cmpr);
4264                                     /* End TB to handle timer interrupt */
4265                                     dc->base.is_jmp = DISAS_EXIT;
4266                                 }
4267                                 break;
4268 
4269                             case 0x10: /* Performance Control */
4270                             case 0x11: /* Performance Instrumentation
4271                                           Counter */
4272                             case 0x12: /* Dispatch Control */
4273 #endif
4274                             default:
4275                                 goto illegal_insn;
4276                             }
4277                         }
4278                         break;
4279 #if !defined(CONFIG_USER_ONLY)
4280                     case 0x31: /* wrpsr, V9 saved, restored */
4281                         {
4282                             if (!supervisor(dc))
4283                                 goto priv_insn;
4284 #ifdef TARGET_SPARC64
4285                             switch (rd) {
4286                             case 0:
4287                                 gen_helper_saved(cpu_env);
4288                                 break;
4289                             case 1:
4290                                 gen_helper_restored(cpu_env);
4291                                 break;
4292                             case 2: /* UA2005 allclean */
4293                             case 3: /* UA2005 otherw */
4294                             case 4: /* UA2005 normalw */
4295                             case 5: /* UA2005 invalw */
4296                                 // XXX
4297                             default:
4298                                 goto illegal_insn;
4299                             }
4300 #else
4301                             cpu_tmp0 = tcg_temp_new();
4302                             tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4303                             gen_helper_wrpsr(cpu_env, cpu_tmp0);
4304                             tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
4305                             dc->cc_op = CC_OP_FLAGS;
4306                             save_state(dc);
4307                             gen_op_next_insn();
4308                             tcg_gen_exit_tb(NULL, 0);
4309                             dc->base.is_jmp = DISAS_NORETURN;
4310 #endif
4311                         }
4312                         break;
4313                     case 0x32: /* wrwim, V9 wrpr */
4314                         {
4315                             if (!supervisor(dc))
4316                                 goto priv_insn;
4317                             cpu_tmp0 = tcg_temp_new();
4318                             tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4319 #ifdef TARGET_SPARC64
4320                             switch (rd) {
4321                             case 0: // tpc
4322                                 {
4323                                     TCGv_ptr r_tsptr;
4324 
4325                                     r_tsptr = tcg_temp_new_ptr();
4326                                     gen_load_trap_state_at_tl(r_tsptr, cpu_env);
4327                                     tcg_gen_st_tl(cpu_tmp0, r_tsptr,
4328                                                   offsetof(trap_state, tpc));
4329                                 }
4330                                 break;
4331                             case 1: // tnpc
4332                                 {
4333                                     TCGv_ptr r_tsptr;
4334 
4335                                     r_tsptr = tcg_temp_new_ptr();
4336                                     gen_load_trap_state_at_tl(r_tsptr, cpu_env);
4337                                     tcg_gen_st_tl(cpu_tmp0, r_tsptr,
4338                                                   offsetof(trap_state, tnpc));
4339                                 }
4340                                 break;
4341                             case 2: // tstate
4342                                 {
4343                                     TCGv_ptr r_tsptr;
4344 
4345                                     r_tsptr = tcg_temp_new_ptr();
4346                                     gen_load_trap_state_at_tl(r_tsptr, cpu_env);
4347                                     tcg_gen_st_tl(cpu_tmp0, r_tsptr,
4348                                                   offsetof(trap_state,
4349                                                            tstate));
4350                                 }
4351                                 break;
4352                             case 3: // tt
4353                                 {
4354                                     TCGv_ptr r_tsptr;
4355 
4356                                     r_tsptr = tcg_temp_new_ptr();
4357                                     gen_load_trap_state_at_tl(r_tsptr, cpu_env);
4358                                     tcg_gen_st32_tl(cpu_tmp0, r_tsptr,
4359                                                     offsetof(trap_state, tt));
4360                                 }
4361                                 break;
4362                             case 4: // tick
4363                                 {
4364                                     TCGv_ptr r_tickptr;
4365 
4366                                     r_tickptr = tcg_temp_new_ptr();
4367                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
4368                                                    offsetof(CPUSPARCState, tick));
4369                                     if (tb_cflags(dc->base.tb) &
4370                                            CF_USE_ICOUNT) {
4371                                         gen_io_start();
4372                                     }
4373                                     gen_helper_tick_set_count(r_tickptr,
4374                                                               cpu_tmp0);
4375                                     /* End TB to handle timer interrupt */
4376                                     dc->base.is_jmp = DISAS_EXIT;
4377                                 }
4378                                 break;
4379                             case 5: // tba
4380                                 tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
4381                                 break;
4382                             case 6: // pstate
4383                                 save_state(dc);
4384                                 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
4385                                     gen_io_start();
4386                                 }
4387                                 gen_helper_wrpstate(cpu_env, cpu_tmp0);
4388                                 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
4389                                     /* I/O ops in icount mode must end the TB */
4390                                     dc->base.is_jmp = DISAS_EXIT;
4391                                 }
4392                                 dc->npc = DYNAMIC_PC;
4393                                 break;
4394                             case 7: // tl
4395                                 save_state(dc);
4396                                 tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4397                                                offsetof(CPUSPARCState, tl));
4398                                 dc->npc = DYNAMIC_PC;
4399                                 break;
4400                             case 8: // pil
4401                                 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
4402                                     gen_io_start();
4403                                 }
4404                                 gen_helper_wrpil(cpu_env, cpu_tmp0);
4405                                 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
4406                                     /* I/O ops in icount mode must end the TB */
4407                                     dc->base.is_jmp = DISAS_EXIT;
4408                                 }
4409                                 break;
4410                             case 9: // cwp
4411                                 gen_helper_wrcwp(cpu_env, cpu_tmp0);
4412                                 break;
4413                             case 10: // cansave
4414                                 tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4415                                                 offsetof(CPUSPARCState,
4416                                                          cansave));
4417                                 break;
4418                             case 11: // canrestore
4419                                 tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4420                                                 offsetof(CPUSPARCState,
4421                                                          canrestore));
4422                                 break;
4423                             case 12: // cleanwin
4424                                 tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4425                                                 offsetof(CPUSPARCState,
4426                                                          cleanwin));
4427                                 break;
4428                             case 13: // otherwin
4429                                 tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4430                                                 offsetof(CPUSPARCState,
4431                                                          otherwin));
4432                                 break;
4433                             case 14: // wstate
4434                                 tcg_gen_st32_tl(cpu_tmp0, cpu_env,
4435                                                 offsetof(CPUSPARCState,
4436                                                          wstate));
4437                                 break;
4438                             case 16: // UA2005 gl
4439                                 CHECK_IU_FEATURE(dc, GL);
4440                                 gen_helper_wrgl(cpu_env, cpu_tmp0);
4441                                 break;
4442                             case 26: // UA2005 strand status
4443                                 CHECK_IU_FEATURE(dc, HYPV);
4444                                 if (!hypervisor(dc))
4445                                     goto priv_insn;
4446                                 tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
4447                                 break;
4448                             default:
4449                                 goto illegal_insn;
4450                             }
4451 #else
4452                             tcg_gen_trunc_tl_i32(cpu_wim, cpu_tmp0);
4453                             if (dc->def->nwindows != 32) {
4454                                 tcg_gen_andi_tl(cpu_wim, cpu_wim,
4455                                                 (1 << dc->def->nwindows) - 1);
4456                             }
4457 #endif
4458                         }
4459                         break;
4460                     case 0x33: /* wrtbr, UA2005 wrhpr */
4461                         {
4462 #ifndef TARGET_SPARC64
4463                             if (!supervisor(dc))
4464                                 goto priv_insn;
4465                             tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
4466 #else
4467                             CHECK_IU_FEATURE(dc, HYPV);
4468                             if (!hypervisor(dc))
4469                                 goto priv_insn;
4470                             cpu_tmp0 = tcg_temp_new();
4471                             tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
4472                             switch (rd) {
4473                             case 0: // hpstate
4474                                 tcg_gen_st_i64(cpu_tmp0, cpu_env,
4475                                                offsetof(CPUSPARCState,
4476                                                         hpstate));
4477                                 save_state(dc);
4478                                 gen_op_next_insn();
4479                                 tcg_gen_exit_tb(NULL, 0);
4480                                 dc->base.is_jmp = DISAS_NORETURN;
4481                                 break;
4482                             case 1: // htstate
4483                                 // XXX gen_op_wrhtstate();
4484                                 break;
4485                             case 3: // hintp
4486                                 tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
4487                                 break;
4488                             case 5: // htba
4489                                 tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
4490                                 break;
4491                             case 31: // hstick_cmpr
4492                                 {
4493                                     TCGv_ptr r_tickptr;
4494 
4495                                     tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
4496                                     r_tickptr = tcg_temp_new_ptr();
4497                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
4498                                                    offsetof(CPUSPARCState, hstick));
4499                                     if (tb_cflags(dc->base.tb) &
4500                                            CF_USE_ICOUNT) {
4501                                         gen_io_start();
4502                                     }
4503                                     gen_helper_tick_set_limit(r_tickptr,
4504                                                               cpu_hstick_cmpr);
4505                                     /* End TB to handle timer interrupt */
4506                                     dc->base.is_jmp = DISAS_EXIT;
4507                                 }
4508                                 break;
4509                             case 6: // hver readonly
4510                             default:
4511                                 goto illegal_insn;
4512                             }
4513 #endif
4514                         }
4515                         break;
4516 #endif
4517 #ifdef TARGET_SPARC64
4518                     case 0x2c: /* V9 movcc */
4519                         {
4520                             int cc = GET_FIELD_SP(insn, 11, 12);
4521                             int cond = GET_FIELD_SP(insn, 14, 17);
4522                             DisasCompare cmp;
4523                             TCGv dst;
4524 
4525                             if (insn & (1 << 18)) {
4526                                 if (cc == 0) {
4527                                     gen_compare(&cmp, 0, cond, dc);
4528                                 } else if (cc == 2) {
4529                                     gen_compare(&cmp, 1, cond, dc);
4530                                 } else {
4531                                     goto illegal_insn;
4532                                 }
4533                             } else {
4534                                 gen_fcompare(&cmp, cc, cond);
4535                             }
4536 
4537                             /* The get_src2 above loaded the normal 13-bit
4538                                immediate field, not the 11-bit field we have
4539                                in movcc.  But it did handle the reg case.  */
4540                             if (IS_IMM) {
4541                                 simm = GET_FIELD_SPs(insn, 0, 10);
4542                                 tcg_gen_movi_tl(cpu_src2, simm);
4543                             }
4544 
4545                             dst = gen_load_gpr(dc, rd);
4546                             tcg_gen_movcond_tl(cmp.cond, dst,
4547                                                cmp.c1, cmp.c2,
4548                                                cpu_src2, dst);
4549                             gen_store_gpr(dc, rd, dst);
4550                             break;
4551                         }
4552                     case 0x2d: /* V9 sdivx */
4553                         gen_helper_sdivx(cpu_dst, cpu_env, cpu_src1, cpu_src2);
4554                         gen_store_gpr(dc, rd, cpu_dst);
4555                         break;
4556                     case 0x2e: /* V9 popc */
4557                         tcg_gen_ctpop_tl(cpu_dst, cpu_src2);
4558                         gen_store_gpr(dc, rd, cpu_dst);
4559                         break;
4560                     case 0x2f: /* V9 movr */
4561                         {
4562                             int cond = GET_FIELD_SP(insn, 10, 12);
4563                             DisasCompare cmp;
4564                             TCGv dst;
4565 
4566                             gen_compare_reg(&cmp, cond, cpu_src1);
4567 
4568                             /* The get_src2 above loaded the normal 13-bit
4569                                immediate field, not the 10-bit field we have
4570                                in movr.  But it did handle the reg case.  */
4571                             if (IS_IMM) {
4572                                 simm = GET_FIELD_SPs(insn, 0, 9);
4573                                 tcg_gen_movi_tl(cpu_src2, simm);
4574                             }
4575 
4576                             dst = gen_load_gpr(dc, rd);
4577                             tcg_gen_movcond_tl(cmp.cond, dst,
4578                                                cmp.c1, cmp.c2,
4579                                                cpu_src2, dst);
4580                             gen_store_gpr(dc, rd, dst);
4581                             break;
4582                         }
4583 #endif
4584                     default:
4585                         goto illegal_insn;
4586                     }
4587                 }
4588             } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
4589 #ifdef TARGET_SPARC64
4590                 int opf = GET_FIELD_SP(insn, 5, 13);
4591                 rs1 = GET_FIELD(insn, 13, 17);
4592                 rs2 = GET_FIELD(insn, 27, 31);
4593                 if (gen_trap_ifnofpu(dc)) {
4594                     goto jmp_insn;
4595                 }
4596 
4597                 switch (opf) {
4598                 case 0x000: /* VIS I edge8cc */
4599                     CHECK_FPU_FEATURE(dc, VIS1);
4600                     cpu_src1 = gen_load_gpr(dc, rs1);
4601                     cpu_src2 = gen_load_gpr(dc, rs2);
4602                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 0);
4603                     gen_store_gpr(dc, rd, cpu_dst);
4604                     break;
4605                 case 0x001: /* VIS II edge8n */
4606                     CHECK_FPU_FEATURE(dc, VIS2);
4607                     cpu_src1 = gen_load_gpr(dc, rs1);
4608                     cpu_src2 = gen_load_gpr(dc, rs2);
4609                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 0);
4610                     gen_store_gpr(dc, rd, cpu_dst);
4611                     break;
4612                 case 0x002: /* VIS I edge8lcc */
4613                     CHECK_FPU_FEATURE(dc, VIS1);
4614                     cpu_src1 = gen_load_gpr(dc, rs1);
4615                     cpu_src2 = gen_load_gpr(dc, rs2);
4616                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 1);
4617                     gen_store_gpr(dc, rd, cpu_dst);
4618                     break;
4619                 case 0x003: /* VIS II edge8ln */
4620                     CHECK_FPU_FEATURE(dc, VIS2);
4621                     cpu_src1 = gen_load_gpr(dc, rs1);
4622                     cpu_src2 = gen_load_gpr(dc, rs2);
4623                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 1);
4624                     gen_store_gpr(dc, rd, cpu_dst);
4625                     break;
4626                 case 0x004: /* VIS I edge16cc */
4627                     CHECK_FPU_FEATURE(dc, VIS1);
4628                     cpu_src1 = gen_load_gpr(dc, rs1);
4629                     cpu_src2 = gen_load_gpr(dc, rs2);
4630                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 0);
4631                     gen_store_gpr(dc, rd, cpu_dst);
4632                     break;
4633                 case 0x005: /* VIS II edge16n */
4634                     CHECK_FPU_FEATURE(dc, VIS2);
4635                     cpu_src1 = gen_load_gpr(dc, rs1);
4636                     cpu_src2 = gen_load_gpr(dc, rs2);
4637                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 0);
4638                     gen_store_gpr(dc, rd, cpu_dst);
4639                     break;
4640                 case 0x006: /* VIS I edge16lcc */
4641                     CHECK_FPU_FEATURE(dc, VIS1);
4642                     cpu_src1 = gen_load_gpr(dc, rs1);
4643                     cpu_src2 = gen_load_gpr(dc, rs2);
4644                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 1);
4645                     gen_store_gpr(dc, rd, cpu_dst);
4646                     break;
4647                 case 0x007: /* VIS II edge16ln */
4648                     CHECK_FPU_FEATURE(dc, VIS2);
4649                     cpu_src1 = gen_load_gpr(dc, rs1);
4650                     cpu_src2 = gen_load_gpr(dc, rs2);
4651                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 1);
4652                     gen_store_gpr(dc, rd, cpu_dst);
4653                     break;
4654                 case 0x008: /* VIS I edge32cc */
4655                     CHECK_FPU_FEATURE(dc, VIS1);
4656                     cpu_src1 = gen_load_gpr(dc, rs1);
4657                     cpu_src2 = gen_load_gpr(dc, rs2);
4658                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 0);
4659                     gen_store_gpr(dc, rd, cpu_dst);
4660                     break;
4661                 case 0x009: /* VIS II edge32n */
4662                     CHECK_FPU_FEATURE(dc, VIS2);
4663                     cpu_src1 = gen_load_gpr(dc, rs1);
4664                     cpu_src2 = gen_load_gpr(dc, rs2);
4665                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 0);
4666                     gen_store_gpr(dc, rd, cpu_dst);
4667                     break;
4668                 case 0x00a: /* VIS I edge32lcc */
4669                     CHECK_FPU_FEATURE(dc, VIS1);
4670                     cpu_src1 = gen_load_gpr(dc, rs1);
4671                     cpu_src2 = gen_load_gpr(dc, rs2);
4672                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 1);
4673                     gen_store_gpr(dc, rd, cpu_dst);
4674                     break;
4675                 case 0x00b: /* VIS II edge32ln */
4676                     CHECK_FPU_FEATURE(dc, VIS2);
4677                     cpu_src1 = gen_load_gpr(dc, rs1);
4678                     cpu_src2 = gen_load_gpr(dc, rs2);
4679                     gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 1);
4680                     gen_store_gpr(dc, rd, cpu_dst);
4681                     break;
4682                 case 0x010: /* VIS I array8 */
4683                     CHECK_FPU_FEATURE(dc, VIS1);
4684                     cpu_src1 = gen_load_gpr(dc, rs1);
4685                     cpu_src2 = gen_load_gpr(dc, rs2);
4686                     gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
4687                     gen_store_gpr(dc, rd, cpu_dst);
4688                     break;
4689                 case 0x012: /* VIS I array16 */
4690                     CHECK_FPU_FEATURE(dc, VIS1);
4691                     cpu_src1 = gen_load_gpr(dc, rs1);
4692                     cpu_src2 = gen_load_gpr(dc, rs2);
4693                     gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
4694                     tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
4695                     gen_store_gpr(dc, rd, cpu_dst);
4696                     break;
4697                 case 0x014: /* VIS I array32 */
4698                     CHECK_FPU_FEATURE(dc, VIS1);
4699                     cpu_src1 = gen_load_gpr(dc, rs1);
4700                     cpu_src2 = gen_load_gpr(dc, rs2);
4701                     gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
4702                     tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
4703                     gen_store_gpr(dc, rd, cpu_dst);
4704                     break;
4705                 case 0x018: /* VIS I alignaddr */
4706                     CHECK_FPU_FEATURE(dc, VIS1);
4707                     cpu_src1 = gen_load_gpr(dc, rs1);
4708                     cpu_src2 = gen_load_gpr(dc, rs2);
4709                     gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 0);
4710                     gen_store_gpr(dc, rd, cpu_dst);
4711                     break;
4712                 case 0x01a: /* VIS I alignaddrl */
4713                     CHECK_FPU_FEATURE(dc, VIS1);
4714                     cpu_src1 = gen_load_gpr(dc, rs1);
4715                     cpu_src2 = gen_load_gpr(dc, rs2);
4716                     gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 1);
4717                     gen_store_gpr(dc, rd, cpu_dst);
4718                     break;
4719                 case 0x019: /* VIS II bmask */
4720                     CHECK_FPU_FEATURE(dc, VIS2);
4721                     cpu_src1 = gen_load_gpr(dc, rs1);
4722                     cpu_src2 = gen_load_gpr(dc, rs2);
4723                     tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4724                     tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, cpu_dst, 32, 32);
4725                     gen_store_gpr(dc, rd, cpu_dst);
4726                     break;
4727                 case 0x020: /* VIS I fcmple16 */
4728                     CHECK_FPU_FEATURE(dc, VIS1);
4729                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4730                     cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4731                     gen_helper_fcmple16(cpu_dst, cpu_src1_64, cpu_src2_64);
4732                     gen_store_gpr(dc, rd, cpu_dst);
4733                     break;
4734                 case 0x022: /* VIS I fcmpne16 */
4735                     CHECK_FPU_FEATURE(dc, VIS1);
4736                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4737                     cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4738                     gen_helper_fcmpne16(cpu_dst, cpu_src1_64, cpu_src2_64);
4739                     gen_store_gpr(dc, rd, cpu_dst);
4740                     break;
4741                 case 0x024: /* VIS I fcmple32 */
4742                     CHECK_FPU_FEATURE(dc, VIS1);
4743                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4744                     cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4745                     gen_helper_fcmple32(cpu_dst, cpu_src1_64, cpu_src2_64);
4746                     gen_store_gpr(dc, rd, cpu_dst);
4747                     break;
4748                 case 0x026: /* VIS I fcmpne32 */
4749                     CHECK_FPU_FEATURE(dc, VIS1);
4750                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4751                     cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4752                     gen_helper_fcmpne32(cpu_dst, cpu_src1_64, cpu_src2_64);
4753                     gen_store_gpr(dc, rd, cpu_dst);
4754                     break;
4755                 case 0x028: /* VIS I fcmpgt16 */
4756                     CHECK_FPU_FEATURE(dc, VIS1);
4757                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4758                     cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4759                     gen_helper_fcmpgt16(cpu_dst, cpu_src1_64, cpu_src2_64);
4760                     gen_store_gpr(dc, rd, cpu_dst);
4761                     break;
4762                 case 0x02a: /* VIS I fcmpeq16 */
4763                     CHECK_FPU_FEATURE(dc, VIS1);
4764                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4765                     cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4766                     gen_helper_fcmpeq16(cpu_dst, cpu_src1_64, cpu_src2_64);
4767                     gen_store_gpr(dc, rd, cpu_dst);
4768                     break;
4769                 case 0x02c: /* VIS I fcmpgt32 */
4770                     CHECK_FPU_FEATURE(dc, VIS1);
4771                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4772                     cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4773                     gen_helper_fcmpgt32(cpu_dst, cpu_src1_64, cpu_src2_64);
4774                     gen_store_gpr(dc, rd, cpu_dst);
4775                     break;
4776                 case 0x02e: /* VIS I fcmpeq32 */
4777                     CHECK_FPU_FEATURE(dc, VIS1);
4778                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4779                     cpu_src2_64 = gen_load_fpr_D(dc, rs2);
4780                     gen_helper_fcmpeq32(cpu_dst, cpu_src1_64, cpu_src2_64);
4781                     gen_store_gpr(dc, rd, cpu_dst);
4782                     break;
4783                 case 0x031: /* VIS I fmul8x16 */
4784                     CHECK_FPU_FEATURE(dc, VIS1);
4785                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16);
4786                     break;
4787                 case 0x033: /* VIS I fmul8x16au */
4788                     CHECK_FPU_FEATURE(dc, VIS1);
4789                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16au);
4790                     break;
4791                 case 0x035: /* VIS I fmul8x16al */
4792                     CHECK_FPU_FEATURE(dc, VIS1);
4793                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16al);
4794                     break;
4795                 case 0x036: /* VIS I fmul8sux16 */
4796                     CHECK_FPU_FEATURE(dc, VIS1);
4797                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8sux16);
4798                     break;
4799                 case 0x037: /* VIS I fmul8ulx16 */
4800                     CHECK_FPU_FEATURE(dc, VIS1);
4801                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8ulx16);
4802                     break;
4803                 case 0x038: /* VIS I fmuld8sux16 */
4804                     CHECK_FPU_FEATURE(dc, VIS1);
4805                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8sux16);
4806                     break;
4807                 case 0x039: /* VIS I fmuld8ulx16 */
4808                     CHECK_FPU_FEATURE(dc, VIS1);
4809                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8ulx16);
4810                     break;
4811                 case 0x03a: /* VIS I fpack32 */
4812                     CHECK_FPU_FEATURE(dc, VIS1);
4813                     gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpack32);
4814                     break;
4815                 case 0x03b: /* VIS I fpack16 */
4816                     CHECK_FPU_FEATURE(dc, VIS1);
4817                     cpu_src1_64 = gen_load_fpr_D(dc, rs2);
4818                     cpu_dst_32 = gen_dest_fpr_F(dc);
4819                     gen_helper_fpack16(cpu_dst_32, cpu_gsr, cpu_src1_64);
4820                     gen_store_fpr_F(dc, rd, cpu_dst_32);
4821                     break;
4822                 case 0x03d: /* VIS I fpackfix */
4823                     CHECK_FPU_FEATURE(dc, VIS1);
4824                     cpu_src1_64 = gen_load_fpr_D(dc, rs2);
4825                     cpu_dst_32 = gen_dest_fpr_F(dc);
4826                     gen_helper_fpackfix(cpu_dst_32, cpu_gsr, cpu_src1_64);
4827                     gen_store_fpr_F(dc, rd, cpu_dst_32);
4828                     break;
4829                 case 0x03e: /* VIS I pdist */
4830                     CHECK_FPU_FEATURE(dc, VIS1);
4831                     gen_ne_fop_DDDD(dc, rd, rs1, rs2, gen_helper_pdist);
4832                     break;
4833                 case 0x048: /* VIS I faligndata */
4834                     CHECK_FPU_FEATURE(dc, VIS1);
4835                     gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_faligndata);
4836                     break;
4837                 case 0x04b: /* VIS I fpmerge */
4838                     CHECK_FPU_FEATURE(dc, VIS1);
4839                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpmerge);
4840                     break;
4841                 case 0x04c: /* VIS II bshuffle */
4842                     CHECK_FPU_FEATURE(dc, VIS2);
4843                     gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_bshuffle);
4844                     break;
4845                 case 0x04d: /* VIS I fexpand */
4846                     CHECK_FPU_FEATURE(dc, VIS1);
4847                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fexpand);
4848                     break;
4849                 case 0x050: /* VIS I fpadd16 */
4850                     CHECK_FPU_FEATURE(dc, VIS1);
4851                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd16);
4852                     break;
4853                 case 0x051: /* VIS I fpadd16s */
4854                     CHECK_FPU_FEATURE(dc, VIS1);
4855                     gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpadd16s);
4856                     break;
4857                 case 0x052: /* VIS I fpadd32 */
4858                     CHECK_FPU_FEATURE(dc, VIS1);
4859                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd32);
4860                     break;
4861                 case 0x053: /* VIS I fpadd32s */
4862                     CHECK_FPU_FEATURE(dc, VIS1);
4863                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_add_i32);
4864                     break;
4865                 case 0x054: /* VIS I fpsub16 */
4866                     CHECK_FPU_FEATURE(dc, VIS1);
4867                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub16);
4868                     break;
4869                 case 0x055: /* VIS I fpsub16s */
4870                     CHECK_FPU_FEATURE(dc, VIS1);
4871                     gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpsub16s);
4872                     break;
4873                 case 0x056: /* VIS I fpsub32 */
4874                     CHECK_FPU_FEATURE(dc, VIS1);
4875                     gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub32);
4876                     break;
4877                 case 0x057: /* VIS I fpsub32s */
4878                     CHECK_FPU_FEATURE(dc, VIS1);
4879                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_sub_i32);
4880                     break;
4881                 case 0x060: /* VIS I fzero */
4882                     CHECK_FPU_FEATURE(dc, VIS1);
4883                     cpu_dst_64 = gen_dest_fpr_D(dc, rd);
4884                     tcg_gen_movi_i64(cpu_dst_64, 0);
4885                     gen_store_fpr_D(dc, rd, cpu_dst_64);
4886                     break;
4887                 case 0x061: /* VIS I fzeros */
4888                     CHECK_FPU_FEATURE(dc, VIS1);
4889                     cpu_dst_32 = gen_dest_fpr_F(dc);
4890                     tcg_gen_movi_i32(cpu_dst_32, 0);
4891                     gen_store_fpr_F(dc, rd, cpu_dst_32);
4892                     break;
4893                 case 0x062: /* VIS I fnor */
4894                     CHECK_FPU_FEATURE(dc, VIS1);
4895                     gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nor_i64);
4896                     break;
4897                 case 0x063: /* VIS I fnors */
4898                     CHECK_FPU_FEATURE(dc, VIS1);
4899                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nor_i32);
4900                     break;
4901                 case 0x064: /* VIS I fandnot2 */
4902                     CHECK_FPU_FEATURE(dc, VIS1);
4903                     gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_andc_i64);
4904                     break;
4905                 case 0x065: /* VIS I fandnot2s */
4906                     CHECK_FPU_FEATURE(dc, VIS1);
4907                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_andc_i32);
4908                     break;
4909                 case 0x066: /* VIS I fnot2 */
4910                     CHECK_FPU_FEATURE(dc, VIS1);
4911                     gen_ne_fop_DD(dc, rd, rs2, tcg_gen_not_i64);
4912                     break;
4913                 case 0x067: /* VIS I fnot2s */
4914                     CHECK_FPU_FEATURE(dc, VIS1);
4915                     gen_ne_fop_FF(dc, rd, rs2, tcg_gen_not_i32);
4916                     break;
4917                 case 0x068: /* VIS I fandnot1 */
4918                     CHECK_FPU_FEATURE(dc, VIS1);
4919                     gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_andc_i64);
4920                     break;
4921                 case 0x069: /* VIS I fandnot1s */
4922                     CHECK_FPU_FEATURE(dc, VIS1);
4923                     gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_andc_i32);
4924                     break;
4925                 case 0x06a: /* VIS I fnot1 */
4926                     CHECK_FPU_FEATURE(dc, VIS1);
4927                     gen_ne_fop_DD(dc, rd, rs1, tcg_gen_not_i64);
4928                     break;
4929                 case 0x06b: /* VIS I fnot1s */
4930                     CHECK_FPU_FEATURE(dc, VIS1);
4931                     gen_ne_fop_FF(dc, rd, rs1, tcg_gen_not_i32);
4932                     break;
4933                 case 0x06c: /* VIS I fxor */
4934                     CHECK_FPU_FEATURE(dc, VIS1);
4935                     gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_xor_i64);
4936                     break;
4937                 case 0x06d: /* VIS I fxors */
4938                     CHECK_FPU_FEATURE(dc, VIS1);
4939                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_xor_i32);
4940                     break;
4941                 case 0x06e: /* VIS I fnand */
4942                     CHECK_FPU_FEATURE(dc, VIS1);
4943                     gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nand_i64);
4944                     break;
4945                 case 0x06f: /* VIS I fnands */
4946                     CHECK_FPU_FEATURE(dc, VIS1);
4947                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nand_i32);
4948                     break;
4949                 case 0x070: /* VIS I fand */
4950                     CHECK_FPU_FEATURE(dc, VIS1);
4951                     gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_and_i64);
4952                     break;
4953                 case 0x071: /* VIS I fands */
4954                     CHECK_FPU_FEATURE(dc, VIS1);
4955                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_and_i32);
4956                     break;
4957                 case 0x072: /* VIS I fxnor */
4958                     CHECK_FPU_FEATURE(dc, VIS1);
4959                     gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_eqv_i64);
4960                     break;
4961                 case 0x073: /* VIS I fxnors */
4962                     CHECK_FPU_FEATURE(dc, VIS1);
4963                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_eqv_i32);
4964                     break;
4965                 case 0x074: /* VIS I fsrc1 */
4966                     CHECK_FPU_FEATURE(dc, VIS1);
4967                     cpu_src1_64 = gen_load_fpr_D(dc, rs1);
4968                     gen_store_fpr_D(dc, rd, cpu_src1_64);
4969                     break;
4970                 case 0x075: /* VIS I fsrc1s */
4971                     CHECK_FPU_FEATURE(dc, VIS1);
4972                     cpu_src1_32 = gen_load_fpr_F(dc, rs1);
4973                     gen_store_fpr_F(dc, rd, cpu_src1_32);
4974                     break;
4975                 case 0x076: /* VIS I fornot2 */
4976                     CHECK_FPU_FEATURE(dc, VIS1);
4977                     gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_orc_i64);
4978                     break;
4979                 case 0x077: /* VIS I fornot2s */
4980                     CHECK_FPU_FEATURE(dc, VIS1);
4981                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_orc_i32);
4982                     break;
4983                 case 0x078: /* VIS I fsrc2 */
4984                     CHECK_FPU_FEATURE(dc, VIS1);
4985                     cpu_src1_64 = gen_load_fpr_D(dc, rs2);
4986                     gen_store_fpr_D(dc, rd, cpu_src1_64);
4987                     break;
4988                 case 0x079: /* VIS I fsrc2s */
4989                     CHECK_FPU_FEATURE(dc, VIS1);
4990                     cpu_src1_32 = gen_load_fpr_F(dc, rs2);
4991                     gen_store_fpr_F(dc, rd, cpu_src1_32);
4992                     break;
4993                 case 0x07a: /* VIS I fornot1 */
4994                     CHECK_FPU_FEATURE(dc, VIS1);
4995                     gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_orc_i64);
4996                     break;
4997                 case 0x07b: /* VIS I fornot1s */
4998                     CHECK_FPU_FEATURE(dc, VIS1);
4999                     gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_orc_i32);
5000                     break;
5001                 case 0x07c: /* VIS I for */
5002                     CHECK_FPU_FEATURE(dc, VIS1);
5003                     gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_or_i64);
5004                     break;
5005                 case 0x07d: /* VIS I fors */
5006                     CHECK_FPU_FEATURE(dc, VIS1);
5007                     gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_or_i32);
5008                     break;
5009                 case 0x07e: /* VIS I fone */
5010                     CHECK_FPU_FEATURE(dc, VIS1);
5011                     cpu_dst_64 = gen_dest_fpr_D(dc, rd);
5012                     tcg_gen_movi_i64(cpu_dst_64, -1);
5013                     gen_store_fpr_D(dc, rd, cpu_dst_64);
5014                     break;
5015                 case 0x07f: /* VIS I fones */
5016                     CHECK_FPU_FEATURE(dc, VIS1);
5017                     cpu_dst_32 = gen_dest_fpr_F(dc);
5018                     tcg_gen_movi_i32(cpu_dst_32, -1);
5019                     gen_store_fpr_F(dc, rd, cpu_dst_32);
5020                     break;
5021                 case 0x080: /* VIS I shutdown */
5022                 case 0x081: /* VIS II siam */
5023                     // XXX
5024                     goto illegal_insn;
5025                 default:
5026                     goto illegal_insn;
5027                 }
5028 #else
5029                 goto ncp_insn;
5030 #endif
5031             } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
5032 #ifdef TARGET_SPARC64
5033                 goto illegal_insn;
5034 #else
5035                 goto ncp_insn;
5036 #endif
5037 #ifdef TARGET_SPARC64
5038             } else if (xop == 0x39) { /* V9 return */
5039                 save_state(dc);
5040                 cpu_src1 = get_src1(dc, insn);
5041                 cpu_tmp0 = tcg_temp_new();
5042                 if (IS_IMM) {   /* immediate */
5043                     simm = GET_FIELDs(insn, 19, 31);
5044                     tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
5045                 } else {                /* register */
5046                     rs2 = GET_FIELD(insn, 27, 31);
5047                     if (rs2) {
5048                         cpu_src2 = gen_load_gpr(dc, rs2);
5049                         tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
5050                     } else {
5051                         tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
5052                     }
5053                 }
5054                 gen_helper_restore(cpu_env);
5055                 gen_mov_pc_npc(dc);
5056                 gen_check_align(cpu_tmp0, 3);
5057                 tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
5058                 dc->npc = DYNAMIC_PC;
5059                 goto jmp_insn;
5060 #endif
5061             } else {
5062                 cpu_src1 = get_src1(dc, insn);
5063                 cpu_tmp0 = tcg_temp_new();
5064                 if (IS_IMM) {   /* immediate */
5065                     simm = GET_FIELDs(insn, 19, 31);
5066                     tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
5067                 } else {                /* register */
5068                     rs2 = GET_FIELD(insn, 27, 31);
5069                     if (rs2) {
5070                         cpu_src2 = gen_load_gpr(dc, rs2);
5071                         tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
5072                     } else {
5073                         tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
5074                     }
5075                 }
5076                 switch (xop) {
5077                 case 0x38:      /* jmpl */
5078                     {
5079                         TCGv t = gen_dest_gpr(dc, rd);
5080                         tcg_gen_movi_tl(t, dc->pc);
5081                         gen_store_gpr(dc, rd, t);
5082 
5083                         gen_mov_pc_npc(dc);
5084                         gen_check_align(cpu_tmp0, 3);
5085                         gen_address_mask(dc, cpu_tmp0);
5086                         tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
5087                         dc->npc = DYNAMIC_PC;
5088                     }
5089                     goto jmp_insn;
5090 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
5091                 case 0x39:      /* rett, V9 return */
5092                     {
5093                         if (!supervisor(dc))
5094                             goto priv_insn;
5095                         gen_mov_pc_npc(dc);
5096                         gen_check_align(cpu_tmp0, 3);
5097                         tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
5098                         dc->npc = DYNAMIC_PC;
5099                         gen_helper_rett(cpu_env);
5100                     }
5101                     goto jmp_insn;
5102 #endif
5103                 case 0x3b: /* flush */
5104                     if (!((dc)->def->features & CPU_FEATURE_FLUSH))
5105                         goto unimp_flush;
5106                     /* nop */
5107                     break;
5108                 case 0x3c:      /* save */
5109                     gen_helper_save(cpu_env);
5110                     gen_store_gpr(dc, rd, cpu_tmp0);
5111                     break;
5112                 case 0x3d:      /* restore */
5113                     gen_helper_restore(cpu_env);
5114                     gen_store_gpr(dc, rd, cpu_tmp0);
5115                     break;
5116 #if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
5117                 case 0x3e:      /* V9 done/retry */
5118                     {
5119                         switch (rd) {
5120                         case 0:
5121                             if (!supervisor(dc))
5122                                 goto priv_insn;
5123                             dc->npc = DYNAMIC_PC;
5124                             dc->pc = DYNAMIC_PC;
5125                             if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
5126                                 gen_io_start();
5127                             }
5128                             gen_helper_done(cpu_env);
5129                             goto jmp_insn;
5130                         case 1:
5131                             if (!supervisor(dc))
5132                                 goto priv_insn;
5133                             dc->npc = DYNAMIC_PC;
5134                             dc->pc = DYNAMIC_PC;
5135                             if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
5136                                 gen_io_start();
5137                             }
5138                             gen_helper_retry(cpu_env);
5139                             goto jmp_insn;
5140                         default:
5141                             goto illegal_insn;
5142                         }
5143                     }
5144                     break;
5145 #endif
5146                 default:
5147                     goto illegal_insn;
5148                 }
5149             }
5150             break;
5151         }
5152         break;
5153     case 3:                     /* load/store instructions */
5154         {
5155             unsigned int xop = GET_FIELD(insn, 7, 12);
5156             /* ??? gen_address_mask prevents us from using a source
5157                register directly.  Always generate a temporary.  */
5158             TCGv cpu_addr = tcg_temp_new();
5159 
5160             tcg_gen_mov_tl(cpu_addr, get_src1(dc, insn));
5161             if (xop == 0x3c || xop == 0x3e) {
5162                 /* V9 casa/casxa : no offset */
5163             } else if (IS_IMM) {     /* immediate */
5164                 simm = GET_FIELDs(insn, 19, 31);
5165                 if (simm != 0) {
5166                     tcg_gen_addi_tl(cpu_addr, cpu_addr, simm);
5167                 }
5168             } else {            /* register */
5169                 rs2 = GET_FIELD(insn, 27, 31);
5170                 if (rs2 != 0) {
5171                     tcg_gen_add_tl(cpu_addr, cpu_addr, gen_load_gpr(dc, rs2));
5172                 }
5173             }
5174             if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
5175                 (xop > 0x17 && xop <= 0x1d ) ||
5176                 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
5177                 TCGv cpu_val = gen_dest_gpr(dc, rd);
5178 
5179                 switch (xop) {
5180                 case 0x0:       /* ld, V9 lduw, load unsigned word */
5181                     gen_address_mask(dc, cpu_addr);
5182                     tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
5183                     break;
5184                 case 0x1:       /* ldub, load unsigned byte */
5185                     gen_address_mask(dc, cpu_addr);
5186                     tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
5187                     break;
5188                 case 0x2:       /* lduh, load unsigned halfword */
5189                     gen_address_mask(dc, cpu_addr);
5190                     tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
5191                     break;
5192                 case 0x3:       /* ldd, load double word */
5193                     if (rd & 1)
5194                         goto illegal_insn;
5195                     else {
5196                         TCGv_i64 t64;
5197 
5198                         gen_address_mask(dc, cpu_addr);
5199                         t64 = tcg_temp_new_i64();
5200                         tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
5201                         tcg_gen_trunc_i64_tl(cpu_val, t64);
5202                         tcg_gen_ext32u_tl(cpu_val, cpu_val);
5203                         gen_store_gpr(dc, rd + 1, cpu_val);
5204                         tcg_gen_shri_i64(t64, t64, 32);
5205                         tcg_gen_trunc_i64_tl(cpu_val, t64);
5206                         tcg_gen_ext32u_tl(cpu_val, cpu_val);
5207                     }
5208                     break;
5209                 case 0x9:       /* ldsb, load signed byte */
5210                     gen_address_mask(dc, cpu_addr);
5211                     tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
5212                     break;
5213                 case 0xa:       /* ldsh, load signed halfword */
5214                     gen_address_mask(dc, cpu_addr);
5215                     tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
5216                     break;
5217                 case 0xd:       /* ldstub */
5218                     gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
5219                     break;
5220                 case 0x0f:
5221                     /* swap, swap register with memory. Also atomically */
5222                     CHECK_IU_FEATURE(dc, SWAP);
5223                     cpu_src1 = gen_load_gpr(dc, rd);
5224                     gen_swap(dc, cpu_val, cpu_src1, cpu_addr,
5225                              dc->mem_idx, MO_TEUL);
5226                     break;
5227 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5228                 case 0x10:      /* lda, V9 lduwa, load word alternate */
5229                     gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
5230                     break;
5231                 case 0x11:      /* lduba, load unsigned byte alternate */
5232                     gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
5233                     break;
5234                 case 0x12:      /* lduha, load unsigned halfword alternate */
5235                     gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
5236                     break;
5237                 case 0x13:      /* ldda, load double word alternate */
5238                     if (rd & 1) {
5239                         goto illegal_insn;
5240                     }
5241                     gen_ldda_asi(dc, cpu_addr, insn, rd);
5242                     goto skip_move;
5243                 case 0x19:      /* ldsba, load signed byte alternate */
5244                     gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_SB);
5245                     break;
5246                 case 0x1a:      /* ldsha, load signed halfword alternate */
5247                     gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESW);
5248                     break;
5249                 case 0x1d:      /* ldstuba -- XXX: should be atomically */
5250                     gen_ldstub_asi(dc, cpu_val, cpu_addr, insn);
5251                     break;
5252                 case 0x1f:      /* swapa, swap reg with alt. memory. Also
5253                                    atomically */
5254                     CHECK_IU_FEATURE(dc, SWAP);
5255                     cpu_src1 = gen_load_gpr(dc, rd);
5256                     gen_swap_asi(dc, cpu_val, cpu_src1, cpu_addr, insn);
5257                     break;
5258 
5259 #ifndef TARGET_SPARC64
5260                 case 0x30: /* ldc */
5261                 case 0x31: /* ldcsr */
5262                 case 0x33: /* lddc */
5263                     goto ncp_insn;
5264 #endif
5265 #endif
5266 #ifdef TARGET_SPARC64
5267                 case 0x08: /* V9 ldsw */
5268                     gen_address_mask(dc, cpu_addr);
5269                     tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
5270                     break;
5271                 case 0x0b: /* V9 ldx */
5272                     gen_address_mask(dc, cpu_addr);
5273                     tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
5274                     break;
5275                 case 0x18: /* V9 ldswa */
5276                     gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
5277                     break;
5278                 case 0x1b: /* V9 ldxa */
5279                     gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
5280                     break;
5281                 case 0x2d: /* V9 prefetch, no effect */
5282                     goto skip_move;
5283                 case 0x30: /* V9 ldfa */
5284                     if (gen_trap_ifnofpu(dc)) {
5285                         goto jmp_insn;
5286                     }
5287                     gen_ldf_asi(dc, cpu_addr, insn, 4, rd);
5288                     gen_update_fprs_dirty(dc, rd);
5289                     goto skip_move;
5290                 case 0x33: /* V9 lddfa */
5291                     if (gen_trap_ifnofpu(dc)) {
5292                         goto jmp_insn;
5293                     }
5294                     gen_ldf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
5295                     gen_update_fprs_dirty(dc, DFPREG(rd));
5296                     goto skip_move;
5297                 case 0x3d: /* V9 prefetcha, no effect */
5298                     goto skip_move;
5299                 case 0x32: /* V9 ldqfa */
5300                     CHECK_FPU_FEATURE(dc, FLOAT128);
5301                     if (gen_trap_ifnofpu(dc)) {
5302                         goto jmp_insn;
5303                     }
5304                     gen_ldf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
5305                     gen_update_fprs_dirty(dc, QFPREG(rd));
5306                     goto skip_move;
5307 #endif
5308                 default:
5309                     goto illegal_insn;
5310                 }
5311                 gen_store_gpr(dc, rd, cpu_val);
5312 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5313             skip_move: ;
5314 #endif
5315             } else if (xop >= 0x20 && xop < 0x24) {
5316                 if (gen_trap_ifnofpu(dc)) {
5317                     goto jmp_insn;
5318                 }
5319                 switch (xop) {
5320                 case 0x20:      /* ldf, load fpreg */
5321                     gen_address_mask(dc, cpu_addr);
5322                     cpu_dst_32 = gen_dest_fpr_F(dc);
5323                     tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
5324                                         dc->mem_idx, MO_TEUL);
5325                     gen_store_fpr_F(dc, rd, cpu_dst_32);
5326                     break;
5327                 case 0x21:      /* ldfsr, V9 ldxfsr */
5328 #ifdef TARGET_SPARC64
5329                     gen_address_mask(dc, cpu_addr);
5330                     if (rd == 1) {
5331                         TCGv_i64 t64 = tcg_temp_new_i64();
5332                         tcg_gen_qemu_ld_i64(t64, cpu_addr,
5333                                             dc->mem_idx, MO_TEUQ);
5334                         gen_helper_ldxfsr(cpu_fsr, cpu_env, cpu_fsr, t64);
5335                         break;
5336                     }
5337 #endif
5338                     cpu_dst_32 = tcg_temp_new_i32();
5339                     tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
5340                                         dc->mem_idx, MO_TEUL);
5341                     gen_helper_ldfsr(cpu_fsr, cpu_env, cpu_fsr, cpu_dst_32);
5342                     break;
5343                 case 0x22:      /* ldqf, load quad fpreg */
5344                     CHECK_FPU_FEATURE(dc, FLOAT128);
5345                     gen_address_mask(dc, cpu_addr);
5346                     cpu_src1_64 = tcg_temp_new_i64();
5347                     tcg_gen_qemu_ld_i64(cpu_src1_64, cpu_addr, dc->mem_idx,
5348                                         MO_TEUQ | MO_ALIGN_4);
5349                     tcg_gen_addi_tl(cpu_addr, cpu_addr, 8);
5350                     cpu_src2_64 = tcg_temp_new_i64();
5351                     tcg_gen_qemu_ld_i64(cpu_src2_64, cpu_addr, dc->mem_idx,
5352                                         MO_TEUQ | MO_ALIGN_4);
5353                     gen_store_fpr_Q(dc, rd, cpu_src1_64, cpu_src2_64);
5354                     break;
5355                 case 0x23:      /* lddf, load double fpreg */
5356                     gen_address_mask(dc, cpu_addr);
5357                     cpu_dst_64 = gen_dest_fpr_D(dc, rd);
5358                     tcg_gen_qemu_ld_i64(cpu_dst_64, cpu_addr, dc->mem_idx,
5359                                         MO_TEUQ | MO_ALIGN_4);
5360                     gen_store_fpr_D(dc, rd, cpu_dst_64);
5361                     break;
5362                 default:
5363                     goto illegal_insn;
5364                 }
5365             } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
5366                        xop == 0xe || xop == 0x1e) {
5367                 TCGv cpu_val = gen_load_gpr(dc, rd);
5368 
5369                 switch (xop) {
5370                 case 0x4: /* st, store word */
5371                     gen_address_mask(dc, cpu_addr);
5372                     tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
5373                     break;
5374                 case 0x5: /* stb, store byte */
5375                     gen_address_mask(dc, cpu_addr);
5376                     tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
5377                     break;
5378                 case 0x6: /* sth, store halfword */
5379                     gen_address_mask(dc, cpu_addr);
5380                     tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
5381                     break;
5382                 case 0x7: /* std, store double word */
5383                     if (rd & 1)
5384                         goto illegal_insn;
5385                     else {
5386                         TCGv_i64 t64;
5387                         TCGv lo;
5388 
5389                         gen_address_mask(dc, cpu_addr);
5390                         lo = gen_load_gpr(dc, rd + 1);
5391                         t64 = tcg_temp_new_i64();
5392                         tcg_gen_concat_tl_i64(t64, lo, cpu_val);
5393                         tcg_gen_qemu_st64(t64, cpu_addr, dc->mem_idx);
5394                     }
5395                     break;
5396 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5397                 case 0x14: /* sta, V9 stwa, store word alternate */
5398                     gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
5399                     break;
5400                 case 0x15: /* stba, store byte alternate */
5401                     gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
5402                     break;
5403                 case 0x16: /* stha, store halfword alternate */
5404                     gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
5405                     break;
5406                 case 0x17: /* stda, store double word alternate */
5407                     if (rd & 1) {
5408                         goto illegal_insn;
5409                     }
5410                     gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
5411                     break;
5412 #endif
5413 #ifdef TARGET_SPARC64
5414                 case 0x0e: /* V9 stx */
5415                     gen_address_mask(dc, cpu_addr);
5416                     tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
5417                     break;
5418                 case 0x1e: /* V9 stxa */
5419                     gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
5420                     break;
5421 #endif
5422                 default:
5423                     goto illegal_insn;
5424                 }
5425             } else if (xop > 0x23 && xop < 0x28) {
5426                 if (gen_trap_ifnofpu(dc)) {
5427                     goto jmp_insn;
5428                 }
5429                 switch (xop) {
5430                 case 0x24: /* stf, store fpreg */
5431                     gen_address_mask(dc, cpu_addr);
5432                     cpu_src1_32 = gen_load_fpr_F(dc, rd);
5433                     tcg_gen_qemu_st_i32(cpu_src1_32, cpu_addr,
5434                                         dc->mem_idx, MO_TEUL);
5435                     break;
5436                 case 0x25: /* stfsr, V9 stxfsr */
5437                     {
5438 #ifdef TARGET_SPARC64
5439                         gen_address_mask(dc, cpu_addr);
5440                         if (rd == 1) {
5441                             tcg_gen_qemu_st64(cpu_fsr, cpu_addr, dc->mem_idx);
5442                             break;
5443                         }
5444 #endif
5445                         tcg_gen_qemu_st32(cpu_fsr, cpu_addr, dc->mem_idx);
5446                     }
5447                     break;
5448                 case 0x26:
5449 #ifdef TARGET_SPARC64
5450                     /* V9 stqf, store quad fpreg */
5451                     CHECK_FPU_FEATURE(dc, FLOAT128);
5452                     gen_address_mask(dc, cpu_addr);
5453                     /* ??? While stqf only requires 4-byte alignment, it is
5454                        legal for the cpu to signal the unaligned exception.
5455                        The OS trap handler is then required to fix it up.
5456                        For qemu, this avoids having to probe the second page
5457                        before performing the first write.  */
5458                     cpu_src1_64 = gen_load_fpr_Q0(dc, rd);
5459                     tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr,
5460                                         dc->mem_idx, MO_TEUQ | MO_ALIGN_16);
5461                     tcg_gen_addi_tl(cpu_addr, cpu_addr, 8);
5462                     cpu_src2_64 = gen_load_fpr_Q1(dc, rd);
5463                     tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr,
5464                                         dc->mem_idx, MO_TEUQ);
5465                     break;
5466 #else /* !TARGET_SPARC64 */
5467                     /* stdfq, store floating point queue */
5468 #if defined(CONFIG_USER_ONLY)
5469                     goto illegal_insn;
5470 #else
5471                     if (!supervisor(dc))
5472                         goto priv_insn;
5473                     if (gen_trap_ifnofpu(dc)) {
5474                         goto jmp_insn;
5475                     }
5476                     goto nfq_insn;
5477 #endif
5478 #endif
5479                 case 0x27: /* stdf, store double fpreg */
5480                     gen_address_mask(dc, cpu_addr);
5481                     cpu_src1_64 = gen_load_fpr_D(dc, rd);
5482                     tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr, dc->mem_idx,
5483                                         MO_TEUQ | MO_ALIGN_4);
5484                     break;
5485                 default:
5486                     goto illegal_insn;
5487                 }
5488             } else if (xop > 0x33 && xop < 0x3f) {
5489                 switch (xop) {
5490 #ifdef TARGET_SPARC64
5491                 case 0x34: /* V9 stfa */
5492                     if (gen_trap_ifnofpu(dc)) {
5493                         goto jmp_insn;
5494                     }
5495                     gen_stf_asi(dc, cpu_addr, insn, 4, rd);
5496                     break;
5497                 case 0x36: /* V9 stqfa */
5498                     {
5499                         CHECK_FPU_FEATURE(dc, FLOAT128);
5500                         if (gen_trap_ifnofpu(dc)) {
5501                             goto jmp_insn;
5502                         }
5503                         gen_stf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
5504                     }
5505                     break;
5506                 case 0x37: /* V9 stdfa */
5507                     if (gen_trap_ifnofpu(dc)) {
5508                         goto jmp_insn;
5509                     }
5510                     gen_stf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
5511                     break;
5512                 case 0x3e: /* V9 casxa */
5513                     rs2 = GET_FIELD(insn, 27, 31);
5514                     cpu_src2 = gen_load_gpr(dc, rs2);
5515                     gen_casx_asi(dc, cpu_addr, cpu_src2, insn, rd);
5516                     break;
5517 #else
5518                 case 0x34: /* stc */
5519                 case 0x35: /* stcsr */
5520                 case 0x36: /* stdcq */
5521                 case 0x37: /* stdc */
5522                     goto ncp_insn;
5523 #endif
5524 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
5525                 case 0x3c: /* V9 or LEON3 casa */
5526 #ifndef TARGET_SPARC64
5527                     CHECK_IU_FEATURE(dc, CASA);
5528 #endif
5529                     rs2 = GET_FIELD(insn, 27, 31);
5530                     cpu_src2 = gen_load_gpr(dc, rs2);
5531                     gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
5532                     break;
5533 #endif
5534                 default:
5535                     goto illegal_insn;
5536                 }
5537             } else {
5538                 goto illegal_insn;
5539             }
5540         }
5541         break;
5542     }
5543     /* default case for non jump instructions */
5544     if (dc->npc == DYNAMIC_PC) {
5545         dc->pc = DYNAMIC_PC;
5546         gen_op_next_insn();
5547     } else if (dc->npc == JUMP_PC) {
5548         /* we can do a static jump */
5549         gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
5550         dc->base.is_jmp = DISAS_NORETURN;
5551     } else {
5552         dc->pc = dc->npc;
5553         dc->npc = dc->npc + 4;
5554     }
5555  jmp_insn:
5556     return;
5557  illegal_insn:
5558     gen_exception(dc, TT_ILL_INSN);
5559     return;
5560  unimp_flush:
5561     gen_exception(dc, TT_UNIMP_FLUSH);
5562     return;
5563 #if !defined(CONFIG_USER_ONLY)
5564  priv_insn:
5565     gen_exception(dc, TT_PRIV_INSN);
5566     return;
5567 #endif
5568  nfpu_insn:
5569     gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
5570     return;
5571 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
5572  nfq_insn:
5573     gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
5574     return;
5575 #endif
5576 #ifndef TARGET_SPARC64
5577  ncp_insn:
5578     gen_exception(dc, TT_NCP_INSN);
5579     return;
5580 #endif
5581 }
5582 
5583 static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
5584 {
5585     DisasContext *dc = container_of(dcbase, DisasContext, base);
5586     CPUSPARCState *env = cs->env_ptr;
5587     int bound;
5588 
5589     dc->pc = dc->base.pc_first;
5590     dc->npc = (target_ulong)dc->base.tb->cs_base;
5591     dc->cc_op = CC_OP_DYNAMIC;
5592     dc->mem_idx = dc->base.tb->flags & TB_FLAG_MMU_MASK;
5593     dc->def = &env->def;
5594     dc->fpu_enabled = tb_fpu_enabled(dc->base.tb->flags);
5595     dc->address_mask_32bit = tb_am_enabled(dc->base.tb->flags);
5596 #ifndef CONFIG_USER_ONLY
5597     dc->supervisor = (dc->base.tb->flags & TB_FLAG_SUPER) != 0;
5598 #endif
5599 #ifdef TARGET_SPARC64
5600     dc->fprs_dirty = 0;
5601     dc->asi = (dc->base.tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
5602 #ifndef CONFIG_USER_ONLY
5603     dc->hypervisor = (dc->base.tb->flags & TB_FLAG_HYPER) != 0;
5604 #endif
5605 #endif
5606     /*
5607      * if we reach a page boundary, we stop generation so that the
5608      * PC of a TT_TFAULT exception is always in the right page
5609      */
5610     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
5611     dc->base.max_insns = MIN(dc->base.max_insns, bound);
5612 }
5613 
5614 static void sparc_tr_tb_start(DisasContextBase *db, CPUState *cs)
5615 {
5616 }
5617 
5618 static void sparc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
5619 {
5620     DisasContext *dc = container_of(dcbase, DisasContext, base);
5621 
5622     if (dc->npc & JUMP_PC) {
5623         assert(dc->jump_pc[1] == dc->pc + 4);
5624         tcg_gen_insn_start(dc->pc, dc->jump_pc[0] | JUMP_PC);
5625     } else {
5626         tcg_gen_insn_start(dc->pc, dc->npc);
5627     }
5628 }
5629 
5630 static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
5631 {
5632     DisasContext *dc = container_of(dcbase, DisasContext, base);
5633     CPUSPARCState *env = cs->env_ptr;
5634     unsigned int insn;
5635 
5636     insn = translator_ldl(env, &dc->base, dc->pc);
5637     dc->base.pc_next += 4;
5638     disas_sparc_insn(dc, insn);
5639 
5640     if (dc->base.is_jmp == DISAS_NORETURN) {
5641         return;
5642     }
5643     if (dc->pc != dc->base.pc_next) {
5644         dc->base.is_jmp = DISAS_TOO_MANY;
5645     }
5646 }
5647 
5648 static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
5649 {
5650     DisasContext *dc = container_of(dcbase, DisasContext, base);
5651 
5652     switch (dc->base.is_jmp) {
5653     case DISAS_NEXT:
5654     case DISAS_TOO_MANY:
5655         if (dc->pc != DYNAMIC_PC &&
5656             (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
5657             /* static PC and NPC: we can use direct chaining */
5658             gen_goto_tb(dc, 0, dc->pc, dc->npc);
5659         } else {
5660             if (dc->pc != DYNAMIC_PC) {
5661                 tcg_gen_movi_tl(cpu_pc, dc->pc);
5662             }
5663             save_npc(dc);
5664             tcg_gen_exit_tb(NULL, 0);
5665         }
5666         break;
5667 
5668     case DISAS_NORETURN:
5669        break;
5670 
5671     case DISAS_EXIT:
5672         /* Exit TB */
5673         save_state(dc);
5674         tcg_gen_exit_tb(NULL, 0);
5675         break;
5676 
5677     default:
5678         g_assert_not_reached();
5679     }
5680 }
5681 
5682 static void sparc_tr_disas_log(const DisasContextBase *dcbase,
5683                                CPUState *cpu, FILE *logfile)
5684 {
5685     fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
5686     target_disas(logfile, cpu, dcbase->pc_first, dcbase->tb->size);
5687 }
5688 
5689 static const TranslatorOps sparc_tr_ops = {
5690     .init_disas_context = sparc_tr_init_disas_context,
5691     .tb_start           = sparc_tr_tb_start,
5692     .insn_start         = sparc_tr_insn_start,
5693     .translate_insn     = sparc_tr_translate_insn,
5694     .tb_stop            = sparc_tr_tb_stop,
5695     .disas_log          = sparc_tr_disas_log,
5696 };
5697 
5698 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
5699                            target_ulong pc, void *host_pc)
5700 {
5701     DisasContext dc = {};
5702 
5703     translator_loop(cs, tb, max_insns, pc, host_pc, &sparc_tr_ops, &dc.base);
5704 }
5705 
5706 void sparc_tcg_init(void)
5707 {
5708     static const char gregnames[32][4] = {
5709         "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
5710         "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
5711         "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
5712         "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
5713     };
5714     static const char fregnames[32][4] = {
5715         "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14",
5716         "f16", "f18", "f20", "f22", "f24", "f26", "f28", "f30",
5717         "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
5718         "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
5719     };
5720 
5721     static const struct { TCGv_i32 *ptr; int off; const char *name; } r32[] = {
5722 #ifdef TARGET_SPARC64
5723         { &cpu_xcc, offsetof(CPUSPARCState, xcc), "xcc" },
5724         { &cpu_fprs, offsetof(CPUSPARCState, fprs), "fprs" },
5725 #else
5726         { &cpu_wim, offsetof(CPUSPARCState, wim), "wim" },
5727 #endif
5728         { &cpu_cc_op, offsetof(CPUSPARCState, cc_op), "cc_op" },
5729         { &cpu_psr, offsetof(CPUSPARCState, psr), "psr" },
5730     };
5731 
5732     static const struct { TCGv *ptr; int off; const char *name; } rtl[] = {
5733 #ifdef TARGET_SPARC64
5734         { &cpu_gsr, offsetof(CPUSPARCState, gsr), "gsr" },
5735         { &cpu_tick_cmpr, offsetof(CPUSPARCState, tick_cmpr), "tick_cmpr" },
5736         { &cpu_stick_cmpr, offsetof(CPUSPARCState, stick_cmpr), "stick_cmpr" },
5737         { &cpu_hstick_cmpr, offsetof(CPUSPARCState, hstick_cmpr),
5738           "hstick_cmpr" },
5739         { &cpu_hintp, offsetof(CPUSPARCState, hintp), "hintp" },
5740         { &cpu_htba, offsetof(CPUSPARCState, htba), "htba" },
5741         { &cpu_hver, offsetof(CPUSPARCState, hver), "hver" },
5742         { &cpu_ssr, offsetof(CPUSPARCState, ssr), "ssr" },
5743         { &cpu_ver, offsetof(CPUSPARCState, version), "ver" },
5744 #endif
5745         { &cpu_cond, offsetof(CPUSPARCState, cond), "cond" },
5746         { &cpu_cc_src, offsetof(CPUSPARCState, cc_src), "cc_src" },
5747         { &cpu_cc_src2, offsetof(CPUSPARCState, cc_src2), "cc_src2" },
5748         { &cpu_cc_dst, offsetof(CPUSPARCState, cc_dst), "cc_dst" },
5749         { &cpu_fsr, offsetof(CPUSPARCState, fsr), "fsr" },
5750         { &cpu_pc, offsetof(CPUSPARCState, pc), "pc" },
5751         { &cpu_npc, offsetof(CPUSPARCState, npc), "npc" },
5752         { &cpu_y, offsetof(CPUSPARCState, y), "y" },
5753 #ifndef CONFIG_USER_ONLY
5754         { &cpu_tbr, offsetof(CPUSPARCState, tbr), "tbr" },
5755 #endif
5756     };
5757 
5758     unsigned int i;
5759 
5760     cpu_regwptr = tcg_global_mem_new_ptr(cpu_env,
5761                                          offsetof(CPUSPARCState, regwptr),
5762                                          "regwptr");
5763 
5764     for (i = 0; i < ARRAY_SIZE(r32); ++i) {
5765         *r32[i].ptr = tcg_global_mem_new_i32(cpu_env, r32[i].off, r32[i].name);
5766     }
5767 
5768     for (i = 0; i < ARRAY_SIZE(rtl); ++i) {
5769         *rtl[i].ptr = tcg_global_mem_new(cpu_env, rtl[i].off, rtl[i].name);
5770     }
5771 
5772     cpu_regs[0] = NULL;
5773     for (i = 1; i < 8; ++i) {
5774         cpu_regs[i] = tcg_global_mem_new(cpu_env,
5775                                          offsetof(CPUSPARCState, gregs[i]),
5776                                          gregnames[i]);
5777     }
5778 
5779     for (i = 8; i < 32; ++i) {
5780         cpu_regs[i] = tcg_global_mem_new(cpu_regwptr,
5781                                          (i - 8) * sizeof(target_ulong),
5782                                          gregnames[i]);
5783     }
5784 
5785     for (i = 0; i < TARGET_DPREGS; i++) {
5786         cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
5787                                             offsetof(CPUSPARCState, fpr[i]),
5788                                             fregnames[i]);
5789     }
5790 }
5791 
5792 void sparc_restore_state_to_opc(CPUState *cs,
5793                                 const TranslationBlock *tb,
5794                                 const uint64_t *data)
5795 {
5796     SPARCCPU *cpu = SPARC_CPU(cs);
5797     CPUSPARCState *env = &cpu->env;
5798     target_ulong pc = data[0];
5799     target_ulong npc = data[1];
5800 
5801     env->pc = pc;
5802     if (npc == DYNAMIC_PC) {
5803         /* dynamic NPC: already stored */
5804     } else if (npc & JUMP_PC) {
5805         /* jump PC: use 'cond' and the jump targets of the translation */
5806         if (env->cond) {
5807             env->npc = npc & ~3;
5808         } else {
5809             env->npc = pc + 4;
5810         }
5811     } else {
5812         env->npc = npc;
5813     }
5814 }
5815