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