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