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 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 <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <inttypes.h>
26 
27 #include "cpu.h"
28 #include "exec-all.h"
29 #include "disas.h"
30 #include "helper.h"
31 #include "tcg-op.h"
32 
33 #define GEN_HELPER 1
34 #include "helper.h"
35 
36 #define DEBUG_DISAS
37 
38 #define DYNAMIC_PC  1 /* dynamic pc value */
39 #define JUMP_PC     2 /* dynamic pc value which takes only two values
40                          according to jump_pc[T2] */
41 
42 /* global register indexes */
43 static TCGv_ptr cpu_env, cpu_regwptr;
44 static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
45 static TCGv_i32 cpu_cc_op;
46 static TCGv_i32 cpu_psr;
47 static TCGv cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
48 static TCGv cpu_y;
49 #ifndef CONFIG_USER_ONLY
50 static TCGv cpu_tbr;
51 #endif
52 static TCGv cpu_cond, cpu_dst, cpu_addr, cpu_val;
53 #ifdef TARGET_SPARC64
54 static TCGv_i32 cpu_xcc, cpu_asi, cpu_fprs;
55 static TCGv cpu_gsr;
56 static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
57 static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
58 static TCGv_i32 cpu_softint;
59 #else
60 static TCGv cpu_wim;
61 #endif
62 /* local register indexes (only used inside old micro ops) */
63 static TCGv cpu_tmp0;
64 static TCGv_i32 cpu_tmp32;
65 static TCGv_i64 cpu_tmp64;
66 /* Floating point registers */
67 static TCGv_i32 cpu_fpr[TARGET_FPREGS];
68 
69 static target_ulong gen_opc_npc[OPC_BUF_SIZE];
70 static target_ulong gen_opc_jump_pc[2];
71 
72 #include "gen-icount.h"
73 
74 typedef struct DisasContext {
75     target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
76     target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
77     target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
78     int is_br;
79     int mem_idx;
80     int fpu_enabled;
81     int address_mask_32bit;
82     int singlestep;
83     uint32_t cc_op;  /* current CC operation */
84     struct TranslationBlock *tb;
85     sparc_def_t *def;
86 } DisasContext;
87 
88 // This function uses non-native bit order
89 #define GET_FIELD(X, FROM, TO)                                  \
90     ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
91 
92 // This function uses the order in the manuals, i.e. bit 0 is 2^0
93 #define GET_FIELD_SP(X, FROM, TO)               \
94     GET_FIELD(X, 31 - (TO), 31 - (FROM))
95 
96 #define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
97 #define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
98 
99 #ifdef TARGET_SPARC64
100 #define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
101 #define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
102 #else
103 #define DFPREG(r) (r & 0x1e)
104 #define QFPREG(r) (r & 0x1c)
105 #endif
106 
107 #define UA2005_HTRAP_MASK 0xff
108 #define V8_TRAP_MASK 0x7f
109 
sign_extend(int x,int len)110 static int sign_extend(int x, int len)
111 {
112     len = 32 - len;
113     return (x << len) >> len;
114 }
115 
116 #define IS_IMM (insn & (1<<13))
117 
118 /* floating point registers moves */
gen_op_load_fpr_DT0(unsigned int src)119 static void gen_op_load_fpr_DT0(unsigned int src)
120 {
121     tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) +
122                    offsetof(CPU_DoubleU, l.upper));
123     tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
124                    offsetof(CPU_DoubleU, l.lower));
125 }
126 
gen_op_load_fpr_DT1(unsigned int src)127 static void gen_op_load_fpr_DT1(unsigned int src)
128 {
129     tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt1) +
130                    offsetof(CPU_DoubleU, l.upper));
131     tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt1) +
132                    offsetof(CPU_DoubleU, l.lower));
133 }
134 
gen_op_store_DT0_fpr(unsigned int dst)135 static void gen_op_store_DT0_fpr(unsigned int dst)
136 {
137     tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, dt0) +
138                    offsetof(CPU_DoubleU, l.upper));
139     tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
140                    offsetof(CPU_DoubleU, l.lower));
141 }
142 
gen_op_load_fpr_QT0(unsigned int src)143 static void gen_op_load_fpr_QT0(unsigned int src)
144 {
145     tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) +
146                    offsetof(CPU_QuadU, l.upmost));
147     tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
148                    offsetof(CPU_QuadU, l.upper));
149     tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
150                    offsetof(CPU_QuadU, l.lower));
151     tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
152                    offsetof(CPU_QuadU, l.lowest));
153 }
154 
gen_op_load_fpr_QT1(unsigned int src)155 static void gen_op_load_fpr_QT1(unsigned int src)
156 {
157     tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt1) +
158                    offsetof(CPU_QuadU, l.upmost));
159     tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt1) +
160                    offsetof(CPU_QuadU, l.upper));
161     tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt1) +
162                    offsetof(CPU_QuadU, l.lower));
163     tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt1) +
164                    offsetof(CPU_QuadU, l.lowest));
165 }
166 
gen_op_store_QT0_fpr(unsigned int dst)167 static void gen_op_store_QT0_fpr(unsigned int dst)
168 {
169     tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) +
170                    offsetof(CPU_QuadU, l.upmost));
171     tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
172                    offsetof(CPU_QuadU, l.upper));
173     tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
174                    offsetof(CPU_QuadU, l.lower));
175     tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
176                    offsetof(CPU_QuadU, l.lowest));
177 }
178 
179 /* moves */
180 #ifdef CONFIG_USER_ONLY
181 #define supervisor(dc) 0
182 #ifdef TARGET_SPARC64
183 #define hypervisor(dc) 0
184 #endif
185 #else
186 #define supervisor(dc) (dc->mem_idx >= MMU_KERNEL_IDX)
187 #ifdef TARGET_SPARC64
188 #define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX)
189 #else
190 #endif
191 #endif
192 
193 #ifdef TARGET_SPARC64
194 #ifndef TARGET_ABI32
195 #define AM_CHECK(dc) ((dc)->address_mask_32bit)
196 #else
197 #define AM_CHECK(dc) (1)
198 #endif
199 #endif
200 
gen_address_mask(DisasContext * dc,TCGv addr)201 static inline void gen_address_mask(DisasContext *dc, TCGv addr)
202 {
203 #ifdef TARGET_SPARC64
204     if (AM_CHECK(dc))
205         tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
206 #endif
207 }
208 
gen_movl_reg_TN(int reg,TCGv tn)209 static inline void gen_movl_reg_TN(int reg, TCGv tn)
210 {
211     if (reg == 0)
212         tcg_gen_movi_tl(tn, 0);
213     else if (reg < 8)
214         tcg_gen_mov_tl(tn, cpu_gregs[reg]);
215     else {
216         tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
217     }
218 }
219 
gen_movl_TN_reg(int reg,TCGv tn)220 static inline void gen_movl_TN_reg(int reg, TCGv tn)
221 {
222     if (reg == 0)
223         return;
224     else if (reg < 8)
225         tcg_gen_mov_tl(cpu_gregs[reg], tn);
226     else {
227         tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
228     }
229 }
230 
gen_goto_tb(DisasContext * s,int tb_num,target_ulong pc,target_ulong npc)231 static inline void gen_goto_tb(DisasContext *s, int tb_num,
232                                target_ulong pc, target_ulong npc)
233 {
234     TranslationBlock *tb;
235 
236     tb = s->tb;
237     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
238         (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
239         !s->singlestep)  {
240         /* jump to same page: we can use a direct jump */
241         tcg_gen_goto_tb(tb_num);
242         tcg_gen_movi_tl(cpu_pc, pc);
243         tcg_gen_movi_tl(cpu_npc, npc);
244         tcg_gen_exit_tb((long)tb + tb_num);
245     } else {
246         /* jump to another page: currently not optimized */
247         tcg_gen_movi_tl(cpu_pc, pc);
248         tcg_gen_movi_tl(cpu_npc, npc);
249         tcg_gen_exit_tb(0);
250     }
251 }
252 
253 // XXX suboptimal
gen_mov_reg_N(TCGv reg,TCGv_i32 src)254 static inline void gen_mov_reg_N(TCGv reg, TCGv_i32 src)
255 {
256     tcg_gen_extu_i32_tl(reg, src);
257     tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
258     tcg_gen_andi_tl(reg, reg, 0x1);
259 }
260 
gen_mov_reg_Z(TCGv reg,TCGv_i32 src)261 static inline void gen_mov_reg_Z(TCGv reg, TCGv_i32 src)
262 {
263     tcg_gen_extu_i32_tl(reg, src);
264     tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
265     tcg_gen_andi_tl(reg, reg, 0x1);
266 }
267 
gen_mov_reg_V(TCGv reg,TCGv_i32 src)268 static inline void gen_mov_reg_V(TCGv reg, TCGv_i32 src)
269 {
270     tcg_gen_extu_i32_tl(reg, src);
271     tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
272     tcg_gen_andi_tl(reg, reg, 0x1);
273 }
274 
gen_mov_reg_C(TCGv reg,TCGv_i32 src)275 static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
276 {
277     tcg_gen_extu_i32_tl(reg, src);
278     tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
279     tcg_gen_andi_tl(reg, reg, 0x1);
280 }
281 
gen_add_tv(TCGv dst,TCGv src1,TCGv src2)282 static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
283 {
284     TCGv r_temp;
285     TCGv_i32 r_const;
286     int l1;
287 
288     l1 = gen_new_label();
289 
290     r_temp = tcg_temp_new();
291     tcg_gen_xor_tl(r_temp, src1, src2);
292     tcg_gen_not_tl(r_temp, r_temp);
293     tcg_gen_xor_tl(cpu_tmp0, src1, dst);
294     tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
295     tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
296     tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
297     r_const = tcg_const_i32(TT_TOVF);
298     gen_helper_raise_exception(r_const);
299     tcg_temp_free_i32(r_const);
300     gen_set_label(l1);
301     tcg_temp_free(r_temp);
302 }
303 
gen_tag_tv(TCGv src1,TCGv src2)304 static inline void gen_tag_tv(TCGv src1, TCGv src2)
305 {
306     int l1;
307     TCGv_i32 r_const;
308 
309     l1 = gen_new_label();
310     tcg_gen_or_tl(cpu_tmp0, src1, src2);
311     tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
312     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
313     r_const = tcg_const_i32(TT_TOVF);
314     gen_helper_raise_exception(r_const);
315     tcg_temp_free_i32(r_const);
316     gen_set_label(l1);
317 }
318 
gen_op_addi_cc(TCGv dst,TCGv src1,target_long src2)319 static inline void gen_op_addi_cc(TCGv dst, TCGv src1, target_long src2)
320 {
321     tcg_gen_mov_tl(cpu_cc_src, src1);
322     tcg_gen_movi_tl(cpu_cc_src2, src2);
323     tcg_gen_addi_tl(cpu_cc_dst, cpu_cc_src, src2);
324     tcg_gen_mov_tl(dst, cpu_cc_dst);
325 }
326 
gen_op_add_cc(TCGv dst,TCGv src1,TCGv src2)327 static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
328 {
329     tcg_gen_mov_tl(cpu_cc_src, src1);
330     tcg_gen_mov_tl(cpu_cc_src2, src2);
331     tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
332     tcg_gen_mov_tl(dst, cpu_cc_dst);
333 }
334 
gen_add32_carry32(void)335 static TCGv_i32 gen_add32_carry32(void)
336 {
337     TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
338 
339     /* Carry is computed from a previous add: (dst < src)  */
340 #if TARGET_LONG_BITS == 64
341     cc_src1_32 = tcg_temp_new_i32();
342     cc_src2_32 = tcg_temp_new_i32();
343     tcg_gen_trunc_i64_i32(cc_src1_32, cpu_cc_dst);
344     tcg_gen_trunc_i64_i32(cc_src2_32, cpu_cc_src);
345 #else
346     cc_src1_32 = cpu_cc_dst;
347     cc_src2_32 = cpu_cc_src;
348 #endif
349 
350     carry_32 = tcg_temp_new_i32();
351     tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
352 
353 #if TARGET_LONG_BITS == 64
354     tcg_temp_free_i32(cc_src1_32);
355     tcg_temp_free_i32(cc_src2_32);
356 #endif
357 
358     return carry_32;
359 }
360 
gen_sub32_carry32(void)361 static TCGv_i32 gen_sub32_carry32(void)
362 {
363     TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
364 
365     /* Carry is computed from a previous borrow: (src1 < src2)  */
366 #if TARGET_LONG_BITS == 64
367     cc_src1_32 = tcg_temp_new_i32();
368     cc_src2_32 = tcg_temp_new_i32();
369     tcg_gen_trunc_i64_i32(cc_src1_32, cpu_cc_src);
370     tcg_gen_trunc_i64_i32(cc_src2_32, cpu_cc_src2);
371 #else
372     cc_src1_32 = cpu_cc_src;
373     cc_src2_32 = cpu_cc_src2;
374 #endif
375 
376     carry_32 = tcg_temp_new_i32();
377     tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
378 
379 #if TARGET_LONG_BITS == 64
380     tcg_temp_free_i32(cc_src1_32);
381     tcg_temp_free_i32(cc_src2_32);
382 #endif
383 
384     return carry_32;
385 }
386 
gen_op_addx_int(DisasContext * dc,TCGv dst,TCGv src1,TCGv src2,int update_cc)387 static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
388                             TCGv src2, int update_cc)
389 {
390     TCGv_i32 carry_32;
391     TCGv carry;
392 
393     switch (dc->cc_op) {
394     case CC_OP_DIV:
395     case CC_OP_LOGIC:
396         /* Carry is known to be zero.  Fall back to plain ADD.  */
397         if (update_cc) {
398             gen_op_add_cc(dst, src1, src2);
399         } else {
400             tcg_gen_add_tl(dst, src1, src2);
401         }
402         return;
403 
404     case CC_OP_ADD:
405     case CC_OP_TADD:
406     case CC_OP_TADDTV:
407 #if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
408         {
409             /* For 32-bit hosts, we can re-use the host's hardware carry
410                generation by using an ADD2 opcode.  We discard the low
411                part of the output.  Ideally we'd combine this operation
412                with the add that generated the carry in the first place.  */
413             TCGv dst_low = tcg_temp_new();
414             tcg_gen_op6_i32(INDEX_op_add2_i32, dst_low, dst,
415                             cpu_cc_src, src1, cpu_cc_src2, src2);
416             tcg_temp_free(dst_low);
417             goto add_done;
418         }
419 #endif
420         carry_32 = gen_add32_carry32();
421         break;
422 
423     case CC_OP_SUB:
424     case CC_OP_TSUB:
425     case CC_OP_TSUBTV:
426         carry_32 = gen_sub32_carry32();
427         break;
428 
429     default:
430         /* We need external help to produce the carry.  */
431         carry_32 = tcg_temp_new_i32();
432         gen_helper_compute_C_icc(carry_32);
433         break;
434     }
435 
436 #if TARGET_LONG_BITS == 64
437     carry = tcg_temp_new();
438     tcg_gen_extu_i32_i64(carry, carry_32);
439 #else
440     carry = carry_32;
441 #endif
442 
443     tcg_gen_add_tl(dst, src1, src2);
444     tcg_gen_add_tl(dst, dst, carry);
445 
446     tcg_temp_free_i32(carry_32);
447 #if TARGET_LONG_BITS == 64
448     tcg_temp_free(carry);
449 #endif
450 
451 #if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
452  add_done:
453 #endif
454     if (update_cc) {
455         tcg_gen_mov_tl(cpu_cc_src, src1);
456         tcg_gen_mov_tl(cpu_cc_src2, src2);
457         tcg_gen_mov_tl(cpu_cc_dst, dst);
458         tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADDX);
459         dc->cc_op = CC_OP_ADDX;
460     }
461 }
462 
gen_op_tadd_cc(TCGv dst,TCGv src1,TCGv src2)463 static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
464 {
465     tcg_gen_mov_tl(cpu_cc_src, src1);
466     tcg_gen_mov_tl(cpu_cc_src2, src2);
467     tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
468     tcg_gen_mov_tl(dst, cpu_cc_dst);
469 }
470 
gen_op_tadd_ccTV(TCGv dst,TCGv src1,TCGv src2)471 static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
472 {
473     tcg_gen_mov_tl(cpu_cc_src, src1);
474     tcg_gen_mov_tl(cpu_cc_src2, src2);
475     gen_tag_tv(cpu_cc_src, cpu_cc_src2);
476     tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
477     gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
478     tcg_gen_mov_tl(dst, cpu_cc_dst);
479 }
480 
gen_sub_tv(TCGv dst,TCGv src1,TCGv src2)481 static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
482 {
483     TCGv r_temp;
484     TCGv_i32 r_const;
485     int l1;
486 
487     l1 = gen_new_label();
488 
489     r_temp = tcg_temp_new();
490     tcg_gen_xor_tl(r_temp, src1, src2);
491     tcg_gen_xor_tl(cpu_tmp0, src1, dst);
492     tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
493     tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
494     tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
495     r_const = tcg_const_i32(TT_TOVF);
496     gen_helper_raise_exception(r_const);
497     tcg_temp_free_i32(r_const);
498     gen_set_label(l1);
499     tcg_temp_free(r_temp);
500 }
501 
gen_op_subi_cc(TCGv dst,TCGv src1,target_long src2,DisasContext * dc)502 static inline void gen_op_subi_cc(TCGv dst, TCGv src1, target_long src2, DisasContext *dc)
503 {
504     tcg_gen_mov_tl(cpu_cc_src, src1);
505     tcg_gen_movi_tl(cpu_cc_src2, src2);
506     if (src2 == 0) {
507         tcg_gen_mov_tl(cpu_cc_dst, src1);
508         tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
509         dc->cc_op = CC_OP_LOGIC;
510     } else {
511         tcg_gen_subi_tl(cpu_cc_dst, cpu_cc_src, src2);
512         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
513         dc->cc_op = CC_OP_SUB;
514     }
515     tcg_gen_mov_tl(dst, cpu_cc_dst);
516 }
517 
gen_op_sub_cc(TCGv dst,TCGv src1,TCGv src2)518 static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
519 {
520     tcg_gen_mov_tl(cpu_cc_src, src1);
521     tcg_gen_mov_tl(cpu_cc_src2, src2);
522     tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
523     tcg_gen_mov_tl(dst, cpu_cc_dst);
524 }
525 
gen_op_subx_int(DisasContext * dc,TCGv dst,TCGv src1,TCGv src2,int update_cc)526 static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
527                             TCGv src2, int update_cc)
528 {
529     TCGv_i32 carry_32;
530     TCGv carry;
531 
532     switch (dc->cc_op) {
533     case CC_OP_DIV:
534     case CC_OP_LOGIC:
535         /* Carry is known to be zero.  Fall back to plain SUB.  */
536         if (update_cc) {
537             gen_op_sub_cc(dst, src1, src2);
538         } else {
539             tcg_gen_sub_tl(dst, src1, src2);
540         }
541         return;
542 
543     case CC_OP_ADD:
544     case CC_OP_TADD:
545     case CC_OP_TADDTV:
546         carry_32 = gen_add32_carry32();
547         break;
548 
549     case CC_OP_SUB:
550     case CC_OP_TSUB:
551     case CC_OP_TSUBTV:
552 #if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
553         {
554             /* For 32-bit hosts, we can re-use the host's hardware carry
555                generation by using a SUB2 opcode.  We discard the low
556                part of the output.  Ideally we'd combine this operation
557                with the add that generated the carry in the first place.  */
558             TCGv dst_low = tcg_temp_new();
559             tcg_gen_op6_i32(INDEX_op_sub2_i32, dst_low, dst,
560                             cpu_cc_src, src1, cpu_cc_src2, src2);
561             tcg_temp_free(dst_low);
562             goto sub_done;
563         }
564 #endif
565         carry_32 = gen_sub32_carry32();
566         break;
567 
568     default:
569         /* We need external help to produce the carry.  */
570         carry_32 = tcg_temp_new_i32();
571         gen_helper_compute_C_icc(carry_32);
572         break;
573     }
574 
575 #if TARGET_LONG_BITS == 64
576     carry = tcg_temp_new();
577     tcg_gen_extu_i32_i64(carry, carry_32);
578 #else
579     carry = carry_32;
580 #endif
581 
582     tcg_gen_sub_tl(dst, src1, src2);
583     tcg_gen_sub_tl(dst, dst, carry);
584 
585     tcg_temp_free_i32(carry_32);
586 #if TARGET_LONG_BITS == 64
587     tcg_temp_free(carry);
588 #endif
589 
590 #if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
591  sub_done:
592 #endif
593     if (update_cc) {
594         tcg_gen_mov_tl(cpu_cc_src, src1);
595         tcg_gen_mov_tl(cpu_cc_src2, src2);
596         tcg_gen_mov_tl(cpu_cc_dst, dst);
597         tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUBX);
598         dc->cc_op = CC_OP_SUBX;
599     }
600 }
601 
gen_op_tsub_cc(TCGv dst,TCGv src1,TCGv src2)602 static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
603 {
604     tcg_gen_mov_tl(cpu_cc_src, src1);
605     tcg_gen_mov_tl(cpu_cc_src2, src2);
606     tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
607     tcg_gen_mov_tl(dst, cpu_cc_dst);
608 }
609 
gen_op_tsub_ccTV(TCGv dst,TCGv src1,TCGv src2)610 static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
611 {
612     tcg_gen_mov_tl(cpu_cc_src, src1);
613     tcg_gen_mov_tl(cpu_cc_src2, src2);
614     gen_tag_tv(cpu_cc_src, cpu_cc_src2);
615     tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
616     gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
617     tcg_gen_mov_tl(dst, cpu_cc_dst);
618 }
619 
gen_op_mulscc(TCGv dst,TCGv src1,TCGv src2)620 static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
621 {
622     TCGv r_temp;
623     int l1;
624 
625     l1 = gen_new_label();
626     r_temp = tcg_temp_new();
627 
628     /* old op:
629     if (!(env->y & 1))
630         T1 = 0;
631     */
632     tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
633     tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
634     tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
635     tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
636     tcg_gen_movi_tl(cpu_cc_src2, 0);
637     gen_set_label(l1);
638 
639     // b2 = T0 & 1;
640     // env->y = (b2 << 31) | (env->y >> 1);
641     tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
642     tcg_gen_shli_tl(r_temp, r_temp, 31);
643     tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
644     tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);
645     tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
646     tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
647 
648     // b1 = N ^ V;
649     gen_mov_reg_N(cpu_tmp0, cpu_psr);
650     gen_mov_reg_V(r_temp, cpu_psr);
651     tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
652     tcg_temp_free(r_temp);
653 
654     // T0 = (b1 << 31) | (T0 >> 1);
655     // src1 = T0;
656     tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
657     tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
658     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
659 
660     tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
661 
662     tcg_gen_mov_tl(dst, cpu_cc_dst);
663 }
664 
gen_op_multiply(TCGv dst,TCGv src1,TCGv src2,int sign_ext)665 static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)
666 {
667     TCGv_i32 r_src1, r_src2;
668     TCGv_i64 r_temp, r_temp2;
669 
670     r_src1 = tcg_temp_new_i32();
671     r_src2 = tcg_temp_new_i32();
672 
673     tcg_gen_trunc_tl_i32(r_src1, src1);
674     tcg_gen_trunc_tl_i32(r_src2, src2);
675 
676     r_temp = tcg_temp_new_i64();
677     r_temp2 = tcg_temp_new_i64();
678 
679     if (sign_ext) {
680         tcg_gen_ext_i32_i64(r_temp, r_src2);
681         tcg_gen_ext_i32_i64(r_temp2, r_src1);
682     } else {
683         tcg_gen_extu_i32_i64(r_temp, r_src2);
684         tcg_gen_extu_i32_i64(r_temp2, r_src1);
685     }
686 
687     tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
688 
689     tcg_gen_shri_i64(r_temp, r_temp2, 32);
690     tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
691     tcg_temp_free_i64(r_temp);
692     tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
693 
694     tcg_gen_trunc_i64_tl(dst, r_temp2);
695 
696     tcg_temp_free_i64(r_temp2);
697 
698     tcg_temp_free_i32(r_src1);
699     tcg_temp_free_i32(r_src2);
700 }
701 
gen_op_umul(TCGv dst,TCGv src1,TCGv src2)702 static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
703 {
704     /* zero-extend truncated operands before multiplication */
705     gen_op_multiply(dst, src1, src2, 0);
706 }
707 
gen_op_smul(TCGv dst,TCGv src1,TCGv src2)708 static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
709 {
710     /* sign-extend truncated operands before multiplication */
711     gen_op_multiply(dst, src1, src2, 1);
712 }
713 
714 #ifdef TARGET_SPARC64
gen_trap_ifdivzero_tl(TCGv divisor)715 static inline void gen_trap_ifdivzero_tl(TCGv divisor)
716 {
717     TCGv_i32 r_const;
718     int l1;
719 
720     l1 = gen_new_label();
721     tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
722     r_const = tcg_const_i32(TT_DIV_ZERO);
723     gen_helper_raise_exception(r_const);
724     tcg_temp_free_i32(r_const);
725     gen_set_label(l1);
726 }
727 
gen_op_sdivx(TCGv dst,TCGv src1,TCGv src2)728 static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
729 {
730     int l1, l2;
731 
732     l1 = gen_new_label();
733     l2 = gen_new_label();
734     tcg_gen_mov_tl(cpu_cc_src, src1);
735     tcg_gen_mov_tl(cpu_cc_src2, src2);
736     gen_trap_ifdivzero_tl(cpu_cc_src2);
737     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
738     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
739     tcg_gen_movi_i64(dst, INT64_MIN);
740     tcg_gen_br(l2);
741     gen_set_label(l1);
742     tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
743     gen_set_label(l2);
744 }
745 #endif
746 
747 // 1
gen_op_eval_ba(TCGv dst)748 static inline void gen_op_eval_ba(TCGv dst)
749 {
750     tcg_gen_movi_tl(dst, 1);
751 }
752 
753 // Z
gen_op_eval_be(TCGv dst,TCGv_i32 src)754 static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
755 {
756     gen_mov_reg_Z(dst, src);
757 }
758 
759 // Z | (N ^ V)
gen_op_eval_ble(TCGv dst,TCGv_i32 src)760 static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
761 {
762     gen_mov_reg_N(cpu_tmp0, src);
763     gen_mov_reg_V(dst, src);
764     tcg_gen_xor_tl(dst, dst, cpu_tmp0);
765     gen_mov_reg_Z(cpu_tmp0, src);
766     tcg_gen_or_tl(dst, dst, cpu_tmp0);
767 }
768 
769 // N ^ V
gen_op_eval_bl(TCGv dst,TCGv_i32 src)770 static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
771 {
772     gen_mov_reg_V(cpu_tmp0, src);
773     gen_mov_reg_N(dst, src);
774     tcg_gen_xor_tl(dst, dst, cpu_tmp0);
775 }
776 
777 // C | Z
gen_op_eval_bleu(TCGv dst,TCGv_i32 src)778 static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
779 {
780     gen_mov_reg_Z(cpu_tmp0, src);
781     gen_mov_reg_C(dst, src);
782     tcg_gen_or_tl(dst, dst, cpu_tmp0);
783 }
784 
785 // C
gen_op_eval_bcs(TCGv dst,TCGv_i32 src)786 static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
787 {
788     gen_mov_reg_C(dst, src);
789 }
790 
791 // V
gen_op_eval_bvs(TCGv dst,TCGv_i32 src)792 static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
793 {
794     gen_mov_reg_V(dst, src);
795 }
796 
797 // 0
gen_op_eval_bn(TCGv dst)798 static inline void gen_op_eval_bn(TCGv dst)
799 {
800     tcg_gen_movi_tl(dst, 0);
801 }
802 
803 // N
gen_op_eval_bneg(TCGv dst,TCGv_i32 src)804 static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
805 {
806     gen_mov_reg_N(dst, src);
807 }
808 
809 // !Z
gen_op_eval_bne(TCGv dst,TCGv_i32 src)810 static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
811 {
812     gen_mov_reg_Z(dst, src);
813     tcg_gen_xori_tl(dst, dst, 0x1);
814 }
815 
816 // !(Z | (N ^ V))
gen_op_eval_bg(TCGv dst,TCGv_i32 src)817 static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
818 {
819     gen_mov_reg_N(cpu_tmp0, src);
820     gen_mov_reg_V(dst, src);
821     tcg_gen_xor_tl(dst, dst, cpu_tmp0);
822     gen_mov_reg_Z(cpu_tmp0, src);
823     tcg_gen_or_tl(dst, dst, cpu_tmp0);
824     tcg_gen_xori_tl(dst, dst, 0x1);
825 }
826 
827 // !(N ^ V)
gen_op_eval_bge(TCGv dst,TCGv_i32 src)828 static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
829 {
830     gen_mov_reg_V(cpu_tmp0, src);
831     gen_mov_reg_N(dst, src);
832     tcg_gen_xor_tl(dst, dst, cpu_tmp0);
833     tcg_gen_xori_tl(dst, dst, 0x1);
834 }
835 
836 // !(C | Z)
gen_op_eval_bgu(TCGv dst,TCGv_i32 src)837 static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
838 {
839     gen_mov_reg_Z(cpu_tmp0, src);
840     gen_mov_reg_C(dst, src);
841     tcg_gen_or_tl(dst, dst, cpu_tmp0);
842     tcg_gen_xori_tl(dst, dst, 0x1);
843 }
844 
845 // !C
gen_op_eval_bcc(TCGv dst,TCGv_i32 src)846 static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
847 {
848     gen_mov_reg_C(dst, src);
849     tcg_gen_xori_tl(dst, dst, 0x1);
850 }
851 
852 // !N
gen_op_eval_bpos(TCGv dst,TCGv_i32 src)853 static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
854 {
855     gen_mov_reg_N(dst, src);
856     tcg_gen_xori_tl(dst, dst, 0x1);
857 }
858 
859 // !V
gen_op_eval_bvc(TCGv dst,TCGv_i32 src)860 static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
861 {
862     gen_mov_reg_V(dst, src);
863     tcg_gen_xori_tl(dst, dst, 0x1);
864 }
865 
866 /*
867   FPSR bit field FCC1 | FCC0:
868    0 =
869    1 <
870    2 >
871    3 unordered
872 */
gen_mov_reg_FCC0(TCGv reg,TCGv src,unsigned int fcc_offset)873 static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
874                                     unsigned int fcc_offset)
875 {
876     tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
877     tcg_gen_andi_tl(reg, reg, 0x1);
878 }
879 
gen_mov_reg_FCC1(TCGv reg,TCGv src,unsigned int fcc_offset)880 static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
881                                     unsigned int fcc_offset)
882 {
883     tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
884     tcg_gen_andi_tl(reg, reg, 0x1);
885 }
886 
887 // !0: FCC0 | FCC1
gen_op_eval_fbne(TCGv dst,TCGv src,unsigned int fcc_offset)888 static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
889                                     unsigned int fcc_offset)
890 {
891     gen_mov_reg_FCC0(dst, src, fcc_offset);
892     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
893     tcg_gen_or_tl(dst, dst, cpu_tmp0);
894 }
895 
896 // 1 or 2: FCC0 ^ FCC1
gen_op_eval_fblg(TCGv dst,TCGv src,unsigned int fcc_offset)897 static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
898                                     unsigned int fcc_offset)
899 {
900     gen_mov_reg_FCC0(dst, src, fcc_offset);
901     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
902     tcg_gen_xor_tl(dst, dst, cpu_tmp0);
903 }
904 
905 // 1 or 3: FCC0
gen_op_eval_fbul(TCGv dst,TCGv src,unsigned int fcc_offset)906 static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
907                                     unsigned int fcc_offset)
908 {
909     gen_mov_reg_FCC0(dst, src, fcc_offset);
910 }
911 
912 // 1: FCC0 & !FCC1
gen_op_eval_fbl(TCGv dst,TCGv src,unsigned int fcc_offset)913 static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
914                                     unsigned int fcc_offset)
915 {
916     gen_mov_reg_FCC0(dst, src, fcc_offset);
917     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
918     tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
919     tcg_gen_and_tl(dst, dst, cpu_tmp0);
920 }
921 
922 // 2 or 3: FCC1
gen_op_eval_fbug(TCGv dst,TCGv src,unsigned int fcc_offset)923 static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
924                                     unsigned int fcc_offset)
925 {
926     gen_mov_reg_FCC1(dst, src, fcc_offset);
927 }
928 
929 // 2: !FCC0 & FCC1
gen_op_eval_fbg(TCGv dst,TCGv src,unsigned int fcc_offset)930 static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
931                                     unsigned int fcc_offset)
932 {
933     gen_mov_reg_FCC0(dst, src, fcc_offset);
934     tcg_gen_xori_tl(dst, dst, 0x1);
935     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
936     tcg_gen_and_tl(dst, dst, cpu_tmp0);
937 }
938 
939 // 3: FCC0 & FCC1
gen_op_eval_fbu(TCGv dst,TCGv src,unsigned int fcc_offset)940 static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
941                                     unsigned int fcc_offset)
942 {
943     gen_mov_reg_FCC0(dst, src, fcc_offset);
944     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
945     tcg_gen_and_tl(dst, dst, cpu_tmp0);
946 }
947 
948 // 0: !(FCC0 | FCC1)
gen_op_eval_fbe(TCGv dst,TCGv src,unsigned int fcc_offset)949 static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
950                                     unsigned int fcc_offset)
951 {
952     gen_mov_reg_FCC0(dst, src, fcc_offset);
953     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
954     tcg_gen_or_tl(dst, dst, cpu_tmp0);
955     tcg_gen_xori_tl(dst, dst, 0x1);
956 }
957 
958 // 0 or 3: !(FCC0 ^ FCC1)
gen_op_eval_fbue(TCGv dst,TCGv src,unsigned int fcc_offset)959 static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
960                                     unsigned int fcc_offset)
961 {
962     gen_mov_reg_FCC0(dst, src, fcc_offset);
963     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
964     tcg_gen_xor_tl(dst, dst, cpu_tmp0);
965     tcg_gen_xori_tl(dst, dst, 0x1);
966 }
967 
968 // 0 or 2: !FCC0
gen_op_eval_fbge(TCGv dst,TCGv src,unsigned int fcc_offset)969 static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
970                                     unsigned int fcc_offset)
971 {
972     gen_mov_reg_FCC0(dst, src, fcc_offset);
973     tcg_gen_xori_tl(dst, dst, 0x1);
974 }
975 
976 // !1: !(FCC0 & !FCC1)
gen_op_eval_fbuge(TCGv dst,TCGv src,unsigned int fcc_offset)977 static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
978                                     unsigned int fcc_offset)
979 {
980     gen_mov_reg_FCC0(dst, src, fcc_offset);
981     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
982     tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
983     tcg_gen_and_tl(dst, dst, cpu_tmp0);
984     tcg_gen_xori_tl(dst, dst, 0x1);
985 }
986 
987 // 0 or 1: !FCC1
gen_op_eval_fble(TCGv dst,TCGv src,unsigned int fcc_offset)988 static inline void gen_op_eval_fble(TCGv dst, TCGv src,
989                                     unsigned int fcc_offset)
990 {
991     gen_mov_reg_FCC1(dst, src, fcc_offset);
992     tcg_gen_xori_tl(dst, dst, 0x1);
993 }
994 
995 // !2: !(!FCC0 & FCC1)
gen_op_eval_fbule(TCGv dst,TCGv src,unsigned int fcc_offset)996 static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
997                                     unsigned int fcc_offset)
998 {
999     gen_mov_reg_FCC0(dst, src, fcc_offset);
1000     tcg_gen_xori_tl(dst, dst, 0x1);
1001     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1002     tcg_gen_and_tl(dst, dst, cpu_tmp0);
1003     tcg_gen_xori_tl(dst, dst, 0x1);
1004 }
1005 
1006 // !3: !(FCC0 & FCC1)
gen_op_eval_fbo(TCGv dst,TCGv src,unsigned int fcc_offset)1007 static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1008                                     unsigned int fcc_offset)
1009 {
1010     gen_mov_reg_FCC0(dst, src, fcc_offset);
1011     gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1012     tcg_gen_and_tl(dst, dst, cpu_tmp0);
1013     tcg_gen_xori_tl(dst, dst, 0x1);
1014 }
1015 
gen_branch2(DisasContext * dc,target_ulong pc1,target_ulong pc2,TCGv r_cond)1016 static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1017                                target_ulong pc2, TCGv r_cond)
1018 {
1019     int l1;
1020 
1021     l1 = gen_new_label();
1022 
1023     tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1024 
1025     gen_goto_tb(dc, 0, pc1, pc1 + 4);
1026 
1027     gen_set_label(l1);
1028     gen_goto_tb(dc, 1, pc2, pc2 + 4);
1029 }
1030 
gen_branch_a(DisasContext * dc,target_ulong pc1,target_ulong pc2,TCGv r_cond)1031 static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1032                                 target_ulong pc2, TCGv r_cond)
1033 {
1034     int l1;
1035 
1036     l1 = gen_new_label();
1037 
1038     tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1039 
1040     gen_goto_tb(dc, 0, pc2, pc1);
1041 
1042     gen_set_label(l1);
1043     gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1044 }
1045 
gen_generic_branch(target_ulong npc1,target_ulong npc2,TCGv r_cond)1046 static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1047                                       TCGv r_cond)
1048 {
1049     int l1, l2;
1050 
1051     l1 = gen_new_label();
1052     l2 = gen_new_label();
1053 
1054     tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1055 
1056     tcg_gen_movi_tl(cpu_npc, npc1);
1057     tcg_gen_br(l2);
1058 
1059     gen_set_label(l1);
1060     tcg_gen_movi_tl(cpu_npc, npc2);
1061     gen_set_label(l2);
1062 }
1063 
1064 /* call this function before using the condition register as it may
1065    have been set for a jump */
flush_cond(DisasContext * dc,TCGv cond)1066 static inline void flush_cond(DisasContext *dc, TCGv cond)
1067 {
1068     if (dc->npc == JUMP_PC) {
1069         gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1070         dc->npc = DYNAMIC_PC;
1071     }
1072 }
1073 
save_npc(DisasContext * dc,TCGv cond)1074 static inline void save_npc(DisasContext *dc, TCGv cond)
1075 {
1076     if (dc->npc == JUMP_PC) {
1077         gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1078         dc->npc = DYNAMIC_PC;
1079     } else if (dc->npc != DYNAMIC_PC) {
1080         tcg_gen_movi_tl(cpu_npc, dc->npc);
1081     }
1082 }
1083 
save_state(DisasContext * dc,TCGv cond)1084 static inline void save_state(DisasContext *dc, TCGv cond)
1085 {
1086     tcg_gen_movi_tl(cpu_pc, dc->pc);
1087     /* flush pending conditional evaluations before exposing cpu state */
1088     if (dc->cc_op != CC_OP_FLAGS) {
1089         dc->cc_op = CC_OP_FLAGS;
1090         gen_helper_compute_psr();
1091     }
1092     save_npc(dc, cond);
1093 }
1094 
gen_mov_pc_npc(DisasContext * dc,TCGv cond)1095 static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1096 {
1097     if (dc->npc == JUMP_PC) {
1098         gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1099         tcg_gen_mov_tl(cpu_pc, cpu_npc);
1100         dc->pc = DYNAMIC_PC;
1101     } else if (dc->npc == DYNAMIC_PC) {
1102         tcg_gen_mov_tl(cpu_pc, cpu_npc);
1103         dc->pc = DYNAMIC_PC;
1104     } else {
1105         dc->pc = dc->npc;
1106     }
1107 }
1108 
gen_op_next_insn(void)1109 static inline void gen_op_next_insn(void)
1110 {
1111     tcg_gen_mov_tl(cpu_pc, cpu_npc);
1112     tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1113 }
1114 
gen_cond(TCGv r_dst,unsigned int cc,unsigned int cond,DisasContext * dc)1115 static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
1116                             DisasContext *dc)
1117 {
1118     TCGv_i32 r_src;
1119 
1120 #ifdef TARGET_SPARC64
1121     if (cc)
1122         r_src = cpu_xcc;
1123     else
1124         r_src = cpu_psr;
1125 #else
1126     r_src = cpu_psr;
1127 #endif
1128     switch (dc->cc_op) {
1129     case CC_OP_FLAGS:
1130         break;
1131     default:
1132         gen_helper_compute_psr();
1133         dc->cc_op = CC_OP_FLAGS;
1134         break;
1135     }
1136     switch (cond) {
1137     case 0x0:
1138         gen_op_eval_bn(r_dst);
1139         break;
1140     case 0x1:
1141         gen_op_eval_be(r_dst, r_src);
1142         break;
1143     case 0x2:
1144         gen_op_eval_ble(r_dst, r_src);
1145         break;
1146     case 0x3:
1147         gen_op_eval_bl(r_dst, r_src);
1148         break;
1149     case 0x4:
1150         gen_op_eval_bleu(r_dst, r_src);
1151         break;
1152     case 0x5:
1153         gen_op_eval_bcs(r_dst, r_src);
1154         break;
1155     case 0x6:
1156         gen_op_eval_bneg(r_dst, r_src);
1157         break;
1158     case 0x7:
1159         gen_op_eval_bvs(r_dst, r_src);
1160         break;
1161     case 0x8:
1162         gen_op_eval_ba(r_dst);
1163         break;
1164     case 0x9:
1165         gen_op_eval_bne(r_dst, r_src);
1166         break;
1167     case 0xa:
1168         gen_op_eval_bg(r_dst, r_src);
1169         break;
1170     case 0xb:
1171         gen_op_eval_bge(r_dst, r_src);
1172         break;
1173     case 0xc:
1174         gen_op_eval_bgu(r_dst, r_src);
1175         break;
1176     case 0xd:
1177         gen_op_eval_bcc(r_dst, r_src);
1178         break;
1179     case 0xe:
1180         gen_op_eval_bpos(r_dst, r_src);
1181         break;
1182     case 0xf:
1183         gen_op_eval_bvc(r_dst, r_src);
1184         break;
1185     }
1186 }
1187 
gen_fcond(TCGv r_dst,unsigned int cc,unsigned int cond)1188 static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1189 {
1190     unsigned int offset;
1191 
1192     switch (cc) {
1193     default:
1194     case 0x0:
1195         offset = 0;
1196         break;
1197     case 0x1:
1198         offset = 32 - 10;
1199         break;
1200     case 0x2:
1201         offset = 34 - 10;
1202         break;
1203     case 0x3:
1204         offset = 36 - 10;
1205         break;
1206     }
1207 
1208     switch (cond) {
1209     case 0x0:
1210         gen_op_eval_bn(r_dst);
1211         break;
1212     case 0x1:
1213         gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1214         break;
1215     case 0x2:
1216         gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1217         break;
1218     case 0x3:
1219         gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1220         break;
1221     case 0x4:
1222         gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1223         break;
1224     case 0x5:
1225         gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1226         break;
1227     case 0x6:
1228         gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1229         break;
1230     case 0x7:
1231         gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1232         break;
1233     case 0x8:
1234         gen_op_eval_ba(r_dst);
1235         break;
1236     case 0x9:
1237         gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1238         break;
1239     case 0xa:
1240         gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1241         break;
1242     case 0xb:
1243         gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1244         break;
1245     case 0xc:
1246         gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1247         break;
1248     case 0xd:
1249         gen_op_eval_fble(r_dst, cpu_fsr, offset);
1250         break;
1251     case 0xe:
1252         gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1253         break;
1254     case 0xf:
1255         gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1256         break;
1257     }
1258 }
1259 
1260 #ifdef TARGET_SPARC64
1261 // Inverted logic
1262 static const int gen_tcg_cond_reg[8] = {
1263     -1,
1264     TCG_COND_NE,
1265     TCG_COND_GT,
1266     TCG_COND_GE,
1267     -1,
1268     TCG_COND_EQ,
1269     TCG_COND_LE,
1270     TCG_COND_LT,
1271 };
1272 
gen_cond_reg(TCGv r_dst,int cond,TCGv r_src)1273 static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1274 {
1275     int l1;
1276 
1277     l1 = gen_new_label();
1278     tcg_gen_movi_tl(r_dst, 0);
1279     tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1280     tcg_gen_movi_tl(r_dst, 1);
1281     gen_set_label(l1);
1282 }
1283 #endif
1284 
1285 /* XXX: potentially incorrect if dynamic npc */
do_branch(DisasContext * dc,int32_t offset,uint32_t insn,int cc,TCGv r_cond)1286 static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1287                       TCGv r_cond)
1288 {
1289     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1290     target_ulong target = dc->pc + offset;
1291 
1292     if (cond == 0x0) {
1293         /* unconditional not taken */
1294         if (a) {
1295             dc->pc = dc->npc + 4;
1296             dc->npc = dc->pc + 4;
1297         } else {
1298             dc->pc = dc->npc;
1299             dc->npc = dc->pc + 4;
1300         }
1301     } else if (cond == 0x8) {
1302         /* unconditional taken */
1303         if (a) {
1304             dc->pc = target;
1305             dc->npc = dc->pc + 4;
1306         } else {
1307             dc->pc = dc->npc;
1308             dc->npc = target;
1309             tcg_gen_mov_tl(cpu_pc, cpu_npc);
1310         }
1311     } else {
1312         flush_cond(dc, r_cond);
1313         gen_cond(r_cond, cc, cond, dc);
1314         if (a) {
1315             gen_branch_a(dc, target, dc->npc, r_cond);
1316             dc->is_br = 1;
1317         } else {
1318             dc->pc = dc->npc;
1319             dc->jump_pc[0] = target;
1320             dc->jump_pc[1] = dc->npc + 4;
1321             dc->npc = JUMP_PC;
1322         }
1323     }
1324 }
1325 
1326 /* XXX: potentially incorrect if dynamic npc */
do_fbranch(DisasContext * dc,int32_t offset,uint32_t insn,int cc,TCGv r_cond)1327 static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1328                       TCGv r_cond)
1329 {
1330     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1331     target_ulong target = dc->pc + offset;
1332 
1333     if (cond == 0x0) {
1334         /* unconditional not taken */
1335         if (a) {
1336             dc->pc = dc->npc + 4;
1337             dc->npc = dc->pc + 4;
1338         } else {
1339             dc->pc = dc->npc;
1340             dc->npc = dc->pc + 4;
1341         }
1342     } else if (cond == 0x8) {
1343         /* unconditional taken */
1344         if (a) {
1345             dc->pc = target;
1346             dc->npc = dc->pc + 4;
1347         } else {
1348             dc->pc = dc->npc;
1349             dc->npc = target;
1350             tcg_gen_mov_tl(cpu_pc, cpu_npc);
1351         }
1352     } else {
1353         flush_cond(dc, r_cond);
1354         gen_fcond(r_cond, cc, cond);
1355         if (a) {
1356             gen_branch_a(dc, target, dc->npc, r_cond);
1357             dc->is_br = 1;
1358         } else {
1359             dc->pc = dc->npc;
1360             dc->jump_pc[0] = target;
1361             dc->jump_pc[1] = dc->npc + 4;
1362             dc->npc = JUMP_PC;
1363         }
1364     }
1365 }
1366 
1367 #ifdef TARGET_SPARC64
1368 /* XXX: potentially incorrect if dynamic npc */
do_branch_reg(DisasContext * dc,int32_t offset,uint32_t insn,TCGv r_cond,TCGv r_reg)1369 static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1370                           TCGv r_cond, TCGv r_reg)
1371 {
1372     unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1373     target_ulong target = dc->pc + offset;
1374 
1375     flush_cond(dc, r_cond);
1376     gen_cond_reg(r_cond, cond, r_reg);
1377     if (a) {
1378         gen_branch_a(dc, target, dc->npc, r_cond);
1379         dc->is_br = 1;
1380     } else {
1381         dc->pc = dc->npc;
1382         dc->jump_pc[0] = target;
1383         dc->jump_pc[1] = dc->npc + 4;
1384         dc->npc = JUMP_PC;
1385     }
1386 }
1387 
gen_op_fcmps(int fccno,TCGv_i32 r_rs1,TCGv_i32 r_rs2)1388 static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1389 {
1390     switch (fccno) {
1391     case 0:
1392         gen_helper_fcmps(r_rs1, r_rs2);
1393         break;
1394     case 1:
1395         gen_helper_fcmps_fcc1(r_rs1, r_rs2);
1396         break;
1397     case 2:
1398         gen_helper_fcmps_fcc2(r_rs1, r_rs2);
1399         break;
1400     case 3:
1401         gen_helper_fcmps_fcc3(r_rs1, r_rs2);
1402         break;
1403     }
1404 }
1405 
gen_op_fcmpd(int fccno)1406 static inline void gen_op_fcmpd(int fccno)
1407 {
1408     switch (fccno) {
1409     case 0:
1410         gen_helper_fcmpd();
1411         break;
1412     case 1:
1413         gen_helper_fcmpd_fcc1();
1414         break;
1415     case 2:
1416         gen_helper_fcmpd_fcc2();
1417         break;
1418     case 3:
1419         gen_helper_fcmpd_fcc3();
1420         break;
1421     }
1422 }
1423 
gen_op_fcmpq(int fccno)1424 static inline void gen_op_fcmpq(int fccno)
1425 {
1426     switch (fccno) {
1427     case 0:
1428         gen_helper_fcmpq();
1429         break;
1430     case 1:
1431         gen_helper_fcmpq_fcc1();
1432         break;
1433     case 2:
1434         gen_helper_fcmpq_fcc2();
1435         break;
1436     case 3:
1437         gen_helper_fcmpq_fcc3();
1438         break;
1439     }
1440 }
1441 
gen_op_fcmpes(int fccno,TCGv_i32 r_rs1,TCGv_i32 r_rs2)1442 static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1443 {
1444     switch (fccno) {
1445     case 0:
1446         gen_helper_fcmpes(r_rs1, r_rs2);
1447         break;
1448     case 1:
1449         gen_helper_fcmpes_fcc1(r_rs1, r_rs2);
1450         break;
1451     case 2:
1452         gen_helper_fcmpes_fcc2(r_rs1, r_rs2);
1453         break;
1454     case 3:
1455         gen_helper_fcmpes_fcc3(r_rs1, r_rs2);
1456         break;
1457     }
1458 }
1459 
gen_op_fcmped(int fccno)1460 static inline void gen_op_fcmped(int fccno)
1461 {
1462     switch (fccno) {
1463     case 0:
1464         gen_helper_fcmped();
1465         break;
1466     case 1:
1467         gen_helper_fcmped_fcc1();
1468         break;
1469     case 2:
1470         gen_helper_fcmped_fcc2();
1471         break;
1472     case 3:
1473         gen_helper_fcmped_fcc3();
1474         break;
1475     }
1476 }
1477 
gen_op_fcmpeq(int fccno)1478 static inline void gen_op_fcmpeq(int fccno)
1479 {
1480     switch (fccno) {
1481     case 0:
1482         gen_helper_fcmpeq();
1483         break;
1484     case 1:
1485         gen_helper_fcmpeq_fcc1();
1486         break;
1487     case 2:
1488         gen_helper_fcmpeq_fcc2();
1489         break;
1490     case 3:
1491         gen_helper_fcmpeq_fcc3();
1492         break;
1493     }
1494 }
1495 
1496 #else
1497 
gen_op_fcmps(int fccno,TCGv r_rs1,TCGv r_rs2)1498 static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1499 {
1500     gen_helper_fcmps(r_rs1, r_rs2);
1501 }
1502 
gen_op_fcmpd(int fccno)1503 static inline void gen_op_fcmpd(int fccno)
1504 {
1505     gen_helper_fcmpd();
1506 }
1507 
gen_op_fcmpq(int fccno)1508 static inline void gen_op_fcmpq(int fccno)
1509 {
1510     gen_helper_fcmpq();
1511 }
1512 
gen_op_fcmpes(int fccno,TCGv r_rs1,TCGv r_rs2)1513 static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1514 {
1515     gen_helper_fcmpes(r_rs1, r_rs2);
1516 }
1517 
gen_op_fcmped(int fccno)1518 static inline void gen_op_fcmped(int fccno)
1519 {
1520     gen_helper_fcmped();
1521 }
1522 
gen_op_fcmpeq(int fccno)1523 static inline void gen_op_fcmpeq(int fccno)
1524 {
1525     gen_helper_fcmpeq();
1526 }
1527 #endif
1528 
gen_op_fpexception_im(int fsr_flags)1529 static inline void gen_op_fpexception_im(int fsr_flags)
1530 {
1531     TCGv_i32 r_const;
1532 
1533     tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
1534     tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1535     r_const = tcg_const_i32(TT_FP_EXCP);
1536     gen_helper_raise_exception(r_const);
1537     tcg_temp_free_i32(r_const);
1538 }
1539 
gen_trap_ifnofpu(DisasContext * dc,TCGv r_cond)1540 static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1541 {
1542 #if !defined(CONFIG_USER_ONLY)
1543     if (!dc->fpu_enabled) {
1544         TCGv_i32 r_const;
1545 
1546         save_state(dc, r_cond);
1547         r_const = tcg_const_i32(TT_NFPU_INSN);
1548         gen_helper_raise_exception(r_const);
1549         tcg_temp_free_i32(r_const);
1550         dc->is_br = 1;
1551         return 1;
1552     }
1553 #endif
1554     return 0;
1555 }
1556 
gen_op_clear_ieee_excp_and_FTT(void)1557 static inline void gen_op_clear_ieee_excp_and_FTT(void)
1558 {
1559     tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1560 }
1561 
gen_clear_float_exceptions(void)1562 static inline void gen_clear_float_exceptions(void)
1563 {
1564     gen_helper_clear_float_exceptions();
1565 }
1566 
1567 /* asi moves */
1568 #ifdef TARGET_SPARC64
gen_get_asi(int insn,TCGv r_addr)1569 static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
1570 {
1571     int asi;
1572     TCGv_i32 r_asi;
1573 
1574     if (IS_IMM) {
1575         r_asi = tcg_temp_new_i32();
1576         tcg_gen_mov_i32(r_asi, cpu_asi);
1577     } else {
1578         asi = GET_FIELD(insn, 19, 26);
1579         r_asi = tcg_const_i32(asi);
1580     }
1581     return r_asi;
1582 }
1583 
gen_ld_asi(TCGv dst,TCGv addr,int insn,int size,int sign)1584 static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1585                               int sign)
1586 {
1587     TCGv_i32 r_asi, r_size, r_sign;
1588 
1589     r_asi = gen_get_asi(insn, addr);
1590     r_size = tcg_const_i32(size);
1591     r_sign = tcg_const_i32(sign);
1592     gen_helper_ld_asi(dst, addr, r_asi, r_size, r_sign);
1593     tcg_temp_free_i32(r_sign);
1594     tcg_temp_free_i32(r_size);
1595     tcg_temp_free_i32(r_asi);
1596 }
1597 
gen_st_asi(TCGv src,TCGv addr,int insn,int size)1598 static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1599 {
1600     TCGv_i32 r_asi, r_size;
1601 
1602     r_asi = gen_get_asi(insn, addr);
1603     r_size = tcg_const_i32(size);
1604     gen_helper_st_asi(addr, src, r_asi, r_size);
1605     tcg_temp_free_i32(r_size);
1606     tcg_temp_free_i32(r_asi);
1607 }
1608 
gen_ldf_asi(TCGv addr,int insn,int size,int rd)1609 static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1610 {
1611     TCGv_i32 r_asi, r_size, r_rd;
1612 
1613     r_asi = gen_get_asi(insn, addr);
1614     r_size = tcg_const_i32(size);
1615     r_rd = tcg_const_i32(rd);
1616     gen_helper_ldf_asi(addr, r_asi, r_size, r_rd);
1617     tcg_temp_free_i32(r_rd);
1618     tcg_temp_free_i32(r_size);
1619     tcg_temp_free_i32(r_asi);
1620 }
1621 
gen_stf_asi(TCGv addr,int insn,int size,int rd)1622 static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1623 {
1624     TCGv_i32 r_asi, r_size, r_rd;
1625 
1626     r_asi = gen_get_asi(insn, addr);
1627     r_size = tcg_const_i32(size);
1628     r_rd = tcg_const_i32(rd);
1629     gen_helper_stf_asi(addr, r_asi, r_size, r_rd);
1630     tcg_temp_free_i32(r_rd);
1631     tcg_temp_free_i32(r_size);
1632     tcg_temp_free_i32(r_asi);
1633 }
1634 
gen_swap_asi(TCGv dst,TCGv addr,int insn)1635 static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1636 {
1637     TCGv_i32 r_asi, r_size, r_sign;
1638 
1639     r_asi = gen_get_asi(insn, addr);
1640     r_size = tcg_const_i32(4);
1641     r_sign = tcg_const_i32(0);
1642     gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1643     tcg_temp_free_i32(r_sign);
1644     gen_helper_st_asi(addr, dst, r_asi, r_size);
1645     tcg_temp_free_i32(r_size);
1646     tcg_temp_free_i32(r_asi);
1647     tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1648 }
1649 
gen_ldda_asi(TCGv hi,TCGv addr,int insn,int rd)1650 static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1651 {
1652     TCGv_i32 r_asi, r_rd;
1653 
1654     r_asi = gen_get_asi(insn, addr);
1655     r_rd = tcg_const_i32(rd);
1656     gen_helper_ldda_asi(addr, r_asi, r_rd);
1657     tcg_temp_free_i32(r_rd);
1658     tcg_temp_free_i32(r_asi);
1659 }
1660 
gen_stda_asi(TCGv hi,TCGv addr,int insn,int rd)1661 static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1662 {
1663     TCGv_i32 r_asi, r_size;
1664 
1665     gen_movl_reg_TN(rd + 1, cpu_tmp0);
1666     tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1667     r_asi = gen_get_asi(insn, addr);
1668     r_size = tcg_const_i32(8);
1669     gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1670     tcg_temp_free_i32(r_size);
1671     tcg_temp_free_i32(r_asi);
1672 }
1673 
gen_cas_asi(TCGv dst,TCGv addr,TCGv val2,int insn,int rd)1674 static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1675                                int rd)
1676 {
1677     TCGv r_val1;
1678     TCGv_i32 r_asi;
1679 
1680     r_val1 = tcg_temp_new();
1681     gen_movl_reg_TN(rd, r_val1);
1682     r_asi = gen_get_asi(insn, addr);
1683     gen_helper_cas_asi(dst, addr, r_val1, val2, r_asi);
1684     tcg_temp_free_i32(r_asi);
1685     tcg_temp_free(r_val1);
1686 }
1687 
gen_casx_asi(TCGv dst,TCGv addr,TCGv val2,int insn,int rd)1688 static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1689                                 int rd)
1690 {
1691     TCGv_i32 r_asi;
1692 
1693     gen_movl_reg_TN(rd, cpu_tmp64);
1694     r_asi = gen_get_asi(insn, addr);
1695     gen_helper_casx_asi(dst, addr, cpu_tmp64, val2, r_asi);
1696     tcg_temp_free_i32(r_asi);
1697 }
1698 
1699 #elif !defined(CONFIG_USER_ONLY)
1700 
gen_ld_asi(TCGv dst,TCGv addr,int insn,int size,int sign)1701 static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1702                               int sign)
1703 {
1704     TCGv_i32 r_asi, r_size, r_sign;
1705 
1706     r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1707     r_size = tcg_const_i32(size);
1708     r_sign = tcg_const_i32(sign);
1709     gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1710     tcg_temp_free(r_sign);
1711     tcg_temp_free(r_size);
1712     tcg_temp_free(r_asi);
1713     tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1714 }
1715 
gen_st_asi(TCGv src,TCGv addr,int insn,int size)1716 static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1717 {
1718     TCGv_i32 r_asi, r_size;
1719 
1720     tcg_gen_extu_tl_i64(cpu_tmp64, src);
1721     r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1722     r_size = tcg_const_i32(size);
1723     gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1724     tcg_temp_free(r_size);
1725     tcg_temp_free(r_asi);
1726 }
1727 
gen_swap_asi(TCGv dst,TCGv addr,int insn)1728 static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1729 {
1730     TCGv_i32 r_asi, r_size, r_sign;
1731     TCGv_i64 r_val;
1732 
1733     r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1734     r_size = tcg_const_i32(4);
1735     r_sign = tcg_const_i32(0);
1736     gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1737     tcg_temp_free(r_sign);
1738     r_val = tcg_temp_new_i64();
1739     tcg_gen_extu_tl_i64(r_val, dst);
1740     gen_helper_st_asi(addr, r_val, r_asi, r_size);
1741     tcg_temp_free_i64(r_val);
1742     tcg_temp_free(r_size);
1743     tcg_temp_free(r_asi);
1744     tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1745 }
1746 
gen_ldda_asi(TCGv hi,TCGv addr,int insn,int rd)1747 static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1748 {
1749     TCGv_i32 r_asi, r_size, r_sign;
1750 
1751     r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1752     r_size = tcg_const_i32(8);
1753     r_sign = tcg_const_i32(0);
1754     gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1755     tcg_temp_free(r_sign);
1756     tcg_temp_free(r_size);
1757     tcg_temp_free(r_asi);
1758     tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
1759     gen_movl_TN_reg(rd + 1, cpu_tmp0);
1760     tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1761     tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1762     gen_movl_TN_reg(rd, hi);
1763 }
1764 
gen_stda_asi(TCGv hi,TCGv addr,int insn,int rd)1765 static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1766 {
1767     TCGv_i32 r_asi, r_size;
1768 
1769     gen_movl_reg_TN(rd + 1, cpu_tmp0);
1770     tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1771     r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1772     r_size = tcg_const_i32(8);
1773     gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1774     tcg_temp_free(r_size);
1775     tcg_temp_free(r_asi);
1776 }
1777 #endif
1778 
1779 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
gen_ldstub_asi(TCGv dst,TCGv addr,int insn)1780 static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1781 {
1782     TCGv_i64 r_val;
1783     TCGv_i32 r_asi, r_size;
1784 
1785     gen_ld_asi(dst, addr, insn, 1, 0);
1786 
1787     r_val = tcg_const_i64(0xffULL);
1788     r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1789     r_size = tcg_const_i32(1);
1790     gen_helper_st_asi(addr, r_val, r_asi, r_size);
1791     tcg_temp_free_i32(r_size);
1792     tcg_temp_free_i32(r_asi);
1793     tcg_temp_free_i64(r_val);
1794 }
1795 #endif
1796 
get_src1(unsigned int insn,TCGv def)1797 static inline TCGv get_src1(unsigned int insn, TCGv def)
1798 {
1799     TCGv r_rs1 = def;
1800     unsigned int rs1;
1801 
1802     rs1 = GET_FIELD(insn, 13, 17);
1803     if (rs1 == 0) {
1804         tcg_gen_movi_tl(def, 0);
1805     } else if (rs1 < 8) {
1806         r_rs1 = cpu_gregs[rs1];
1807     } else {
1808         tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1809     }
1810     return r_rs1;
1811 }
1812 
get_src2(unsigned int insn,TCGv def)1813 static inline TCGv get_src2(unsigned int insn, TCGv def)
1814 {
1815     TCGv r_rs2 = def;
1816 
1817     if (IS_IMM) { /* immediate */
1818         target_long simm = GET_FIELDs(insn, 19, 31);
1819         tcg_gen_movi_tl(def, simm);
1820     } else { /* register */
1821         unsigned int rs2 = GET_FIELD(insn, 27, 31);
1822         if (rs2 == 0) {
1823             tcg_gen_movi_tl(def, 0);
1824         } else if (rs2 < 8) {
1825             r_rs2 = cpu_gregs[rs2];
1826         } else {
1827             tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1828         }
1829     }
1830     return r_rs2;
1831 }
1832 
1833 #ifdef TARGET_SPARC64
gen_load_trap_state_at_tl(TCGv_ptr r_tsptr,TCGv_ptr cpu_env)1834 static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env)
1835 {
1836     TCGv_i32 r_tl = tcg_temp_new_i32();
1837 
1838     /* load env->tl into r_tl */
1839     tcg_gen_ld_i32(r_tl, cpu_env, offsetof(CPUSPARCState, tl));
1840 
1841     /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
1842     tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
1843 
1844     /* calculate offset to current trap state from env->ts, reuse r_tl */
1845     tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
1846     tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUState, ts));
1847 
1848     /* tsptr = env->ts[env->tl & MAXTL_MASK] */
1849     {
1850         TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
1851         tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
1852         tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
1853         tcg_temp_free_ptr(r_tl_tmp);
1854     }
1855 
1856     tcg_temp_free_i32(r_tl);
1857 }
1858 #endif
1859 
1860 #define CHECK_IU_FEATURE(dc, FEATURE)                      \
1861     if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1862         goto illegal_insn;
1863 #define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1864     if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1865         goto nfpu_insn;
1866 
1867 /* before an instruction, dc->pc must be static */
disas_sparc_insn(DisasContext * dc)1868 static void disas_sparc_insn(DisasContext * dc)
1869 {
1870     unsigned int insn, opc, rs1, rs2, rd;
1871     TCGv cpu_src1, cpu_src2, cpu_tmp1, cpu_tmp2;
1872     target_long simm;
1873 
1874     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
1875         tcg_gen_debug_insn_start(dc->pc);
1876     insn = ldl_code(dc->pc);
1877     opc = GET_FIELD(insn, 0, 1);
1878 
1879     rd = GET_FIELD(insn, 2, 6);
1880 
1881     cpu_tmp1 = cpu_src1 = tcg_temp_new();
1882     cpu_tmp2 = cpu_src2 = tcg_temp_new();
1883 
1884     switch (opc) {
1885     case 0:                     /* branches/sethi */
1886         {
1887             unsigned int xop = GET_FIELD(insn, 7, 9);
1888             int32_t target;
1889             switch (xop) {
1890 #ifdef TARGET_SPARC64
1891             case 0x1:           /* V9 BPcc */
1892                 {
1893                     int cc;
1894 
1895                     target = GET_FIELD_SP(insn, 0, 18);
1896                     target = sign_extend(target, 18);
1897                     target <<= 2;
1898                     cc = GET_FIELD_SP(insn, 20, 21);
1899                     if (cc == 0)
1900                         do_branch(dc, target, insn, 0, cpu_cond);
1901                     else if (cc == 2)
1902                         do_branch(dc, target, insn, 1, cpu_cond);
1903                     else
1904                         goto illegal_insn;
1905                     goto jmp_insn;
1906                 }
1907             case 0x3:           /* V9 BPr */
1908                 {
1909                     target = GET_FIELD_SP(insn, 0, 13) |
1910                         (GET_FIELD_SP(insn, 20, 21) << 14);
1911                     target = sign_extend(target, 16);
1912                     target <<= 2;
1913                     cpu_src1 = get_src1(insn, cpu_src1);
1914                     do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
1915                     goto jmp_insn;
1916                 }
1917             case 0x5:           /* V9 FBPcc */
1918                 {
1919                     int cc = GET_FIELD_SP(insn, 20, 21);
1920                     if (gen_trap_ifnofpu(dc, cpu_cond))
1921                         goto jmp_insn;
1922                     target = GET_FIELD_SP(insn, 0, 18);
1923                     target = sign_extend(target, 19);
1924                     target <<= 2;
1925                     do_fbranch(dc, target, insn, cc, cpu_cond);
1926                     goto jmp_insn;
1927                 }
1928 #else
1929             case 0x7:           /* CBN+x */
1930                 {
1931                     goto ncp_insn;
1932                 }
1933 #endif
1934             case 0x2:           /* BN+x */
1935                 {
1936                     target = GET_FIELD(insn, 10, 31);
1937                     target = sign_extend(target, 22);
1938                     target <<= 2;
1939                     do_branch(dc, target, insn, 0, cpu_cond);
1940                     goto jmp_insn;
1941                 }
1942             case 0x6:           /* FBN+x */
1943                 {
1944                     if (gen_trap_ifnofpu(dc, cpu_cond))
1945                         goto jmp_insn;
1946                     target = GET_FIELD(insn, 10, 31);
1947                     target = sign_extend(target, 22);
1948                     target <<= 2;
1949                     do_fbranch(dc, target, insn, 0, cpu_cond);
1950                     goto jmp_insn;
1951                 }
1952             case 0x4:           /* SETHI */
1953                 if (rd) { // nop
1954                     uint32_t value = GET_FIELD(insn, 10, 31);
1955                     TCGv r_const;
1956 
1957                     r_const = tcg_const_tl(value << 10);
1958                     gen_movl_TN_reg(rd, r_const);
1959                     tcg_temp_free(r_const);
1960                 }
1961                 break;
1962             case 0x0:           /* UNIMPL */
1963             default:
1964                 goto illegal_insn;
1965             }
1966             break;
1967         }
1968         break;
1969     case 1:                     /*CALL*/
1970         {
1971             target_long target = GET_FIELDs(insn, 2, 31) << 2;
1972             TCGv r_const;
1973 
1974             r_const = tcg_const_tl(dc->pc);
1975             gen_movl_TN_reg(15, r_const);
1976             tcg_temp_free(r_const);
1977             target += dc->pc;
1978             gen_mov_pc_npc(dc, cpu_cond);
1979             dc->npc = target;
1980         }
1981         goto jmp_insn;
1982     case 2:                     /* FPU & Logical Operations */
1983         {
1984             unsigned int xop = GET_FIELD(insn, 7, 12);
1985             if (xop == 0x3a) {  /* generate trap */
1986                 int cond;
1987 
1988                 cpu_src1 = get_src1(insn, cpu_src1);
1989                 if (IS_IMM) {
1990                     rs2 = GET_FIELD(insn, 25, 31);
1991                     tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
1992                 } else {
1993                     rs2 = GET_FIELD(insn, 27, 31);
1994                     if (rs2 != 0) {
1995                         gen_movl_reg_TN(rs2, cpu_src2);
1996                         tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
1997                     } else
1998                         tcg_gen_mov_tl(cpu_dst, cpu_src1);
1999                 }
2000 
2001                 cond = GET_FIELD(insn, 3, 6);
2002                 if (cond == 0x8) { /* Trap Always */
2003                     save_state(dc, cpu_cond);
2004                     if ((dc->def->features & CPU_FEATURE_HYPV) &&
2005                         supervisor(dc))
2006                         tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
2007                     else
2008                         tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
2009                     tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
2010                     tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2011 
2012                     if (rs2 == 0 &&
2013                         dc->def->features & CPU_FEATURE_TA0_SHUTDOWN) {
2014 
2015                         gen_helper_shutdown();
2016 
2017                     } else {
2018                         gen_helper_raise_exception(cpu_tmp32);
2019                     }
2020                 } else if (cond != 0) {
2021                     TCGv r_cond = tcg_temp_new();
2022                     int l1;
2023 #ifdef TARGET_SPARC64
2024                     /* V9 icc/xcc */
2025                     int cc = GET_FIELD_SP(insn, 11, 12);
2026 
2027                     save_state(dc, cpu_cond);
2028                     if (cc == 0)
2029                         gen_cond(r_cond, 0, cond, dc);
2030                     else if (cc == 2)
2031                         gen_cond(r_cond, 1, cond, dc);
2032                     else
2033                         goto illegal_insn;
2034 #else
2035                     save_state(dc, cpu_cond);
2036                     gen_cond(r_cond, 0, cond, dc);
2037 #endif
2038                     l1 = gen_new_label();
2039                     tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
2040 
2041                     if ((dc->def->features & CPU_FEATURE_HYPV) &&
2042                         supervisor(dc))
2043                         tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
2044                     else
2045                         tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
2046                     tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
2047                     tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2048                     gen_helper_raise_exception(cpu_tmp32);
2049 
2050                     gen_set_label(l1);
2051                     tcg_temp_free(r_cond);
2052                 }
2053                 gen_op_next_insn();
2054                 tcg_gen_exit_tb(0);
2055                 dc->is_br = 1;
2056                 goto jmp_insn;
2057             } else if (xop == 0x28) {
2058                 rs1 = GET_FIELD(insn, 13, 17);
2059                 switch(rs1) {
2060                 case 0: /* rdy */
2061 #ifndef TARGET_SPARC64
2062                 case 0x01 ... 0x0e: /* undefined in the SPARCv8
2063                                        manual, rdy on the microSPARC
2064                                        II */
2065                 case 0x0f:          /* stbar in the SPARCv8 manual,
2066                                        rdy on the microSPARC II */
2067                 case 0x10 ... 0x1f: /* implementation-dependent in the
2068                                        SPARCv8 manual, rdy on the
2069                                        microSPARC II */
2070                     /* Read Asr17 */
2071                     if (rs1 == 0x11 && dc->def->features & CPU_FEATURE_ASR17) {
2072                         TCGv r_const;
2073 
2074                         /* Read Asr17 for a Leon3 monoprocessor */
2075                         r_const = tcg_const_tl((1 << 8)
2076                                                | (dc->def->nwindows - 1));
2077                         gen_movl_TN_reg(rd, r_const);
2078                         tcg_temp_free(r_const);
2079                         break;
2080                     }
2081 #endif
2082                     gen_movl_TN_reg(rd, cpu_y);
2083                     break;
2084 #ifdef TARGET_SPARC64
2085                 case 0x2: /* V9 rdccr */
2086                     gen_helper_compute_psr();
2087                     gen_helper_rdccr(cpu_dst);
2088                     gen_movl_TN_reg(rd, cpu_dst);
2089                     break;
2090                 case 0x3: /* V9 rdasi */
2091                     tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
2092                     gen_movl_TN_reg(rd, cpu_dst);
2093                     break;
2094                 case 0x4: /* V9 rdtick */
2095                     {
2096                         TCGv_ptr r_tickptr;
2097 
2098                         r_tickptr = tcg_temp_new_ptr();
2099                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
2100                                        offsetof(CPUState, tick));
2101                         gen_helper_tick_get_count(cpu_dst, r_tickptr);
2102                         tcg_temp_free_ptr(r_tickptr);
2103                         gen_movl_TN_reg(rd, cpu_dst);
2104                     }
2105                     break;
2106                 case 0x5: /* V9 rdpc */
2107                     {
2108                         TCGv r_const;
2109 
2110                         r_const = tcg_const_tl(dc->pc);
2111                         gen_movl_TN_reg(rd, r_const);
2112                         tcg_temp_free(r_const);
2113                     }
2114                     break;
2115                 case 0x6: /* V9 rdfprs */
2116                     tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
2117                     gen_movl_TN_reg(rd, cpu_dst);
2118                     break;
2119                 case 0xf: /* V9 membar */
2120                     break; /* no effect */
2121                 case 0x13: /* Graphics Status */
2122                     if (gen_trap_ifnofpu(dc, cpu_cond))
2123                         goto jmp_insn;
2124                     gen_movl_TN_reg(rd, cpu_gsr);
2125                     break;
2126                 case 0x16: /* Softint */
2127                     tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
2128                     gen_movl_TN_reg(rd, cpu_dst);
2129                     break;
2130                 case 0x17: /* Tick compare */
2131                     gen_movl_TN_reg(rd, cpu_tick_cmpr);
2132                     break;
2133                 case 0x18: /* System tick */
2134                     {
2135                         TCGv_ptr r_tickptr;
2136 
2137                         r_tickptr = tcg_temp_new_ptr();
2138                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
2139                                        offsetof(CPUState, stick));
2140                         gen_helper_tick_get_count(cpu_dst, r_tickptr);
2141                         tcg_temp_free_ptr(r_tickptr);
2142                         gen_movl_TN_reg(rd, cpu_dst);
2143                     }
2144                     break;
2145                 case 0x19: /* System tick compare */
2146                     gen_movl_TN_reg(rd, cpu_stick_cmpr);
2147                     break;
2148                 case 0x10: /* Performance Control */
2149                 case 0x11: /* Performance Instrumentation Counter */
2150                 case 0x12: /* Dispatch Control */
2151                 case 0x14: /* Softint set, WO */
2152                 case 0x15: /* Softint clear, WO */
2153 #endif
2154                 default:
2155                     goto illegal_insn;
2156                 }
2157 #if !defined(CONFIG_USER_ONLY)
2158             } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
2159 #ifndef TARGET_SPARC64
2160                 if (!supervisor(dc))
2161                     goto priv_insn;
2162                 gen_helper_compute_psr();
2163                 dc->cc_op = CC_OP_FLAGS;
2164                 gen_helper_rdpsr(cpu_dst);
2165 #else
2166                 CHECK_IU_FEATURE(dc, HYPV);
2167                 if (!hypervisor(dc))
2168                     goto priv_insn;
2169                 rs1 = GET_FIELD(insn, 13, 17);
2170                 switch (rs1) {
2171                 case 0: // hpstate
2172                     // gen_op_rdhpstate();
2173                     break;
2174                 case 1: // htstate
2175                     // gen_op_rdhtstate();
2176                     break;
2177                 case 3: // hintp
2178                     tcg_gen_mov_tl(cpu_dst, cpu_hintp);
2179                     break;
2180                 case 5: // htba
2181                     tcg_gen_mov_tl(cpu_dst, cpu_htba);
2182                     break;
2183                 case 6: // hver
2184                     tcg_gen_mov_tl(cpu_dst, cpu_hver);
2185                     break;
2186                 case 31: // hstick_cmpr
2187                     tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
2188                     break;
2189                 default:
2190                     goto illegal_insn;
2191                 }
2192 #endif
2193                 gen_movl_TN_reg(rd, cpu_dst);
2194                 break;
2195             } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
2196                 if (!supervisor(dc))
2197                     goto priv_insn;
2198 #ifdef TARGET_SPARC64
2199                 rs1 = GET_FIELD(insn, 13, 17);
2200                 switch (rs1) {
2201                 case 0: // tpc
2202                     {
2203                         TCGv_ptr r_tsptr;
2204 
2205                         r_tsptr = tcg_temp_new_ptr();
2206                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2207                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2208                                       offsetof(trap_state, tpc));
2209                         tcg_temp_free_ptr(r_tsptr);
2210                     }
2211                     break;
2212                 case 1: // tnpc
2213                     {
2214                         TCGv_ptr r_tsptr;
2215 
2216                         r_tsptr = tcg_temp_new_ptr();
2217                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2218                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2219                                       offsetof(trap_state, tnpc));
2220                         tcg_temp_free_ptr(r_tsptr);
2221                     }
2222                     break;
2223                 case 2: // tstate
2224                     {
2225                         TCGv_ptr r_tsptr;
2226 
2227                         r_tsptr = tcg_temp_new_ptr();
2228                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2229                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2230                                       offsetof(trap_state, tstate));
2231                         tcg_temp_free_ptr(r_tsptr);
2232                     }
2233                     break;
2234                 case 3: // tt
2235                     {
2236                         TCGv_ptr r_tsptr;
2237 
2238                         r_tsptr = tcg_temp_new_ptr();
2239                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2240                         tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
2241                                        offsetof(trap_state, tt));
2242                         tcg_temp_free_ptr(r_tsptr);
2243                         tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2244                     }
2245                     break;
2246                 case 4: // tick
2247                     {
2248                         TCGv_ptr r_tickptr;
2249 
2250                         r_tickptr = tcg_temp_new_ptr();
2251                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
2252                                        offsetof(CPUState, tick));
2253                         gen_helper_tick_get_count(cpu_tmp0, r_tickptr);
2254                         gen_movl_TN_reg(rd, cpu_tmp0);
2255                         tcg_temp_free_ptr(r_tickptr);
2256                     }
2257                     break;
2258                 case 5: // tba
2259                     tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
2260                     break;
2261                 case 6: // pstate
2262                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2263                                    offsetof(CPUSPARCState, pstate));
2264                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2265                     break;
2266                 case 7: // tl
2267                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2268                                    offsetof(CPUSPARCState, tl));
2269                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2270                     break;
2271                 case 8: // pil
2272                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2273                                    offsetof(CPUSPARCState, psrpil));
2274                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2275                     break;
2276                 case 9: // cwp
2277                     gen_helper_rdcwp(cpu_tmp0);
2278                     break;
2279                 case 10: // cansave
2280                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2281                                    offsetof(CPUSPARCState, cansave));
2282                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2283                     break;
2284                 case 11: // canrestore
2285                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2286                                    offsetof(CPUSPARCState, canrestore));
2287                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2288                     break;
2289                 case 12: // cleanwin
2290                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2291                                    offsetof(CPUSPARCState, cleanwin));
2292                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2293                     break;
2294                 case 13: // otherwin
2295                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2296                                    offsetof(CPUSPARCState, otherwin));
2297                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2298                     break;
2299                 case 14: // wstate
2300                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2301                                    offsetof(CPUSPARCState, wstate));
2302                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2303                     break;
2304                 case 16: // UA2005 gl
2305                     CHECK_IU_FEATURE(dc, GL);
2306                     tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2307                                    offsetof(CPUSPARCState, gl));
2308                     tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2309                     break;
2310                 case 26: // UA2005 strand status
2311                     CHECK_IU_FEATURE(dc, HYPV);
2312                     if (!hypervisor(dc))
2313                         goto priv_insn;
2314                     tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
2315                     break;
2316                 case 31: // ver
2317                     tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
2318                     break;
2319                 case 15: // fq
2320                 default:
2321                     goto illegal_insn;
2322                 }
2323 #else
2324                 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
2325 #endif
2326                 gen_movl_TN_reg(rd, cpu_tmp0);
2327                 break;
2328             } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2329 #ifdef TARGET_SPARC64
2330                 save_state(dc, cpu_cond);
2331                 gen_helper_flushw();
2332 #else
2333                 if (!supervisor(dc))
2334                     goto priv_insn;
2335                 gen_movl_TN_reg(rd, cpu_tbr);
2336 #endif
2337                 break;
2338 #endif
2339             } else if (xop == 0x34) {   /* FPU Operations */
2340                 if (gen_trap_ifnofpu(dc, cpu_cond))
2341                     goto jmp_insn;
2342                 gen_op_clear_ieee_excp_and_FTT();
2343                 rs1 = GET_FIELD(insn, 13, 17);
2344                 rs2 = GET_FIELD(insn, 27, 31);
2345                 xop = GET_FIELD(insn, 18, 26);
2346                 save_state(dc, cpu_cond);
2347                 switch (xop) {
2348                 case 0x1: /* fmovs */
2349                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2350                     break;
2351                 case 0x5: /* fnegs */
2352                     gen_helper_fnegs(cpu_fpr[rd], cpu_fpr[rs2]);
2353                     break;
2354                 case 0x9: /* fabss */
2355                     gen_helper_fabss(cpu_fpr[rd], cpu_fpr[rs2]);
2356                     break;
2357                 case 0x29: /* fsqrts */
2358                     CHECK_FPU_FEATURE(dc, FSQRT);
2359                     gen_clear_float_exceptions();
2360                     gen_helper_fsqrts(cpu_tmp32, cpu_fpr[rs2]);
2361                     gen_helper_check_ieee_exceptions();
2362                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2363                     break;
2364                 case 0x2a: /* fsqrtd */
2365                     CHECK_FPU_FEATURE(dc, FSQRT);
2366                     gen_op_load_fpr_DT1(DFPREG(rs2));
2367                     gen_clear_float_exceptions();
2368                     gen_helper_fsqrtd();
2369                     gen_helper_check_ieee_exceptions();
2370                     gen_op_store_DT0_fpr(DFPREG(rd));
2371                     break;
2372                 case 0x2b: /* fsqrtq */
2373                     CHECK_FPU_FEATURE(dc, FLOAT128);
2374                     gen_op_load_fpr_QT1(QFPREG(rs2));
2375                     gen_clear_float_exceptions();
2376                     gen_helper_fsqrtq();
2377                     gen_helper_check_ieee_exceptions();
2378                     gen_op_store_QT0_fpr(QFPREG(rd));
2379                     break;
2380                 case 0x41: /* fadds */
2381                     gen_clear_float_exceptions();
2382                     gen_helper_fadds(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2383                     gen_helper_check_ieee_exceptions();
2384                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2385                     break;
2386                 case 0x42: /* faddd */
2387                     gen_op_load_fpr_DT0(DFPREG(rs1));
2388                     gen_op_load_fpr_DT1(DFPREG(rs2));
2389                     gen_clear_float_exceptions();
2390                     gen_helper_faddd();
2391                     gen_helper_check_ieee_exceptions();
2392                     gen_op_store_DT0_fpr(DFPREG(rd));
2393                     break;
2394                 case 0x43: /* faddq */
2395                     CHECK_FPU_FEATURE(dc, FLOAT128);
2396                     gen_op_load_fpr_QT0(QFPREG(rs1));
2397                     gen_op_load_fpr_QT1(QFPREG(rs2));
2398                     gen_clear_float_exceptions();
2399                     gen_helper_faddq();
2400                     gen_helper_check_ieee_exceptions();
2401                     gen_op_store_QT0_fpr(QFPREG(rd));
2402                     break;
2403                 case 0x45: /* fsubs */
2404                     gen_clear_float_exceptions();
2405                     gen_helper_fsubs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2406                     gen_helper_check_ieee_exceptions();
2407                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2408                     break;
2409                 case 0x46: /* fsubd */
2410                     gen_op_load_fpr_DT0(DFPREG(rs1));
2411                     gen_op_load_fpr_DT1(DFPREG(rs2));
2412                     gen_clear_float_exceptions();
2413                     gen_helper_fsubd();
2414                     gen_helper_check_ieee_exceptions();
2415                     gen_op_store_DT0_fpr(DFPREG(rd));
2416                     break;
2417                 case 0x47: /* fsubq */
2418                     CHECK_FPU_FEATURE(dc, FLOAT128);
2419                     gen_op_load_fpr_QT0(QFPREG(rs1));
2420                     gen_op_load_fpr_QT1(QFPREG(rs2));
2421                     gen_clear_float_exceptions();
2422                     gen_helper_fsubq();
2423                     gen_helper_check_ieee_exceptions();
2424                     gen_op_store_QT0_fpr(QFPREG(rd));
2425                     break;
2426                 case 0x49: /* fmuls */
2427                     CHECK_FPU_FEATURE(dc, FMUL);
2428                     gen_clear_float_exceptions();
2429                     gen_helper_fmuls(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2430                     gen_helper_check_ieee_exceptions();
2431                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2432                     break;
2433                 case 0x4a: /* fmuld */
2434                     CHECK_FPU_FEATURE(dc, FMUL);
2435                     gen_op_load_fpr_DT0(DFPREG(rs1));
2436                     gen_op_load_fpr_DT1(DFPREG(rs2));
2437                     gen_clear_float_exceptions();
2438                     gen_helper_fmuld();
2439                     gen_helper_check_ieee_exceptions();
2440                     gen_op_store_DT0_fpr(DFPREG(rd));
2441                     break;
2442                 case 0x4b: /* fmulq */
2443                     CHECK_FPU_FEATURE(dc, FLOAT128);
2444                     CHECK_FPU_FEATURE(dc, FMUL);
2445                     gen_op_load_fpr_QT0(QFPREG(rs1));
2446                     gen_op_load_fpr_QT1(QFPREG(rs2));
2447                     gen_clear_float_exceptions();
2448                     gen_helper_fmulq();
2449                     gen_helper_check_ieee_exceptions();
2450                     gen_op_store_QT0_fpr(QFPREG(rd));
2451                     break;
2452                 case 0x4d: /* fdivs */
2453                     gen_clear_float_exceptions();
2454                     gen_helper_fdivs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2455                     gen_helper_check_ieee_exceptions();
2456                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2457                     break;
2458                 case 0x4e: /* fdivd */
2459                     gen_op_load_fpr_DT0(DFPREG(rs1));
2460                     gen_op_load_fpr_DT1(DFPREG(rs2));
2461                     gen_clear_float_exceptions();
2462                     gen_helper_fdivd();
2463                     gen_helper_check_ieee_exceptions();
2464                     gen_op_store_DT0_fpr(DFPREG(rd));
2465                     break;
2466                 case 0x4f: /* fdivq */
2467                     CHECK_FPU_FEATURE(dc, FLOAT128);
2468                     gen_op_load_fpr_QT0(QFPREG(rs1));
2469                     gen_op_load_fpr_QT1(QFPREG(rs2));
2470                     gen_clear_float_exceptions();
2471                     gen_helper_fdivq();
2472                     gen_helper_check_ieee_exceptions();
2473                     gen_op_store_QT0_fpr(QFPREG(rd));
2474                     break;
2475                 case 0x69: /* fsmuld */
2476                     CHECK_FPU_FEATURE(dc, FSMULD);
2477                     gen_clear_float_exceptions();
2478                     gen_helper_fsmuld(cpu_fpr[rs1], cpu_fpr[rs2]);
2479                     gen_helper_check_ieee_exceptions();
2480                     gen_op_store_DT0_fpr(DFPREG(rd));
2481                     break;
2482                 case 0x6e: /* fdmulq */
2483                     CHECK_FPU_FEATURE(dc, FLOAT128);
2484                     gen_op_load_fpr_DT0(DFPREG(rs1));
2485                     gen_op_load_fpr_DT1(DFPREG(rs2));
2486                     gen_clear_float_exceptions();
2487                     gen_helper_fdmulq();
2488                     gen_helper_check_ieee_exceptions();
2489                     gen_op_store_QT0_fpr(QFPREG(rd));
2490                     break;
2491                 case 0xc4: /* fitos */
2492                     gen_clear_float_exceptions();
2493                     gen_helper_fitos(cpu_tmp32, cpu_fpr[rs2]);
2494                     gen_helper_check_ieee_exceptions();
2495                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2496                     break;
2497                 case 0xc6: /* fdtos */
2498                     gen_op_load_fpr_DT1(DFPREG(rs2));
2499                     gen_clear_float_exceptions();
2500                     gen_helper_fdtos(cpu_tmp32);
2501                     gen_helper_check_ieee_exceptions();
2502                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2503                     break;
2504                 case 0xc7: /* fqtos */
2505                     CHECK_FPU_FEATURE(dc, FLOAT128);
2506                     gen_op_load_fpr_QT1(QFPREG(rs2));
2507                     gen_clear_float_exceptions();
2508                     gen_helper_fqtos(cpu_tmp32);
2509                     gen_helper_check_ieee_exceptions();
2510                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2511                     break;
2512                 case 0xc8: /* fitod */
2513                     gen_helper_fitod(cpu_fpr[rs2]);
2514                     gen_op_store_DT0_fpr(DFPREG(rd));
2515                     break;
2516                 case 0xc9: /* fstod */
2517                     gen_helper_fstod(cpu_fpr[rs2]);
2518                     gen_op_store_DT0_fpr(DFPREG(rd));
2519                     break;
2520                 case 0xcb: /* fqtod */
2521                     CHECK_FPU_FEATURE(dc, FLOAT128);
2522                     gen_op_load_fpr_QT1(QFPREG(rs2));
2523                     gen_clear_float_exceptions();
2524                     gen_helper_fqtod();
2525                     gen_helper_check_ieee_exceptions();
2526                     gen_op_store_DT0_fpr(DFPREG(rd));
2527                     break;
2528                 case 0xcc: /* fitoq */
2529                     CHECK_FPU_FEATURE(dc, FLOAT128);
2530                     gen_helper_fitoq(cpu_fpr[rs2]);
2531                     gen_op_store_QT0_fpr(QFPREG(rd));
2532                     break;
2533                 case 0xcd: /* fstoq */
2534                     CHECK_FPU_FEATURE(dc, FLOAT128);
2535                     gen_helper_fstoq(cpu_fpr[rs2]);
2536                     gen_op_store_QT0_fpr(QFPREG(rd));
2537                     break;
2538                 case 0xce: /* fdtoq */
2539                     CHECK_FPU_FEATURE(dc, FLOAT128);
2540                     gen_op_load_fpr_DT1(DFPREG(rs2));
2541                     gen_helper_fdtoq();
2542                     gen_op_store_QT0_fpr(QFPREG(rd));
2543                     break;
2544                 case 0xd1: /* fstoi */
2545                     gen_clear_float_exceptions();
2546                     gen_helper_fstoi(cpu_tmp32, cpu_fpr[rs2]);
2547                     gen_helper_check_ieee_exceptions();
2548                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2549                     break;
2550                 case 0xd2: /* fdtoi */
2551                     gen_op_load_fpr_DT1(DFPREG(rs2));
2552                     gen_clear_float_exceptions();
2553                     gen_helper_fdtoi(cpu_tmp32);
2554                     gen_helper_check_ieee_exceptions();
2555                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2556                     break;
2557                 case 0xd3: /* fqtoi */
2558                     CHECK_FPU_FEATURE(dc, FLOAT128);
2559                     gen_op_load_fpr_QT1(QFPREG(rs2));
2560                     gen_clear_float_exceptions();
2561                     gen_helper_fqtoi(cpu_tmp32);
2562                     gen_helper_check_ieee_exceptions();
2563                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2564                     break;
2565 #ifdef TARGET_SPARC64
2566                 case 0x2: /* V9 fmovd */
2567                     tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2568                     tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
2569                                     cpu_fpr[DFPREG(rs2) + 1]);
2570                     break;
2571                 case 0x3: /* V9 fmovq */
2572                     CHECK_FPU_FEATURE(dc, FLOAT128);
2573                     tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2574                     tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],
2575                                     cpu_fpr[QFPREG(rs2) + 1]);
2576                     tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],
2577                                     cpu_fpr[QFPREG(rs2) + 2]);
2578                     tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],
2579                                     cpu_fpr[QFPREG(rs2) + 3]);
2580                     break;
2581                 case 0x6: /* V9 fnegd */
2582                     gen_op_load_fpr_DT1(DFPREG(rs2));
2583                     gen_helper_fnegd();
2584                     gen_op_store_DT0_fpr(DFPREG(rd));
2585                     break;
2586                 case 0x7: /* V9 fnegq */
2587                     CHECK_FPU_FEATURE(dc, FLOAT128);
2588                     gen_op_load_fpr_QT1(QFPREG(rs2));
2589                     gen_helper_fnegq();
2590                     gen_op_store_QT0_fpr(QFPREG(rd));
2591                     break;
2592                 case 0xa: /* V9 fabsd */
2593                     gen_op_load_fpr_DT1(DFPREG(rs2));
2594                     gen_helper_fabsd();
2595                     gen_op_store_DT0_fpr(DFPREG(rd));
2596                     break;
2597                 case 0xb: /* V9 fabsq */
2598                     CHECK_FPU_FEATURE(dc, FLOAT128);
2599                     gen_op_load_fpr_QT1(QFPREG(rs2));
2600                     gen_helper_fabsq();
2601                     gen_op_store_QT0_fpr(QFPREG(rd));
2602                     break;
2603                 case 0x81: /* V9 fstox */
2604                     gen_clear_float_exceptions();
2605                     gen_helper_fstox(cpu_fpr[rs2]);
2606                     gen_helper_check_ieee_exceptions();
2607                     gen_op_store_DT0_fpr(DFPREG(rd));
2608                     break;
2609                 case 0x82: /* V9 fdtox */
2610                     gen_op_load_fpr_DT1(DFPREG(rs2));
2611                     gen_clear_float_exceptions();
2612                     gen_helper_fdtox();
2613                     gen_helper_check_ieee_exceptions();
2614                     gen_op_store_DT0_fpr(DFPREG(rd));
2615                     break;
2616                 case 0x83: /* V9 fqtox */
2617                     CHECK_FPU_FEATURE(dc, FLOAT128);
2618                     gen_op_load_fpr_QT1(QFPREG(rs2));
2619                     gen_clear_float_exceptions();
2620                     gen_helper_fqtox();
2621                     gen_helper_check_ieee_exceptions();
2622                     gen_op_store_DT0_fpr(DFPREG(rd));
2623                     break;
2624                 case 0x84: /* V9 fxtos */
2625                     gen_op_load_fpr_DT1(DFPREG(rs2));
2626                     gen_clear_float_exceptions();
2627                     gen_helper_fxtos(cpu_tmp32);
2628                     gen_helper_check_ieee_exceptions();
2629                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2630                     break;
2631                 case 0x88: /* V9 fxtod */
2632                     gen_op_load_fpr_DT1(DFPREG(rs2));
2633                     gen_clear_float_exceptions();
2634                     gen_helper_fxtod();
2635                     gen_helper_check_ieee_exceptions();
2636                     gen_op_store_DT0_fpr(DFPREG(rd));
2637                     break;
2638                 case 0x8c: /* V9 fxtoq */
2639                     CHECK_FPU_FEATURE(dc, FLOAT128);
2640                     gen_op_load_fpr_DT1(DFPREG(rs2));
2641                     gen_clear_float_exceptions();
2642                     gen_helper_fxtoq();
2643                     gen_helper_check_ieee_exceptions();
2644                     gen_op_store_QT0_fpr(QFPREG(rd));
2645                     break;
2646 #endif
2647                 default:
2648                     goto illegal_insn;
2649                 }
2650             } else if (xop == 0x35) {   /* FPU Operations */
2651 #ifdef TARGET_SPARC64
2652                 int cond;
2653 #endif
2654                 if (gen_trap_ifnofpu(dc, cpu_cond))
2655                     goto jmp_insn;
2656                 gen_op_clear_ieee_excp_and_FTT();
2657                 rs1 = GET_FIELD(insn, 13, 17);
2658                 rs2 = GET_FIELD(insn, 27, 31);
2659                 xop = GET_FIELD(insn, 18, 26);
2660                 save_state(dc, cpu_cond);
2661 #ifdef TARGET_SPARC64
2662                 if ((xop & 0x11f) == 0x005) { // V9 fmovsr
2663                     int l1;
2664 
2665                     l1 = gen_new_label();
2666                     cond = GET_FIELD_SP(insn, 14, 17);
2667                     cpu_src1 = get_src1(insn, cpu_src1);
2668                     tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2669                                        0, l1);
2670                     tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2671                     gen_set_label(l1);
2672                     break;
2673                 } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2674                     int l1;
2675 
2676                     l1 = gen_new_label();
2677                     cond = GET_FIELD_SP(insn, 14, 17);
2678                     cpu_src1 = get_src1(insn, cpu_src1);
2679                     tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2680                                        0, l1);
2681                     tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2682                     tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
2683                     gen_set_label(l1);
2684                     break;
2685                 } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2686                     int l1;
2687 
2688                     CHECK_FPU_FEATURE(dc, FLOAT128);
2689                     l1 = gen_new_label();
2690                     cond = GET_FIELD_SP(insn, 14, 17);
2691                     cpu_src1 = get_src1(insn, cpu_src1);
2692                     tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2693                                        0, l1);
2694                     tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2695                     tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]);
2696                     tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]);
2697                     tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]);
2698                     gen_set_label(l1);
2699                     break;
2700                 }
2701 #endif
2702                 switch (xop) {
2703 #ifdef TARGET_SPARC64
2704 #define FMOVSCC(fcc)                                                    \
2705                     {                                                   \
2706                         TCGv r_cond;                                    \
2707                         int l1;                                         \
2708                                                                         \
2709                         l1 = gen_new_label();                           \
2710                         r_cond = tcg_temp_new();                        \
2711                         cond = GET_FIELD_SP(insn, 14, 17);              \
2712                         gen_fcond(r_cond, fcc, cond);                   \
2713                         tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2714                                            0, l1);                      \
2715                         tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2716                         gen_set_label(l1);                              \
2717                         tcg_temp_free(r_cond);                          \
2718                     }
2719 #define FMOVDCC(fcc)                                                    \
2720                     {                                                   \
2721                         TCGv r_cond;                                    \
2722                         int l1;                                         \
2723                                                                         \
2724                         l1 = gen_new_label();                           \
2725                         r_cond = tcg_temp_new();                        \
2726                         cond = GET_FIELD_SP(insn, 14, 17);              \
2727                         gen_fcond(r_cond, fcc, cond);                   \
2728                         tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2729                                            0, l1);                      \
2730                         tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
2731                                         cpu_fpr[DFPREG(rs2)]);          \
2732                         tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
2733                                         cpu_fpr[DFPREG(rs2) + 1]);      \
2734                         gen_set_label(l1);                              \
2735                         tcg_temp_free(r_cond);                          \
2736                     }
2737 #define FMOVQCC(fcc)                                                    \
2738                     {                                                   \
2739                         TCGv r_cond;                                    \
2740                         int l1;                                         \
2741                                                                         \
2742                         l1 = gen_new_label();                           \
2743                         r_cond = tcg_temp_new();                        \
2744                         cond = GET_FIELD_SP(insn, 14, 17);              \
2745                         gen_fcond(r_cond, fcc, cond);                   \
2746                         tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2747                                            0, l1);                      \
2748                         tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
2749                                         cpu_fpr[QFPREG(rs2)]);          \
2750                         tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
2751                                         cpu_fpr[QFPREG(rs2) + 1]);      \
2752                         tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
2753                                         cpu_fpr[QFPREG(rs2) + 2]);      \
2754                         tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
2755                                         cpu_fpr[QFPREG(rs2) + 3]);      \
2756                         gen_set_label(l1);                              \
2757                         tcg_temp_free(r_cond);                          \
2758                     }
2759                     case 0x001: /* V9 fmovscc %fcc0 */
2760                         FMOVSCC(0);
2761                         break;
2762                     case 0x002: /* V9 fmovdcc %fcc0 */
2763                         FMOVDCC(0);
2764                         break;
2765                     case 0x003: /* V9 fmovqcc %fcc0 */
2766                         CHECK_FPU_FEATURE(dc, FLOAT128);
2767                         FMOVQCC(0);
2768                         break;
2769                     case 0x041: /* V9 fmovscc %fcc1 */
2770                         FMOVSCC(1);
2771                         break;
2772                     case 0x042: /* V9 fmovdcc %fcc1 */
2773                         FMOVDCC(1);
2774                         break;
2775                     case 0x043: /* V9 fmovqcc %fcc1 */
2776                         CHECK_FPU_FEATURE(dc, FLOAT128);
2777                         FMOVQCC(1);
2778                         break;
2779                     case 0x081: /* V9 fmovscc %fcc2 */
2780                         FMOVSCC(2);
2781                         break;
2782                     case 0x082: /* V9 fmovdcc %fcc2 */
2783                         FMOVDCC(2);
2784                         break;
2785                     case 0x083: /* V9 fmovqcc %fcc2 */
2786                         CHECK_FPU_FEATURE(dc, FLOAT128);
2787                         FMOVQCC(2);
2788                         break;
2789                     case 0x0c1: /* V9 fmovscc %fcc3 */
2790                         FMOVSCC(3);
2791                         break;
2792                     case 0x0c2: /* V9 fmovdcc %fcc3 */
2793                         FMOVDCC(3);
2794                         break;
2795                     case 0x0c3: /* V9 fmovqcc %fcc3 */
2796                         CHECK_FPU_FEATURE(dc, FLOAT128);
2797                         FMOVQCC(3);
2798                         break;
2799 #undef FMOVSCC
2800 #undef FMOVDCC
2801 #undef FMOVQCC
2802 #define FMOVSCC(icc)                                                    \
2803                     {                                                   \
2804                         TCGv r_cond;                                    \
2805                         int l1;                                         \
2806                                                                         \
2807                         l1 = gen_new_label();                           \
2808                         r_cond = tcg_temp_new();                        \
2809                         cond = GET_FIELD_SP(insn, 14, 17);              \
2810                         gen_cond(r_cond, icc, cond, dc);                \
2811                         tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2812                                            0, l1);                      \
2813                         tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2814                         gen_set_label(l1);                              \
2815                         tcg_temp_free(r_cond);                          \
2816                     }
2817 #define FMOVDCC(icc)                                                    \
2818                     {                                                   \
2819                         TCGv r_cond;                                    \
2820                         int l1;                                         \
2821                                                                         \
2822                         l1 = gen_new_label();                           \
2823                         r_cond = tcg_temp_new();                        \
2824                         cond = GET_FIELD_SP(insn, 14, 17);              \
2825                         gen_cond(r_cond, icc, cond, dc);                \
2826                         tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2827                                            0, l1);                      \
2828                         tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
2829                                         cpu_fpr[DFPREG(rs2)]);          \
2830                         tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
2831                                         cpu_fpr[DFPREG(rs2) + 1]);      \
2832                         gen_set_label(l1);                              \
2833                         tcg_temp_free(r_cond);                          \
2834                     }
2835 #define FMOVQCC(icc)                                                    \
2836                     {                                                   \
2837                         TCGv r_cond;                                    \
2838                         int l1;                                         \
2839                                                                         \
2840                         l1 = gen_new_label();                           \
2841                         r_cond = tcg_temp_new();                        \
2842                         cond = GET_FIELD_SP(insn, 14, 17);              \
2843                         gen_cond(r_cond, icc, cond, dc);                \
2844                         tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2845                                            0, l1);                      \
2846                         tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
2847                                         cpu_fpr[QFPREG(rs2)]);          \
2848                         tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
2849                                         cpu_fpr[QFPREG(rs2) + 1]);      \
2850                         tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
2851                                         cpu_fpr[QFPREG(rs2) + 2]);      \
2852                         tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
2853                                         cpu_fpr[QFPREG(rs2) + 3]);      \
2854                         gen_set_label(l1);                              \
2855                         tcg_temp_free(r_cond);                          \
2856                     }
2857 
2858                     case 0x101: /* V9 fmovscc %icc */
2859                         FMOVSCC(0);
2860                         break;
2861                     case 0x102: /* V9 fmovdcc %icc */
2862                         FMOVDCC(0);
2863                     case 0x103: /* V9 fmovqcc %icc */
2864                         CHECK_FPU_FEATURE(dc, FLOAT128);
2865                         FMOVQCC(0);
2866                         break;
2867                     case 0x181: /* V9 fmovscc %xcc */
2868                         FMOVSCC(1);
2869                         break;
2870                     case 0x182: /* V9 fmovdcc %xcc */
2871                         FMOVDCC(1);
2872                         break;
2873                     case 0x183: /* V9 fmovqcc %xcc */
2874                         CHECK_FPU_FEATURE(dc, FLOAT128);
2875                         FMOVQCC(