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