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