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