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