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