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