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