xref: /openbmc/qemu/target/sparc/translate.c (revision 125062e7)
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 "tcg/tcg-op-gvec.h"
29 #include "exec/helper-gen.h"
30 #include "exec/translator.h"
31 #include "exec/log.h"
32 #include "asi.h"
33 
34 #define HELPER_H "helper.h"
35 #include "exec/helper-info.c.inc"
36 #undef  HELPER_H
37 
38 #ifdef TARGET_SPARC64
39 # define gen_helper_rdpsr(D, E)                 qemu_build_not_reached()
40 # define gen_helper_rett(E)                     qemu_build_not_reached()
41 # define gen_helper_power_down(E)               qemu_build_not_reached()
42 # define gen_helper_wrpsr(E, S)                 qemu_build_not_reached()
43 #else
44 # define gen_helper_clear_softint(E, S)         qemu_build_not_reached()
45 # define gen_helper_done(E)                     qemu_build_not_reached()
46 # define gen_helper_fabsd(D, S)                 qemu_build_not_reached()
47 # define gen_helper_flushw(E)                   qemu_build_not_reached()
48 # define gen_helper_fnegd(D, S)                 qemu_build_not_reached()
49 # define gen_helper_rdccr(D, E)                 qemu_build_not_reached()
50 # define gen_helper_rdcwp(D, E)                 qemu_build_not_reached()
51 # define gen_helper_restored(E)                 qemu_build_not_reached()
52 # define gen_helper_retry(E)                    qemu_build_not_reached()
53 # define gen_helper_saved(E)                    qemu_build_not_reached()
54 # define gen_helper_set_softint(E, S)           qemu_build_not_reached()
55 # define gen_helper_tick_get_count(D, E, T, C)  qemu_build_not_reached()
56 # define gen_helper_tick_set_count(P, S)        qemu_build_not_reached()
57 # define gen_helper_tick_set_limit(P, S)        qemu_build_not_reached()
58 # define gen_helper_wrccr(E, S)                 qemu_build_not_reached()
59 # define gen_helper_wrcwp(E, S)                 qemu_build_not_reached()
60 # define gen_helper_wrgl(E, S)                  qemu_build_not_reached()
61 # define gen_helper_write_softint(E, S)         qemu_build_not_reached()
62 # define gen_helper_wrpil(E, S)                 qemu_build_not_reached()
63 # define gen_helper_wrpstate(E, S)              qemu_build_not_reached()
64 # define gen_helper_fabsq                ({ qemu_build_not_reached(); NULL; })
65 # define gen_helper_fcmpeq16             ({ qemu_build_not_reached(); NULL; })
66 # define gen_helper_fcmpeq32             ({ qemu_build_not_reached(); NULL; })
67 # define gen_helper_fcmpgt16             ({ qemu_build_not_reached(); NULL; })
68 # define gen_helper_fcmpgt32             ({ qemu_build_not_reached(); NULL; })
69 # define gen_helper_fcmple16             ({ qemu_build_not_reached(); NULL; })
70 # define gen_helper_fcmple32             ({ qemu_build_not_reached(); NULL; })
71 # define gen_helper_fcmpne16             ({ qemu_build_not_reached(); NULL; })
72 # define gen_helper_fcmpne32             ({ qemu_build_not_reached(); NULL; })
73 # define gen_helper_fdtox                ({ qemu_build_not_reached(); NULL; })
74 # define gen_helper_fexpand              ({ qemu_build_not_reached(); NULL; })
75 # define gen_helper_fmul8sux16           ({ qemu_build_not_reached(); NULL; })
76 # define gen_helper_fmul8ulx16           ({ qemu_build_not_reached(); NULL; })
77 # define gen_helper_fmul8x16al           ({ qemu_build_not_reached(); NULL; })
78 # define gen_helper_fmul8x16au           ({ qemu_build_not_reached(); NULL; })
79 # define gen_helper_fmul8x16             ({ qemu_build_not_reached(); NULL; })
80 # define gen_helper_fmuld8sux16          ({ qemu_build_not_reached(); NULL; })
81 # define gen_helper_fmuld8ulx16          ({ qemu_build_not_reached(); NULL; })
82 # define gen_helper_fnegq                ({ qemu_build_not_reached(); NULL; })
83 # define gen_helper_fpmerge              ({ qemu_build_not_reached(); NULL; })
84 # define gen_helper_fqtox                ({ qemu_build_not_reached(); NULL; })
85 # define gen_helper_fstox                ({ qemu_build_not_reached(); NULL; })
86 # define gen_helper_fxtod                ({ qemu_build_not_reached(); NULL; })
87 # define gen_helper_fxtoq                ({ qemu_build_not_reached(); NULL; })
88 # define gen_helper_fxtos                ({ qemu_build_not_reached(); NULL; })
89 # define gen_helper_pdist                ({ qemu_build_not_reached(); NULL; })
90 # define FSR_LDXFSR_MASK                        0
91 # define FSR_LDXFSR_OLDMASK                     0
92 # define MAXTL_MASK                             0
93 #endif
94 
95 /* Dynamic PC, must exit to main loop. */
96 #define DYNAMIC_PC         1
97 /* Dynamic PC, one of two values according to jump_pc[T2]. */
98 #define JUMP_PC            2
99 /* Dynamic PC, may lookup next TB. */
100 #define DYNAMIC_PC_LOOKUP  3
101 
102 #define DISAS_EXIT  DISAS_TARGET_0
103 
104 /* global register indexes */
105 static TCGv_ptr cpu_regwptr;
106 static TCGv cpu_fsr, cpu_pc, cpu_npc;
107 static TCGv cpu_regs[32];
108 static TCGv cpu_y;
109 static TCGv cpu_tbr;
110 static TCGv cpu_cond;
111 static TCGv cpu_cc_N;
112 static TCGv cpu_cc_V;
113 static TCGv cpu_icc_Z;
114 static TCGv cpu_icc_C;
115 #ifdef TARGET_SPARC64
116 static TCGv cpu_xcc_Z;
117 static TCGv cpu_xcc_C;
118 static TCGv_i32 cpu_fprs;
119 static TCGv cpu_gsr;
120 #else
121 # define cpu_fprs               ({ qemu_build_not_reached(); (TCGv)NULL; })
122 # define cpu_gsr                ({ qemu_build_not_reached(); (TCGv)NULL; })
123 #endif
124 
125 #ifdef TARGET_SPARC64
126 #define cpu_cc_Z  cpu_xcc_Z
127 #define cpu_cc_C  cpu_xcc_C
128 #else
129 #define cpu_cc_Z  cpu_icc_Z
130 #define cpu_cc_C  cpu_icc_C
131 #define cpu_xcc_Z ({ qemu_build_not_reached(); NULL; })
132 #define cpu_xcc_C ({ qemu_build_not_reached(); NULL; })
133 #endif
134 
135 /* Floating point registers */
136 static TCGv_i64 cpu_fpr[TARGET_DPREGS];
137 
138 #define env_field_offsetof(X)     offsetof(CPUSPARCState, X)
139 #ifdef TARGET_SPARC64
140 # define env32_field_offsetof(X)  ({ qemu_build_not_reached(); 0; })
141 # define env64_field_offsetof(X)  env_field_offsetof(X)
142 #else
143 # define env32_field_offsetof(X)  env_field_offsetof(X)
144 # define env64_field_offsetof(X)  ({ qemu_build_not_reached(); 0; })
145 #endif
146 
147 typedef struct DisasCompare {
148     TCGCond cond;
149     TCGv c1;
150     int c2;
151 } DisasCompare;
152 
153 typedef struct DisasDelayException {
154     struct DisasDelayException *next;
155     TCGLabel *lab;
156     TCGv_i32 excp;
157     /* Saved state at parent insn. */
158     target_ulong pc;
159     target_ulong npc;
160 } DisasDelayException;
161 
162 typedef struct DisasContext {
163     DisasContextBase base;
164     target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
165     target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
166 
167     /* Used when JUMP_PC value is used. */
168     DisasCompare jump;
169     target_ulong jump_pc[2];
170 
171     int mem_idx;
172     bool cpu_cond_live;
173     bool fpu_enabled;
174     bool address_mask_32bit;
175 #ifndef CONFIG_USER_ONLY
176     bool supervisor;
177 #ifdef TARGET_SPARC64
178     bool hypervisor;
179 #endif
180 #endif
181 
182     sparc_def_t *def;
183 #ifdef TARGET_SPARC64
184     int fprs_dirty;
185     int asi;
186 #endif
187     DisasDelayException *delay_excp_list;
188 } DisasContext;
189 
190 // This function uses non-native bit order
191 #define GET_FIELD(X, FROM, TO)                                  \
192     ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
193 
194 // This function uses the order in the manuals, i.e. bit 0 is 2^0
195 #define GET_FIELD_SP(X, FROM, TO)               \
196     GET_FIELD(X, 31 - (TO), 31 - (FROM))
197 
198 #define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
199 #define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
200 
201 #ifdef TARGET_SPARC64
202 #define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
203 #define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
204 #else
205 #define DFPREG(r) (r & 0x1e)
206 #define QFPREG(r) (r & 0x1c)
207 #endif
208 
209 #define UA2005_HTRAP_MASK 0xff
210 #define V8_TRAP_MASK 0x7f
211 
212 #define IS_IMM (insn & (1<<13))
213 
214 static void gen_update_fprs_dirty(DisasContext *dc, int rd)
215 {
216 #if defined(TARGET_SPARC64)
217     int bit = (rd < 32) ? 1 : 2;
218     /* If we know we've already set this bit within the TB,
219        we can avoid setting it again.  */
220     if (!(dc->fprs_dirty & bit)) {
221         dc->fprs_dirty |= bit;
222         tcg_gen_ori_i32(cpu_fprs, cpu_fprs, bit);
223     }
224 #endif
225 }
226 
227 /* floating point registers moves */
228 static TCGv_i32 gen_load_fpr_F(DisasContext *dc, unsigned int src)
229 {
230     TCGv_i32 ret = tcg_temp_new_i32();
231     if (src & 1) {
232         tcg_gen_extrl_i64_i32(ret, cpu_fpr[src / 2]);
233     } else {
234         tcg_gen_extrh_i64_i32(ret, cpu_fpr[src / 2]);
235     }
236     return ret;
237 }
238 
239 static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v)
240 {
241     TCGv_i64 t = tcg_temp_new_i64();
242 
243     tcg_gen_extu_i32_i64(t, v);
244     tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t,
245                         (dst & 1 ? 0 : 32), 32);
246     gen_update_fprs_dirty(dc, dst);
247 }
248 
249 static TCGv_i32 gen_dest_fpr_F(DisasContext *dc)
250 {
251     return tcg_temp_new_i32();
252 }
253 
254 static TCGv_i64 gen_load_fpr_D(DisasContext *dc, unsigned int src)
255 {
256     src = DFPREG(src);
257     return cpu_fpr[src / 2];
258 }
259 
260 static void gen_store_fpr_D(DisasContext *dc, unsigned int dst, TCGv_i64 v)
261 {
262     dst = DFPREG(dst);
263     tcg_gen_mov_i64(cpu_fpr[dst / 2], v);
264     gen_update_fprs_dirty(dc, dst);
265 }
266 
267 static TCGv_i64 gen_dest_fpr_D(DisasContext *dc, unsigned int dst)
268 {
269     return cpu_fpr[DFPREG(dst) / 2];
270 }
271 
272 static void gen_op_load_fpr_QT0(unsigned int src)
273 {
274     tcg_gen_st_i64(cpu_fpr[src / 2], tcg_env, offsetof(CPUSPARCState, qt0) +
275                    offsetof(CPU_QuadU, ll.upper));
276     tcg_gen_st_i64(cpu_fpr[src/2 + 1], tcg_env, offsetof(CPUSPARCState, qt0) +
277                    offsetof(CPU_QuadU, ll.lower));
278 }
279 
280 static void gen_op_load_fpr_QT1(unsigned int src)
281 {
282     tcg_gen_st_i64(cpu_fpr[src / 2], tcg_env, offsetof(CPUSPARCState, qt1) +
283                    offsetof(CPU_QuadU, ll.upper));
284     tcg_gen_st_i64(cpu_fpr[src/2 + 1], tcg_env, offsetof(CPUSPARCState, qt1) +
285                    offsetof(CPU_QuadU, ll.lower));
286 }
287 
288 static void gen_op_store_QT0_fpr(unsigned int dst)
289 {
290     tcg_gen_ld_i64(cpu_fpr[dst / 2], tcg_env, offsetof(CPUSPARCState, qt0) +
291                    offsetof(CPU_QuadU, ll.upper));
292     tcg_gen_ld_i64(cpu_fpr[dst/2 + 1], tcg_env, offsetof(CPUSPARCState, qt0) +
293                    offsetof(CPU_QuadU, ll.lower));
294 }
295 
296 /* moves */
297 #ifdef CONFIG_USER_ONLY
298 #define supervisor(dc) 0
299 #define hypervisor(dc) 0
300 #else
301 #ifdef TARGET_SPARC64
302 #define hypervisor(dc) (dc->hypervisor)
303 #define supervisor(dc) (dc->supervisor | dc->hypervisor)
304 #else
305 #define supervisor(dc) (dc->supervisor)
306 #define hypervisor(dc) 0
307 #endif
308 #endif
309 
310 #if !defined(TARGET_SPARC64)
311 # define AM_CHECK(dc)  false
312 #elif defined(TARGET_ABI32)
313 # define AM_CHECK(dc)  true
314 #elif defined(CONFIG_USER_ONLY)
315 # define AM_CHECK(dc)  false
316 #else
317 # define AM_CHECK(dc)  ((dc)->address_mask_32bit)
318 #endif
319 
320 static void gen_address_mask(DisasContext *dc, TCGv addr)
321 {
322     if (AM_CHECK(dc)) {
323         tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
324     }
325 }
326 
327 static target_ulong address_mask_i(DisasContext *dc, target_ulong addr)
328 {
329     return AM_CHECK(dc) ? (uint32_t)addr : addr;
330 }
331 
332 static TCGv gen_load_gpr(DisasContext *dc, int reg)
333 {
334     if (reg > 0) {
335         assert(reg < 32);
336         return cpu_regs[reg];
337     } else {
338         TCGv t = tcg_temp_new();
339         tcg_gen_movi_tl(t, 0);
340         return t;
341     }
342 }
343 
344 static void gen_store_gpr(DisasContext *dc, int reg, TCGv v)
345 {
346     if (reg > 0) {
347         assert(reg < 32);
348         tcg_gen_mov_tl(cpu_regs[reg], v);
349     }
350 }
351 
352 static TCGv gen_dest_gpr(DisasContext *dc, int reg)
353 {
354     if (reg > 0) {
355         assert(reg < 32);
356         return cpu_regs[reg];
357     } else {
358         return tcg_temp_new();
359     }
360 }
361 
362 static bool use_goto_tb(DisasContext *s, target_ulong pc, target_ulong npc)
363 {
364     return translator_use_goto_tb(&s->base, pc) &&
365            translator_use_goto_tb(&s->base, npc);
366 }
367 
368 static void gen_goto_tb(DisasContext *s, int tb_num,
369                         target_ulong pc, target_ulong npc)
370 {
371     if (use_goto_tb(s, pc, npc))  {
372         /* jump to same page: we can use a direct jump */
373         tcg_gen_goto_tb(tb_num);
374         tcg_gen_movi_tl(cpu_pc, pc);
375         tcg_gen_movi_tl(cpu_npc, npc);
376         tcg_gen_exit_tb(s->base.tb, tb_num);
377     } else {
378         /* jump to another page: we can use an indirect jump */
379         tcg_gen_movi_tl(cpu_pc, pc);
380         tcg_gen_movi_tl(cpu_npc, npc);
381         tcg_gen_lookup_and_goto_ptr();
382     }
383 }
384 
385 static TCGv gen_carry32(void)
386 {
387     if (TARGET_LONG_BITS == 64) {
388         TCGv t = tcg_temp_new();
389         tcg_gen_extract_tl(t, cpu_icc_C, 32, 1);
390         return t;
391     }
392     return cpu_icc_C;
393 }
394 
395 static void gen_op_addcc_int(TCGv dst, TCGv src1, TCGv src2, TCGv cin)
396 {
397     TCGv z = tcg_constant_tl(0);
398 
399     if (cin) {
400         tcg_gen_add2_tl(cpu_cc_N, cpu_cc_C, src1, z, cin, z);
401         tcg_gen_add2_tl(cpu_cc_N, cpu_cc_C, cpu_cc_N, cpu_cc_C, src2, z);
402     } else {
403         tcg_gen_add2_tl(cpu_cc_N, cpu_cc_C, src1, z, src2, z);
404     }
405     tcg_gen_xor_tl(cpu_cc_Z, src1, src2);
406     tcg_gen_xor_tl(cpu_cc_V, cpu_cc_N, src2);
407     tcg_gen_andc_tl(cpu_cc_V, cpu_cc_V, cpu_cc_Z);
408     if (TARGET_LONG_BITS == 64) {
409         /*
410          * Carry-in to bit 32 is result ^ src1 ^ src2.
411          * We already have the src xor term in Z, from computation of V.
412          */
413         tcg_gen_xor_tl(cpu_icc_C, cpu_cc_Z, cpu_cc_N);
414         tcg_gen_mov_tl(cpu_icc_Z, cpu_cc_N);
415     }
416     tcg_gen_mov_tl(cpu_cc_Z, cpu_cc_N);
417     tcg_gen_mov_tl(dst, cpu_cc_N);
418 }
419 
420 static void gen_op_addcc(TCGv dst, TCGv src1, TCGv src2)
421 {
422     gen_op_addcc_int(dst, src1, src2, NULL);
423 }
424 
425 static void gen_op_taddcc(TCGv dst, TCGv src1, TCGv src2)
426 {
427     TCGv t = tcg_temp_new();
428 
429     /* Save the tag bits around modification of dst. */
430     tcg_gen_or_tl(t, src1, src2);
431 
432     gen_op_addcc(dst, src1, src2);
433 
434     /* Incorprate tag bits into icc.V */
435     tcg_gen_andi_tl(t, t, 3);
436     tcg_gen_neg_tl(t, t);
437     tcg_gen_ext32u_tl(t, t);
438     tcg_gen_or_tl(cpu_cc_V, cpu_cc_V, t);
439 }
440 
441 static void gen_op_addc(TCGv dst, TCGv src1, TCGv src2)
442 {
443     tcg_gen_add_tl(dst, src1, src2);
444     tcg_gen_add_tl(dst, dst, gen_carry32());
445 }
446 
447 static void gen_op_addccc(TCGv dst, TCGv src1, TCGv src2)
448 {
449     gen_op_addcc_int(dst, src1, src2, gen_carry32());
450 }
451 
452 static void gen_op_subcc_int(TCGv dst, TCGv src1, TCGv src2, TCGv cin)
453 {
454     TCGv z = tcg_constant_tl(0);
455 
456     if (cin) {
457         tcg_gen_sub2_tl(cpu_cc_N, cpu_cc_C, src1, z, cin, z);
458         tcg_gen_sub2_tl(cpu_cc_N, cpu_cc_C, cpu_cc_N, cpu_cc_C, src2, z);
459     } else {
460         tcg_gen_sub2_tl(cpu_cc_N, cpu_cc_C, src1, z, src2, z);
461     }
462     tcg_gen_neg_tl(cpu_cc_C, cpu_cc_C);
463     tcg_gen_xor_tl(cpu_cc_Z, src1, src2);
464     tcg_gen_xor_tl(cpu_cc_V, cpu_cc_N, src1);
465     tcg_gen_and_tl(cpu_cc_V, cpu_cc_V, cpu_cc_Z);
466 #ifdef TARGET_SPARC64
467     tcg_gen_xor_tl(cpu_icc_C, cpu_cc_Z, cpu_cc_N);
468     tcg_gen_mov_tl(cpu_icc_Z, cpu_cc_N);
469 #endif
470     tcg_gen_mov_tl(cpu_cc_Z, cpu_cc_N);
471     tcg_gen_mov_tl(dst, cpu_cc_N);
472 }
473 
474 static void gen_op_subcc(TCGv dst, TCGv src1, TCGv src2)
475 {
476     gen_op_subcc_int(dst, src1, src2, NULL);
477 }
478 
479 static void gen_op_tsubcc(TCGv dst, TCGv src1, TCGv src2)
480 {
481     TCGv t = tcg_temp_new();
482 
483     /* Save the tag bits around modification of dst. */
484     tcg_gen_or_tl(t, src1, src2);
485 
486     gen_op_subcc(dst, src1, src2);
487 
488     /* Incorprate tag bits into icc.V */
489     tcg_gen_andi_tl(t, t, 3);
490     tcg_gen_neg_tl(t, t);
491     tcg_gen_ext32u_tl(t, t);
492     tcg_gen_or_tl(cpu_cc_V, cpu_cc_V, t);
493 }
494 
495 static void gen_op_subc(TCGv dst, TCGv src1, TCGv src2)
496 {
497     tcg_gen_sub_tl(dst, src1, src2);
498     tcg_gen_sub_tl(dst, dst, gen_carry32());
499 }
500 
501 static void gen_op_subccc(TCGv dst, TCGv src1, TCGv src2)
502 {
503     gen_op_subcc_int(dst, src1, src2, gen_carry32());
504 }
505 
506 static void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
507 {
508     TCGv zero = tcg_constant_tl(0);
509     TCGv t_src1 = tcg_temp_new();
510     TCGv t_src2 = tcg_temp_new();
511     TCGv t0 = tcg_temp_new();
512 
513     tcg_gen_ext32u_tl(t_src1, src1);
514     tcg_gen_ext32u_tl(t_src2, src2);
515 
516     /*
517      * if (!(env->y & 1))
518      *   src2 = 0;
519      */
520     tcg_gen_andi_tl(t0, cpu_y, 0x1);
521     tcg_gen_movcond_tl(TCG_COND_EQ, t_src2, t0, zero, zero, t_src2);
522 
523     /*
524      * b2 = src1 & 1;
525      * y = (b2 << 31) | (y >> 1);
526      */
527     tcg_gen_extract_tl(t0, cpu_y, 1, 31);
528     tcg_gen_deposit_tl(cpu_y, t0, src1, 31, 1);
529 
530     // b1 = N ^ V;
531     tcg_gen_xor_tl(t0, cpu_cc_N, cpu_cc_V);
532 
533     /*
534      * src1 = (b1 << 31) | (src1 >> 1)
535      */
536     tcg_gen_andi_tl(t0, t0, 1u << 31);
537     tcg_gen_shri_tl(t_src1, t_src1, 1);
538     tcg_gen_or_tl(t_src1, t_src1, t0);
539 
540     gen_op_addcc(dst, t_src1, t_src2);
541 }
542 
543 static void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)
544 {
545 #if TARGET_LONG_BITS == 32
546     if (sign_ext) {
547         tcg_gen_muls2_tl(dst, cpu_y, src1, src2);
548     } else {
549         tcg_gen_mulu2_tl(dst, cpu_y, src1, src2);
550     }
551 #else
552     TCGv t0 = tcg_temp_new_i64();
553     TCGv t1 = tcg_temp_new_i64();
554 
555     if (sign_ext) {
556         tcg_gen_ext32s_i64(t0, src1);
557         tcg_gen_ext32s_i64(t1, src2);
558     } else {
559         tcg_gen_ext32u_i64(t0, src1);
560         tcg_gen_ext32u_i64(t1, src2);
561     }
562 
563     tcg_gen_mul_i64(dst, t0, t1);
564     tcg_gen_shri_i64(cpu_y, dst, 32);
565 #endif
566 }
567 
568 static void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
569 {
570     /* zero-extend truncated operands before multiplication */
571     gen_op_multiply(dst, src1, src2, 0);
572 }
573 
574 static void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
575 {
576     /* sign-extend truncated operands before multiplication */
577     gen_op_multiply(dst, src1, src2, 1);
578 }
579 
580 static void gen_op_sdiv(TCGv dst, TCGv src1, TCGv src2)
581 {
582 #ifdef TARGET_SPARC64
583     gen_helper_sdiv(dst, tcg_env, src1, src2);
584     tcg_gen_ext32s_tl(dst, dst);
585 #else
586     TCGv_i64 t64 = tcg_temp_new_i64();
587     gen_helper_sdiv(t64, tcg_env, src1, src2);
588     tcg_gen_trunc_i64_tl(dst, t64);
589 #endif
590 }
591 
592 static void gen_op_udivcc(TCGv dst, TCGv src1, TCGv src2)
593 {
594     TCGv_i64 t64;
595 
596 #ifdef TARGET_SPARC64
597     t64 = cpu_cc_V;
598 #else
599     t64 = tcg_temp_new_i64();
600 #endif
601 
602     gen_helper_udiv(t64, tcg_env, src1, src2);
603 
604 #ifdef TARGET_SPARC64
605     tcg_gen_ext32u_tl(cpu_cc_N, t64);
606     tcg_gen_shri_tl(cpu_cc_V, t64, 32);
607     tcg_gen_mov_tl(cpu_icc_Z, cpu_cc_N);
608     tcg_gen_movi_tl(cpu_icc_C, 0);
609 #else
610     tcg_gen_extr_i64_tl(cpu_cc_N, cpu_cc_V, t64);
611 #endif
612     tcg_gen_mov_tl(cpu_cc_Z, cpu_cc_N);
613     tcg_gen_movi_tl(cpu_cc_C, 0);
614     tcg_gen_mov_tl(dst, cpu_cc_N);
615 }
616 
617 static void gen_op_sdivcc(TCGv dst, TCGv src1, TCGv src2)
618 {
619     TCGv_i64 t64;
620 
621 #ifdef TARGET_SPARC64
622     t64 = cpu_cc_V;
623 #else
624     t64 = tcg_temp_new_i64();
625 #endif
626 
627     gen_helper_sdiv(t64, tcg_env, src1, src2);
628 
629 #ifdef TARGET_SPARC64
630     tcg_gen_ext32s_tl(cpu_cc_N, t64);
631     tcg_gen_shri_tl(cpu_cc_V, t64, 32);
632     tcg_gen_mov_tl(cpu_icc_Z, cpu_cc_N);
633     tcg_gen_movi_tl(cpu_icc_C, 0);
634 #else
635     tcg_gen_extr_i64_tl(cpu_cc_N, cpu_cc_V, t64);
636 #endif
637     tcg_gen_mov_tl(cpu_cc_Z, cpu_cc_N);
638     tcg_gen_movi_tl(cpu_cc_C, 0);
639     tcg_gen_mov_tl(dst, cpu_cc_N);
640 }
641 
642 static void gen_op_taddcctv(TCGv dst, TCGv src1, TCGv src2)
643 {
644     gen_helper_taddcctv(dst, tcg_env, src1, src2);
645 }
646 
647 static void gen_op_tsubcctv(TCGv dst, TCGv src1, TCGv src2)
648 {
649     gen_helper_tsubcctv(dst, tcg_env, src1, src2);
650 }
651 
652 static void gen_op_popc(TCGv dst, TCGv src1, TCGv src2)
653 {
654     tcg_gen_ctpop_tl(dst, src2);
655 }
656 
657 #ifndef TARGET_SPARC64
658 static void gen_helper_array8(TCGv dst, TCGv src1, TCGv src2)
659 {
660     g_assert_not_reached();
661 }
662 #endif
663 
664 static void gen_op_array16(TCGv dst, TCGv src1, TCGv src2)
665 {
666     gen_helper_array8(dst, src1, src2);
667     tcg_gen_shli_tl(dst, dst, 1);
668 }
669 
670 static void gen_op_array32(TCGv dst, TCGv src1, TCGv src2)
671 {
672     gen_helper_array8(dst, src1, src2);
673     tcg_gen_shli_tl(dst, dst, 2);
674 }
675 
676 static void gen_op_fpack16(TCGv_i32 dst, TCGv_i64 src)
677 {
678 #ifdef TARGET_SPARC64
679     gen_helper_fpack16(dst, cpu_gsr, src);
680 #else
681     g_assert_not_reached();
682 #endif
683 }
684 
685 static void gen_op_fpackfix(TCGv_i32 dst, TCGv_i64 src)
686 {
687 #ifdef TARGET_SPARC64
688     gen_helper_fpackfix(dst, cpu_gsr, src);
689 #else
690     g_assert_not_reached();
691 #endif
692 }
693 
694 static void gen_op_fpack32(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2)
695 {
696 #ifdef TARGET_SPARC64
697     gen_helper_fpack32(dst, cpu_gsr, src1, src2);
698 #else
699     g_assert_not_reached();
700 #endif
701 }
702 
703 static void gen_op_faligndata(TCGv_i64 dst, TCGv_i64 s1, TCGv_i64 s2)
704 {
705 #ifdef TARGET_SPARC64
706     TCGv t1, t2, shift;
707 
708     t1 = tcg_temp_new();
709     t2 = tcg_temp_new();
710     shift = tcg_temp_new();
711 
712     tcg_gen_andi_tl(shift, cpu_gsr, 7);
713     tcg_gen_shli_tl(shift, shift, 3);
714     tcg_gen_shl_tl(t1, s1, shift);
715 
716     /*
717      * A shift of 64 does not produce 0 in TCG.  Divide this into a
718      * shift of (up to 63) followed by a constant shift of 1.
719      */
720     tcg_gen_xori_tl(shift, shift, 63);
721     tcg_gen_shr_tl(t2, s2, shift);
722     tcg_gen_shri_tl(t2, t2, 1);
723 
724     tcg_gen_or_tl(dst, t1, t2);
725 #else
726     g_assert_not_reached();
727 #endif
728 }
729 
730 static void gen_op_bshuffle(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2)
731 {
732 #ifdef TARGET_SPARC64
733     gen_helper_bshuffle(dst, cpu_gsr, src1, src2);
734 #else
735     g_assert_not_reached();
736 #endif
737 }
738 
739 // 1
740 static void gen_op_eval_ba(TCGv dst)
741 {
742     tcg_gen_movi_tl(dst, 1);
743 }
744 
745 // 0
746 static void gen_op_eval_bn(TCGv dst)
747 {
748     tcg_gen_movi_tl(dst, 0);
749 }
750 
751 /*
752   FPSR bit field FCC1 | FCC0:
753    0 =
754    1 <
755    2 >
756    3 unordered
757 */
758 static void gen_mov_reg_FCC0(TCGv reg, TCGv src,
759                                     unsigned int fcc_offset)
760 {
761     tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
762     tcg_gen_andi_tl(reg, reg, 0x1);
763 }
764 
765 static void gen_mov_reg_FCC1(TCGv reg, TCGv src, unsigned int fcc_offset)
766 {
767     tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
768     tcg_gen_andi_tl(reg, reg, 0x1);
769 }
770 
771 // !0: FCC0 | FCC1
772 static void gen_op_eval_fbne(TCGv dst, TCGv src, unsigned int fcc_offset)
773 {
774     TCGv t0 = tcg_temp_new();
775     gen_mov_reg_FCC0(dst, src, fcc_offset);
776     gen_mov_reg_FCC1(t0, src, fcc_offset);
777     tcg_gen_or_tl(dst, dst, t0);
778 }
779 
780 // 1 or 2: FCC0 ^ FCC1
781 static void gen_op_eval_fblg(TCGv dst, TCGv src, unsigned int fcc_offset)
782 {
783     TCGv t0 = tcg_temp_new();
784     gen_mov_reg_FCC0(dst, src, fcc_offset);
785     gen_mov_reg_FCC1(t0, src, fcc_offset);
786     tcg_gen_xor_tl(dst, dst, t0);
787 }
788 
789 // 1 or 3: FCC0
790 static void gen_op_eval_fbul(TCGv dst, TCGv src, unsigned int fcc_offset)
791 {
792     gen_mov_reg_FCC0(dst, src, fcc_offset);
793 }
794 
795 // 1: FCC0 & !FCC1
796 static void gen_op_eval_fbl(TCGv dst, TCGv src, unsigned int fcc_offset)
797 {
798     TCGv t0 = tcg_temp_new();
799     gen_mov_reg_FCC0(dst, src, fcc_offset);
800     gen_mov_reg_FCC1(t0, src, fcc_offset);
801     tcg_gen_andc_tl(dst, dst, t0);
802 }
803 
804 // 2 or 3: FCC1
805 static void gen_op_eval_fbug(TCGv dst, TCGv src, unsigned int fcc_offset)
806 {
807     gen_mov_reg_FCC1(dst, src, fcc_offset);
808 }
809 
810 // 2: !FCC0 & FCC1
811 static void gen_op_eval_fbg(TCGv dst, TCGv src, unsigned int fcc_offset)
812 {
813     TCGv t0 = tcg_temp_new();
814     gen_mov_reg_FCC0(dst, src, fcc_offset);
815     gen_mov_reg_FCC1(t0, src, fcc_offset);
816     tcg_gen_andc_tl(dst, t0, dst);
817 }
818 
819 // 3: FCC0 & FCC1
820 static void gen_op_eval_fbu(TCGv dst, TCGv src, unsigned int fcc_offset)
821 {
822     TCGv t0 = tcg_temp_new();
823     gen_mov_reg_FCC0(dst, src, fcc_offset);
824     gen_mov_reg_FCC1(t0, src, fcc_offset);
825     tcg_gen_and_tl(dst, dst, t0);
826 }
827 
828 // 0: !(FCC0 | FCC1)
829 static void gen_op_eval_fbe(TCGv dst, TCGv src, unsigned int fcc_offset)
830 {
831     TCGv t0 = tcg_temp_new();
832     gen_mov_reg_FCC0(dst, src, fcc_offset);
833     gen_mov_reg_FCC1(t0, src, fcc_offset);
834     tcg_gen_or_tl(dst, dst, t0);
835     tcg_gen_xori_tl(dst, dst, 0x1);
836 }
837 
838 // 0 or 3: !(FCC0 ^ FCC1)
839 static void gen_op_eval_fbue(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_xor_tl(dst, dst, t0);
845     tcg_gen_xori_tl(dst, dst, 0x1);
846 }
847 
848 // 0 or 2: !FCC0
849 static void gen_op_eval_fbge(TCGv dst, TCGv src, unsigned int fcc_offset)
850 {
851     gen_mov_reg_FCC0(dst, src, fcc_offset);
852     tcg_gen_xori_tl(dst, dst, 0x1);
853 }
854 
855 // !1: !(FCC0 & !FCC1)
856 static void gen_op_eval_fbuge(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, dst, t0);
862     tcg_gen_xori_tl(dst, dst, 0x1);
863 }
864 
865 // 0 or 1: !FCC1
866 static void gen_op_eval_fble(TCGv dst, TCGv src, unsigned int fcc_offset)
867 {
868     gen_mov_reg_FCC1(dst, src, fcc_offset);
869     tcg_gen_xori_tl(dst, dst, 0x1);
870 }
871 
872 // !2: !(!FCC0 & FCC1)
873 static void gen_op_eval_fbule(TCGv dst, TCGv src, unsigned int fcc_offset)
874 {
875     TCGv t0 = tcg_temp_new();
876     gen_mov_reg_FCC0(dst, src, fcc_offset);
877     gen_mov_reg_FCC1(t0, src, fcc_offset);
878     tcg_gen_andc_tl(dst, t0, dst);
879     tcg_gen_xori_tl(dst, dst, 0x1);
880 }
881 
882 // !3: !(FCC0 & FCC1)
883 static void gen_op_eval_fbo(TCGv dst, TCGv src, unsigned int fcc_offset)
884 {
885     TCGv t0 = tcg_temp_new();
886     gen_mov_reg_FCC0(dst, src, fcc_offset);
887     gen_mov_reg_FCC1(t0, src, fcc_offset);
888     tcg_gen_and_tl(dst, dst, t0);
889     tcg_gen_xori_tl(dst, dst, 0x1);
890 }
891 
892 static void finishing_insn(DisasContext *dc)
893 {
894     /*
895      * From here, there is no future path through an unwinding exception.
896      * If the current insn cannot raise an exception, the computation of
897      * cpu_cond may be able to be elided.
898      */
899     if (dc->cpu_cond_live) {
900         tcg_gen_discard_tl(cpu_cond);
901         dc->cpu_cond_live = false;
902     }
903 }
904 
905 static void gen_generic_branch(DisasContext *dc)
906 {
907     TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
908     TCGv npc1 = tcg_constant_tl(dc->jump_pc[1]);
909     TCGv c2 = tcg_constant_tl(dc->jump.c2);
910 
911     tcg_gen_movcond_tl(dc->jump.cond, cpu_npc, dc->jump.c1, c2, npc0, npc1);
912 }
913 
914 /* call this function before using the condition register as it may
915    have been set for a jump */
916 static void flush_cond(DisasContext *dc)
917 {
918     if (dc->npc == JUMP_PC) {
919         gen_generic_branch(dc);
920         dc->npc = DYNAMIC_PC_LOOKUP;
921     }
922 }
923 
924 static void save_npc(DisasContext *dc)
925 {
926     if (dc->npc & 3) {
927         switch (dc->npc) {
928         case JUMP_PC:
929             gen_generic_branch(dc);
930             dc->npc = DYNAMIC_PC_LOOKUP;
931             break;
932         case DYNAMIC_PC:
933         case DYNAMIC_PC_LOOKUP:
934             break;
935         default:
936             g_assert_not_reached();
937         }
938     } else {
939         tcg_gen_movi_tl(cpu_npc, dc->npc);
940     }
941 }
942 
943 static void save_state(DisasContext *dc)
944 {
945     tcg_gen_movi_tl(cpu_pc, dc->pc);
946     save_npc(dc);
947 }
948 
949 static void gen_exception(DisasContext *dc, int which)
950 {
951     finishing_insn(dc);
952     save_state(dc);
953     gen_helper_raise_exception(tcg_env, tcg_constant_i32(which));
954     dc->base.is_jmp = DISAS_NORETURN;
955 }
956 
957 static TCGLabel *delay_exceptionv(DisasContext *dc, TCGv_i32 excp)
958 {
959     DisasDelayException *e = g_new0(DisasDelayException, 1);
960 
961     e->next = dc->delay_excp_list;
962     dc->delay_excp_list = e;
963 
964     e->lab = gen_new_label();
965     e->excp = excp;
966     e->pc = dc->pc;
967     /* Caller must have used flush_cond before branch. */
968     assert(e->npc != JUMP_PC);
969     e->npc = dc->npc;
970 
971     return e->lab;
972 }
973 
974 static TCGLabel *delay_exception(DisasContext *dc, int excp)
975 {
976     return delay_exceptionv(dc, tcg_constant_i32(excp));
977 }
978 
979 static void gen_check_align(DisasContext *dc, TCGv addr, int mask)
980 {
981     TCGv t = tcg_temp_new();
982     TCGLabel *lab;
983 
984     tcg_gen_andi_tl(t, addr, mask);
985 
986     flush_cond(dc);
987     lab = delay_exception(dc, TT_UNALIGNED);
988     tcg_gen_brcondi_tl(TCG_COND_NE, t, 0, lab);
989 }
990 
991 static void gen_mov_pc_npc(DisasContext *dc)
992 {
993     finishing_insn(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_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
1016                         DisasContext *dc)
1017 {
1018     TCGv t1;
1019 
1020     cmp->c1 = t1 = tcg_temp_new();
1021     cmp->c2 = 0;
1022 
1023     switch (cond & 7) {
1024     case 0x0: /* never */
1025         cmp->cond = TCG_COND_NEVER;
1026         cmp->c1 = tcg_constant_tl(0);
1027         break;
1028 
1029     case 0x1: /* eq: Z */
1030         cmp->cond = TCG_COND_EQ;
1031         if (TARGET_LONG_BITS == 32 || xcc) {
1032             tcg_gen_mov_tl(t1, cpu_cc_Z);
1033         } else {
1034             tcg_gen_ext32u_tl(t1, cpu_icc_Z);
1035         }
1036         break;
1037 
1038     case 0x2: /* le: Z | (N ^ V) */
1039         /*
1040          * Simplify:
1041          *   cc_Z || (N ^ V) < 0        NE
1042          *   cc_Z && !((N ^ V) < 0)     EQ
1043          *   cc_Z & ~((N ^ V) >> TLB)   EQ
1044          */
1045         cmp->cond = TCG_COND_EQ;
1046         tcg_gen_xor_tl(t1, cpu_cc_N, cpu_cc_V);
1047         tcg_gen_sextract_tl(t1, t1, xcc ? 63 : 31, 1);
1048         tcg_gen_andc_tl(t1, xcc ? cpu_cc_Z : cpu_icc_Z, t1);
1049         if (TARGET_LONG_BITS == 64 && !xcc) {
1050             tcg_gen_ext32u_tl(t1, t1);
1051         }
1052         break;
1053 
1054     case 0x3: /* lt: N ^ V */
1055         cmp->cond = TCG_COND_LT;
1056         tcg_gen_xor_tl(t1, cpu_cc_N, cpu_cc_V);
1057         if (TARGET_LONG_BITS == 64 && !xcc) {
1058             tcg_gen_ext32s_tl(t1, t1);
1059         }
1060         break;
1061 
1062     case 0x4: /* leu: Z | C */
1063         /*
1064          * Simplify:
1065          *   cc_Z == 0 || cc_C != 0     NE
1066          *   cc_Z != 0 && cc_C == 0     EQ
1067          *   cc_Z & (cc_C ? 0 : -1)     EQ
1068          *   cc_Z & (cc_C - 1)          EQ
1069          */
1070         cmp->cond = TCG_COND_EQ;
1071         if (TARGET_LONG_BITS == 32 || xcc) {
1072             tcg_gen_subi_tl(t1, cpu_cc_C, 1);
1073             tcg_gen_and_tl(t1, t1, cpu_cc_Z);
1074         } else {
1075             tcg_gen_extract_tl(t1, cpu_icc_C, 32, 1);
1076             tcg_gen_subi_tl(t1, t1, 1);
1077             tcg_gen_and_tl(t1, t1, cpu_icc_Z);
1078             tcg_gen_ext32u_tl(t1, t1);
1079         }
1080         break;
1081 
1082     case 0x5: /* ltu: C */
1083         cmp->cond = TCG_COND_NE;
1084         if (TARGET_LONG_BITS == 32 || xcc) {
1085             tcg_gen_mov_tl(t1, cpu_cc_C);
1086         } else {
1087             tcg_gen_extract_tl(t1, cpu_icc_C, 32, 1);
1088         }
1089         break;
1090 
1091     case 0x6: /* neg: N */
1092         cmp->cond = TCG_COND_LT;
1093         if (TARGET_LONG_BITS == 32 || xcc) {
1094             tcg_gen_mov_tl(t1, cpu_cc_N);
1095         } else {
1096             tcg_gen_ext32s_tl(t1, cpu_cc_N);
1097         }
1098         break;
1099 
1100     case 0x7: /* vs: V */
1101         cmp->cond = TCG_COND_LT;
1102         if (TARGET_LONG_BITS == 32 || xcc) {
1103             tcg_gen_mov_tl(t1, cpu_cc_V);
1104         } else {
1105             tcg_gen_ext32s_tl(t1, cpu_cc_V);
1106         }
1107         break;
1108     }
1109     if (cond & 8) {
1110         cmp->cond = tcg_invert_cond(cmp->cond);
1111     }
1112 }
1113 
1114 static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
1115 {
1116     unsigned int offset;
1117     TCGv r_dst;
1118 
1119     /* For now we still generate a straight boolean result.  */
1120     cmp->cond = TCG_COND_NE;
1121     cmp->c1 = r_dst = tcg_temp_new();
1122     cmp->c2 = 0;
1123 
1124     switch (cc) {
1125     default:
1126     case 0x0:
1127         offset = 0;
1128         break;
1129     case 0x1:
1130         offset = 32 - 10;
1131         break;
1132     case 0x2:
1133         offset = 34 - 10;
1134         break;
1135     case 0x3:
1136         offset = 36 - 10;
1137         break;
1138     }
1139 
1140     switch (cond) {
1141     case 0x0:
1142         gen_op_eval_bn(r_dst);
1143         break;
1144     case 0x1:
1145         gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1146         break;
1147     case 0x2:
1148         gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1149         break;
1150     case 0x3:
1151         gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1152         break;
1153     case 0x4:
1154         gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1155         break;
1156     case 0x5:
1157         gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1158         break;
1159     case 0x6:
1160         gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1161         break;
1162     case 0x7:
1163         gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1164         break;
1165     case 0x8:
1166         gen_op_eval_ba(r_dst);
1167         break;
1168     case 0x9:
1169         gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1170         break;
1171     case 0xa:
1172         gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1173         break;
1174     case 0xb:
1175         gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1176         break;
1177     case 0xc:
1178         gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1179         break;
1180     case 0xd:
1181         gen_op_eval_fble(r_dst, cpu_fsr, offset);
1182         break;
1183     case 0xe:
1184         gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1185         break;
1186     case 0xf:
1187         gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1188         break;
1189     }
1190 }
1191 
1192 static bool gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
1193 {
1194     static const TCGCond cond_reg[4] = {
1195         TCG_COND_NEVER,  /* reserved */
1196         TCG_COND_EQ,
1197         TCG_COND_LE,
1198         TCG_COND_LT,
1199     };
1200     TCGCond tcond;
1201 
1202     if ((cond & 3) == 0) {
1203         return false;
1204     }
1205     tcond = cond_reg[cond & 3];
1206     if (cond & 4) {
1207         tcond = tcg_invert_cond(tcond);
1208     }
1209 
1210     cmp->cond = tcond;
1211     cmp->c1 = tcg_temp_new();
1212     cmp->c2 = 0;
1213     tcg_gen_mov_tl(cmp->c1, r_src);
1214     return true;
1215 }
1216 
1217 static void gen_op_clear_ieee_excp_and_FTT(void)
1218 {
1219     tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1220 }
1221 
1222 static void gen_op_fmovs(TCGv_i32 dst, TCGv_i32 src)
1223 {
1224     gen_op_clear_ieee_excp_and_FTT();
1225     tcg_gen_mov_i32(dst, src);
1226 }
1227 
1228 static void gen_op_fnegs(TCGv_i32 dst, TCGv_i32 src)
1229 {
1230     gen_op_clear_ieee_excp_and_FTT();
1231     gen_helper_fnegs(dst, src);
1232 }
1233 
1234 static void gen_op_fabss(TCGv_i32 dst, TCGv_i32 src)
1235 {
1236     gen_op_clear_ieee_excp_and_FTT();
1237     gen_helper_fabss(dst, src);
1238 }
1239 
1240 static void gen_op_fmovd(TCGv_i64 dst, TCGv_i64 src)
1241 {
1242     gen_op_clear_ieee_excp_and_FTT();
1243     tcg_gen_mov_i64(dst, src);
1244 }
1245 
1246 static void gen_op_fnegd(TCGv_i64 dst, TCGv_i64 src)
1247 {
1248     gen_op_clear_ieee_excp_and_FTT();
1249     gen_helper_fnegd(dst, src);
1250 }
1251 
1252 static void gen_op_fabsd(TCGv_i64 dst, TCGv_i64 src)
1253 {
1254     gen_op_clear_ieee_excp_and_FTT();
1255     gen_helper_fabsd(dst, src);
1256 }
1257 
1258 #ifdef TARGET_SPARC64
1259 static void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1260 {
1261     switch (fccno) {
1262     case 0:
1263         gen_helper_fcmps(cpu_fsr, tcg_env, r_rs1, r_rs2);
1264         break;
1265     case 1:
1266         gen_helper_fcmps_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
1267         break;
1268     case 2:
1269         gen_helper_fcmps_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
1270         break;
1271     case 3:
1272         gen_helper_fcmps_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
1273         break;
1274     }
1275 }
1276 
1277 static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1278 {
1279     switch (fccno) {
1280     case 0:
1281         gen_helper_fcmpd(cpu_fsr, tcg_env, r_rs1, r_rs2);
1282         break;
1283     case 1:
1284         gen_helper_fcmpd_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
1285         break;
1286     case 2:
1287         gen_helper_fcmpd_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
1288         break;
1289     case 3:
1290         gen_helper_fcmpd_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
1291         break;
1292     }
1293 }
1294 
1295 static void gen_op_fcmpq(int fccno)
1296 {
1297     switch (fccno) {
1298     case 0:
1299         gen_helper_fcmpq(cpu_fsr, tcg_env);
1300         break;
1301     case 1:
1302         gen_helper_fcmpq_fcc1(cpu_fsr, tcg_env);
1303         break;
1304     case 2:
1305         gen_helper_fcmpq_fcc2(cpu_fsr, tcg_env);
1306         break;
1307     case 3:
1308         gen_helper_fcmpq_fcc3(cpu_fsr, tcg_env);
1309         break;
1310     }
1311 }
1312 
1313 static void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1314 {
1315     switch (fccno) {
1316     case 0:
1317         gen_helper_fcmpes(cpu_fsr, tcg_env, r_rs1, r_rs2);
1318         break;
1319     case 1:
1320         gen_helper_fcmpes_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
1321         break;
1322     case 2:
1323         gen_helper_fcmpes_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
1324         break;
1325     case 3:
1326         gen_helper_fcmpes_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
1327         break;
1328     }
1329 }
1330 
1331 static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1332 {
1333     switch (fccno) {
1334     case 0:
1335         gen_helper_fcmped(cpu_fsr, tcg_env, r_rs1, r_rs2);
1336         break;
1337     case 1:
1338         gen_helper_fcmped_fcc1(cpu_fsr, tcg_env, r_rs1, r_rs2);
1339         break;
1340     case 2:
1341         gen_helper_fcmped_fcc2(cpu_fsr, tcg_env, r_rs1, r_rs2);
1342         break;
1343     case 3:
1344         gen_helper_fcmped_fcc3(cpu_fsr, tcg_env, r_rs1, r_rs2);
1345         break;
1346     }
1347 }
1348 
1349 static void gen_op_fcmpeq(int fccno)
1350 {
1351     switch (fccno) {
1352     case 0:
1353         gen_helper_fcmpeq(cpu_fsr, tcg_env);
1354         break;
1355     case 1:
1356         gen_helper_fcmpeq_fcc1(cpu_fsr, tcg_env);
1357         break;
1358     case 2:
1359         gen_helper_fcmpeq_fcc2(cpu_fsr, tcg_env);
1360         break;
1361     case 3:
1362         gen_helper_fcmpeq_fcc3(cpu_fsr, tcg_env);
1363         break;
1364     }
1365 }
1366 
1367 #else
1368 
1369 static void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1370 {
1371     gen_helper_fcmps(cpu_fsr, tcg_env, r_rs1, r_rs2);
1372 }
1373 
1374 static void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1375 {
1376     gen_helper_fcmpd(cpu_fsr, tcg_env, r_rs1, r_rs2);
1377 }
1378 
1379 static void gen_op_fcmpq(int fccno)
1380 {
1381     gen_helper_fcmpq(cpu_fsr, tcg_env);
1382 }
1383 
1384 static void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1385 {
1386     gen_helper_fcmpes(cpu_fsr, tcg_env, r_rs1, r_rs2);
1387 }
1388 
1389 static void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
1390 {
1391     gen_helper_fcmped(cpu_fsr, tcg_env, r_rs1, r_rs2);
1392 }
1393 
1394 static void gen_op_fcmpeq(int fccno)
1395 {
1396     gen_helper_fcmpeq(cpu_fsr, tcg_env);
1397 }
1398 #endif
1399 
1400 static void gen_op_fpexception_im(DisasContext *dc, int fsr_flags)
1401 {
1402     tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
1403     tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1404     gen_exception(dc, TT_FP_EXCP);
1405 }
1406 
1407 static int gen_trap_ifnofpu(DisasContext *dc)
1408 {
1409 #if !defined(CONFIG_USER_ONLY)
1410     if (!dc->fpu_enabled) {
1411         gen_exception(dc, TT_NFPU_INSN);
1412         return 1;
1413     }
1414 #endif
1415     return 0;
1416 }
1417 
1418 /* asi moves */
1419 typedef enum {
1420     GET_ASI_HELPER,
1421     GET_ASI_EXCP,
1422     GET_ASI_DIRECT,
1423     GET_ASI_DTWINX,
1424     GET_ASI_BLOCK,
1425     GET_ASI_SHORT,
1426     GET_ASI_BCOPY,
1427     GET_ASI_BFILL,
1428 } ASIType;
1429 
1430 typedef struct {
1431     ASIType type;
1432     int asi;
1433     int mem_idx;
1434     MemOp memop;
1435 } DisasASI;
1436 
1437 /*
1438  * Build DisasASI.
1439  * For asi == -1, treat as non-asi.
1440  * For ask == -2, treat as immediate offset (v8 error, v9 %asi).
1441  */
1442 static DisasASI resolve_asi(DisasContext *dc, int asi, MemOp memop)
1443 {
1444     ASIType type = GET_ASI_HELPER;
1445     int mem_idx = dc->mem_idx;
1446 
1447     if (asi == -1) {
1448         /* Artificial "non-asi" case. */
1449         type = GET_ASI_DIRECT;
1450         goto done;
1451     }
1452 
1453 #ifndef TARGET_SPARC64
1454     /* Before v9, all asis are immediate and privileged.  */
1455     if (asi < 0) {
1456         gen_exception(dc, TT_ILL_INSN);
1457         type = GET_ASI_EXCP;
1458     } else if (supervisor(dc)
1459                /* Note that LEON accepts ASI_USERDATA in user mode, for
1460                   use with CASA.  Also note that previous versions of
1461                   QEMU allowed (and old versions of gcc emitted) ASI_P
1462                   for LEON, which is incorrect.  */
1463                || (asi == ASI_USERDATA
1464                    && (dc->def->features & CPU_FEATURE_CASA))) {
1465         switch (asi) {
1466         case ASI_USERDATA:   /* User data access */
1467             mem_idx = MMU_USER_IDX;
1468             type = GET_ASI_DIRECT;
1469             break;
1470         case ASI_KERNELDATA: /* Supervisor data access */
1471             mem_idx = MMU_KERNEL_IDX;
1472             type = GET_ASI_DIRECT;
1473             break;
1474         case ASI_M_BYPASS:    /* MMU passthrough */
1475         case ASI_LEON_BYPASS: /* LEON MMU passthrough */
1476             mem_idx = MMU_PHYS_IDX;
1477             type = GET_ASI_DIRECT;
1478             break;
1479         case ASI_M_BCOPY: /* Block copy, sta access */
1480             mem_idx = MMU_KERNEL_IDX;
1481             type = GET_ASI_BCOPY;
1482             break;
1483         case ASI_M_BFILL: /* Block fill, stda access */
1484             mem_idx = MMU_KERNEL_IDX;
1485             type = GET_ASI_BFILL;
1486             break;
1487         }
1488 
1489         /* MMU_PHYS_IDX is used when the MMU is disabled to passthrough the
1490          * permissions check in get_physical_address(..).
1491          */
1492         mem_idx = (dc->mem_idx == MMU_PHYS_IDX) ? MMU_PHYS_IDX : mem_idx;
1493     } else {
1494         gen_exception(dc, TT_PRIV_INSN);
1495         type = GET_ASI_EXCP;
1496     }
1497 #else
1498     if (asi < 0) {
1499         asi = dc->asi;
1500     }
1501     /* With v9, all asis below 0x80 are privileged.  */
1502     /* ??? We ought to check cpu_has_hypervisor, but we didn't copy
1503        down that bit into DisasContext.  For the moment that's ok,
1504        since the direct implementations below doesn't have any ASIs
1505        in the restricted [0x30, 0x7f] range, and the check will be
1506        done properly in the helper.  */
1507     if (!supervisor(dc) && asi < 0x80) {
1508         gen_exception(dc, TT_PRIV_ACT);
1509         type = GET_ASI_EXCP;
1510     } else {
1511         switch (asi) {
1512         case ASI_REAL:      /* Bypass */
1513         case ASI_REAL_IO:   /* Bypass, non-cacheable */
1514         case ASI_REAL_L:    /* Bypass LE */
1515         case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
1516         case ASI_TWINX_REAL:   /* Real address, twinx */
1517         case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
1518         case ASI_QUAD_LDD_PHYS:
1519         case ASI_QUAD_LDD_PHYS_L:
1520             mem_idx = MMU_PHYS_IDX;
1521             break;
1522         case ASI_N:  /* Nucleus */
1523         case ASI_NL: /* Nucleus LE */
1524         case ASI_TWINX_N:
1525         case ASI_TWINX_NL:
1526         case ASI_NUCLEUS_QUAD_LDD:
1527         case ASI_NUCLEUS_QUAD_LDD_L:
1528             if (hypervisor(dc)) {
1529                 mem_idx = MMU_PHYS_IDX;
1530             } else {
1531                 mem_idx = MMU_NUCLEUS_IDX;
1532             }
1533             break;
1534         case ASI_AIUP:  /* As if user primary */
1535         case ASI_AIUPL: /* As if user primary LE */
1536         case ASI_TWINX_AIUP:
1537         case ASI_TWINX_AIUP_L:
1538         case ASI_BLK_AIUP_4V:
1539         case ASI_BLK_AIUP_L_4V:
1540         case ASI_BLK_AIUP:
1541         case ASI_BLK_AIUPL:
1542             mem_idx = MMU_USER_IDX;
1543             break;
1544         case ASI_AIUS:  /* As if user secondary */
1545         case ASI_AIUSL: /* As if user secondary LE */
1546         case ASI_TWINX_AIUS:
1547         case ASI_TWINX_AIUS_L:
1548         case ASI_BLK_AIUS_4V:
1549         case ASI_BLK_AIUS_L_4V:
1550         case ASI_BLK_AIUS:
1551         case ASI_BLK_AIUSL:
1552             mem_idx = MMU_USER_SECONDARY_IDX;
1553             break;
1554         case ASI_S:  /* Secondary */
1555         case ASI_SL: /* Secondary LE */
1556         case ASI_TWINX_S:
1557         case ASI_TWINX_SL:
1558         case ASI_BLK_COMMIT_S:
1559         case ASI_BLK_S:
1560         case ASI_BLK_SL:
1561         case ASI_FL8_S:
1562         case ASI_FL8_SL:
1563         case ASI_FL16_S:
1564         case ASI_FL16_SL:
1565             if (mem_idx == MMU_USER_IDX) {
1566                 mem_idx = MMU_USER_SECONDARY_IDX;
1567             } else if (mem_idx == MMU_KERNEL_IDX) {
1568                 mem_idx = MMU_KERNEL_SECONDARY_IDX;
1569             }
1570             break;
1571         case ASI_P:  /* Primary */
1572         case ASI_PL: /* Primary LE */
1573         case ASI_TWINX_P:
1574         case ASI_TWINX_PL:
1575         case ASI_BLK_COMMIT_P:
1576         case ASI_BLK_P:
1577         case ASI_BLK_PL:
1578         case ASI_FL8_P:
1579         case ASI_FL8_PL:
1580         case ASI_FL16_P:
1581         case ASI_FL16_PL:
1582             break;
1583         }
1584         switch (asi) {
1585         case ASI_REAL:
1586         case ASI_REAL_IO:
1587         case ASI_REAL_L:
1588         case ASI_REAL_IO_L:
1589         case ASI_N:
1590         case ASI_NL:
1591         case ASI_AIUP:
1592         case ASI_AIUPL:
1593         case ASI_AIUS:
1594         case ASI_AIUSL:
1595         case ASI_S:
1596         case ASI_SL:
1597         case ASI_P:
1598         case ASI_PL:
1599             type = GET_ASI_DIRECT;
1600             break;
1601         case ASI_TWINX_REAL:
1602         case ASI_TWINX_REAL_L:
1603         case ASI_TWINX_N:
1604         case ASI_TWINX_NL:
1605         case ASI_TWINX_AIUP:
1606         case ASI_TWINX_AIUP_L:
1607         case ASI_TWINX_AIUS:
1608         case ASI_TWINX_AIUS_L:
1609         case ASI_TWINX_P:
1610         case ASI_TWINX_PL:
1611         case ASI_TWINX_S:
1612         case ASI_TWINX_SL:
1613         case ASI_QUAD_LDD_PHYS:
1614         case ASI_QUAD_LDD_PHYS_L:
1615         case ASI_NUCLEUS_QUAD_LDD:
1616         case ASI_NUCLEUS_QUAD_LDD_L:
1617             type = GET_ASI_DTWINX;
1618             break;
1619         case ASI_BLK_COMMIT_P:
1620         case ASI_BLK_COMMIT_S:
1621         case ASI_BLK_AIUP_4V:
1622         case ASI_BLK_AIUP_L_4V:
1623         case ASI_BLK_AIUP:
1624         case ASI_BLK_AIUPL:
1625         case ASI_BLK_AIUS_4V:
1626         case ASI_BLK_AIUS_L_4V:
1627         case ASI_BLK_AIUS:
1628         case ASI_BLK_AIUSL:
1629         case ASI_BLK_S:
1630         case ASI_BLK_SL:
1631         case ASI_BLK_P:
1632         case ASI_BLK_PL:
1633             type = GET_ASI_BLOCK;
1634             break;
1635         case ASI_FL8_S:
1636         case ASI_FL8_SL:
1637         case ASI_FL8_P:
1638         case ASI_FL8_PL:
1639             memop = MO_UB;
1640             type = GET_ASI_SHORT;
1641             break;
1642         case ASI_FL16_S:
1643         case ASI_FL16_SL:
1644         case ASI_FL16_P:
1645         case ASI_FL16_PL:
1646             memop = MO_TEUW;
1647             type = GET_ASI_SHORT;
1648             break;
1649         }
1650         /* The little-endian asis all have bit 3 set.  */
1651         if (asi & 8) {
1652             memop ^= MO_BSWAP;
1653         }
1654     }
1655 #endif
1656 
1657  done:
1658     return (DisasASI){ type, asi, mem_idx, memop };
1659 }
1660 
1661 #if defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
1662 static void gen_helper_ld_asi(TCGv_i64 r, TCGv_env e, TCGv a,
1663                               TCGv_i32 asi, TCGv_i32 mop)
1664 {
1665     g_assert_not_reached();
1666 }
1667 
1668 static void gen_helper_st_asi(TCGv_env e, TCGv a, TCGv_i64 r,
1669                               TCGv_i32 asi, TCGv_i32 mop)
1670 {
1671     g_assert_not_reached();
1672 }
1673 #endif
1674 
1675 static void gen_ld_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
1676 {
1677     switch (da->type) {
1678     case GET_ASI_EXCP:
1679         break;
1680     case GET_ASI_DTWINX: /* Reserved for ldda.  */
1681         gen_exception(dc, TT_ILL_INSN);
1682         break;
1683     case GET_ASI_DIRECT:
1684         tcg_gen_qemu_ld_tl(dst, addr, da->mem_idx, da->memop | MO_ALIGN);
1685         break;
1686     default:
1687         {
1688             TCGv_i32 r_asi = tcg_constant_i32(da->asi);
1689             TCGv_i32 r_mop = tcg_constant_i32(da->memop | MO_ALIGN);
1690 
1691             save_state(dc);
1692 #ifdef TARGET_SPARC64
1693             gen_helper_ld_asi(dst, tcg_env, addr, r_asi, r_mop);
1694 #else
1695             {
1696                 TCGv_i64 t64 = tcg_temp_new_i64();
1697                 gen_helper_ld_asi(t64, tcg_env, addr, r_asi, r_mop);
1698                 tcg_gen_trunc_i64_tl(dst, t64);
1699             }
1700 #endif
1701         }
1702         break;
1703     }
1704 }
1705 
1706 static void gen_st_asi(DisasContext *dc, DisasASI *da, TCGv src, TCGv addr)
1707 {
1708     switch (da->type) {
1709     case GET_ASI_EXCP:
1710         break;
1711 
1712     case GET_ASI_DTWINX: /* Reserved for stda.  */
1713         if (TARGET_LONG_BITS == 32) {
1714             gen_exception(dc, TT_ILL_INSN);
1715             break;
1716         } else if (!(dc->def->features & CPU_FEATURE_HYPV)) {
1717             /* Pre OpenSPARC CPUs don't have these */
1718             gen_exception(dc, TT_ILL_INSN);
1719             break;
1720         }
1721         /* In OpenSPARC T1+ CPUs TWINX ASIs in store are ST_BLKINIT_ ASIs */
1722         /* fall through */
1723 
1724     case GET_ASI_DIRECT:
1725         tcg_gen_qemu_st_tl(src, addr, da->mem_idx, da->memop | MO_ALIGN);
1726         break;
1727 
1728     case GET_ASI_BCOPY:
1729         assert(TARGET_LONG_BITS == 32);
1730         /* Copy 32 bytes from the address in SRC to ADDR.  */
1731         /* ??? The original qemu code suggests 4-byte alignment, dropping
1732            the low bits, but the only place I can see this used is in the
1733            Linux kernel with 32 byte alignment, which would make more sense
1734            as a cacheline-style operation.  */
1735         {
1736             TCGv saddr = tcg_temp_new();
1737             TCGv daddr = tcg_temp_new();
1738             TCGv four = tcg_constant_tl(4);
1739             TCGv_i32 tmp = tcg_temp_new_i32();
1740             int i;
1741 
1742             tcg_gen_andi_tl(saddr, src, -4);
1743             tcg_gen_andi_tl(daddr, addr, -4);
1744             for (i = 0; i < 32; i += 4) {
1745                 /* Since the loads and stores are paired, allow the
1746                    copy to happen in the host endianness.  */
1747                 tcg_gen_qemu_ld_i32(tmp, saddr, da->mem_idx, MO_UL);
1748                 tcg_gen_qemu_st_i32(tmp, daddr, da->mem_idx, MO_UL);
1749                 tcg_gen_add_tl(saddr, saddr, four);
1750                 tcg_gen_add_tl(daddr, daddr, four);
1751             }
1752         }
1753         break;
1754 
1755     default:
1756         {
1757             TCGv_i32 r_asi = tcg_constant_i32(da->asi);
1758             TCGv_i32 r_mop = tcg_constant_i32(da->memop | MO_ALIGN);
1759 
1760             save_state(dc);
1761 #ifdef TARGET_SPARC64
1762             gen_helper_st_asi(tcg_env, addr, src, r_asi, r_mop);
1763 #else
1764             {
1765                 TCGv_i64 t64 = tcg_temp_new_i64();
1766                 tcg_gen_extu_tl_i64(t64, src);
1767                 gen_helper_st_asi(tcg_env, addr, t64, r_asi, r_mop);
1768             }
1769 #endif
1770 
1771             /* A write to a TLB register may alter page maps.  End the TB. */
1772             dc->npc = DYNAMIC_PC;
1773         }
1774         break;
1775     }
1776 }
1777 
1778 static void gen_swap_asi(DisasContext *dc, DisasASI *da,
1779                          TCGv dst, TCGv src, TCGv addr)
1780 {
1781     switch (da->type) {
1782     case GET_ASI_EXCP:
1783         break;
1784     case GET_ASI_DIRECT:
1785         tcg_gen_atomic_xchg_tl(dst, addr, src,
1786                                da->mem_idx, da->memop | MO_ALIGN);
1787         break;
1788     default:
1789         /* ??? Should be DAE_invalid_asi.  */
1790         gen_exception(dc, TT_DATA_ACCESS);
1791         break;
1792     }
1793 }
1794 
1795 static void gen_cas_asi(DisasContext *dc, DisasASI *da,
1796                         TCGv oldv, TCGv newv, TCGv cmpv, TCGv addr)
1797 {
1798     switch (da->type) {
1799     case GET_ASI_EXCP:
1800         return;
1801     case GET_ASI_DIRECT:
1802         tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, newv,
1803                                   da->mem_idx, da->memop | MO_ALIGN);
1804         break;
1805     default:
1806         /* ??? Should be DAE_invalid_asi.  */
1807         gen_exception(dc, TT_DATA_ACCESS);
1808         break;
1809     }
1810 }
1811 
1812 static void gen_ldstub_asi(DisasContext *dc, DisasASI *da, TCGv dst, TCGv addr)
1813 {
1814     switch (da->type) {
1815     case GET_ASI_EXCP:
1816         break;
1817     case GET_ASI_DIRECT:
1818         tcg_gen_atomic_xchg_tl(dst, addr, tcg_constant_tl(0xff),
1819                                da->mem_idx, MO_UB);
1820         break;
1821     default:
1822         /* ??? In theory, this should be raise DAE_invalid_asi.
1823            But the SS-20 roms do ldstuba [%l0] #ASI_M_CTL, %o1.  */
1824         if (tb_cflags(dc->base.tb) & CF_PARALLEL) {
1825             gen_helper_exit_atomic(tcg_env);
1826         } else {
1827             TCGv_i32 r_asi = tcg_constant_i32(da->asi);
1828             TCGv_i32 r_mop = tcg_constant_i32(MO_UB);
1829             TCGv_i64 s64, t64;
1830 
1831             save_state(dc);
1832             t64 = tcg_temp_new_i64();
1833             gen_helper_ld_asi(t64, tcg_env, addr, r_asi, r_mop);
1834 
1835             s64 = tcg_constant_i64(0xff);
1836             gen_helper_st_asi(tcg_env, addr, s64, r_asi, r_mop);
1837 
1838             tcg_gen_trunc_i64_tl(dst, t64);
1839 
1840             /* End the TB.  */
1841             dc->npc = DYNAMIC_PC;
1842         }
1843         break;
1844     }
1845 }
1846 
1847 static void gen_ldf_asi(DisasContext *dc, DisasASI *da, MemOp orig_size,
1848                         TCGv addr, int rd)
1849 {
1850     MemOp memop = da->memop;
1851     MemOp size = memop & MO_SIZE;
1852     TCGv_i32 d32;
1853     TCGv_i64 d64;
1854     TCGv addr_tmp;
1855 
1856     /* TODO: Use 128-bit load/store below. */
1857     if (size == MO_128) {
1858         memop = (memop & ~MO_SIZE) | MO_64;
1859     }
1860 
1861     switch (da->type) {
1862     case GET_ASI_EXCP:
1863         break;
1864 
1865     case GET_ASI_DIRECT:
1866         memop |= MO_ALIGN_4;
1867         switch (size) {
1868         case MO_32:
1869             d32 = gen_dest_fpr_F(dc);
1870             tcg_gen_qemu_ld_i32(d32, addr, da->mem_idx, memop);
1871             gen_store_fpr_F(dc, rd, d32);
1872             break;
1873 
1874         case MO_64:
1875             tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da->mem_idx, memop);
1876             break;
1877 
1878         case MO_128:
1879             d64 = tcg_temp_new_i64();
1880             tcg_gen_qemu_ld_i64(d64, addr, da->mem_idx, memop);
1881             addr_tmp = tcg_temp_new();
1882             tcg_gen_addi_tl(addr_tmp, addr, 8);
1883             tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + 1], addr_tmp, da->mem_idx, memop);
1884             tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
1885             break;
1886         default:
1887             g_assert_not_reached();
1888         }
1889         break;
1890 
1891     case GET_ASI_BLOCK:
1892         /* Valid for lddfa on aligned registers only.  */
1893         if (orig_size == MO_64 && (rd & 7) == 0) {
1894             /* The first operation checks required alignment.  */
1895             addr_tmp = tcg_temp_new();
1896             for (int i = 0; ; ++i) {
1897                 tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr, da->mem_idx,
1898                                     memop | (i == 0 ? MO_ALIGN_64 : 0));
1899                 if (i == 7) {
1900                     break;
1901                 }
1902                 tcg_gen_addi_tl(addr_tmp, addr, 8);
1903                 addr = addr_tmp;
1904             }
1905         } else {
1906             gen_exception(dc, TT_ILL_INSN);
1907         }
1908         break;
1909 
1910     case GET_ASI_SHORT:
1911         /* Valid for lddfa only.  */
1912         if (orig_size == MO_64) {
1913             tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
1914                                 memop | MO_ALIGN);
1915         } else {
1916             gen_exception(dc, TT_ILL_INSN);
1917         }
1918         break;
1919 
1920     default:
1921         {
1922             TCGv_i32 r_asi = tcg_constant_i32(da->asi);
1923             TCGv_i32 r_mop = tcg_constant_i32(memop | MO_ALIGN);
1924 
1925             save_state(dc);
1926             /* According to the table in the UA2011 manual, the only
1927                other asis that are valid for ldfa/lddfa/ldqfa are
1928                the NO_FAULT asis.  We still need a helper for these,
1929                but we can just use the integer asi helper for them.  */
1930             switch (size) {
1931             case MO_32:
1932                 d64 = tcg_temp_new_i64();
1933                 gen_helper_ld_asi(d64, tcg_env, addr, r_asi, r_mop);
1934                 d32 = gen_dest_fpr_F(dc);
1935                 tcg_gen_extrl_i64_i32(d32, d64);
1936                 gen_store_fpr_F(dc, rd, d32);
1937                 break;
1938             case MO_64:
1939                 gen_helper_ld_asi(cpu_fpr[rd / 2], tcg_env, addr,
1940                                   r_asi, r_mop);
1941                 break;
1942             case MO_128:
1943                 d64 = tcg_temp_new_i64();
1944                 gen_helper_ld_asi(d64, tcg_env, addr, r_asi, r_mop);
1945                 addr_tmp = tcg_temp_new();
1946                 tcg_gen_addi_tl(addr_tmp, addr, 8);
1947                 gen_helper_ld_asi(cpu_fpr[rd / 2 + 1], tcg_env, addr_tmp,
1948                                   r_asi, r_mop);
1949                 tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
1950                 break;
1951             default:
1952                 g_assert_not_reached();
1953             }
1954         }
1955         break;
1956     }
1957 }
1958 
1959 static void gen_stf_asi(DisasContext *dc, DisasASI *da, MemOp orig_size,
1960                         TCGv addr, int rd)
1961 {
1962     MemOp memop = da->memop;
1963     MemOp size = memop & MO_SIZE;
1964     TCGv_i32 d32;
1965     TCGv addr_tmp;
1966 
1967     /* TODO: Use 128-bit load/store below. */
1968     if (size == MO_128) {
1969         memop = (memop & ~MO_SIZE) | MO_64;
1970     }
1971 
1972     switch (da->type) {
1973     case GET_ASI_EXCP:
1974         break;
1975 
1976     case GET_ASI_DIRECT:
1977         memop |= MO_ALIGN_4;
1978         switch (size) {
1979         case MO_32:
1980             d32 = gen_load_fpr_F(dc, rd);
1981             tcg_gen_qemu_st_i32(d32, addr, da->mem_idx, memop | MO_ALIGN);
1982             break;
1983         case MO_64:
1984             tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
1985                                 memop | MO_ALIGN_4);
1986             break;
1987         case MO_128:
1988             /* Only 4-byte alignment required.  However, it is legal for the
1989                cpu to signal the alignment fault, and the OS trap handler is
1990                required to fix it up.  Requiring 16-byte alignment here avoids
1991                having to probe the second page before performing the first
1992                write.  */
1993             tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
1994                                 memop | MO_ALIGN_16);
1995             addr_tmp = tcg_temp_new();
1996             tcg_gen_addi_tl(addr_tmp, addr, 8);
1997             tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + 1], addr_tmp, da->mem_idx, memop);
1998             break;
1999         default:
2000             g_assert_not_reached();
2001         }
2002         break;
2003 
2004     case GET_ASI_BLOCK:
2005         /* Valid for stdfa on aligned registers only.  */
2006         if (orig_size == MO_64 && (rd & 7) == 0) {
2007             /* The first operation checks required alignment.  */
2008             addr_tmp = tcg_temp_new();
2009             for (int i = 0; ; ++i) {
2010                 tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr, da->mem_idx,
2011                                     memop | (i == 0 ? MO_ALIGN_64 : 0));
2012                 if (i == 7) {
2013                     break;
2014                 }
2015                 tcg_gen_addi_tl(addr_tmp, addr, 8);
2016                 addr = addr_tmp;
2017             }
2018         } else {
2019             gen_exception(dc, TT_ILL_INSN);
2020         }
2021         break;
2022 
2023     case GET_ASI_SHORT:
2024         /* Valid for stdfa only.  */
2025         if (orig_size == MO_64) {
2026             tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da->mem_idx,
2027                                 memop | MO_ALIGN);
2028         } else {
2029             gen_exception(dc, TT_ILL_INSN);
2030         }
2031         break;
2032 
2033     default:
2034         /* According to the table in the UA2011 manual, the only
2035            other asis that are valid for ldfa/lddfa/ldqfa are
2036            the PST* asis, which aren't currently handled.  */
2037         gen_exception(dc, TT_ILL_INSN);
2038         break;
2039     }
2040 }
2041 
2042 static void gen_ldda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
2043 {
2044     TCGv hi = gen_dest_gpr(dc, rd);
2045     TCGv lo = gen_dest_gpr(dc, rd + 1);
2046 
2047     switch (da->type) {
2048     case GET_ASI_EXCP:
2049         return;
2050 
2051     case GET_ASI_DTWINX:
2052 #ifdef TARGET_SPARC64
2053         {
2054             MemOp mop = (da->memop & MO_BSWAP) | MO_128 | MO_ALIGN_16;
2055             TCGv_i128 t = tcg_temp_new_i128();
2056 
2057             tcg_gen_qemu_ld_i128(t, addr, da->mem_idx, mop);
2058             /*
2059              * Note that LE twinx acts as if each 64-bit register result is
2060              * byte swapped.  We perform one 128-bit LE load, so must swap
2061              * the order of the writebacks.
2062              */
2063             if ((mop & MO_BSWAP) == MO_TE) {
2064                 tcg_gen_extr_i128_i64(lo, hi, t);
2065             } else {
2066                 tcg_gen_extr_i128_i64(hi, lo, t);
2067             }
2068         }
2069         break;
2070 #else
2071         g_assert_not_reached();
2072 #endif
2073 
2074     case GET_ASI_DIRECT:
2075         {
2076             TCGv_i64 tmp = tcg_temp_new_i64();
2077 
2078             tcg_gen_qemu_ld_i64(tmp, addr, da->mem_idx, da->memop | MO_ALIGN);
2079 
2080             /* Note that LE ldda acts as if each 32-bit register
2081                result is byte swapped.  Having just performed one
2082                64-bit bswap, we need now to swap the writebacks.  */
2083             if ((da->memop & MO_BSWAP) == MO_TE) {
2084                 tcg_gen_extr_i64_tl(lo, hi, tmp);
2085             } else {
2086                 tcg_gen_extr_i64_tl(hi, lo, tmp);
2087             }
2088         }
2089         break;
2090 
2091     default:
2092         /* ??? In theory we've handled all of the ASIs that are valid
2093            for ldda, and this should raise DAE_invalid_asi.  However,
2094            real hardware allows others.  This can be seen with e.g.
2095            FreeBSD 10.3 wrt ASI_IC_TAG.  */
2096         {
2097             TCGv_i32 r_asi = tcg_constant_i32(da->asi);
2098             TCGv_i32 r_mop = tcg_constant_i32(da->memop);
2099             TCGv_i64 tmp = tcg_temp_new_i64();
2100 
2101             save_state(dc);
2102             gen_helper_ld_asi(tmp, tcg_env, addr, r_asi, r_mop);
2103 
2104             /* See above.  */
2105             if ((da->memop & MO_BSWAP) == MO_TE) {
2106                 tcg_gen_extr_i64_tl(lo, hi, tmp);
2107             } else {
2108                 tcg_gen_extr_i64_tl(hi, lo, tmp);
2109             }
2110         }
2111         break;
2112     }
2113 
2114     gen_store_gpr(dc, rd, hi);
2115     gen_store_gpr(dc, rd + 1, lo);
2116 }
2117 
2118 static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
2119 {
2120     TCGv hi = gen_load_gpr(dc, rd);
2121     TCGv lo = gen_load_gpr(dc, rd + 1);
2122 
2123     switch (da->type) {
2124     case GET_ASI_EXCP:
2125         break;
2126 
2127     case GET_ASI_DTWINX:
2128 #ifdef TARGET_SPARC64
2129         {
2130             MemOp mop = (da->memop & MO_BSWAP) | MO_128 | MO_ALIGN_16;
2131             TCGv_i128 t = tcg_temp_new_i128();
2132 
2133             /*
2134              * Note that LE twinx acts as if each 64-bit register result is
2135              * byte swapped.  We perform one 128-bit LE store, so must swap
2136              * the order of the construction.
2137              */
2138             if ((mop & MO_BSWAP) == MO_TE) {
2139                 tcg_gen_concat_i64_i128(t, lo, hi);
2140             } else {
2141                 tcg_gen_concat_i64_i128(t, hi, lo);
2142             }
2143             tcg_gen_qemu_st_i128(t, addr, da->mem_idx, mop);
2144         }
2145         break;
2146 #else
2147         g_assert_not_reached();
2148 #endif
2149 
2150     case GET_ASI_DIRECT:
2151         {
2152             TCGv_i64 t64 = tcg_temp_new_i64();
2153 
2154             /* Note that LE stda acts as if each 32-bit register result is
2155                byte swapped.  We will perform one 64-bit LE store, so now
2156                we must swap the order of the construction.  */
2157             if ((da->memop & MO_BSWAP) == MO_TE) {
2158                 tcg_gen_concat_tl_i64(t64, lo, hi);
2159             } else {
2160                 tcg_gen_concat_tl_i64(t64, hi, lo);
2161             }
2162             tcg_gen_qemu_st_i64(t64, addr, da->mem_idx, da->memop | MO_ALIGN);
2163         }
2164         break;
2165 
2166     case GET_ASI_BFILL:
2167         assert(TARGET_LONG_BITS == 32);
2168         /* Store 32 bytes of T64 to ADDR.  */
2169         /* ??? The original qemu code suggests 8-byte alignment, dropping
2170            the low bits, but the only place I can see this used is in the
2171            Linux kernel with 32 byte alignment, which would make more sense
2172            as a cacheline-style operation.  */
2173         {
2174             TCGv_i64 t64 = tcg_temp_new_i64();
2175             TCGv d_addr = tcg_temp_new();
2176             TCGv eight = tcg_constant_tl(8);
2177             int i;
2178 
2179             tcg_gen_concat_tl_i64(t64, lo, hi);
2180             tcg_gen_andi_tl(d_addr, addr, -8);
2181             for (i = 0; i < 32; i += 8) {
2182                 tcg_gen_qemu_st_i64(t64, d_addr, da->mem_idx, da->memop);
2183                 tcg_gen_add_tl(d_addr, d_addr, eight);
2184             }
2185         }
2186         break;
2187 
2188     default:
2189         /* ??? In theory we've handled all of the ASIs that are valid
2190            for stda, and this should raise DAE_invalid_asi.  */
2191         {
2192             TCGv_i32 r_asi = tcg_constant_i32(da->asi);
2193             TCGv_i32 r_mop = tcg_constant_i32(da->memop);
2194             TCGv_i64 t64 = tcg_temp_new_i64();
2195 
2196             /* See above.  */
2197             if ((da->memop & MO_BSWAP) == MO_TE) {
2198                 tcg_gen_concat_tl_i64(t64, lo, hi);
2199             } else {
2200                 tcg_gen_concat_tl_i64(t64, hi, lo);
2201             }
2202 
2203             save_state(dc);
2204             gen_helper_st_asi(tcg_env, addr, t64, r_asi, r_mop);
2205         }
2206         break;
2207     }
2208 }
2209 
2210 static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2211 {
2212 #ifdef TARGET_SPARC64
2213     TCGv_i32 c32, zero, dst, s1, s2;
2214     TCGv_i64 c64 = tcg_temp_new_i64();
2215 
2216     /* We have two choices here: extend the 32 bit data and use movcond_i64,
2217        or fold the comparison down to 32 bits and use movcond_i32.  Choose
2218        the later.  */
2219     c32 = tcg_temp_new_i32();
2220     tcg_gen_setcondi_i64(cmp->cond, c64, cmp->c1, cmp->c2);
2221     tcg_gen_extrl_i64_i32(c32, c64);
2222 
2223     s1 = gen_load_fpr_F(dc, rs);
2224     s2 = gen_load_fpr_F(dc, rd);
2225     dst = gen_dest_fpr_F(dc);
2226     zero = tcg_constant_i32(0);
2227 
2228     tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
2229 
2230     gen_store_fpr_F(dc, rd, dst);
2231 #else
2232     qemu_build_not_reached();
2233 #endif
2234 }
2235 
2236 static void gen_fmovd(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2237 {
2238 #ifdef TARGET_SPARC64
2239     TCGv_i64 dst = gen_dest_fpr_D(dc, rd);
2240     tcg_gen_movcond_i64(cmp->cond, dst, cmp->c1, tcg_constant_tl(cmp->c2),
2241                         gen_load_fpr_D(dc, rs),
2242                         gen_load_fpr_D(dc, rd));
2243     gen_store_fpr_D(dc, rd, dst);
2244 #else
2245     qemu_build_not_reached();
2246 #endif
2247 }
2248 
2249 static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
2250 {
2251 #ifdef TARGET_SPARC64
2252     int qd = QFPREG(rd);
2253     int qs = QFPREG(rs);
2254     TCGv c2 = tcg_constant_tl(cmp->c2);
2255 
2256     tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2], cmp->c1, c2,
2257                         cpu_fpr[qs / 2], cpu_fpr[qd / 2]);
2258     tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, c2,
2259                         cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
2260 
2261     gen_update_fprs_dirty(dc, qd);
2262 #else
2263     qemu_build_not_reached();
2264 #endif
2265 }
2266 
2267 #ifdef TARGET_SPARC64
2268 static void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr)
2269 {
2270     TCGv_i32 r_tl = tcg_temp_new_i32();
2271 
2272     /* load env->tl into r_tl */
2273     tcg_gen_ld_i32(r_tl, tcg_env, offsetof(CPUSPARCState, tl));
2274 
2275     /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
2276     tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
2277 
2278     /* calculate offset to current trap state from env->ts, reuse r_tl */
2279     tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
2280     tcg_gen_addi_ptr(r_tsptr, tcg_env, offsetof(CPUSPARCState, ts));
2281 
2282     /* tsptr = env->ts[env->tl & MAXTL_MASK] */
2283     {
2284         TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
2285         tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
2286         tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
2287     }
2288 }
2289 #endif
2290 
2291 static int extract_dfpreg(DisasContext *dc, int x)
2292 {
2293     return DFPREG(x);
2294 }
2295 
2296 static int extract_qfpreg(DisasContext *dc, int x)
2297 {
2298     return QFPREG(x);
2299 }
2300 
2301 /* Include the auto-generated decoder.  */
2302 #include "decode-insns.c.inc"
2303 
2304 #define TRANS(NAME, AVAIL, FUNC, ...) \
2305     static bool trans_##NAME(DisasContext *dc, arg_##NAME *a) \
2306     { return avail_##AVAIL(dc) && FUNC(dc, __VA_ARGS__); }
2307 
2308 #define avail_ALL(C)      true
2309 #ifdef TARGET_SPARC64
2310 # define avail_32(C)      false
2311 # define avail_ASR17(C)   false
2312 # define avail_CASA(C)    true
2313 # define avail_DIV(C)     true
2314 # define avail_MUL(C)     true
2315 # define avail_POWERDOWN(C) false
2316 # define avail_64(C)      true
2317 # define avail_GL(C)      ((C)->def->features & CPU_FEATURE_GL)
2318 # define avail_HYPV(C)    ((C)->def->features & CPU_FEATURE_HYPV)
2319 # define avail_VIS1(C)    ((C)->def->features & CPU_FEATURE_VIS1)
2320 # define avail_VIS2(C)    ((C)->def->features & CPU_FEATURE_VIS2)
2321 #else
2322 # define avail_32(C)      true
2323 # define avail_ASR17(C)   ((C)->def->features & CPU_FEATURE_ASR17)
2324 # define avail_CASA(C)    ((C)->def->features & CPU_FEATURE_CASA)
2325 # define avail_DIV(C)     ((C)->def->features & CPU_FEATURE_DIV)
2326 # define avail_MUL(C)     ((C)->def->features & CPU_FEATURE_MUL)
2327 # define avail_POWERDOWN(C) ((C)->def->features & CPU_FEATURE_POWERDOWN)
2328 # define avail_64(C)      false
2329 # define avail_GL(C)      false
2330 # define avail_HYPV(C)    false
2331 # define avail_VIS1(C)    false
2332 # define avail_VIS2(C)    false
2333 #endif
2334 
2335 /* Default case for non jump instructions. */
2336 static bool advance_pc(DisasContext *dc)
2337 {
2338     TCGLabel *l1;
2339 
2340     finishing_insn(dc);
2341 
2342     if (dc->npc & 3) {
2343         switch (dc->npc) {
2344         case DYNAMIC_PC:
2345         case DYNAMIC_PC_LOOKUP:
2346             dc->pc = dc->npc;
2347             tcg_gen_mov_tl(cpu_pc, cpu_npc);
2348             tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
2349             break;
2350 
2351         case JUMP_PC:
2352             /* we can do a static jump */
2353             l1 = gen_new_label();
2354             tcg_gen_brcondi_tl(dc->jump.cond, dc->jump.c1, dc->jump.c2, l1);
2355 
2356             /* jump not taken */
2357             gen_goto_tb(dc, 1, dc->jump_pc[1], dc->jump_pc[1] + 4);
2358 
2359             /* jump taken */
2360             gen_set_label(l1);
2361             gen_goto_tb(dc, 0, dc->jump_pc[0], dc->jump_pc[0] + 4);
2362 
2363             dc->base.is_jmp = DISAS_NORETURN;
2364             break;
2365 
2366         default:
2367             g_assert_not_reached();
2368         }
2369     } else {
2370         dc->pc = dc->npc;
2371         dc->npc = dc->npc + 4;
2372     }
2373     return true;
2374 }
2375 
2376 /*
2377  * Major opcodes 00 and 01 -- branches, call, and sethi
2378  */
2379 
2380 static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
2381                               bool annul, int disp)
2382 {
2383     target_ulong dest = address_mask_i(dc, dc->pc + disp * 4);
2384     target_ulong npc;
2385 
2386     finishing_insn(dc);
2387 
2388     if (cmp->cond == TCG_COND_ALWAYS) {
2389         if (annul) {
2390             dc->pc = dest;
2391             dc->npc = dest + 4;
2392         } else {
2393             gen_mov_pc_npc(dc);
2394             dc->npc = dest;
2395         }
2396         return true;
2397     }
2398 
2399     if (cmp->cond == TCG_COND_NEVER) {
2400         npc = dc->npc;
2401         if (npc & 3) {
2402             gen_mov_pc_npc(dc);
2403             if (annul) {
2404                 tcg_gen_addi_tl(cpu_pc, cpu_pc, 4);
2405             }
2406             tcg_gen_addi_tl(cpu_npc, cpu_pc, 4);
2407         } else {
2408             dc->pc = npc + (annul ? 4 : 0);
2409             dc->npc = dc->pc + 4;
2410         }
2411         return true;
2412     }
2413 
2414     flush_cond(dc);
2415     npc = dc->npc;
2416 
2417     if (annul) {
2418         TCGLabel *l1 = gen_new_label();
2419 
2420         tcg_gen_brcondi_tl(tcg_invert_cond(cmp->cond), cmp->c1, cmp->c2, l1);
2421         gen_goto_tb(dc, 0, npc, dest);
2422         gen_set_label(l1);
2423         gen_goto_tb(dc, 1, npc + 4, npc + 8);
2424 
2425         dc->base.is_jmp = DISAS_NORETURN;
2426     } else {
2427         if (npc & 3) {
2428             switch (npc) {
2429             case DYNAMIC_PC:
2430             case DYNAMIC_PC_LOOKUP:
2431                 tcg_gen_mov_tl(cpu_pc, cpu_npc);
2432                 tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
2433                 tcg_gen_movcond_tl(cmp->cond, cpu_npc,
2434                                    cmp->c1, tcg_constant_tl(cmp->c2),
2435                                    tcg_constant_tl(dest), cpu_npc);
2436                 dc->pc = npc;
2437                 break;
2438             default:
2439                 g_assert_not_reached();
2440             }
2441         } else {
2442             dc->pc = npc;
2443             dc->npc = JUMP_PC;
2444             dc->jump = *cmp;
2445             dc->jump_pc[0] = dest;
2446             dc->jump_pc[1] = npc + 4;
2447 
2448             /* The condition for cpu_cond is always NE -- normalize. */
2449             if (cmp->cond == TCG_COND_NE) {
2450                 tcg_gen_xori_tl(cpu_cond, cmp->c1, cmp->c2);
2451             } else {
2452                 tcg_gen_setcondi_tl(cmp->cond, cpu_cond, cmp->c1, cmp->c2);
2453             }
2454             dc->cpu_cond_live = true;
2455         }
2456     }
2457     return true;
2458 }
2459 
2460 static bool raise_priv(DisasContext *dc)
2461 {
2462     gen_exception(dc, TT_PRIV_INSN);
2463     return true;
2464 }
2465 
2466 static bool raise_unimpfpop(DisasContext *dc)
2467 {
2468     gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
2469     return true;
2470 }
2471 
2472 static bool gen_trap_float128(DisasContext *dc)
2473 {
2474     if (dc->def->features & CPU_FEATURE_FLOAT128) {
2475         return false;
2476     }
2477     return raise_unimpfpop(dc);
2478 }
2479 
2480 static bool do_bpcc(DisasContext *dc, arg_bcc *a)
2481 {
2482     DisasCompare cmp;
2483 
2484     gen_compare(&cmp, a->cc, a->cond, dc);
2485     return advance_jump_cond(dc, &cmp, a->a, a->i);
2486 }
2487 
2488 TRANS(Bicc, ALL, do_bpcc, a)
2489 TRANS(BPcc,  64, do_bpcc, a)
2490 
2491 static bool do_fbpfcc(DisasContext *dc, arg_bcc *a)
2492 {
2493     DisasCompare cmp;
2494 
2495     if (gen_trap_ifnofpu(dc)) {
2496         return true;
2497     }
2498     gen_fcompare(&cmp, a->cc, a->cond);
2499     return advance_jump_cond(dc, &cmp, a->a, a->i);
2500 }
2501 
2502 TRANS(FBPfcc,  64, do_fbpfcc, a)
2503 TRANS(FBfcc,  ALL, do_fbpfcc, a)
2504 
2505 static bool trans_BPr(DisasContext *dc, arg_BPr *a)
2506 {
2507     DisasCompare cmp;
2508 
2509     if (!avail_64(dc)) {
2510         return false;
2511     }
2512     if (!gen_compare_reg(&cmp, a->cond, gen_load_gpr(dc, a->rs1))) {
2513         return false;
2514     }
2515     return advance_jump_cond(dc, &cmp, a->a, a->i);
2516 }
2517 
2518 static bool trans_CALL(DisasContext *dc, arg_CALL *a)
2519 {
2520     target_long target = address_mask_i(dc, dc->pc + a->i * 4);
2521 
2522     gen_store_gpr(dc, 15, tcg_constant_tl(dc->pc));
2523     gen_mov_pc_npc(dc);
2524     dc->npc = target;
2525     return true;
2526 }
2527 
2528 static bool trans_NCP(DisasContext *dc, arg_NCP *a)
2529 {
2530     /*
2531      * For sparc32, always generate the no-coprocessor exception.
2532      * For sparc64, always generate illegal instruction.
2533      */
2534 #ifdef TARGET_SPARC64
2535     return false;
2536 #else
2537     gen_exception(dc, TT_NCP_INSN);
2538     return true;
2539 #endif
2540 }
2541 
2542 static bool trans_SETHI(DisasContext *dc, arg_SETHI *a)
2543 {
2544     /* Special-case %g0 because that's the canonical nop.  */
2545     if (a->rd) {
2546         gen_store_gpr(dc, a->rd, tcg_constant_tl((uint32_t)a->i << 10));
2547     }
2548     return advance_pc(dc);
2549 }
2550 
2551 /*
2552  * Major Opcode 10 -- integer, floating-point, vis, and system insns.
2553  */
2554 
2555 static bool do_tcc(DisasContext *dc, int cond, int cc,
2556                    int rs1, bool imm, int rs2_or_imm)
2557 {
2558     int mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc)
2559                 ? UA2005_HTRAP_MASK : V8_TRAP_MASK);
2560     DisasCompare cmp;
2561     TCGLabel *lab;
2562     TCGv_i32 trap;
2563 
2564     /* Trap never.  */
2565     if (cond == 0) {
2566         return advance_pc(dc);
2567     }
2568 
2569     /*
2570      * Immediate traps are the most common case.  Since this value is
2571      * live across the branch, it really pays to evaluate the constant.
2572      */
2573     if (rs1 == 0 && (imm || rs2_or_imm == 0)) {
2574         trap = tcg_constant_i32((rs2_or_imm & mask) + TT_TRAP);
2575     } else {
2576         trap = tcg_temp_new_i32();
2577         tcg_gen_trunc_tl_i32(trap, gen_load_gpr(dc, rs1));
2578         if (imm) {
2579             tcg_gen_addi_i32(trap, trap, rs2_or_imm);
2580         } else {
2581             TCGv_i32 t2 = tcg_temp_new_i32();
2582             tcg_gen_trunc_tl_i32(t2, gen_load_gpr(dc, rs2_or_imm));
2583             tcg_gen_add_i32(trap, trap, t2);
2584         }
2585         tcg_gen_andi_i32(trap, trap, mask);
2586         tcg_gen_addi_i32(trap, trap, TT_TRAP);
2587     }
2588 
2589     finishing_insn(dc);
2590 
2591     /* Trap always.  */
2592     if (cond == 8) {
2593         save_state(dc);
2594         gen_helper_raise_exception(tcg_env, trap);
2595         dc->base.is_jmp = DISAS_NORETURN;
2596         return true;
2597     }
2598 
2599     /* Conditional trap.  */
2600     flush_cond(dc);
2601     lab = delay_exceptionv(dc, trap);
2602     gen_compare(&cmp, cc, cond, dc);
2603     tcg_gen_brcondi_tl(cmp.cond, cmp.c1, cmp.c2, lab);
2604 
2605     return advance_pc(dc);
2606 }
2607 
2608 static bool trans_Tcc_r(DisasContext *dc, arg_Tcc_r *a)
2609 {
2610     if (avail_32(dc) && a->cc) {
2611         return false;
2612     }
2613     return do_tcc(dc, a->cond, a->cc, a->rs1, false, a->rs2);
2614 }
2615 
2616 static bool trans_Tcc_i_v7(DisasContext *dc, arg_Tcc_i_v7 *a)
2617 {
2618     if (avail_64(dc)) {
2619         return false;
2620     }
2621     return do_tcc(dc, a->cond, 0, a->rs1, true, a->i);
2622 }
2623 
2624 static bool trans_Tcc_i_v9(DisasContext *dc, arg_Tcc_i_v9 *a)
2625 {
2626     if (avail_32(dc)) {
2627         return false;
2628     }
2629     return do_tcc(dc, a->cond, a->cc, a->rs1, true, a->i);
2630 }
2631 
2632 static bool trans_STBAR(DisasContext *dc, arg_STBAR *a)
2633 {
2634     tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
2635     return advance_pc(dc);
2636 }
2637 
2638 static bool trans_MEMBAR(DisasContext *dc, arg_MEMBAR *a)
2639 {
2640     if (avail_32(dc)) {
2641         return false;
2642     }
2643     if (a->mmask) {
2644         /* Note TCG_MO_* was modeled on sparc64, so mmask matches. */
2645         tcg_gen_mb(a->mmask | TCG_BAR_SC);
2646     }
2647     if (a->cmask) {
2648         /* For #Sync, etc, end the TB to recognize interrupts. */
2649         dc->base.is_jmp = DISAS_EXIT;
2650     }
2651     return advance_pc(dc);
2652 }
2653 
2654 static bool do_rd_special(DisasContext *dc, bool priv, int rd,
2655                           TCGv (*func)(DisasContext *, TCGv))
2656 {
2657     if (!priv) {
2658         return raise_priv(dc);
2659     }
2660     gen_store_gpr(dc, rd, func(dc, gen_dest_gpr(dc, rd)));
2661     return advance_pc(dc);
2662 }
2663 
2664 static TCGv do_rdy(DisasContext *dc, TCGv dst)
2665 {
2666     return cpu_y;
2667 }
2668 
2669 static bool trans_RDY(DisasContext *dc, arg_RDY *a)
2670 {
2671     /*
2672      * TODO: Need a feature bit for sparcv8.  In the meantime, treat all
2673      * 32-bit cpus like sparcv7, which ignores the rs1 field.
2674      * This matches after all other ASR, so Leon3 Asr17 is handled first.
2675      */
2676     if (avail_64(dc) && a->rs1 != 0) {
2677         return false;
2678     }
2679     return do_rd_special(dc, true, a->rd, do_rdy);
2680 }
2681 
2682 static TCGv do_rd_leon3_config(DisasContext *dc, TCGv dst)
2683 {
2684     uint32_t val;
2685 
2686     /*
2687      * TODO: There are many more fields to be filled,
2688      * some of which are writable.
2689      */
2690     val = dc->def->nwindows - 1;   /* [4:0] NWIN */
2691     val |= 1 << 8;                 /* [8]   V8   */
2692 
2693     return tcg_constant_tl(val);
2694 }
2695 
2696 TRANS(RDASR17, ASR17, do_rd_special, true, a->rd, do_rd_leon3_config)
2697 
2698 static TCGv do_rdccr(DisasContext *dc, TCGv dst)
2699 {
2700     gen_helper_rdccr(dst, tcg_env);
2701     return dst;
2702 }
2703 
2704 TRANS(RDCCR, 64, do_rd_special, true, a->rd, do_rdccr)
2705 
2706 static TCGv do_rdasi(DisasContext *dc, TCGv dst)
2707 {
2708 #ifdef TARGET_SPARC64
2709     return tcg_constant_tl(dc->asi);
2710 #else
2711     qemu_build_not_reached();
2712 #endif
2713 }
2714 
2715 TRANS(RDASI, 64, do_rd_special, true, a->rd, do_rdasi)
2716 
2717 static TCGv do_rdtick(DisasContext *dc, TCGv dst)
2718 {
2719     TCGv_ptr r_tickptr = tcg_temp_new_ptr();
2720 
2721     tcg_gen_ld_ptr(r_tickptr, tcg_env, env64_field_offsetof(tick));
2722     if (translator_io_start(&dc->base)) {
2723         dc->base.is_jmp = DISAS_EXIT;
2724     }
2725     gen_helper_tick_get_count(dst, tcg_env, r_tickptr,
2726                               tcg_constant_i32(dc->mem_idx));
2727     return dst;
2728 }
2729 
2730 /* TODO: non-priv access only allowed when enabled. */
2731 TRANS(RDTICK, 64, do_rd_special, true, a->rd, do_rdtick)
2732 
2733 static TCGv do_rdpc(DisasContext *dc, TCGv dst)
2734 {
2735     return tcg_constant_tl(address_mask_i(dc, dc->pc));
2736 }
2737 
2738 TRANS(RDPC, 64, do_rd_special, true, a->rd, do_rdpc)
2739 
2740 static TCGv do_rdfprs(DisasContext *dc, TCGv dst)
2741 {
2742     tcg_gen_ext_i32_tl(dst, cpu_fprs);
2743     return dst;
2744 }
2745 
2746 TRANS(RDFPRS, 64, do_rd_special, true, a->rd, do_rdfprs)
2747 
2748 static TCGv do_rdgsr(DisasContext *dc, TCGv dst)
2749 {
2750     gen_trap_ifnofpu(dc);
2751     return cpu_gsr;
2752 }
2753 
2754 TRANS(RDGSR, 64, do_rd_special, true, a->rd, do_rdgsr)
2755 
2756 static TCGv do_rdsoftint(DisasContext *dc, TCGv dst)
2757 {
2758     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(softint));
2759     return dst;
2760 }
2761 
2762 TRANS(RDSOFTINT, 64, do_rd_special, supervisor(dc), a->rd, do_rdsoftint)
2763 
2764 static TCGv do_rdtick_cmpr(DisasContext *dc, TCGv dst)
2765 {
2766     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(tick_cmpr));
2767     return dst;
2768 }
2769 
2770 /* TODO: non-priv access only allowed when enabled. */
2771 TRANS(RDTICK_CMPR, 64, do_rd_special, true, a->rd, do_rdtick_cmpr)
2772 
2773 static TCGv do_rdstick(DisasContext *dc, TCGv dst)
2774 {
2775     TCGv_ptr r_tickptr = tcg_temp_new_ptr();
2776 
2777     tcg_gen_ld_ptr(r_tickptr, tcg_env, env64_field_offsetof(stick));
2778     if (translator_io_start(&dc->base)) {
2779         dc->base.is_jmp = DISAS_EXIT;
2780     }
2781     gen_helper_tick_get_count(dst, tcg_env, r_tickptr,
2782                               tcg_constant_i32(dc->mem_idx));
2783     return dst;
2784 }
2785 
2786 /* TODO: non-priv access only allowed when enabled. */
2787 TRANS(RDSTICK, 64, do_rd_special, true, a->rd, do_rdstick)
2788 
2789 static TCGv do_rdstick_cmpr(DisasContext *dc, TCGv dst)
2790 {
2791     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(stick_cmpr));
2792     return dst;
2793 }
2794 
2795 /* TODO: supervisor access only allowed when enabled by hypervisor. */
2796 TRANS(RDSTICK_CMPR, 64, do_rd_special, supervisor(dc), a->rd, do_rdstick_cmpr)
2797 
2798 /*
2799  * UltraSPARC-T1 Strand status.
2800  * HYPV check maybe not enough, UA2005 & UA2007 describe
2801  * this ASR as impl. dep
2802  */
2803 static TCGv do_rdstrand_status(DisasContext *dc, TCGv dst)
2804 {
2805     return tcg_constant_tl(1);
2806 }
2807 
2808 TRANS(RDSTRAND_STATUS, HYPV, do_rd_special, true, a->rd, do_rdstrand_status)
2809 
2810 static TCGv do_rdpsr(DisasContext *dc, TCGv dst)
2811 {
2812     gen_helper_rdpsr(dst, tcg_env);
2813     return dst;
2814 }
2815 
2816 TRANS(RDPSR, 32, do_rd_special, supervisor(dc), a->rd, do_rdpsr)
2817 
2818 static TCGv do_rdhpstate(DisasContext *dc, TCGv dst)
2819 {
2820     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(hpstate));
2821     return dst;
2822 }
2823 
2824 TRANS(RDHPR_hpstate, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhpstate)
2825 
2826 static TCGv do_rdhtstate(DisasContext *dc, TCGv dst)
2827 {
2828     TCGv_i32 tl = tcg_temp_new_i32();
2829     TCGv_ptr tp = tcg_temp_new_ptr();
2830 
2831     tcg_gen_ld_i32(tl, tcg_env, env64_field_offsetof(tl));
2832     tcg_gen_andi_i32(tl, tl, MAXTL_MASK);
2833     tcg_gen_shli_i32(tl, tl, 3);
2834     tcg_gen_ext_i32_ptr(tp, tl);
2835     tcg_gen_add_ptr(tp, tp, tcg_env);
2836 
2837     tcg_gen_ld_tl(dst, tp, env64_field_offsetof(htstate));
2838     return dst;
2839 }
2840 
2841 TRANS(RDHPR_htstate, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhtstate)
2842 
2843 static TCGv do_rdhintp(DisasContext *dc, TCGv dst)
2844 {
2845     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(hintp));
2846     return dst;
2847 }
2848 
2849 TRANS(RDHPR_hintp, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhintp)
2850 
2851 static TCGv do_rdhtba(DisasContext *dc, TCGv dst)
2852 {
2853     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(htba));
2854     return dst;
2855 }
2856 
2857 TRANS(RDHPR_htba, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhtba)
2858 
2859 static TCGv do_rdhver(DisasContext *dc, TCGv dst)
2860 {
2861     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(hver));
2862     return dst;
2863 }
2864 
2865 TRANS(RDHPR_hver, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhver)
2866 
2867 static TCGv do_rdhstick_cmpr(DisasContext *dc, TCGv dst)
2868 {
2869     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(hstick_cmpr));
2870     return dst;
2871 }
2872 
2873 TRANS(RDHPR_hstick_cmpr, HYPV, do_rd_special, hypervisor(dc), a->rd,
2874       do_rdhstick_cmpr)
2875 
2876 static TCGv do_rdwim(DisasContext *dc, TCGv dst)
2877 {
2878     tcg_gen_ld_tl(dst, tcg_env, env32_field_offsetof(wim));
2879     return dst;
2880 }
2881 
2882 TRANS(RDWIM, 32, do_rd_special, supervisor(dc), a->rd, do_rdwim)
2883 
2884 static TCGv do_rdtpc(DisasContext *dc, TCGv dst)
2885 {
2886 #ifdef TARGET_SPARC64
2887     TCGv_ptr r_tsptr = tcg_temp_new_ptr();
2888 
2889     gen_load_trap_state_at_tl(r_tsptr);
2890     tcg_gen_ld_tl(dst, r_tsptr, offsetof(trap_state, tpc));
2891     return dst;
2892 #else
2893     qemu_build_not_reached();
2894 #endif
2895 }
2896 
2897 TRANS(RDPR_tpc, 64, do_rd_special, supervisor(dc), a->rd, do_rdtpc)
2898 
2899 static TCGv do_rdtnpc(DisasContext *dc, TCGv dst)
2900 {
2901 #ifdef TARGET_SPARC64
2902     TCGv_ptr r_tsptr = tcg_temp_new_ptr();
2903 
2904     gen_load_trap_state_at_tl(r_tsptr);
2905     tcg_gen_ld_tl(dst, r_tsptr, offsetof(trap_state, tnpc));
2906     return dst;
2907 #else
2908     qemu_build_not_reached();
2909 #endif
2910 }
2911 
2912 TRANS(RDPR_tnpc, 64, do_rd_special, supervisor(dc), a->rd, do_rdtnpc)
2913 
2914 static TCGv do_rdtstate(DisasContext *dc, TCGv dst)
2915 {
2916 #ifdef TARGET_SPARC64
2917     TCGv_ptr r_tsptr = tcg_temp_new_ptr();
2918 
2919     gen_load_trap_state_at_tl(r_tsptr);
2920     tcg_gen_ld_tl(dst, r_tsptr, offsetof(trap_state, tstate));
2921     return dst;
2922 #else
2923     qemu_build_not_reached();
2924 #endif
2925 }
2926 
2927 TRANS(RDPR_tstate, 64, do_rd_special, supervisor(dc), a->rd, do_rdtstate)
2928 
2929 static TCGv do_rdtt(DisasContext *dc, TCGv dst)
2930 {
2931 #ifdef TARGET_SPARC64
2932     TCGv_ptr r_tsptr = tcg_temp_new_ptr();
2933 
2934     gen_load_trap_state_at_tl(r_tsptr);
2935     tcg_gen_ld32s_tl(dst, r_tsptr, offsetof(trap_state, tt));
2936     return dst;
2937 #else
2938     qemu_build_not_reached();
2939 #endif
2940 }
2941 
2942 TRANS(RDPR_tt, 64, do_rd_special, supervisor(dc), a->rd, do_rdtt)
2943 TRANS(RDPR_tick, 64, do_rd_special, supervisor(dc), a->rd, do_rdtick)
2944 
2945 static TCGv do_rdtba(DisasContext *dc, TCGv dst)
2946 {
2947     return cpu_tbr;
2948 }
2949 
2950 TRANS(RDTBR, 32, do_rd_special, supervisor(dc), a->rd, do_rdtba)
2951 TRANS(RDPR_tba, 64, do_rd_special, supervisor(dc), a->rd, do_rdtba)
2952 
2953 static TCGv do_rdpstate(DisasContext *dc, TCGv dst)
2954 {
2955     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(pstate));
2956     return dst;
2957 }
2958 
2959 TRANS(RDPR_pstate, 64, do_rd_special, supervisor(dc), a->rd, do_rdpstate)
2960 
2961 static TCGv do_rdtl(DisasContext *dc, TCGv dst)
2962 {
2963     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(tl));
2964     return dst;
2965 }
2966 
2967 TRANS(RDPR_tl, 64, do_rd_special, supervisor(dc), a->rd, do_rdtl)
2968 
2969 static TCGv do_rdpil(DisasContext *dc, TCGv dst)
2970 {
2971     tcg_gen_ld32s_tl(dst, tcg_env, env_field_offsetof(psrpil));
2972     return dst;
2973 }
2974 
2975 TRANS(RDPR_pil, 64, do_rd_special, supervisor(dc), a->rd, do_rdpil)
2976 
2977 static TCGv do_rdcwp(DisasContext *dc, TCGv dst)
2978 {
2979     gen_helper_rdcwp(dst, tcg_env);
2980     return dst;
2981 }
2982 
2983 TRANS(RDPR_cwp, 64, do_rd_special, supervisor(dc), a->rd, do_rdcwp)
2984 
2985 static TCGv do_rdcansave(DisasContext *dc, TCGv dst)
2986 {
2987     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(cansave));
2988     return dst;
2989 }
2990 
2991 TRANS(RDPR_cansave, 64, do_rd_special, supervisor(dc), a->rd, do_rdcansave)
2992 
2993 static TCGv do_rdcanrestore(DisasContext *dc, TCGv dst)
2994 {
2995     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(canrestore));
2996     return dst;
2997 }
2998 
2999 TRANS(RDPR_canrestore, 64, do_rd_special, supervisor(dc), a->rd,
3000       do_rdcanrestore)
3001 
3002 static TCGv do_rdcleanwin(DisasContext *dc, TCGv dst)
3003 {
3004     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(cleanwin));
3005     return dst;
3006 }
3007 
3008 TRANS(RDPR_cleanwin, 64, do_rd_special, supervisor(dc), a->rd, do_rdcleanwin)
3009 
3010 static TCGv do_rdotherwin(DisasContext *dc, TCGv dst)
3011 {
3012     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(otherwin));
3013     return dst;
3014 }
3015 
3016 TRANS(RDPR_otherwin, 64, do_rd_special, supervisor(dc), a->rd, do_rdotherwin)
3017 
3018 static TCGv do_rdwstate(DisasContext *dc, TCGv dst)
3019 {
3020     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(wstate));
3021     return dst;
3022 }
3023 
3024 TRANS(RDPR_wstate, 64, do_rd_special, supervisor(dc), a->rd, do_rdwstate)
3025 
3026 static TCGv do_rdgl(DisasContext *dc, TCGv dst)
3027 {
3028     tcg_gen_ld32s_tl(dst, tcg_env, env64_field_offsetof(gl));
3029     return dst;
3030 }
3031 
3032 TRANS(RDPR_gl, GL, do_rd_special, supervisor(dc), a->rd, do_rdgl)
3033 
3034 /* UA2005 strand status */
3035 static TCGv do_rdssr(DisasContext *dc, TCGv dst)
3036 {
3037     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(ssr));
3038     return dst;
3039 }
3040 
3041 TRANS(RDPR_strand_status, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdssr)
3042 
3043 static TCGv do_rdver(DisasContext *dc, TCGv dst)
3044 {
3045     tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(version));
3046     return dst;
3047 }
3048 
3049 TRANS(RDPR_ver, 64, do_rd_special, supervisor(dc), a->rd, do_rdver)
3050 
3051 static bool trans_FLUSHW(DisasContext *dc, arg_FLUSHW *a)
3052 {
3053     if (avail_64(dc)) {
3054         gen_helper_flushw(tcg_env);
3055         return advance_pc(dc);
3056     }
3057     return false;
3058 }
3059 
3060 static bool do_wr_special(DisasContext *dc, arg_r_r_ri *a, bool priv,
3061                           void (*func)(DisasContext *, TCGv))
3062 {
3063     TCGv src;
3064 
3065     /* For simplicity, we under-decoded the rs2 form. */
3066     if (!a->imm && (a->rs2_or_imm & ~0x1f)) {
3067         return false;
3068     }
3069     if (!priv) {
3070         return raise_priv(dc);
3071     }
3072 
3073     if (a->rs1 == 0 && (a->imm || a->rs2_or_imm == 0)) {
3074         src = tcg_constant_tl(a->rs2_or_imm);
3075     } else {
3076         TCGv src1 = gen_load_gpr(dc, a->rs1);
3077         if (a->rs2_or_imm == 0) {
3078             src = src1;
3079         } else {
3080             src = tcg_temp_new();
3081             if (a->imm) {
3082                 tcg_gen_xori_tl(src, src1, a->rs2_or_imm);
3083             } else {
3084                 tcg_gen_xor_tl(src, src1, gen_load_gpr(dc, a->rs2_or_imm));
3085             }
3086         }
3087     }
3088     func(dc, src);
3089     return advance_pc(dc);
3090 }
3091 
3092 static void do_wry(DisasContext *dc, TCGv src)
3093 {
3094     tcg_gen_ext32u_tl(cpu_y, src);
3095 }
3096 
3097 TRANS(WRY, ALL, do_wr_special, a, true, do_wry)
3098 
3099 static void do_wrccr(DisasContext *dc, TCGv src)
3100 {
3101     gen_helper_wrccr(tcg_env, src);
3102 }
3103 
3104 TRANS(WRCCR, 64, do_wr_special, a, true, do_wrccr)
3105 
3106 static void do_wrasi(DisasContext *dc, TCGv src)
3107 {
3108     TCGv tmp = tcg_temp_new();
3109 
3110     tcg_gen_ext8u_tl(tmp, src);
3111     tcg_gen_st32_tl(tmp, tcg_env, env64_field_offsetof(asi));
3112     /* End TB to notice changed ASI. */
3113     dc->base.is_jmp = DISAS_EXIT;
3114 }
3115 
3116 TRANS(WRASI, 64, do_wr_special, a, true, do_wrasi)
3117 
3118 static void do_wrfprs(DisasContext *dc, TCGv src)
3119 {
3120 #ifdef TARGET_SPARC64
3121     tcg_gen_trunc_tl_i32(cpu_fprs, src);
3122     dc->fprs_dirty = 0;
3123     dc->base.is_jmp = DISAS_EXIT;
3124 #else
3125     qemu_build_not_reached();
3126 #endif
3127 }
3128 
3129 TRANS(WRFPRS, 64, do_wr_special, a, true, do_wrfprs)
3130 
3131 static void do_wrgsr(DisasContext *dc, TCGv src)
3132 {
3133     gen_trap_ifnofpu(dc);
3134     tcg_gen_mov_tl(cpu_gsr, src);
3135 }
3136 
3137 TRANS(WRGSR, 64, do_wr_special, a, true, do_wrgsr)
3138 
3139 static void do_wrsoftint_set(DisasContext *dc, TCGv src)
3140 {
3141     gen_helper_set_softint(tcg_env, src);
3142 }
3143 
3144 TRANS(WRSOFTINT_SET, 64, do_wr_special, a, supervisor(dc), do_wrsoftint_set)
3145 
3146 static void do_wrsoftint_clr(DisasContext *dc, TCGv src)
3147 {
3148     gen_helper_clear_softint(tcg_env, src);
3149 }
3150 
3151 TRANS(WRSOFTINT_CLR, 64, do_wr_special, a, supervisor(dc), do_wrsoftint_clr)
3152 
3153 static void do_wrsoftint(DisasContext *dc, TCGv src)
3154 {
3155     gen_helper_write_softint(tcg_env, src);
3156 }
3157 
3158 TRANS(WRSOFTINT, 64, do_wr_special, a, supervisor(dc), do_wrsoftint)
3159 
3160 static void do_wrtick_cmpr(DisasContext *dc, TCGv src)
3161 {
3162     TCGv_ptr r_tickptr = tcg_temp_new_ptr();
3163 
3164     tcg_gen_st_tl(src, tcg_env, env64_field_offsetof(tick_cmpr));
3165     tcg_gen_ld_ptr(r_tickptr, tcg_env, env64_field_offsetof(tick));
3166     translator_io_start(&dc->base);
3167     gen_helper_tick_set_limit(r_tickptr, src);
3168     /* End TB to handle timer interrupt */
3169     dc->base.is_jmp = DISAS_EXIT;
3170 }
3171 
3172 TRANS(WRTICK_CMPR, 64, do_wr_special, a, supervisor(dc), do_wrtick_cmpr)
3173 
3174 static void do_wrstick(DisasContext *dc, TCGv src)
3175 {
3176 #ifdef TARGET_SPARC64
3177     TCGv_ptr r_tickptr = tcg_temp_new_ptr();
3178 
3179     tcg_gen_ld_ptr(r_tickptr, tcg_env, offsetof(CPUSPARCState, stick));
3180     translator_io_start(&dc->base);
3181     gen_helper_tick_set_count(r_tickptr, src);
3182     /* End TB to handle timer interrupt */
3183     dc->base.is_jmp = DISAS_EXIT;
3184 #else
3185     qemu_build_not_reached();
3186 #endif
3187 }
3188 
3189 TRANS(WRSTICK, 64, do_wr_special, a, supervisor(dc), do_wrstick)
3190 
3191 static void do_wrstick_cmpr(DisasContext *dc, TCGv src)
3192 {
3193     TCGv_ptr r_tickptr = tcg_temp_new_ptr();
3194 
3195     tcg_gen_st_tl(src, tcg_env, env64_field_offsetof(stick_cmpr));
3196     tcg_gen_ld_ptr(r_tickptr, tcg_env, env64_field_offsetof(stick));
3197     translator_io_start(&dc->base);
3198     gen_helper_tick_set_limit(r_tickptr, src);
3199     /* End TB to handle timer interrupt */
3200     dc->base.is_jmp = DISAS_EXIT;
3201 }
3202 
3203 TRANS(WRSTICK_CMPR, 64, do_wr_special, a, supervisor(dc), do_wrstick_cmpr)
3204 
3205 static void do_wrpowerdown(DisasContext *dc, TCGv src)
3206 {
3207     finishing_insn(dc);
3208     save_state(dc);
3209     gen_helper_power_down(tcg_env);
3210 }
3211 
3212 TRANS(WRPOWERDOWN, POWERDOWN, do_wr_special, a, supervisor(dc), do_wrpowerdown)
3213 
3214 static void do_wrpsr(DisasContext *dc, TCGv src)
3215 {
3216     gen_helper_wrpsr(tcg_env, src);
3217     dc->base.is_jmp = DISAS_EXIT;
3218 }
3219 
3220 TRANS(WRPSR, 32, do_wr_special, a, supervisor(dc), do_wrpsr)
3221 
3222 static void do_wrwim(DisasContext *dc, TCGv src)
3223 {
3224     target_ulong mask = MAKE_64BIT_MASK(0, dc->def->nwindows);
3225     TCGv tmp = tcg_temp_new();
3226 
3227     tcg_gen_andi_tl(tmp, src, mask);
3228     tcg_gen_st_tl(tmp, tcg_env, env32_field_offsetof(wim));
3229 }
3230 
3231 TRANS(WRWIM, 32, do_wr_special, a, supervisor(dc), do_wrwim)
3232 
3233 static void do_wrtpc(DisasContext *dc, TCGv src)
3234 {
3235 #ifdef TARGET_SPARC64
3236     TCGv_ptr r_tsptr = tcg_temp_new_ptr();
3237 
3238     gen_load_trap_state_at_tl(r_tsptr);
3239     tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tpc));
3240 #else
3241     qemu_build_not_reached();
3242 #endif
3243 }
3244 
3245 TRANS(WRPR_tpc, 64, do_wr_special, a, supervisor(dc), do_wrtpc)
3246 
3247 static void do_wrtnpc(DisasContext *dc, TCGv src)
3248 {
3249 #ifdef TARGET_SPARC64
3250     TCGv_ptr r_tsptr = tcg_temp_new_ptr();
3251 
3252     gen_load_trap_state_at_tl(r_tsptr);
3253     tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tnpc));
3254 #else
3255     qemu_build_not_reached();
3256 #endif
3257 }
3258 
3259 TRANS(WRPR_tnpc, 64, do_wr_special, a, supervisor(dc), do_wrtnpc)
3260 
3261 static void do_wrtstate(DisasContext *dc, TCGv src)
3262 {
3263 #ifdef TARGET_SPARC64
3264     TCGv_ptr r_tsptr = tcg_temp_new_ptr();
3265 
3266     gen_load_trap_state_at_tl(r_tsptr);
3267     tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tstate));
3268 #else
3269     qemu_build_not_reached();
3270 #endif
3271 }
3272 
3273 TRANS(WRPR_tstate, 64, do_wr_special, a, supervisor(dc), do_wrtstate)
3274 
3275 static void do_wrtt(DisasContext *dc, TCGv src)
3276 {
3277 #ifdef TARGET_SPARC64
3278     TCGv_ptr r_tsptr = tcg_temp_new_ptr();
3279 
3280     gen_load_trap_state_at_tl(r_tsptr);
3281     tcg_gen_st32_tl(src, r_tsptr, offsetof(trap_state, tt));
3282 #else
3283     qemu_build_not_reached();
3284 #endif
3285 }
3286 
3287 TRANS(WRPR_tt, 64, do_wr_special, a, supervisor(dc), do_wrtt)
3288 
3289 static void do_wrtick(DisasContext *dc, TCGv src)
3290 {
3291     TCGv_ptr r_tickptr = tcg_temp_new_ptr();
3292 
3293     tcg_gen_ld_ptr(r_tickptr, tcg_env, env64_field_offsetof(tick));
3294     translator_io_start(&dc->base);
3295     gen_helper_tick_set_count(r_tickptr, src);
3296     /* End TB to handle timer interrupt */
3297     dc->base.is_jmp = DISAS_EXIT;
3298 }
3299 
3300 TRANS(WRPR_tick, 64, do_wr_special, a, supervisor(dc), do_wrtick)
3301 
3302 static void do_wrtba(DisasContext *dc, TCGv src)
3303 {
3304     tcg_gen_mov_tl(cpu_tbr, src);
3305 }
3306 
3307 TRANS(WRPR_tba, 64, do_wr_special, a, supervisor(dc), do_wrtba)
3308 
3309 static void do_wrpstate(DisasContext *dc, TCGv src)
3310 {
3311     save_state(dc);
3312     if (translator_io_start(&dc->base)) {
3313         dc->base.is_jmp = DISAS_EXIT;
3314     }
3315     gen_helper_wrpstate(tcg_env, src);
3316     dc->npc = DYNAMIC_PC;
3317 }
3318 
3319 TRANS(WRPR_pstate, 64, do_wr_special, a, supervisor(dc), do_wrpstate)
3320 
3321 static void do_wrtl(DisasContext *dc, TCGv src)
3322 {
3323     save_state(dc);
3324     tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(tl));
3325     dc->npc = DYNAMIC_PC;
3326 }
3327 
3328 TRANS(WRPR_tl, 64, do_wr_special, a, supervisor(dc), do_wrtl)
3329 
3330 static void do_wrpil(DisasContext *dc, TCGv src)
3331 {
3332     if (translator_io_start(&dc->base)) {
3333         dc->base.is_jmp = DISAS_EXIT;
3334     }
3335     gen_helper_wrpil(tcg_env, src);
3336 }
3337 
3338 TRANS(WRPR_pil, 64, do_wr_special, a, supervisor(dc), do_wrpil)
3339 
3340 static void do_wrcwp(DisasContext *dc, TCGv src)
3341 {
3342     gen_helper_wrcwp(tcg_env, src);
3343 }
3344 
3345 TRANS(WRPR_cwp, 64, do_wr_special, a, supervisor(dc), do_wrcwp)
3346 
3347 static void do_wrcansave(DisasContext *dc, TCGv src)
3348 {
3349     tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(cansave));
3350 }
3351 
3352 TRANS(WRPR_cansave, 64, do_wr_special, a, supervisor(dc), do_wrcansave)
3353 
3354 static void do_wrcanrestore(DisasContext *dc, TCGv src)
3355 {
3356     tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(canrestore));
3357 }
3358 
3359 TRANS(WRPR_canrestore, 64, do_wr_special, a, supervisor(dc), do_wrcanrestore)
3360 
3361 static void do_wrcleanwin(DisasContext *dc, TCGv src)
3362 {
3363     tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(cleanwin));
3364 }
3365 
3366 TRANS(WRPR_cleanwin, 64, do_wr_special, a, supervisor(dc), do_wrcleanwin)
3367 
3368 static void do_wrotherwin(DisasContext *dc, TCGv src)
3369 {
3370     tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(otherwin));
3371 }
3372 
3373 TRANS(WRPR_otherwin, 64, do_wr_special, a, supervisor(dc), do_wrotherwin)
3374 
3375 static void do_wrwstate(DisasContext *dc, TCGv src)
3376 {
3377     tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(wstate));
3378 }
3379 
3380 TRANS(WRPR_wstate, 64, do_wr_special, a, supervisor(dc), do_wrwstate)
3381 
3382 static void do_wrgl(DisasContext *dc, TCGv src)
3383 {
3384     gen_helper_wrgl(tcg_env, src);
3385 }
3386 
3387 TRANS(WRPR_gl, GL, do_wr_special, a, supervisor(dc), do_wrgl)
3388 
3389 /* UA2005 strand status */
3390 static void do_wrssr(DisasContext *dc, TCGv src)
3391 {
3392     tcg_gen_st_tl(src, tcg_env, env64_field_offsetof(ssr));
3393 }
3394 
3395 TRANS(WRPR_strand_status, HYPV, do_wr_special, a, hypervisor(dc), do_wrssr)
3396 
3397 TRANS(WRTBR, 32, do_wr_special, a, supervisor(dc), do_wrtba)
3398 
3399 static void do_wrhpstate(DisasContext *dc, TCGv src)
3400 {
3401     tcg_gen_st_tl(src, tcg_env, env64_field_offsetof(hpstate));
3402     dc->base.is_jmp = DISAS_EXIT;
3403 }
3404 
3405 TRANS(WRHPR_hpstate, HYPV, do_wr_special, a, hypervisor(dc), do_wrhpstate)
3406 
3407 static void do_wrhtstate(DisasContext *dc, TCGv src)
3408 {
3409     TCGv_i32 tl = tcg_temp_new_i32();
3410     TCGv_ptr tp = tcg_temp_new_ptr();
3411 
3412     tcg_gen_ld_i32(tl, tcg_env, env64_field_offsetof(tl));
3413     tcg_gen_andi_i32(tl, tl, MAXTL_MASK);
3414     tcg_gen_shli_i32(tl, tl, 3);
3415     tcg_gen_ext_i32_ptr(tp, tl);
3416     tcg_gen_add_ptr(tp, tp, tcg_env);
3417 
3418     tcg_gen_st_tl(src, tp, env64_field_offsetof(htstate));
3419 }
3420 
3421 TRANS(WRHPR_htstate, HYPV, do_wr_special, a, hypervisor(dc), do_wrhtstate)
3422 
3423 static void do_wrhintp(DisasContext *dc, TCGv src)
3424 {
3425     tcg_gen_st_tl(src, tcg_env, env64_field_offsetof(hintp));
3426 }
3427 
3428 TRANS(WRHPR_hintp, HYPV, do_wr_special, a, hypervisor(dc), do_wrhintp)
3429 
3430 static void do_wrhtba(DisasContext *dc, TCGv src)
3431 {
3432     tcg_gen_st_tl(src, tcg_env, env64_field_offsetof(htba));
3433 }
3434 
3435 TRANS(WRHPR_htba, HYPV, do_wr_special, a, hypervisor(dc), do_wrhtba)
3436 
3437 static void do_wrhstick_cmpr(DisasContext *dc, TCGv src)
3438 {
3439     TCGv_ptr r_tickptr = tcg_temp_new_ptr();
3440 
3441     tcg_gen_st_tl(src, tcg_env, env64_field_offsetof(hstick_cmpr));
3442     tcg_gen_ld_ptr(r_tickptr, tcg_env, env64_field_offsetof(hstick));
3443     translator_io_start(&dc->base);
3444     gen_helper_tick_set_limit(r_tickptr, src);
3445     /* End TB to handle timer interrupt */
3446     dc->base.is_jmp = DISAS_EXIT;
3447 }
3448 
3449 TRANS(WRHPR_hstick_cmpr, HYPV, do_wr_special, a, hypervisor(dc),
3450       do_wrhstick_cmpr)
3451 
3452 static bool do_saved_restored(DisasContext *dc, bool saved)
3453 {
3454     if (!supervisor(dc)) {
3455         return raise_priv(dc);
3456     }
3457     if (saved) {
3458         gen_helper_saved(tcg_env);
3459     } else {
3460         gen_helper_restored(tcg_env);
3461     }
3462     return advance_pc(dc);
3463 }
3464 
3465 TRANS(SAVED, 64, do_saved_restored, true)
3466 TRANS(RESTORED, 64, do_saved_restored, false)
3467 
3468 static bool trans_NOP(DisasContext *dc, arg_NOP *a)
3469 {
3470     return advance_pc(dc);
3471 }
3472 
3473 /*
3474  * TODO: Need a feature bit for sparcv8.
3475  * In the meantime, treat all 32-bit cpus like sparcv7.
3476  */
3477 TRANS(NOP_v7, 32, trans_NOP, a)
3478 TRANS(NOP_v9, 64, trans_NOP, a)
3479 
3480 static bool do_arith_int(DisasContext *dc, arg_r_r_ri_cc *a,
3481                          void (*func)(TCGv, TCGv, TCGv),
3482                          void (*funci)(TCGv, TCGv, target_long),
3483                          bool logic_cc)
3484 {
3485     TCGv dst, src1;
3486 
3487     /* For simplicity, we under-decoded the rs2 form. */
3488     if (!a->imm && a->rs2_or_imm & ~0x1f) {
3489         return false;
3490     }
3491 
3492     if (logic_cc) {
3493         dst = cpu_cc_N;
3494     } else {
3495         dst = gen_dest_gpr(dc, a->rd);
3496     }
3497     src1 = gen_load_gpr(dc, a->rs1);
3498 
3499     if (a->imm || a->rs2_or_imm == 0) {
3500         if (funci) {
3501             funci(dst, src1, a->rs2_or_imm);
3502         } else {
3503             func(dst, src1, tcg_constant_tl(a->rs2_or_imm));
3504         }
3505     } else {
3506         func(dst, src1, cpu_regs[a->rs2_or_imm]);
3507     }
3508 
3509     if (logic_cc) {
3510         if (TARGET_LONG_BITS == 64) {
3511             tcg_gen_mov_tl(cpu_icc_Z, cpu_cc_N);
3512             tcg_gen_movi_tl(cpu_icc_C, 0);
3513         }
3514         tcg_gen_mov_tl(cpu_cc_Z, cpu_cc_N);
3515         tcg_gen_movi_tl(cpu_cc_C, 0);
3516         tcg_gen_movi_tl(cpu_cc_V, 0);
3517     }
3518 
3519     gen_store_gpr(dc, a->rd, dst);
3520     return advance_pc(dc);
3521 }
3522 
3523 static bool do_arith(DisasContext *dc, arg_r_r_ri_cc *a,
3524                      void (*func)(TCGv, TCGv, TCGv),
3525                      void (*funci)(TCGv, TCGv, target_long),
3526                      void (*func_cc)(TCGv, TCGv, TCGv))
3527 {
3528     if (a->cc) {
3529         return do_arith_int(dc, a, func_cc, NULL, false);
3530     }
3531     return do_arith_int(dc, a, func, funci, false);
3532 }
3533 
3534 static bool do_logic(DisasContext *dc, arg_r_r_ri_cc *a,
3535                      void (*func)(TCGv, TCGv, TCGv),
3536                      void (*funci)(TCGv, TCGv, target_long))
3537 {
3538     return do_arith_int(dc, a, func, funci, a->cc);
3539 }
3540 
3541 TRANS(ADD, ALL, do_arith, a, tcg_gen_add_tl, tcg_gen_addi_tl, gen_op_addcc)
3542 TRANS(SUB, ALL, do_arith, a, tcg_gen_sub_tl, tcg_gen_subi_tl, gen_op_subcc)
3543 TRANS(ADDC, ALL, do_arith, a, gen_op_addc, NULL, gen_op_addccc)
3544 TRANS(SUBC, ALL, do_arith, a, gen_op_subc, NULL, gen_op_subccc)
3545 
3546 TRANS(TADDcc, ALL, do_arith, a, NULL, NULL, gen_op_taddcc)
3547 TRANS(TSUBcc, ALL, do_arith, a, NULL, NULL, gen_op_tsubcc)
3548 TRANS(TADDccTV, ALL, do_arith, a, NULL, NULL, gen_op_taddcctv)
3549 TRANS(TSUBccTV, ALL, do_arith, a, NULL, NULL, gen_op_tsubcctv)
3550 
3551 TRANS(AND, ALL, do_logic, a, tcg_gen_and_tl, tcg_gen_andi_tl)
3552 TRANS(XOR, ALL, do_logic, a, tcg_gen_xor_tl, tcg_gen_xori_tl)
3553 TRANS(ANDN, ALL, do_logic, a, tcg_gen_andc_tl, NULL)
3554 TRANS(ORN, ALL, do_logic, a, tcg_gen_orc_tl, NULL)
3555 TRANS(XORN, ALL, do_logic, a, tcg_gen_eqv_tl, NULL)
3556 
3557 TRANS(MULX, 64, do_arith, a, tcg_gen_mul_tl, tcg_gen_muli_tl, NULL)
3558 TRANS(UMUL, MUL, do_logic, a, gen_op_umul, NULL)
3559 TRANS(SMUL, MUL, do_logic, a, gen_op_smul, NULL)
3560 TRANS(MULScc, ALL, do_arith, a, NULL, NULL, gen_op_mulscc)
3561 
3562 TRANS(UDIVcc, DIV, do_arith, a, NULL, NULL, gen_op_udivcc)
3563 TRANS(SDIV, DIV, do_arith, a, gen_op_sdiv, NULL, gen_op_sdivcc)
3564 
3565 /* TODO: Should have feature bit -- comes in with UltraSparc T2. */
3566 TRANS(POPC, 64, do_arith, a, gen_op_popc, NULL, NULL)
3567 
3568 static bool trans_OR(DisasContext *dc, arg_r_r_ri_cc *a)
3569 {
3570     /* OR with %g0 is the canonical alias for MOV. */
3571     if (!a->cc && a->rs1 == 0) {
3572         if (a->imm || a->rs2_or_imm == 0) {
3573             gen_store_gpr(dc, a->rd, tcg_constant_tl(a->rs2_or_imm));
3574         } else if (a->rs2_or_imm & ~0x1f) {
3575             /* For simplicity, we under-decoded the rs2 form. */
3576             return false;
3577         } else {
3578             gen_store_gpr(dc, a->rd, cpu_regs[a->rs2_or_imm]);
3579         }
3580         return advance_pc(dc);
3581     }
3582     return do_logic(dc, a, tcg_gen_or_tl, tcg_gen_ori_tl);
3583 }
3584 
3585 static bool trans_UDIV(DisasContext *dc, arg_r_r_ri *a)
3586 {
3587     TCGv_i64 t1, t2;
3588     TCGv dst;
3589 
3590     if (!avail_DIV(dc)) {
3591         return false;
3592     }
3593     /* For simplicity, we under-decoded the rs2 form. */
3594     if (!a->imm && a->rs2_or_imm & ~0x1f) {
3595         return false;
3596     }
3597 
3598     if (unlikely(a->rs2_or_imm == 0)) {
3599         gen_exception(dc, TT_DIV_ZERO);
3600         return true;
3601     }
3602 
3603     if (a->imm) {
3604         t2 = tcg_constant_i64((uint32_t)a->rs2_or_imm);
3605     } else {
3606         TCGLabel *lab;
3607         TCGv_i32 n2;
3608 
3609         finishing_insn(dc);
3610         flush_cond(dc);
3611 
3612         n2 = tcg_temp_new_i32();
3613         tcg_gen_trunc_tl_i32(n2, cpu_regs[a->rs2_or_imm]);
3614 
3615         lab = delay_exception(dc, TT_DIV_ZERO);
3616         tcg_gen_brcondi_i32(TCG_COND_EQ, n2, 0, lab);
3617 
3618         t2 = tcg_temp_new_i64();
3619 #ifdef TARGET_SPARC64
3620         tcg_gen_ext32u_i64(t2, cpu_regs[a->rs2_or_imm]);
3621 #else
3622         tcg_gen_extu_i32_i64(t2, cpu_regs[a->rs2_or_imm]);
3623 #endif
3624     }
3625 
3626     t1 = tcg_temp_new_i64();
3627     tcg_gen_concat_tl_i64(t1, gen_load_gpr(dc, a->rs1), cpu_y);
3628 
3629     tcg_gen_divu_i64(t1, t1, t2);
3630     tcg_gen_umin_i64(t1, t1, tcg_constant_i64(UINT32_MAX));
3631 
3632     dst = gen_dest_gpr(dc, a->rd);
3633     tcg_gen_trunc_i64_tl(dst, t1);
3634     gen_store_gpr(dc, a->rd, dst);
3635     return advance_pc(dc);
3636 }
3637 
3638 static bool trans_UDIVX(DisasContext *dc, arg_r_r_ri *a)
3639 {
3640     TCGv dst, src1, src2;
3641 
3642     if (!avail_64(dc)) {
3643         return false;
3644     }
3645     /* For simplicity, we under-decoded the rs2 form. */
3646     if (!a->imm && a->rs2_or_imm & ~0x1f) {
3647         return false;
3648     }
3649 
3650     if (unlikely(a->rs2_or_imm == 0)) {
3651         gen_exception(dc, TT_DIV_ZERO);
3652         return true;
3653     }
3654 
3655     if (a->imm) {
3656         src2 = tcg_constant_tl(a->rs2_or_imm);
3657     } else {
3658         TCGLabel *lab;
3659 
3660         finishing_insn(dc);
3661         flush_cond(dc);
3662 
3663         lab = delay_exception(dc, TT_DIV_ZERO);
3664         src2 = cpu_regs[a->rs2_or_imm];
3665         tcg_gen_brcondi_tl(TCG_COND_EQ, src2, 0, lab);
3666     }
3667 
3668     dst = gen_dest_gpr(dc, a->rd);
3669     src1 = gen_load_gpr(dc, a->rs1);
3670 
3671     tcg_gen_divu_tl(dst, src1, src2);
3672     gen_store_gpr(dc, a->rd, dst);
3673     return advance_pc(dc);
3674 }
3675 
3676 static bool trans_SDIVX(DisasContext *dc, arg_r_r_ri *a)
3677 {
3678     TCGv dst, src1, src2;
3679 
3680     if (!avail_64(dc)) {
3681         return false;
3682     }
3683     /* For simplicity, we under-decoded the rs2 form. */
3684     if (!a->imm && a->rs2_or_imm & ~0x1f) {
3685         return false;
3686     }
3687 
3688     if (unlikely(a->rs2_or_imm == 0)) {
3689         gen_exception(dc, TT_DIV_ZERO);
3690         return true;
3691     }
3692 
3693     dst = gen_dest_gpr(dc, a->rd);
3694     src1 = gen_load_gpr(dc, a->rs1);
3695 
3696     if (a->imm) {
3697         if (unlikely(a->rs2_or_imm == -1)) {
3698             tcg_gen_neg_tl(dst, src1);
3699             gen_store_gpr(dc, a->rd, dst);
3700             return advance_pc(dc);
3701         }
3702         src2 = tcg_constant_tl(a->rs2_or_imm);
3703     } else {
3704         TCGLabel *lab;
3705         TCGv t1, t2;
3706 
3707         finishing_insn(dc);
3708         flush_cond(dc);
3709 
3710         lab = delay_exception(dc, TT_DIV_ZERO);
3711         src2 = cpu_regs[a->rs2_or_imm];
3712         tcg_gen_brcondi_tl(TCG_COND_EQ, src2, 0, lab);
3713 
3714         /*
3715          * Need to avoid INT64_MIN / -1, which will trap on x86 host.
3716          * Set SRC2 to 1 as a new divisor, to produce the correct result.
3717          */
3718         t1 = tcg_temp_new();
3719         t2 = tcg_temp_new();
3720         tcg_gen_setcondi_tl(TCG_COND_EQ, t1, src1, (target_long)INT64_MIN);
3721         tcg_gen_setcondi_tl(TCG_COND_EQ, t2, src2, -1);
3722         tcg_gen_and_tl(t1, t1, t2);
3723         tcg_gen_movcond_tl(TCG_COND_NE, t1, t1, tcg_constant_tl(0),
3724                            tcg_constant_tl(1), src2);
3725         src2 = t1;
3726     }
3727 
3728     tcg_gen_div_tl(dst, src1, src2);
3729     gen_store_gpr(dc, a->rd, dst);
3730     return advance_pc(dc);
3731 }
3732 
3733 static bool gen_edge(DisasContext *dc, arg_r_r_r *a,
3734                      int width, bool cc, bool left)
3735 {
3736     TCGv dst, s1, s2, lo1, lo2;
3737     uint64_t amask, tabl, tabr;
3738     int shift, imask, omask;
3739 
3740     dst = gen_dest_gpr(dc, a->rd);
3741     s1 = gen_load_gpr(dc, a->rs1);
3742     s2 = gen_load_gpr(dc, a->rs2);
3743 
3744     if (cc) {
3745         gen_op_subcc(cpu_cc_N, s1, s2);
3746     }
3747 
3748     /*
3749      * Theory of operation: there are two tables, left and right (not to
3750      * be confused with the left and right versions of the opcode).  These
3751      * are indexed by the low 3 bits of the inputs.  To make things "easy",
3752      * these tables are loaded into two constants, TABL and TABR below.
3753      * The operation index = (input & imask) << shift calculates the index
3754      * into the constant, while val = (table >> index) & omask calculates
3755      * the value we're looking for.
3756      */
3757     switch (width) {
3758     case 8:
3759         imask = 0x7;
3760         shift = 3;
3761         omask = 0xff;
3762         if (left) {
3763             tabl = 0x80c0e0f0f8fcfeffULL;
3764             tabr = 0xff7f3f1f0f070301ULL;
3765         } else {
3766             tabl = 0x0103070f1f3f7fffULL;
3767             tabr = 0xfffefcf8f0e0c080ULL;
3768         }
3769         break;
3770     case 16:
3771         imask = 0x6;
3772         shift = 1;
3773         omask = 0xf;
3774         if (left) {
3775             tabl = 0x8cef;
3776             tabr = 0xf731;
3777         } else {
3778             tabl = 0x137f;
3779             tabr = 0xfec8;
3780         }
3781         break;
3782     case 32:
3783         imask = 0x4;
3784         shift = 0;
3785         omask = 0x3;
3786         if (left) {
3787             tabl = (2 << 2) | 3;
3788             tabr = (3 << 2) | 1;
3789         } else {
3790             tabl = (1 << 2) | 3;
3791             tabr = (3 << 2) | 2;
3792         }
3793         break;
3794     default:
3795         abort();
3796     }
3797 
3798     lo1 = tcg_temp_new();
3799     lo2 = tcg_temp_new();
3800     tcg_gen_andi_tl(lo1, s1, imask);
3801     tcg_gen_andi_tl(lo2, s2, imask);
3802     tcg_gen_shli_tl(lo1, lo1, shift);
3803     tcg_gen_shli_tl(lo2, lo2, shift);
3804 
3805     tcg_gen_shr_tl(lo1, tcg_constant_tl(tabl), lo1);
3806     tcg_gen_shr_tl(lo2, tcg_constant_tl(tabr), lo2);
3807     tcg_gen_andi_tl(lo1, lo1, omask);
3808     tcg_gen_andi_tl(lo2, lo2, omask);
3809 
3810     amask = address_mask_i(dc, -8);
3811     tcg_gen_andi_tl(s1, s1, amask);
3812     tcg_gen_andi_tl(s2, s2, amask);
3813 
3814     /* Compute dst = (s1 == s2 ? lo1 : lo1 & lo2). */
3815     tcg_gen_and_tl(lo2, lo2, lo1);
3816     tcg_gen_movcond_tl(TCG_COND_EQ, dst, s1, s2, lo1, lo2);
3817 
3818     gen_store_gpr(dc, a->rd, dst);
3819     return advance_pc(dc);
3820 }
3821 
3822 TRANS(EDGE8cc, VIS1, gen_edge, a, 8, 1, 0)
3823 TRANS(EDGE8Lcc, VIS1, gen_edge, a, 8, 1, 1)
3824 TRANS(EDGE16cc, VIS1, gen_edge, a, 16, 1, 0)
3825 TRANS(EDGE16Lcc, VIS1, gen_edge, a, 16, 1, 1)
3826 TRANS(EDGE32cc, VIS1, gen_edge, a, 32, 1, 0)
3827 TRANS(EDGE32Lcc, VIS1, gen_edge, a, 32, 1, 1)
3828 
3829 TRANS(EDGE8N, VIS2, gen_edge, a, 8, 0, 0)
3830 TRANS(EDGE8LN, VIS2, gen_edge, a, 8, 0, 1)
3831 TRANS(EDGE16N, VIS2, gen_edge, a, 16, 0, 0)
3832 TRANS(EDGE16LN, VIS2, gen_edge, a, 16, 0, 1)
3833 TRANS(EDGE32N, VIS2, gen_edge, a, 32, 0, 0)
3834 TRANS(EDGE32LN, VIS2, gen_edge, a, 32, 0, 1)
3835 
3836 static bool do_rrr(DisasContext *dc, arg_r_r_r *a,
3837                    void (*func)(TCGv, TCGv, TCGv))
3838 {
3839     TCGv dst = gen_dest_gpr(dc, a->rd);
3840     TCGv src1 = gen_load_gpr(dc, a->rs1);
3841     TCGv src2 = gen_load_gpr(dc, a->rs2);
3842 
3843     func(dst, src1, src2);
3844     gen_store_gpr(dc, a->rd, dst);
3845     return advance_pc(dc);
3846 }
3847 
3848 TRANS(ARRAY8, VIS1, do_rrr, a, gen_helper_array8)
3849 TRANS(ARRAY16, VIS1, do_rrr, a, gen_op_array16)
3850 TRANS(ARRAY32, VIS1, do_rrr, a, gen_op_array32)
3851 
3852 static void gen_op_alignaddr(TCGv dst, TCGv s1, TCGv s2)
3853 {
3854 #ifdef TARGET_SPARC64
3855     TCGv tmp = tcg_temp_new();
3856 
3857     tcg_gen_add_tl(tmp, s1, s2);
3858     tcg_gen_andi_tl(dst, tmp, -8);
3859     tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
3860 #else
3861     g_assert_not_reached();
3862 #endif
3863 }
3864 
3865 static void gen_op_alignaddrl(TCGv dst, TCGv s1, TCGv s2)
3866 {
3867 #ifdef TARGET_SPARC64
3868     TCGv tmp = tcg_temp_new();
3869 
3870     tcg_gen_add_tl(tmp, s1, s2);
3871     tcg_gen_andi_tl(dst, tmp, -8);
3872     tcg_gen_neg_tl(tmp, tmp);
3873     tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
3874 #else
3875     g_assert_not_reached();
3876 #endif
3877 }
3878 
3879 TRANS(ALIGNADDR, VIS1, do_rrr, a, gen_op_alignaddr)
3880 TRANS(ALIGNADDRL, VIS1, do_rrr, a, gen_op_alignaddrl)
3881 
3882 static void gen_op_bmask(TCGv dst, TCGv s1, TCGv s2)
3883 {
3884 #ifdef TARGET_SPARC64
3885     tcg_gen_add_tl(dst, s1, s2);
3886     tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, dst, 32, 32);
3887 #else
3888     g_assert_not_reached();
3889 #endif
3890 }
3891 
3892 TRANS(BMASK, VIS2, do_rrr, a, gen_op_bmask)
3893 
3894 static bool do_shift_r(DisasContext *dc, arg_shiftr *a, bool l, bool u)
3895 {
3896     TCGv dst, src1, src2;
3897 
3898     /* Reject 64-bit shifts for sparc32. */
3899     if (avail_32(dc) && a->x) {
3900         return false;
3901     }
3902 
3903     src2 = tcg_temp_new();
3904     tcg_gen_andi_tl(src2, gen_load_gpr(dc, a->rs2), a->x ? 63 : 31);
3905     src1 = gen_load_gpr(dc, a->rs1);
3906     dst = gen_dest_gpr(dc, a->rd);
3907 
3908     if (l) {
3909         tcg_gen_shl_tl(dst, src1, src2);
3910         if (!a->x) {
3911             tcg_gen_ext32u_tl(dst, dst);
3912         }
3913     } else if (u) {
3914         if (!a->x) {
3915             tcg_gen_ext32u_tl(dst, src1);
3916             src1 = dst;
3917         }
3918         tcg_gen_shr_tl(dst, src1, src2);
3919     } else {
3920         if (!a->x) {
3921             tcg_gen_ext32s_tl(dst, src1);
3922             src1 = dst;
3923         }
3924         tcg_gen_sar_tl(dst, src1, src2);
3925     }
3926     gen_store_gpr(dc, a->rd, dst);
3927     return advance_pc(dc);
3928 }
3929 
3930 TRANS(SLL_r, ALL, do_shift_r, a, true, true)
3931 TRANS(SRL_r, ALL, do_shift_r, a, false, true)
3932 TRANS(SRA_r, ALL, do_shift_r, a, false, false)
3933 
3934 static bool do_shift_i(DisasContext *dc, arg_shifti *a, bool l, bool u)
3935 {
3936     TCGv dst, src1;
3937 
3938     /* Reject 64-bit shifts for sparc32. */
3939     if (avail_32(dc) && (a->x || a->i >= 32)) {
3940         return false;
3941     }
3942 
3943     src1 = gen_load_gpr(dc, a->rs1);
3944     dst = gen_dest_gpr(dc, a->rd);
3945 
3946     if (avail_32(dc) || a->x) {
3947         if (l) {
3948             tcg_gen_shli_tl(dst, src1, a->i);
3949         } else if (u) {
3950             tcg_gen_shri_tl(dst, src1, a->i);
3951         } else {
3952             tcg_gen_sari_tl(dst, src1, a->i);
3953         }
3954     } else {
3955         if (l) {
3956             tcg_gen_deposit_z_tl(dst, src1, a->i, 32 - a->i);
3957         } else if (u) {
3958             tcg_gen_extract_tl(dst, src1, a->i, 32 - a->i);
3959         } else {
3960             tcg_gen_sextract_tl(dst, src1, a->i, 32 - a->i);
3961         }
3962     }
3963     gen_store_gpr(dc, a->rd, dst);
3964     return advance_pc(dc);
3965 }
3966 
3967 TRANS(SLL_i, ALL, do_shift_i, a, true, true)
3968 TRANS(SRL_i, ALL, do_shift_i, a, false, true)
3969 TRANS(SRA_i, ALL, do_shift_i, a, false, false)
3970 
3971 static TCGv gen_rs2_or_imm(DisasContext *dc, bool imm, int rs2_or_imm)
3972 {
3973     /* For simplicity, we under-decoded the rs2 form. */
3974     if (!imm && rs2_or_imm & ~0x1f) {
3975         return NULL;
3976     }
3977     if (imm || rs2_or_imm == 0) {
3978         return tcg_constant_tl(rs2_or_imm);
3979     } else {
3980         return cpu_regs[rs2_or_imm];
3981     }
3982 }
3983 
3984 static bool do_mov_cond(DisasContext *dc, DisasCompare *cmp, int rd, TCGv src2)
3985 {
3986     TCGv dst = gen_load_gpr(dc, rd);
3987     TCGv c2 = tcg_constant_tl(cmp->c2);
3988 
3989     tcg_gen_movcond_tl(cmp->cond, dst, cmp->c1, c2, src2, dst);
3990     gen_store_gpr(dc, rd, dst);
3991     return advance_pc(dc);
3992 }
3993 
3994 static bool trans_MOVcc(DisasContext *dc, arg_MOVcc *a)
3995 {
3996     TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
3997     DisasCompare cmp;
3998 
3999     if (src2 == NULL) {
4000         return false;
4001     }
4002     gen_compare(&cmp, a->cc, a->cond, dc);
4003     return do_mov_cond(dc, &cmp, a->rd, src2);
4004 }
4005 
4006 static bool trans_MOVfcc(DisasContext *dc, arg_MOVfcc *a)
4007 {
4008     TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
4009     DisasCompare cmp;
4010 
4011     if (src2 == NULL) {
4012         return false;
4013     }
4014     gen_fcompare(&cmp, a->cc, a->cond);
4015     return do_mov_cond(dc, &cmp, a->rd, src2);
4016 }
4017 
4018 static bool trans_MOVR(DisasContext *dc, arg_MOVR *a)
4019 {
4020     TCGv src2 = gen_rs2_or_imm(dc, a->imm, a->rs2_or_imm);
4021     DisasCompare cmp;
4022 
4023     if (src2 == NULL) {
4024         return false;
4025     }
4026     if (!gen_compare_reg(&cmp, a->cond, gen_load_gpr(dc, a->rs1))) {
4027         return false;
4028     }
4029     return do_mov_cond(dc, &cmp, a->rd, src2);
4030 }
4031 
4032 static bool do_add_special(DisasContext *dc, arg_r_r_ri *a,
4033                            bool (*func)(DisasContext *dc, int rd, TCGv src))
4034 {
4035     TCGv src1, sum;
4036 
4037     /* For simplicity, we under-decoded the rs2 form. */
4038     if (!a->imm && a->rs2_or_imm & ~0x1f) {
4039         return false;
4040     }
4041 
4042     /*
4043      * Always load the sum into a new temporary.
4044      * This is required to capture the value across a window change,
4045      * e.g. SAVE and RESTORE, and may be optimized away otherwise.
4046      */
4047     sum = tcg_temp_new();
4048     src1 = gen_load_gpr(dc, a->rs1);
4049     if (a->imm || a->rs2_or_imm == 0) {
4050         tcg_gen_addi_tl(sum, src1, a->rs2_or_imm);
4051     } else {
4052         tcg_gen_add_tl(sum, src1, cpu_regs[a->rs2_or_imm]);
4053     }
4054     return func(dc, a->rd, sum);
4055 }
4056 
4057 static bool do_jmpl(DisasContext *dc, int rd, TCGv src)
4058 {
4059     /*
4060      * Preserve pc across advance, so that we can delay
4061      * the writeback to rd until after src is consumed.
4062      */
4063     target_ulong cur_pc = dc->pc;
4064 
4065     gen_check_align(dc, src, 3);
4066 
4067     gen_mov_pc_npc(dc);
4068     tcg_gen_mov_tl(cpu_npc, src);
4069     gen_address_mask(dc, cpu_npc);
4070     gen_store_gpr(dc, rd, tcg_constant_tl(cur_pc));
4071 
4072     dc->npc = DYNAMIC_PC_LOOKUP;
4073     return true;
4074 }
4075 
4076 TRANS(JMPL, ALL, do_add_special, a, do_jmpl)
4077 
4078 static bool do_rett(DisasContext *dc, int rd, TCGv src)
4079 {
4080     if (!supervisor(dc)) {
4081         return raise_priv(dc);
4082     }
4083 
4084     gen_check_align(dc, src, 3);
4085 
4086     gen_mov_pc_npc(dc);
4087     tcg_gen_mov_tl(cpu_npc, src);
4088     gen_helper_rett(tcg_env);
4089 
4090     dc->npc = DYNAMIC_PC;
4091     return true;
4092 }
4093 
4094 TRANS(RETT, 32, do_add_special, a, do_rett)
4095 
4096 static bool do_return(DisasContext *dc, int rd, TCGv src)
4097 {
4098     gen_check_align(dc, src, 3);
4099 
4100     gen_mov_pc_npc(dc);
4101     tcg_gen_mov_tl(cpu_npc, src);
4102     gen_address_mask(dc, cpu_npc);
4103 
4104     gen_helper_restore(tcg_env);
4105     dc->npc = DYNAMIC_PC_LOOKUP;
4106     return true;
4107 }
4108 
4109 TRANS(RETURN, 64, do_add_special, a, do_return)
4110 
4111 static bool do_save(DisasContext *dc, int rd, TCGv src)
4112 {
4113     gen_helper_save(tcg_env);
4114     gen_store_gpr(dc, rd, src);
4115     return advance_pc(dc);
4116 }
4117 
4118 TRANS(SAVE, ALL, do_add_special, a, do_save)
4119 
4120 static bool do_restore(DisasContext *dc, int rd, TCGv src)
4121 {
4122     gen_helper_restore(tcg_env);
4123     gen_store_gpr(dc, rd, src);
4124     return advance_pc(dc);
4125 }
4126 
4127 TRANS(RESTORE, ALL, do_add_special, a, do_restore)
4128 
4129 static bool do_done_retry(DisasContext *dc, bool done)
4130 {
4131     if (!supervisor(dc)) {
4132         return raise_priv(dc);
4133     }
4134     dc->npc = DYNAMIC_PC;
4135     dc->pc = DYNAMIC_PC;
4136     translator_io_start(&dc->base);
4137     if (done) {
4138         gen_helper_done(tcg_env);
4139     } else {
4140         gen_helper_retry(tcg_env);
4141     }
4142     return true;
4143 }
4144 
4145 TRANS(DONE, 64, do_done_retry, true)
4146 TRANS(RETRY, 64, do_done_retry, false)
4147 
4148 /*
4149  * Major opcode 11 -- load and store instructions
4150  */
4151 
4152 static TCGv gen_ldst_addr(DisasContext *dc, int rs1, bool imm, int rs2_or_imm)
4153 {
4154     TCGv addr, tmp = NULL;
4155 
4156     /* For simplicity, we under-decoded the rs2 form. */
4157     if (!imm && rs2_or_imm & ~0x1f) {
4158         return NULL;
4159     }
4160 
4161     addr = gen_load_gpr(dc, rs1);
4162     if (rs2_or_imm) {
4163         tmp = tcg_temp_new();
4164         if (imm) {
4165             tcg_gen_addi_tl(tmp, addr, rs2_or_imm);
4166         } else {
4167             tcg_gen_add_tl(tmp, addr, cpu_regs[rs2_or_imm]);
4168         }
4169         addr = tmp;
4170     }
4171     if (AM_CHECK(dc)) {
4172         if (!tmp) {
4173             tmp = tcg_temp_new();
4174         }
4175         tcg_gen_ext32u_tl(tmp, addr);
4176         addr = tmp;
4177     }
4178     return addr;
4179 }
4180 
4181 static bool do_ld_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
4182 {
4183     TCGv reg, addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4184     DisasASI da;
4185 
4186     if (addr == NULL) {
4187         return false;
4188     }
4189     da = resolve_asi(dc, a->asi, mop);
4190 
4191     reg = gen_dest_gpr(dc, a->rd);
4192     gen_ld_asi(dc, &da, reg, addr);
4193     gen_store_gpr(dc, a->rd, reg);
4194     return advance_pc(dc);
4195 }
4196 
4197 TRANS(LDUW, ALL, do_ld_gpr, a, MO_TEUL)
4198 TRANS(LDUB, ALL, do_ld_gpr, a, MO_UB)
4199 TRANS(LDUH, ALL, do_ld_gpr, a, MO_TEUW)
4200 TRANS(LDSB, ALL, do_ld_gpr, a, MO_SB)
4201 TRANS(LDSH, ALL, do_ld_gpr, a, MO_TESW)
4202 TRANS(LDSW, 64, do_ld_gpr, a, MO_TESL)
4203 TRANS(LDX, 64, do_ld_gpr, a, MO_TEUQ)
4204 
4205 static bool do_st_gpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
4206 {
4207     TCGv reg, addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4208     DisasASI da;
4209 
4210     if (addr == NULL) {
4211         return false;
4212     }
4213     da = resolve_asi(dc, a->asi, mop);
4214 
4215     reg = gen_load_gpr(dc, a->rd);
4216     gen_st_asi(dc, &da, reg, addr);
4217     return advance_pc(dc);
4218 }
4219 
4220 TRANS(STW, ALL, do_st_gpr, a, MO_TEUL)
4221 TRANS(STB, ALL, do_st_gpr, a, MO_UB)
4222 TRANS(STH, ALL, do_st_gpr, a, MO_TEUW)
4223 TRANS(STX, 64, do_st_gpr, a, MO_TEUQ)
4224 
4225 static bool trans_LDD(DisasContext *dc, arg_r_r_ri_asi *a)
4226 {
4227     TCGv addr;
4228     DisasASI da;
4229 
4230     if (a->rd & 1) {
4231         return false;
4232     }
4233     addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4234     if (addr == NULL) {
4235         return false;
4236     }
4237     da = resolve_asi(dc, a->asi, MO_TEUQ);
4238     gen_ldda_asi(dc, &da, addr, a->rd);
4239     return advance_pc(dc);
4240 }
4241 
4242 static bool trans_STD(DisasContext *dc, arg_r_r_ri_asi *a)
4243 {
4244     TCGv addr;
4245     DisasASI da;
4246 
4247     if (a->rd & 1) {
4248         return false;
4249     }
4250     addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4251     if (addr == NULL) {
4252         return false;
4253     }
4254     da = resolve_asi(dc, a->asi, MO_TEUQ);
4255     gen_stda_asi(dc, &da, addr, a->rd);
4256     return advance_pc(dc);
4257 }
4258 
4259 static bool trans_LDSTUB(DisasContext *dc, arg_r_r_ri_asi *a)
4260 {
4261     TCGv addr, reg;
4262     DisasASI da;
4263 
4264     addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4265     if (addr == NULL) {
4266         return false;
4267     }
4268     da = resolve_asi(dc, a->asi, MO_UB);
4269 
4270     reg = gen_dest_gpr(dc, a->rd);
4271     gen_ldstub_asi(dc, &da, reg, addr);
4272     gen_store_gpr(dc, a->rd, reg);
4273     return advance_pc(dc);
4274 }
4275 
4276 static bool trans_SWAP(DisasContext *dc, arg_r_r_ri_asi *a)
4277 {
4278     TCGv addr, dst, src;
4279     DisasASI da;
4280 
4281     addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4282     if (addr == NULL) {
4283         return false;
4284     }
4285     da = resolve_asi(dc, a->asi, MO_TEUL);
4286 
4287     dst = gen_dest_gpr(dc, a->rd);
4288     src = gen_load_gpr(dc, a->rd);
4289     gen_swap_asi(dc, &da, dst, src, addr);
4290     gen_store_gpr(dc, a->rd, dst);
4291     return advance_pc(dc);
4292 }
4293 
4294 static bool do_casa(DisasContext *dc, arg_r_r_ri_asi *a, MemOp mop)
4295 {
4296     TCGv addr, o, n, c;
4297     DisasASI da;
4298 
4299     addr = gen_ldst_addr(dc, a->rs1, true, 0);
4300     if (addr == NULL) {
4301         return false;
4302     }
4303     da = resolve_asi(dc, a->asi, mop);
4304 
4305     o = gen_dest_gpr(dc, a->rd);
4306     n = gen_load_gpr(dc, a->rd);
4307     c = gen_load_gpr(dc, a->rs2_or_imm);
4308     gen_cas_asi(dc, &da, o, n, c, addr);
4309     gen_store_gpr(dc, a->rd, o);
4310     return advance_pc(dc);
4311 }
4312 
4313 TRANS(CASA, CASA, do_casa, a, MO_TEUL)
4314 TRANS(CASXA, 64, do_casa, a, MO_TEUQ)
4315 
4316 static bool do_ld_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp sz)
4317 {
4318     TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4319     DisasASI da;
4320 
4321     if (addr == NULL) {
4322         return false;
4323     }
4324     if (gen_trap_ifnofpu(dc)) {
4325         return true;
4326     }
4327     if (sz == MO_128 && gen_trap_float128(dc)) {
4328         return true;
4329     }
4330     da = resolve_asi(dc, a->asi, MO_TE | sz);
4331     gen_ldf_asi(dc, &da, sz, addr, a->rd);
4332     gen_update_fprs_dirty(dc, a->rd);
4333     return advance_pc(dc);
4334 }
4335 
4336 TRANS(LDF, ALL, do_ld_fpr, a, MO_32)
4337 TRANS(LDDF, ALL, do_ld_fpr, a, MO_64)
4338 TRANS(LDQF, ALL, do_ld_fpr, a, MO_128)
4339 
4340 TRANS(LDFA, 64, do_ld_fpr, a, MO_32)
4341 TRANS(LDDFA, 64, do_ld_fpr, a, MO_64)
4342 TRANS(LDQFA, 64, do_ld_fpr, a, MO_128)
4343 
4344 static bool do_st_fpr(DisasContext *dc, arg_r_r_ri_asi *a, MemOp sz)
4345 {
4346     TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4347     DisasASI da;
4348 
4349     if (addr == NULL) {
4350         return false;
4351     }
4352     if (gen_trap_ifnofpu(dc)) {
4353         return true;
4354     }
4355     if (sz == MO_128 && gen_trap_float128(dc)) {
4356         return true;
4357     }
4358     da = resolve_asi(dc, a->asi, MO_TE | sz);
4359     gen_stf_asi(dc, &da, sz, addr, a->rd);
4360     return advance_pc(dc);
4361 }
4362 
4363 TRANS(STF, ALL, do_st_fpr, a, MO_32)
4364 TRANS(STDF, ALL, do_st_fpr, a, MO_64)
4365 TRANS(STQF, ALL, do_st_fpr, a, MO_128)
4366 
4367 TRANS(STFA, 64, do_st_fpr, a, MO_32)
4368 TRANS(STDFA, 64, do_st_fpr, a, MO_64)
4369 TRANS(STQFA, 64, do_st_fpr, a, MO_128)
4370 
4371 static bool trans_STDFQ(DisasContext *dc, arg_STDFQ *a)
4372 {
4373     if (!avail_32(dc)) {
4374         return false;
4375     }
4376     if (!supervisor(dc)) {
4377         return raise_priv(dc);
4378     }
4379     if (gen_trap_ifnofpu(dc)) {
4380         return true;
4381     }
4382     gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
4383     return true;
4384 }
4385 
4386 static bool do_ldfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop,
4387                      target_ulong new_mask, target_ulong old_mask)
4388 {
4389     TCGv tmp, addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4390     if (addr == NULL) {
4391         return false;
4392     }
4393     if (gen_trap_ifnofpu(dc)) {
4394         return true;
4395     }
4396     tmp = tcg_temp_new();
4397     tcg_gen_qemu_ld_tl(tmp, addr, dc->mem_idx, mop | MO_ALIGN);
4398     tcg_gen_andi_tl(tmp, tmp, new_mask);
4399     tcg_gen_andi_tl(cpu_fsr, cpu_fsr, old_mask);
4400     tcg_gen_or_tl(cpu_fsr, cpu_fsr, tmp);
4401     gen_helper_set_fsr(tcg_env, cpu_fsr);
4402     return advance_pc(dc);
4403 }
4404 
4405 TRANS(LDFSR, ALL, do_ldfsr, a, MO_TEUL, FSR_LDFSR_MASK, FSR_LDFSR_OLDMASK)
4406 TRANS(LDXFSR, 64, do_ldfsr, a, MO_TEUQ, FSR_LDXFSR_MASK, FSR_LDXFSR_OLDMASK)
4407 
4408 static bool do_stfsr(DisasContext *dc, arg_r_r_ri *a, MemOp mop)
4409 {
4410     TCGv addr = gen_ldst_addr(dc, a->rs1, a->imm, a->rs2_or_imm);
4411     if (addr == NULL) {
4412         return false;
4413     }
4414     if (gen_trap_ifnofpu(dc)) {
4415         return true;
4416     }
4417     tcg_gen_qemu_st_tl(cpu_fsr, addr, dc->mem_idx, mop | MO_ALIGN);
4418     return advance_pc(dc);
4419 }
4420 
4421 TRANS(STFSR, ALL, do_stfsr, a, MO_TEUL)
4422 TRANS(STXFSR, 64, do_stfsr, a, MO_TEUQ)
4423 
4424 static bool do_fc(DisasContext *dc, int rd, bool c)
4425 {
4426     uint64_t mask;
4427 
4428     if (gen_trap_ifnofpu(dc)) {
4429         return true;
4430     }
4431 
4432     if (rd & 1) {
4433         mask = MAKE_64BIT_MASK(0, 32);
4434     } else {
4435         mask = MAKE_64BIT_MASK(32, 32);
4436     }
4437     if (c) {
4438         tcg_gen_ori_i64(cpu_fpr[rd / 2], cpu_fpr[rd / 2], mask);
4439     } else {
4440         tcg_gen_andi_i64(cpu_fpr[rd / 2], cpu_fpr[rd / 2], ~mask);
4441     }
4442     gen_update_fprs_dirty(dc, rd);
4443     return advance_pc(dc);
4444 }
4445 
4446 TRANS(FZEROs, VIS1, do_fc, a->rd, 0)
4447 TRANS(FONEs, VIS1, do_fc, a->rd, 1)
4448 
4449 static bool do_dc(DisasContext *dc, int rd, int64_t c)
4450 {
4451     if (gen_trap_ifnofpu(dc)) {
4452         return true;
4453     }
4454 
4455     tcg_gen_movi_i64(cpu_fpr[rd / 2], c);
4456     gen_update_fprs_dirty(dc, rd);
4457     return advance_pc(dc);
4458 }
4459 
4460 TRANS(FZEROd, VIS1, do_dc, a->rd, 0)
4461 TRANS(FONEd, VIS1, do_dc, a->rd, -1)
4462 
4463 static bool do_ff(DisasContext *dc, arg_r_r *a,
4464                   void (*func)(TCGv_i32, TCGv_i32))
4465 {
4466     TCGv_i32 tmp;
4467 
4468     if (gen_trap_ifnofpu(dc)) {
4469         return true;
4470     }
4471 
4472     tmp = gen_load_fpr_F(dc, a->rs);
4473     func(tmp, tmp);
4474     gen_store_fpr_F(dc, a->rd, tmp);
4475     return advance_pc(dc);
4476 }
4477 
4478 TRANS(FMOVs, ALL, do_ff, a, gen_op_fmovs)
4479 TRANS(FNEGs, ALL, do_ff, a, gen_op_fnegs)
4480 TRANS(FABSs, ALL, do_ff, a, gen_op_fabss)
4481 TRANS(FSRCs, VIS1, do_ff, a, tcg_gen_mov_i32)
4482 TRANS(FNOTs, VIS1, do_ff, a, tcg_gen_not_i32)
4483 
4484 static bool do_fd(DisasContext *dc, arg_r_r *a,
4485                   void (*func)(TCGv_i32, TCGv_i64))
4486 {
4487     TCGv_i32 dst;
4488     TCGv_i64 src;
4489 
4490     if (gen_trap_ifnofpu(dc)) {
4491         return true;
4492     }
4493 
4494     dst = gen_dest_fpr_F(dc);
4495     src = gen_load_fpr_D(dc, a->rs);
4496     func(dst, src);
4497     gen_store_fpr_F(dc, a->rd, dst);
4498     return advance_pc(dc);
4499 }
4500 
4501 TRANS(FPACK16, VIS1, do_fd, a, gen_op_fpack16)
4502 TRANS(FPACKFIX, VIS1, do_fd, a, gen_op_fpackfix)
4503 
4504 static bool do_env_ff(DisasContext *dc, arg_r_r *a,
4505                       void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
4506 {
4507     TCGv_i32 tmp;
4508 
4509     if (gen_trap_ifnofpu(dc)) {
4510         return true;
4511     }
4512 
4513     gen_op_clear_ieee_excp_and_FTT();
4514     tmp = gen_load_fpr_F(dc, a->rs);
4515     func(tmp, tcg_env, tmp);
4516     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4517     gen_store_fpr_F(dc, a->rd, tmp);
4518     return advance_pc(dc);
4519 }
4520 
4521 TRANS(FSQRTs, ALL, do_env_ff, a, gen_helper_fsqrts)
4522 TRANS(FiTOs, ALL, do_env_ff, a, gen_helper_fitos)
4523 TRANS(FsTOi, ALL, do_env_ff, a, gen_helper_fstoi)
4524 
4525 static bool do_env_fd(DisasContext *dc, arg_r_r *a,
4526                       void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
4527 {
4528     TCGv_i32 dst;
4529     TCGv_i64 src;
4530 
4531     if (gen_trap_ifnofpu(dc)) {
4532         return true;
4533     }
4534 
4535     gen_op_clear_ieee_excp_and_FTT();
4536     dst = gen_dest_fpr_F(dc);
4537     src = gen_load_fpr_D(dc, a->rs);
4538     func(dst, tcg_env, src);
4539     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4540     gen_store_fpr_F(dc, a->rd, dst);
4541     return advance_pc(dc);
4542 }
4543 
4544 TRANS(FdTOs, ALL, do_env_fd, a, gen_helper_fdtos)
4545 TRANS(FdTOi, ALL, do_env_fd, a, gen_helper_fdtoi)
4546 TRANS(FxTOs, 64, do_env_fd, a, gen_helper_fxtos)
4547 
4548 static bool do_dd(DisasContext *dc, arg_r_r *a,
4549                   void (*func)(TCGv_i64, TCGv_i64))
4550 {
4551     TCGv_i64 dst, src;
4552 
4553     if (gen_trap_ifnofpu(dc)) {
4554         return true;
4555     }
4556 
4557     dst = gen_dest_fpr_D(dc, a->rd);
4558     src = gen_load_fpr_D(dc, a->rs);
4559     func(dst, src);
4560     gen_store_fpr_D(dc, a->rd, dst);
4561     return advance_pc(dc);
4562 }
4563 
4564 TRANS(FMOVd, 64, do_dd, a, gen_op_fmovd)
4565 TRANS(FNEGd, 64, do_dd, a, gen_op_fnegd)
4566 TRANS(FABSd, 64, do_dd, a, gen_op_fabsd)
4567 TRANS(FSRCd, VIS1, do_dd, a, tcg_gen_mov_i64)
4568 TRANS(FNOTd, VIS1, do_dd, a, tcg_gen_not_i64)
4569 
4570 static bool do_env_dd(DisasContext *dc, arg_r_r *a,
4571                       void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
4572 {
4573     TCGv_i64 dst, src;
4574 
4575     if (gen_trap_ifnofpu(dc)) {
4576         return true;
4577     }
4578 
4579     gen_op_clear_ieee_excp_and_FTT();
4580     dst = gen_dest_fpr_D(dc, a->rd);
4581     src = gen_load_fpr_D(dc, a->rs);
4582     func(dst, tcg_env, src);
4583     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4584     gen_store_fpr_D(dc, a->rd, dst);
4585     return advance_pc(dc);
4586 }
4587 
4588 TRANS(FSQRTd, ALL, do_env_dd, a, gen_helper_fsqrtd)
4589 TRANS(FxTOd, 64, do_env_dd, a, gen_helper_fxtod)
4590 TRANS(FdTOx, 64, do_env_dd, a, gen_helper_fdtox)
4591 
4592 static bool do_env_df(DisasContext *dc, arg_r_r *a,
4593                       void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
4594 {
4595     TCGv_i64 dst;
4596     TCGv_i32 src;
4597 
4598     if (gen_trap_ifnofpu(dc)) {
4599         return true;
4600     }
4601 
4602     gen_op_clear_ieee_excp_and_FTT();
4603     dst = gen_dest_fpr_D(dc, a->rd);
4604     src = gen_load_fpr_F(dc, a->rs);
4605     func(dst, tcg_env, src);
4606     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4607     gen_store_fpr_D(dc, a->rd, dst);
4608     return advance_pc(dc);
4609 }
4610 
4611 TRANS(FiTOd, ALL, do_env_df, a, gen_helper_fitod)
4612 TRANS(FsTOd, ALL, do_env_df, a, gen_helper_fstod)
4613 TRANS(FsTOx, 64, do_env_df, a, gen_helper_fstox)
4614 
4615 static bool trans_FMOVq(DisasContext *dc, arg_FMOVq *a)
4616 {
4617     int rd, rs;
4618 
4619     if (!avail_64(dc)) {
4620         return false;
4621     }
4622     if (gen_trap_ifnofpu(dc)) {
4623         return true;
4624     }
4625     if (gen_trap_float128(dc)) {
4626         return true;
4627     }
4628 
4629     gen_op_clear_ieee_excp_and_FTT();
4630     rd = QFPREG(a->rd);
4631     rs = QFPREG(a->rs);
4632     tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]);
4633     tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]);
4634     gen_update_fprs_dirty(dc, rd);
4635     return advance_pc(dc);
4636 }
4637 
4638 static bool do_qq(DisasContext *dc, arg_r_r *a,
4639                   void (*func)(TCGv_env))
4640 {
4641     if (gen_trap_ifnofpu(dc)) {
4642         return true;
4643     }
4644     if (gen_trap_float128(dc)) {
4645         return true;
4646     }
4647 
4648     gen_op_clear_ieee_excp_and_FTT();
4649     gen_op_load_fpr_QT1(QFPREG(a->rs));
4650     func(tcg_env);
4651     gen_op_store_QT0_fpr(QFPREG(a->rd));
4652     gen_update_fprs_dirty(dc, QFPREG(a->rd));
4653     return advance_pc(dc);
4654 }
4655 
4656 TRANS(FNEGq, 64, do_qq, a, gen_helper_fnegq)
4657 TRANS(FABSq, 64, do_qq, a, gen_helper_fabsq)
4658 
4659 static bool do_env_qq(DisasContext *dc, arg_r_r *a,
4660                        void (*func)(TCGv_env))
4661 {
4662     if (gen_trap_ifnofpu(dc)) {
4663         return true;
4664     }
4665     if (gen_trap_float128(dc)) {
4666         return true;
4667     }
4668 
4669     gen_op_clear_ieee_excp_and_FTT();
4670     gen_op_load_fpr_QT1(QFPREG(a->rs));
4671     func(tcg_env);
4672     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4673     gen_op_store_QT0_fpr(QFPREG(a->rd));
4674     gen_update_fprs_dirty(dc, QFPREG(a->rd));
4675     return advance_pc(dc);
4676 }
4677 
4678 TRANS(FSQRTq, ALL, do_env_qq, a, gen_helper_fsqrtq)
4679 
4680 static bool do_env_fq(DisasContext *dc, arg_r_r *a,
4681                       void (*func)(TCGv_i32, TCGv_env))
4682 {
4683     TCGv_i32 dst;
4684 
4685     if (gen_trap_ifnofpu(dc)) {
4686         return true;
4687     }
4688     if (gen_trap_float128(dc)) {
4689         return true;
4690     }
4691 
4692     gen_op_clear_ieee_excp_and_FTT();
4693     gen_op_load_fpr_QT1(QFPREG(a->rs));
4694     dst = gen_dest_fpr_F(dc);
4695     func(dst, tcg_env);
4696     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4697     gen_store_fpr_F(dc, a->rd, dst);
4698     return advance_pc(dc);
4699 }
4700 
4701 TRANS(FqTOs, ALL, do_env_fq, a, gen_helper_fqtos)
4702 TRANS(FqTOi, ALL, do_env_fq, a, gen_helper_fqtoi)
4703 
4704 static bool do_env_dq(DisasContext *dc, arg_r_r *a,
4705                       void (*func)(TCGv_i64, TCGv_env))
4706 {
4707     TCGv_i64 dst;
4708 
4709     if (gen_trap_ifnofpu(dc)) {
4710         return true;
4711     }
4712     if (gen_trap_float128(dc)) {
4713         return true;
4714     }
4715 
4716     gen_op_clear_ieee_excp_and_FTT();
4717     gen_op_load_fpr_QT1(QFPREG(a->rs));
4718     dst = gen_dest_fpr_D(dc, a->rd);
4719     func(dst, tcg_env);
4720     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4721     gen_store_fpr_D(dc, a->rd, dst);
4722     return advance_pc(dc);
4723 }
4724 
4725 TRANS(FqTOd, ALL, do_env_dq, a, gen_helper_fqtod)
4726 TRANS(FqTOx, 64, do_env_dq, a, gen_helper_fqtox)
4727 
4728 static bool do_env_qf(DisasContext *dc, arg_r_r *a,
4729                       void (*func)(TCGv_env, TCGv_i32))
4730 {
4731     TCGv_i32 src;
4732 
4733     if (gen_trap_ifnofpu(dc)) {
4734         return true;
4735     }
4736     if (gen_trap_float128(dc)) {
4737         return true;
4738     }
4739 
4740     gen_op_clear_ieee_excp_and_FTT();
4741     src = gen_load_fpr_F(dc, a->rs);
4742     func(tcg_env, src);
4743     gen_op_store_QT0_fpr(QFPREG(a->rd));
4744     gen_update_fprs_dirty(dc, QFPREG(a->rd));
4745     return advance_pc(dc);
4746 }
4747 
4748 TRANS(FiTOq, ALL, do_env_qf, a, gen_helper_fitoq)
4749 TRANS(FsTOq, ALL, do_env_qf, a, gen_helper_fstoq)
4750 
4751 static bool do_env_qd(DisasContext *dc, arg_r_r *a,
4752                       void (*func)(TCGv_env, TCGv_i64))
4753 {
4754     TCGv_i64 src;
4755 
4756     if (gen_trap_ifnofpu(dc)) {
4757         return true;
4758     }
4759     if (gen_trap_float128(dc)) {
4760         return true;
4761     }
4762 
4763     gen_op_clear_ieee_excp_and_FTT();
4764     src = gen_load_fpr_D(dc, a->rs);
4765     func(tcg_env, src);
4766     gen_op_store_QT0_fpr(QFPREG(a->rd));
4767     gen_update_fprs_dirty(dc, QFPREG(a->rd));
4768     return advance_pc(dc);
4769 }
4770 
4771 TRANS(FdTOq, ALL, do_env_qd, a, gen_helper_fdtoq)
4772 TRANS(FxTOq, 64, do_env_qd, a, gen_helper_fxtoq)
4773 
4774 static bool do_fff(DisasContext *dc, arg_r_r_r *a,
4775                    void (*func)(TCGv_i32, TCGv_i32, TCGv_i32))
4776 {
4777     TCGv_i32 src1, src2;
4778 
4779     if (gen_trap_ifnofpu(dc)) {
4780         return true;
4781     }
4782 
4783     src1 = gen_load_fpr_F(dc, a->rs1);
4784     src2 = gen_load_fpr_F(dc, a->rs2);
4785     func(src1, src1, src2);
4786     gen_store_fpr_F(dc, a->rd, src1);
4787     return advance_pc(dc);
4788 }
4789 
4790 TRANS(FPADD16s, VIS1, do_fff, a, tcg_gen_vec_add16_i32)
4791 TRANS(FPADD32s, VIS1, do_fff, a, tcg_gen_add_i32)
4792 TRANS(FPSUB16s, VIS1, do_fff, a, tcg_gen_vec_sub16_i32)
4793 TRANS(FPSUB32s, VIS1, do_fff, a, tcg_gen_sub_i32)
4794 TRANS(FNORs, VIS1, do_fff, a, tcg_gen_nor_i32)
4795 TRANS(FANDNOTs, VIS1, do_fff, a, tcg_gen_andc_i32)
4796 TRANS(FXORs, VIS1, do_fff, a, tcg_gen_xor_i32)
4797 TRANS(FNANDs, VIS1, do_fff, a, tcg_gen_nand_i32)
4798 TRANS(FANDs, VIS1, do_fff, a, tcg_gen_and_i32)
4799 TRANS(FXNORs, VIS1, do_fff, a, tcg_gen_eqv_i32)
4800 TRANS(FORNOTs, VIS1, do_fff, a, tcg_gen_orc_i32)
4801 TRANS(FORs, VIS1, do_fff, a, tcg_gen_or_i32)
4802 
4803 static bool do_env_fff(DisasContext *dc, arg_r_r_r *a,
4804                        void (*func)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
4805 {
4806     TCGv_i32 src1, src2;
4807 
4808     if (gen_trap_ifnofpu(dc)) {
4809         return true;
4810     }
4811 
4812     gen_op_clear_ieee_excp_and_FTT();
4813     src1 = gen_load_fpr_F(dc, a->rs1);
4814     src2 = gen_load_fpr_F(dc, a->rs2);
4815     func(src1, tcg_env, src1, src2);
4816     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4817     gen_store_fpr_F(dc, a->rd, src1);
4818     return advance_pc(dc);
4819 }
4820 
4821 TRANS(FADDs, ALL, do_env_fff, a, gen_helper_fadds)
4822 TRANS(FSUBs, ALL, do_env_fff, a, gen_helper_fsubs)
4823 TRANS(FMULs, ALL, do_env_fff, a, gen_helper_fmuls)
4824 TRANS(FDIVs, ALL, do_env_fff, a, gen_helper_fdivs)
4825 
4826 static bool do_ddd(DisasContext *dc, arg_r_r_r *a,
4827                    void (*func)(TCGv_i64, TCGv_i64, TCGv_i64))
4828 {
4829     TCGv_i64 dst, src1, src2;
4830 
4831     if (gen_trap_ifnofpu(dc)) {
4832         return true;
4833     }
4834 
4835     dst = gen_dest_fpr_D(dc, a->rd);
4836     src1 = gen_load_fpr_D(dc, a->rs1);
4837     src2 = gen_load_fpr_D(dc, a->rs2);
4838     func(dst, src1, src2);
4839     gen_store_fpr_D(dc, a->rd, dst);
4840     return advance_pc(dc);
4841 }
4842 
4843 TRANS(FMUL8x16, VIS1, do_ddd, a, gen_helper_fmul8x16)
4844 TRANS(FMUL8x16AU, VIS1, do_ddd, a, gen_helper_fmul8x16au)
4845 TRANS(FMUL8x16AL, VIS1, do_ddd, a, gen_helper_fmul8x16al)
4846 TRANS(FMUL8SUx16, VIS1, do_ddd, a, gen_helper_fmul8sux16)
4847 TRANS(FMUL8ULx16, VIS1, do_ddd, a, gen_helper_fmul8ulx16)
4848 TRANS(FMULD8SUx16, VIS1, do_ddd, a, gen_helper_fmuld8sux16)
4849 TRANS(FMULD8ULx16, VIS1, do_ddd, a, gen_helper_fmuld8ulx16)
4850 TRANS(FPMERGE, VIS1, do_ddd, a, gen_helper_fpmerge)
4851 TRANS(FEXPAND, VIS1, do_ddd, a, gen_helper_fexpand)
4852 
4853 TRANS(FPADD16, VIS1, do_ddd, a, tcg_gen_vec_add16_i64)
4854 TRANS(FPADD32, VIS1, do_ddd, a, tcg_gen_vec_add32_i64)
4855 TRANS(FPSUB16, VIS1, do_ddd, a, tcg_gen_vec_sub16_i64)
4856 TRANS(FPSUB32, VIS1, do_ddd, a, tcg_gen_vec_sub32_i64)
4857 TRANS(FNORd, VIS1, do_ddd, a, tcg_gen_nor_i64)
4858 TRANS(FANDNOTd, VIS1, do_ddd, a, tcg_gen_andc_i64)
4859 TRANS(FXORd, VIS1, do_ddd, a, tcg_gen_xor_i64)
4860 TRANS(FNANDd, VIS1, do_ddd, a, tcg_gen_nand_i64)
4861 TRANS(FANDd, VIS1, do_ddd, a, tcg_gen_and_i64)
4862 TRANS(FXNORd, VIS1, do_ddd, a, tcg_gen_eqv_i64)
4863 TRANS(FORNOTd, VIS1, do_ddd, a, tcg_gen_orc_i64)
4864 TRANS(FORd, VIS1, do_ddd, a, tcg_gen_or_i64)
4865 
4866 TRANS(FPACK32, VIS1, do_ddd, a, gen_op_fpack32)
4867 TRANS(FALIGNDATAg, VIS1, do_ddd, a, gen_op_faligndata)
4868 TRANS(BSHUFFLE, VIS2, do_ddd, a, gen_op_bshuffle)
4869 
4870 static bool do_rdd(DisasContext *dc, arg_r_r_r *a,
4871                    void (*func)(TCGv, TCGv_i64, TCGv_i64))
4872 {
4873     TCGv_i64 src1, src2;
4874     TCGv dst;
4875 
4876     if (gen_trap_ifnofpu(dc)) {
4877         return true;
4878     }
4879 
4880     dst = gen_dest_gpr(dc, a->rd);
4881     src1 = gen_load_fpr_D(dc, a->rs1);
4882     src2 = gen_load_fpr_D(dc, a->rs2);
4883     func(dst, src1, src2);
4884     gen_store_gpr(dc, a->rd, dst);
4885     return advance_pc(dc);
4886 }
4887 
4888 TRANS(FPCMPLE16, VIS1, do_rdd, a, gen_helper_fcmple16)
4889 TRANS(FPCMPNE16, VIS1, do_rdd, a, gen_helper_fcmpne16)
4890 TRANS(FPCMPGT16, VIS1, do_rdd, a, gen_helper_fcmpgt16)
4891 TRANS(FPCMPEQ16, VIS1, do_rdd, a, gen_helper_fcmpeq16)
4892 
4893 TRANS(FPCMPLE32, VIS1, do_rdd, a, gen_helper_fcmple32)
4894 TRANS(FPCMPNE32, VIS1, do_rdd, a, gen_helper_fcmpne32)
4895 TRANS(FPCMPGT32, VIS1, do_rdd, a, gen_helper_fcmpgt32)
4896 TRANS(FPCMPEQ32, VIS1, do_rdd, a, gen_helper_fcmpeq32)
4897 
4898 static bool do_env_ddd(DisasContext *dc, arg_r_r_r *a,
4899                        void (*func)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
4900 {
4901     TCGv_i64 dst, src1, src2;
4902 
4903     if (gen_trap_ifnofpu(dc)) {
4904         return true;
4905     }
4906 
4907     gen_op_clear_ieee_excp_and_FTT();
4908     dst = gen_dest_fpr_D(dc, a->rd);
4909     src1 = gen_load_fpr_D(dc, a->rs1);
4910     src2 = gen_load_fpr_D(dc, a->rs2);
4911     func(dst, tcg_env, src1, src2);
4912     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4913     gen_store_fpr_D(dc, a->rd, dst);
4914     return advance_pc(dc);
4915 }
4916 
4917 TRANS(FADDd, ALL, do_env_ddd, a, gen_helper_faddd)
4918 TRANS(FSUBd, ALL, do_env_ddd, a, gen_helper_fsubd)
4919 TRANS(FMULd, ALL, do_env_ddd, a, gen_helper_fmuld)
4920 TRANS(FDIVd, ALL, do_env_ddd, a, gen_helper_fdivd)
4921 
4922 static bool trans_FsMULd(DisasContext *dc, arg_r_r_r *a)
4923 {
4924     TCGv_i64 dst;
4925     TCGv_i32 src1, src2;
4926 
4927     if (gen_trap_ifnofpu(dc)) {
4928         return true;
4929     }
4930     if (!(dc->def->features & CPU_FEATURE_FSMULD)) {
4931         return raise_unimpfpop(dc);
4932     }
4933 
4934     gen_op_clear_ieee_excp_and_FTT();
4935     dst = gen_dest_fpr_D(dc, a->rd);
4936     src1 = gen_load_fpr_F(dc, a->rs1);
4937     src2 = gen_load_fpr_F(dc, a->rs2);
4938     gen_helper_fsmuld(dst, tcg_env, src1, src2);
4939     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4940     gen_store_fpr_D(dc, a->rd, dst);
4941     return advance_pc(dc);
4942 }
4943 
4944 static bool do_dddd(DisasContext *dc, arg_r_r_r *a,
4945                     void (*func)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
4946 {
4947     TCGv_i64 dst, src0, src1, src2;
4948 
4949     if (gen_trap_ifnofpu(dc)) {
4950         return true;
4951     }
4952 
4953     dst  = gen_dest_fpr_D(dc, a->rd);
4954     src0 = gen_load_fpr_D(dc, a->rd);
4955     src1 = gen_load_fpr_D(dc, a->rs1);
4956     src2 = gen_load_fpr_D(dc, a->rs2);
4957     func(dst, src0, src1, src2);
4958     gen_store_fpr_D(dc, a->rd, dst);
4959     return advance_pc(dc);
4960 }
4961 
4962 TRANS(PDIST, VIS1, do_dddd, a, gen_helper_pdist)
4963 
4964 static bool do_env_qqq(DisasContext *dc, arg_r_r_r *a,
4965                        void (*func)(TCGv_env))
4966 {
4967     if (gen_trap_ifnofpu(dc)) {
4968         return true;
4969     }
4970     if (gen_trap_float128(dc)) {
4971         return true;
4972     }
4973 
4974     gen_op_clear_ieee_excp_and_FTT();
4975     gen_op_load_fpr_QT0(QFPREG(a->rs1));
4976     gen_op_load_fpr_QT1(QFPREG(a->rs2));
4977     func(tcg_env);
4978     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
4979     gen_op_store_QT0_fpr(QFPREG(a->rd));
4980     gen_update_fprs_dirty(dc, QFPREG(a->rd));
4981     return advance_pc(dc);
4982 }
4983 
4984 TRANS(FADDq, ALL, do_env_qqq, a, gen_helper_faddq)
4985 TRANS(FSUBq, ALL, do_env_qqq, a, gen_helper_fsubq)
4986 TRANS(FMULq, ALL, do_env_qqq, a, gen_helper_fmulq)
4987 TRANS(FDIVq, ALL, do_env_qqq, a, gen_helper_fdivq)
4988 
4989 static bool trans_FdMULq(DisasContext *dc, arg_r_r_r *a)
4990 {
4991     TCGv_i64 src1, src2;
4992 
4993     if (gen_trap_ifnofpu(dc)) {
4994         return true;
4995     }
4996     if (gen_trap_float128(dc)) {
4997         return true;
4998     }
4999 
5000     gen_op_clear_ieee_excp_and_FTT();
5001     src1 = gen_load_fpr_D(dc, a->rs1);
5002     src2 = gen_load_fpr_D(dc, a->rs2);
5003     gen_helper_fdmulq(tcg_env, src1, src2);
5004     gen_helper_check_ieee_exceptions(cpu_fsr, tcg_env);
5005     gen_op_store_QT0_fpr(QFPREG(a->rd));
5006     gen_update_fprs_dirty(dc, QFPREG(a->rd));
5007     return advance_pc(dc);
5008 }
5009 
5010 static bool do_fmovr(DisasContext *dc, arg_FMOVRs *a, bool is_128,
5011                      void (*func)(DisasContext *, DisasCompare *, int, int))
5012 {
5013     DisasCompare cmp;
5014 
5015     if (!gen_compare_reg(&cmp, a->cond, gen_load_gpr(dc, a->rs1))) {
5016         return false;
5017     }
5018     if (gen_trap_ifnofpu(dc)) {
5019         return true;
5020     }
5021     if (is_128 && gen_trap_float128(dc)) {
5022         return true;
5023     }
5024 
5025     gen_op_clear_ieee_excp_and_FTT();
5026     func(dc, &cmp, a->rd, a->rs2);
5027     return advance_pc(dc);
5028 }
5029 
5030 TRANS(FMOVRs, 64, do_fmovr, a, false, gen_fmovs)
5031 TRANS(FMOVRd, 64, do_fmovr, a, false, gen_fmovd)
5032 TRANS(FMOVRq, 64, do_fmovr, a, true, gen_fmovq)
5033 
5034 static bool do_fmovcc(DisasContext *dc, arg_FMOVscc *a, bool is_128,
5035                       void (*func)(DisasContext *, DisasCompare *, int, int))
5036 {
5037     DisasCompare cmp;
5038 
5039     if (gen_trap_ifnofpu(dc)) {
5040         return true;
5041     }
5042     if (is_128 && gen_trap_float128(dc)) {
5043         return true;
5044     }
5045 
5046     gen_op_clear_ieee_excp_and_FTT();
5047     gen_compare(&cmp, a->cc, a->cond, dc);
5048     func(dc, &cmp, a->rd, a->rs2);
5049     return advance_pc(dc);
5050 }
5051 
5052 TRANS(FMOVscc, 64, do_fmovcc, a, false, gen_fmovs)
5053 TRANS(FMOVdcc, 64, do_fmovcc, a, false, gen_fmovd)
5054 TRANS(FMOVqcc, 64, do_fmovcc, a, true, gen_fmovq)
5055 
5056 static bool do_fmovfcc(DisasContext *dc, arg_FMOVsfcc *a, bool is_128,
5057                        void (*func)(DisasContext *, DisasCompare *, int, int))
5058 {
5059     DisasCompare cmp;
5060 
5061     if (gen_trap_ifnofpu(dc)) {
5062         return true;
5063     }
5064     if (is_128 && gen_trap_float128(dc)) {
5065         return true;
5066     }
5067 
5068     gen_op_clear_ieee_excp_and_FTT();
5069     gen_fcompare(&cmp, a->cc, a->cond);
5070     func(dc, &cmp, a->rd, a->rs2);
5071     return advance_pc(dc);
5072 }
5073 
5074 TRANS(FMOVsfcc, 64, do_fmovfcc, a, false, gen_fmovs)
5075 TRANS(FMOVdfcc, 64, do_fmovfcc, a, false, gen_fmovd)
5076 TRANS(FMOVqfcc, 64, do_fmovfcc, a, true, gen_fmovq)
5077 
5078 static bool do_fcmps(DisasContext *dc, arg_FCMPs *a, bool e)
5079 {
5080     TCGv_i32 src1, src2;
5081 
5082     if (avail_32(dc) && a->cc != 0) {
5083         return false;
5084     }
5085     if (gen_trap_ifnofpu(dc)) {
5086         return true;
5087     }
5088 
5089     gen_op_clear_ieee_excp_and_FTT();
5090     src1 = gen_load_fpr_F(dc, a->rs1);
5091     src2 = gen_load_fpr_F(dc, a->rs2);
5092     if (e) {
5093         gen_op_fcmpes(a->cc, src1, src2);
5094     } else {
5095         gen_op_fcmps(a->cc, src1, src2);
5096     }
5097     return advance_pc(dc);
5098 }
5099 
5100 TRANS(FCMPs, ALL, do_fcmps, a, false)
5101 TRANS(FCMPEs, ALL, do_fcmps, a, true)
5102 
5103 static bool do_fcmpd(DisasContext *dc, arg_FCMPd *a, bool e)
5104 {
5105     TCGv_i64 src1, src2;
5106 
5107     if (avail_32(dc) && a->cc != 0) {
5108         return false;
5109     }
5110     if (gen_trap_ifnofpu(dc)) {
5111         return true;
5112     }
5113 
5114     gen_op_clear_ieee_excp_and_FTT();
5115     src1 = gen_load_fpr_D(dc, a->rs1);
5116     src2 = gen_load_fpr_D(dc, a->rs2);
5117     if (e) {
5118         gen_op_fcmped(a->cc, src1, src2);
5119     } else {
5120         gen_op_fcmpd(a->cc, src1, src2);
5121     }
5122     return advance_pc(dc);
5123 }
5124 
5125 TRANS(FCMPd, ALL, do_fcmpd, a, false)
5126 TRANS(FCMPEd, ALL, do_fcmpd, a, true)
5127 
5128 static bool do_fcmpq(DisasContext *dc, arg_FCMPq *a, bool e)
5129 {
5130     if (avail_32(dc) && a->cc != 0) {
5131         return false;
5132     }
5133     if (gen_trap_ifnofpu(dc)) {
5134         return true;
5135     }
5136     if (gen_trap_float128(dc)) {
5137         return true;
5138     }
5139 
5140     gen_op_clear_ieee_excp_and_FTT();
5141     gen_op_load_fpr_QT0(QFPREG(a->rs1));
5142     gen_op_load_fpr_QT1(QFPREG(a->rs2));
5143     if (e) {
5144         gen_op_fcmpeq(a->cc);
5145     } else {
5146         gen_op_fcmpq(a->cc);
5147     }
5148     return advance_pc(dc);
5149 }
5150 
5151 TRANS(FCMPq, ALL, do_fcmpq, a, false)
5152 TRANS(FCMPEq, ALL, do_fcmpq, a, true)
5153 
5154 static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
5155 {
5156     DisasContext *dc = container_of(dcbase, DisasContext, base);
5157     CPUSPARCState *env = cpu_env(cs);
5158     int bound;
5159 
5160     dc->pc = dc->base.pc_first;
5161     dc->npc = (target_ulong)dc->base.tb->cs_base;
5162     dc->mem_idx = dc->base.tb->flags & TB_FLAG_MMU_MASK;
5163     dc->def = &env->def;
5164     dc->fpu_enabled = tb_fpu_enabled(dc->base.tb->flags);
5165     dc->address_mask_32bit = tb_am_enabled(dc->base.tb->flags);
5166 #ifndef CONFIG_USER_ONLY
5167     dc->supervisor = (dc->base.tb->flags & TB_FLAG_SUPER) != 0;
5168 #endif
5169 #ifdef TARGET_SPARC64
5170     dc->fprs_dirty = 0;
5171     dc->asi = (dc->base.tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
5172 #ifndef CONFIG_USER_ONLY
5173     dc->hypervisor = (dc->base.tb->flags & TB_FLAG_HYPER) != 0;
5174 #endif
5175 #endif
5176     /*
5177      * if we reach a page boundary, we stop generation so that the
5178      * PC of a TT_TFAULT exception is always in the right page
5179      */
5180     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
5181     dc->base.max_insns = MIN(dc->base.max_insns, bound);
5182 }
5183 
5184 static void sparc_tr_tb_start(DisasContextBase *db, CPUState *cs)
5185 {
5186 }
5187 
5188 static void sparc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
5189 {
5190     DisasContext *dc = container_of(dcbase, DisasContext, base);
5191     target_ulong npc = dc->npc;
5192 
5193     if (npc & 3) {
5194         switch (npc) {
5195         case JUMP_PC:
5196             assert(dc->jump_pc[1] == dc->pc + 4);
5197             npc = dc->jump_pc[0] | JUMP_PC;
5198             break;
5199         case DYNAMIC_PC:
5200         case DYNAMIC_PC_LOOKUP:
5201             npc = DYNAMIC_PC;
5202             break;
5203         default:
5204             g_assert_not_reached();
5205         }
5206     }
5207     tcg_gen_insn_start(dc->pc, npc);
5208 }
5209 
5210 static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
5211 {
5212     DisasContext *dc = container_of(dcbase, DisasContext, base);
5213     CPUSPARCState *env = cpu_env(cs);
5214     unsigned int insn;
5215 
5216     insn = translator_ldl(env, &dc->base, dc->pc);
5217     dc->base.pc_next += 4;
5218 
5219     if (!decode(dc, insn)) {
5220         gen_exception(dc, TT_ILL_INSN);
5221     }
5222 
5223     if (dc->base.is_jmp == DISAS_NORETURN) {
5224         return;
5225     }
5226     if (dc->pc != dc->base.pc_next) {
5227         dc->base.is_jmp = DISAS_TOO_MANY;
5228     }
5229 }
5230 
5231 static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
5232 {
5233     DisasContext *dc = container_of(dcbase, DisasContext, base);
5234     DisasDelayException *e, *e_next;
5235     bool may_lookup;
5236 
5237     finishing_insn(dc);
5238 
5239     switch (dc->base.is_jmp) {
5240     case DISAS_NEXT:
5241     case DISAS_TOO_MANY:
5242         if (((dc->pc | dc->npc) & 3) == 0) {
5243             /* static PC and NPC: we can use direct chaining */
5244             gen_goto_tb(dc, 0, dc->pc, dc->npc);
5245             break;
5246         }
5247 
5248         may_lookup = true;
5249         if (dc->pc & 3) {
5250             switch (dc->pc) {
5251             case DYNAMIC_PC_LOOKUP:
5252                 break;
5253             case DYNAMIC_PC:
5254                 may_lookup = false;
5255                 break;
5256             default:
5257                 g_assert_not_reached();
5258             }
5259         } else {
5260             tcg_gen_movi_tl(cpu_pc, dc->pc);
5261         }
5262 
5263         if (dc->npc & 3) {
5264             switch (dc->npc) {
5265             case JUMP_PC:
5266                 gen_generic_branch(dc);
5267                 break;
5268             case DYNAMIC_PC:
5269                 may_lookup = false;
5270                 break;
5271             case DYNAMIC_PC_LOOKUP:
5272                 break;
5273             default:
5274                 g_assert_not_reached();
5275             }
5276         } else {
5277             tcg_gen_movi_tl(cpu_npc, dc->npc);
5278         }
5279         if (may_lookup) {
5280             tcg_gen_lookup_and_goto_ptr();
5281         } else {
5282             tcg_gen_exit_tb(NULL, 0);
5283         }
5284         break;
5285 
5286     case DISAS_NORETURN:
5287        break;
5288 
5289     case DISAS_EXIT:
5290         /* Exit TB */
5291         save_state(dc);
5292         tcg_gen_exit_tb(NULL, 0);
5293         break;
5294 
5295     default:
5296         g_assert_not_reached();
5297     }
5298 
5299     for (e = dc->delay_excp_list; e ; e = e_next) {
5300         gen_set_label(e->lab);
5301 
5302         tcg_gen_movi_tl(cpu_pc, e->pc);
5303         if (e->npc % 4 == 0) {
5304             tcg_gen_movi_tl(cpu_npc, e->npc);
5305         }
5306         gen_helper_raise_exception(tcg_env, e->excp);
5307 
5308         e_next = e->next;
5309         g_free(e);
5310     }
5311 }
5312 
5313 static void sparc_tr_disas_log(const DisasContextBase *dcbase,
5314                                CPUState *cpu, FILE *logfile)
5315 {
5316     fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
5317     target_disas(logfile, cpu, dcbase->pc_first, dcbase->tb->size);
5318 }
5319 
5320 static const TranslatorOps sparc_tr_ops = {
5321     .init_disas_context = sparc_tr_init_disas_context,
5322     .tb_start           = sparc_tr_tb_start,
5323     .insn_start         = sparc_tr_insn_start,
5324     .translate_insn     = sparc_tr_translate_insn,
5325     .tb_stop            = sparc_tr_tb_stop,
5326     .disas_log          = sparc_tr_disas_log,
5327 };
5328 
5329 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
5330                            target_ulong pc, void *host_pc)
5331 {
5332     DisasContext dc = {};
5333 
5334     translator_loop(cs, tb, max_insns, pc, host_pc, &sparc_tr_ops, &dc.base);
5335 }
5336 
5337 void sparc_tcg_init(void)
5338 {
5339     static const char gregnames[32][4] = {
5340         "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
5341         "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
5342         "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
5343         "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
5344     };
5345     static const char fregnames[32][4] = {
5346         "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14",
5347         "f16", "f18", "f20", "f22", "f24", "f26", "f28", "f30",
5348         "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
5349         "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
5350     };
5351 
5352     static const struct { TCGv *ptr; int off; const char *name; } rtl[] = {
5353 #ifdef TARGET_SPARC64
5354         { &cpu_gsr, offsetof(CPUSPARCState, gsr), "gsr" },
5355         { &cpu_xcc_Z, offsetof(CPUSPARCState, xcc_Z), "xcc_Z" },
5356         { &cpu_xcc_C, offsetof(CPUSPARCState, xcc_C), "xcc_C" },
5357 #endif
5358         { &cpu_cc_N, offsetof(CPUSPARCState, cc_N), "cc_N" },
5359         { &cpu_cc_V, offsetof(CPUSPARCState, cc_V), "cc_V" },
5360         { &cpu_icc_Z, offsetof(CPUSPARCState, icc_Z), "icc_Z" },
5361         { &cpu_icc_C, offsetof(CPUSPARCState, icc_C), "icc_C" },
5362         { &cpu_cond, offsetof(CPUSPARCState, cond), "cond" },
5363         { &cpu_fsr, offsetof(CPUSPARCState, fsr), "fsr" },
5364         { &cpu_pc, offsetof(CPUSPARCState, pc), "pc" },
5365         { &cpu_npc, offsetof(CPUSPARCState, npc), "npc" },
5366         { &cpu_y, offsetof(CPUSPARCState, y), "y" },
5367         { &cpu_tbr, offsetof(CPUSPARCState, tbr), "tbr" },
5368     };
5369 
5370     unsigned int i;
5371 
5372     cpu_regwptr = tcg_global_mem_new_ptr(tcg_env,
5373                                          offsetof(CPUSPARCState, regwptr),
5374                                          "regwptr");
5375 
5376     for (i = 0; i < ARRAY_SIZE(rtl); ++i) {
5377         *rtl[i].ptr = tcg_global_mem_new(tcg_env, rtl[i].off, rtl[i].name);
5378     }
5379 
5380     cpu_regs[0] = NULL;
5381     for (i = 1; i < 8; ++i) {
5382         cpu_regs[i] = tcg_global_mem_new(tcg_env,
5383                                          offsetof(CPUSPARCState, gregs[i]),
5384                                          gregnames[i]);
5385     }
5386 
5387     for (i = 8; i < 32; ++i) {
5388         cpu_regs[i] = tcg_global_mem_new(cpu_regwptr,
5389                                          (i - 8) * sizeof(target_ulong),
5390                                          gregnames[i]);
5391     }
5392 
5393     for (i = 0; i < TARGET_DPREGS; i++) {
5394         cpu_fpr[i] = tcg_global_mem_new_i64(tcg_env,
5395                                             offsetof(CPUSPARCState, fpr[i]),
5396                                             fregnames[i]);
5397     }
5398 
5399 #ifdef TARGET_SPARC64
5400     cpu_fprs = tcg_global_mem_new_i32(tcg_env,
5401                                       offsetof(CPUSPARCState, fprs), "fprs");
5402 #endif
5403 }
5404 
5405 void sparc_restore_state_to_opc(CPUState *cs,
5406                                 const TranslationBlock *tb,
5407                                 const uint64_t *data)
5408 {
5409     SPARCCPU *cpu = SPARC_CPU(cs);
5410     CPUSPARCState *env = &cpu->env;
5411     target_ulong pc = data[0];
5412     target_ulong npc = data[1];
5413 
5414     env->pc = pc;
5415     if (npc == DYNAMIC_PC) {
5416         /* dynamic NPC: already stored */
5417     } else if (npc & JUMP_PC) {
5418         /* jump PC: use 'cond' and the jump targets of the translation */
5419         if (env->cond) {
5420             env->npc = npc & ~3;
5421         } else {
5422             env->npc = pc + 4;
5423         }
5424     } else {
5425         env->npc = npc;
5426     }
5427 }
5428