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