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