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