4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 Copyright (C) 2003-2005 Fabrice Bellard
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.
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.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, see <http://www.gnu.org/licenses/>.
38 #define DYNAMIC_PC 1 /* dynamic pc value */
39 #define JUMP_PC 2 /* dynamic pc value which takes only two values
40 according to jump_pc[T2] */
42 /* global register indexes */
43 static TCGv_ptr cpu_env
, cpu_regwptr
;
44 static TCGv cpu_cc_src
, cpu_cc_src2
, cpu_cc_dst
;
45 static TCGv_i32 cpu_cc_op
;
46 static TCGv_i32 cpu_psr
;
47 static TCGv cpu_fsr
, cpu_pc
, cpu_npc
, cpu_gregs
[8];
49 #ifndef CONFIG_USER_ONLY
52 static TCGv cpu_cond
, cpu_src1
, cpu_src2
, cpu_dst
, cpu_addr
, cpu_val
;
54 static TCGv_i32 cpu_xcc
, cpu_asi
, cpu_fprs
;
56 static TCGv cpu_tick_cmpr
, cpu_stick_cmpr
, cpu_hstick_cmpr
;
57 static TCGv cpu_hintp
, cpu_htba
, cpu_hver
, cpu_ssr
, cpu_ver
;
58 static TCGv_i32 cpu_softint
;
62 /* local register indexes (only used inside old micro ops) */
64 static TCGv_i32 cpu_tmp32
;
65 static TCGv_i64 cpu_tmp64
;
66 /* Floating point registers */
67 static TCGv_i32 cpu_fpr
[TARGET_FPREGS
];
69 static target_ulong gen_opc_npc
[OPC_BUF_SIZE
];
70 static target_ulong gen_opc_jump_pc
[2];
72 #include "gen-icount.h"
74 typedef struct DisasContext
{
75 target_ulong pc
; /* current Program Counter: integer or DYNAMIC_PC */
76 target_ulong npc
; /* next PC: integer or DYNAMIC_PC or JUMP_PC */
77 target_ulong jump_pc
[2]; /* used when JUMP_PC pc value is used */
81 int address_mask_32bit
;
82 uint32_t cc_op
; /* current CC operation */
83 struct TranslationBlock
*tb
;
87 // This function uses non-native bit order
88 #define GET_FIELD(X, FROM, TO) \
89 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
91 // This function uses the order in the manuals, i.e. bit 0 is 2^0
92 #define GET_FIELD_SP(X, FROM, TO) \
93 GET_FIELD(X, 31 - (TO), 31 - (FROM))
95 #define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
96 #define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
99 #define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
100 #define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
102 #define DFPREG(r) (r & 0x1e)
103 #define QFPREG(r) (r & 0x1c)
106 #define UA2005_HTRAP_MASK 0xff
107 #define V8_TRAP_MASK 0x7f
109 static int sign_extend(int x
, int len
)
112 return (x
<< len
) >> len
;
115 #define IS_IMM (insn & (1<<13))
117 /* floating point registers moves */
118 static void gen_op_load_fpr_DT0(unsigned int src
)
120 tcg_gen_st_i32(cpu_fpr
[src
], cpu_env
, offsetof(CPUSPARCState
, dt0
) +
121 offsetof(CPU_DoubleU
, l
.upper
));
122 tcg_gen_st_i32(cpu_fpr
[src
+ 1], cpu_env
, offsetof(CPUSPARCState
, dt0
) +
123 offsetof(CPU_DoubleU
, l
.lower
));
126 static void gen_op_load_fpr_DT1(unsigned int src
)
128 tcg_gen_st_i32(cpu_fpr
[src
], cpu_env
, offsetof(CPUSPARCState
, dt1
) +
129 offsetof(CPU_DoubleU
, l
.upper
));
130 tcg_gen_st_i32(cpu_fpr
[src
+ 1], cpu_env
, offsetof(CPUSPARCState
, dt1
) +
131 offsetof(CPU_DoubleU
, l
.lower
));
134 static void gen_op_store_DT0_fpr(unsigned int dst
)
136 tcg_gen_ld_i32(cpu_fpr
[dst
], cpu_env
, offsetof(CPUSPARCState
, dt0
) +
137 offsetof(CPU_DoubleU
, l
.upper
));
138 tcg_gen_ld_i32(cpu_fpr
[dst
+ 1], cpu_env
, offsetof(CPUSPARCState
, dt0
) +
139 offsetof(CPU_DoubleU
, l
.lower
));
142 static void gen_op_load_fpr_QT0(unsigned int src
)
144 tcg_gen_st_i32(cpu_fpr
[src
], cpu_env
, offsetof(CPUSPARCState
, qt0
) +
145 offsetof(CPU_QuadU
, l
.upmost
));
146 tcg_gen_st_i32(cpu_fpr
[src
+ 1], cpu_env
, offsetof(CPUSPARCState
, qt0
) +
147 offsetof(CPU_QuadU
, l
.upper
));
148 tcg_gen_st_i32(cpu_fpr
[src
+ 2], cpu_env
, offsetof(CPUSPARCState
, qt0
) +
149 offsetof(CPU_QuadU
, l
.lower
));
150 tcg_gen_st_i32(cpu_fpr
[src
+ 3], cpu_env
, offsetof(CPUSPARCState
, qt0
) +
151 offsetof(CPU_QuadU
, l
.lowest
));
154 static void gen_op_load_fpr_QT1(unsigned int src
)
156 tcg_gen_st_i32(cpu_fpr
[src
], cpu_env
, offsetof(CPUSPARCState
, qt1
) +
157 offsetof(CPU_QuadU
, l
.upmost
));
158 tcg_gen_st_i32(cpu_fpr
[src
+ 1], cpu_env
, offsetof(CPUSPARCState
, qt1
) +
159 offsetof(CPU_QuadU
, l
.upper
));
160 tcg_gen_st_i32(cpu_fpr
[src
+ 2], cpu_env
, offsetof(CPUSPARCState
, qt1
) +
161 offsetof(CPU_QuadU
, l
.lower
));
162 tcg_gen_st_i32(cpu_fpr
[src
+ 3], cpu_env
, offsetof(CPUSPARCState
, qt1
) +
163 offsetof(CPU_QuadU
, l
.lowest
));
166 static void gen_op_store_QT0_fpr(unsigned int dst
)
168 tcg_gen_ld_i32(cpu_fpr
[dst
], cpu_env
, offsetof(CPUSPARCState
, qt0
) +
169 offsetof(CPU_QuadU
, l
.upmost
));
170 tcg_gen_ld_i32(cpu_fpr
[dst
+ 1], cpu_env
, offsetof(CPUSPARCState
, qt0
) +
171 offsetof(CPU_QuadU
, l
.upper
));
172 tcg_gen_ld_i32(cpu_fpr
[dst
+ 2], cpu_env
, offsetof(CPUSPARCState
, qt0
) +
173 offsetof(CPU_QuadU
, l
.lower
));
174 tcg_gen_ld_i32(cpu_fpr
[dst
+ 3], cpu_env
, offsetof(CPUSPARCState
, qt0
) +
175 offsetof(CPU_QuadU
, l
.lowest
));
179 #ifdef CONFIG_USER_ONLY
180 #define supervisor(dc) 0
181 #ifdef TARGET_SPARC64
182 #define hypervisor(dc) 0
185 #define supervisor(dc) (dc->mem_idx >= 1)
186 #ifdef TARGET_SPARC64
187 #define hypervisor(dc) (dc->mem_idx == 2)
192 #ifdef TARGET_SPARC64
194 #define AM_CHECK(dc) ((dc)->address_mask_32bit)
196 #define AM_CHECK(dc) (1)
200 static inline void gen_address_mask(DisasContext
*dc
, TCGv addr
)
202 #ifdef TARGET_SPARC64
204 tcg_gen_andi_tl(addr
, addr
, 0xffffffffULL
);
208 static inline void gen_movl_reg_TN(int reg
, TCGv tn
)
211 tcg_gen_movi_tl(tn
, 0);
213 tcg_gen_mov_tl(tn
, cpu_gregs
[reg
]);
215 tcg_gen_ld_tl(tn
, cpu_regwptr
, (reg
- 8) * sizeof(target_ulong
));
219 static inline void gen_movl_TN_reg(int reg
, TCGv tn
)
224 tcg_gen_mov_tl(cpu_gregs
[reg
], tn
);
226 tcg_gen_st_tl(tn
, cpu_regwptr
, (reg
- 8) * sizeof(target_ulong
));
230 static inline void gen_goto_tb(DisasContext
*s
, int tb_num
,
231 target_ulong pc
, target_ulong npc
)
233 TranslationBlock
*tb
;
236 if ((pc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
) &&
237 (npc
& TARGET_PAGE_MASK
) == (tb
->pc
& TARGET_PAGE_MASK
)) {
238 /* jump to same page: we can use a direct jump */
239 tcg_gen_goto_tb(tb_num
);
240 tcg_gen_movi_tl(cpu_pc
, pc
);
241 tcg_gen_movi_tl(cpu_npc
, npc
);
242 tcg_gen_exit_tb((long)tb
+ tb_num
);
244 /* jump to another page: currently not optimized */
245 tcg_gen_movi_tl(cpu_pc
, pc
);
246 tcg_gen_movi_tl(cpu_npc
, npc
);
252 static inline void gen_mov_reg_N(TCGv reg
, TCGv_i32 src
)
254 tcg_gen_extu_i32_tl(reg
, src
);
255 tcg_gen_shri_tl(reg
, reg
, PSR_NEG_SHIFT
);
256 tcg_gen_andi_tl(reg
, reg
, 0x1);
259 static inline void gen_mov_reg_Z(TCGv reg
, TCGv_i32 src
)
261 tcg_gen_extu_i32_tl(reg
, src
);
262 tcg_gen_shri_tl(reg
, reg
, PSR_ZERO_SHIFT
);
263 tcg_gen_andi_tl(reg
, reg
, 0x1);
266 static inline void gen_mov_reg_V(TCGv reg
, TCGv_i32 src
)
268 tcg_gen_extu_i32_tl(reg
, src
);
269 tcg_gen_shri_tl(reg
, reg
, PSR_OVF_SHIFT
);
270 tcg_gen_andi_tl(reg
, reg
, 0x1);
273 static inline void gen_mov_reg_C(TCGv reg
, TCGv_i32 src
)
275 tcg_gen_extu_i32_tl(reg
, src
);
276 tcg_gen_shri_tl(reg
, reg
, PSR_CARRY_SHIFT
);
277 tcg_gen_andi_tl(reg
, reg
, 0x1);
280 static inline void gen_add_tv(TCGv dst
, TCGv src1
, TCGv src2
)
286 l1
= gen_new_label();
288 r_temp
= tcg_temp_new();
289 tcg_gen_xor_tl(r_temp
, src1
, src2
);
290 tcg_gen_not_tl(r_temp
, r_temp
);
291 tcg_gen_xor_tl(cpu_tmp0
, src1
, dst
);
292 tcg_gen_and_tl(r_temp
, r_temp
, cpu_tmp0
);
293 tcg_gen_andi_tl(r_temp
, r_temp
, (1ULL << 31));
294 tcg_gen_brcondi_tl(TCG_COND_EQ
, r_temp
, 0, l1
);
295 r_const
= tcg_const_i32(TT_TOVF
);
296 gen_helper_raise_exception(r_const
);
297 tcg_temp_free_i32(r_const
);
299 tcg_temp_free(r_temp
);
302 static inline void gen_tag_tv(TCGv src1
, TCGv src2
)
307 l1
= gen_new_label();
308 tcg_gen_or_tl(cpu_tmp0
, src1
, src2
);
309 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, 0x3);
310 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_tmp0
, 0, l1
);
311 r_const
= tcg_const_i32(TT_TOVF
);
312 gen_helper_raise_exception(r_const
);
313 tcg_temp_free_i32(r_const
);
317 static inline void gen_op_addi_cc(TCGv dst
, TCGv src1
, target_long src2
)
319 tcg_gen_mov_tl(cpu_cc_src
, src1
);
320 tcg_gen_movi_tl(cpu_cc_src2
, src2
);
321 tcg_gen_addi_tl(cpu_cc_dst
, cpu_cc_src
, src2
);
322 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
325 static inline void gen_op_add_cc(TCGv dst
, TCGv src1
, TCGv src2
)
327 tcg_gen_mov_tl(cpu_cc_src
, src1
);
328 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
329 tcg_gen_add_tl(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
330 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
333 static inline void gen_op_addxi_cc(TCGv dst
, TCGv src1
, target_long src2
)
335 tcg_gen_mov_tl(cpu_cc_src
, src1
);
336 tcg_gen_movi_tl(cpu_cc_src2
, src2
);
337 gen_mov_reg_C(cpu_tmp0
, cpu_psr
);
338 tcg_gen_add_tl(cpu_cc_dst
, cpu_cc_src
, cpu_tmp0
);
339 tcg_gen_addi_tl(cpu_cc_dst
, cpu_cc_dst
, src2
);
340 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
343 static inline void gen_op_addx_cc(TCGv dst
, TCGv src1
, TCGv src2
)
345 tcg_gen_mov_tl(cpu_cc_src
, src1
);
346 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
347 gen_mov_reg_C(cpu_tmp0
, cpu_psr
);
348 tcg_gen_add_tl(cpu_cc_dst
, cpu_cc_src
, cpu_tmp0
);
349 tcg_gen_add_tl(cpu_cc_dst
, cpu_cc_dst
, cpu_cc_src2
);
350 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
353 static inline void gen_op_tadd_cc(TCGv dst
, TCGv src1
, TCGv src2
)
355 tcg_gen_mov_tl(cpu_cc_src
, src1
);
356 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
357 tcg_gen_add_tl(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
358 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
361 static inline void gen_op_tadd_ccTV(TCGv dst
, TCGv src1
, TCGv src2
)
363 tcg_gen_mov_tl(cpu_cc_src
, src1
);
364 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
365 gen_tag_tv(cpu_cc_src
, cpu_cc_src2
);
366 tcg_gen_add_tl(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
367 gen_add_tv(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
368 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
371 static inline void gen_sub_tv(TCGv dst
, TCGv src1
, TCGv src2
)
377 l1
= gen_new_label();
379 r_temp
= tcg_temp_new();
380 tcg_gen_xor_tl(r_temp
, src1
, src2
);
381 tcg_gen_xor_tl(cpu_tmp0
, src1
, dst
);
382 tcg_gen_and_tl(r_temp
, r_temp
, cpu_tmp0
);
383 tcg_gen_andi_tl(r_temp
, r_temp
, (1ULL << 31));
384 tcg_gen_brcondi_tl(TCG_COND_EQ
, r_temp
, 0, l1
);
385 r_const
= tcg_const_i32(TT_TOVF
);
386 gen_helper_raise_exception(r_const
);
387 tcg_temp_free_i32(r_const
);
389 tcg_temp_free(r_temp
);
392 static inline void gen_op_subi_cc(TCGv dst
, TCGv src1
, target_long src2
, DisasContext
*dc
)
394 tcg_gen_mov_tl(cpu_cc_src
, src1
);
395 tcg_gen_movi_tl(cpu_cc_src2
, src2
);
397 tcg_gen_mov_tl(cpu_cc_dst
, src1
);
398 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
399 dc
->cc_op
= CC_OP_LOGIC
;
401 tcg_gen_subi_tl(cpu_cc_dst
, cpu_cc_src
, src2
);
402 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SUB
);
403 dc
->cc_op
= CC_OP_SUB
;
405 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
408 static inline void gen_op_sub_cc(TCGv dst
, TCGv src1
, TCGv src2
)
410 tcg_gen_mov_tl(cpu_cc_src
, src1
);
411 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
412 tcg_gen_sub_tl(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
413 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
416 static inline void gen_op_subxi_cc(TCGv dst
, TCGv src1
, target_long src2
)
418 tcg_gen_mov_tl(cpu_cc_src
, src1
);
419 tcg_gen_movi_tl(cpu_cc_src2
, src2
);
420 gen_mov_reg_C(cpu_tmp0
, cpu_psr
);
421 tcg_gen_sub_tl(cpu_cc_dst
, cpu_cc_src
, cpu_tmp0
);
422 tcg_gen_subi_tl(cpu_cc_dst
, cpu_cc_dst
, src2
);
423 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
426 static inline void gen_op_subx_cc(TCGv dst
, TCGv src1
, TCGv src2
)
428 tcg_gen_mov_tl(cpu_cc_src
, src1
);
429 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
430 gen_mov_reg_C(cpu_tmp0
, cpu_psr
);
431 tcg_gen_sub_tl(cpu_cc_dst
, cpu_cc_src
, cpu_tmp0
);
432 tcg_gen_sub_tl(cpu_cc_dst
, cpu_cc_dst
, cpu_cc_src2
);
433 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
436 static inline void gen_op_tsub_cc(TCGv dst
, TCGv src1
, TCGv src2
)
438 tcg_gen_mov_tl(cpu_cc_src
, src1
);
439 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
440 tcg_gen_sub_tl(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
441 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
444 static inline void gen_op_tsub_ccTV(TCGv dst
, TCGv src1
, TCGv src2
)
446 tcg_gen_mov_tl(cpu_cc_src
, src1
);
447 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
448 gen_tag_tv(cpu_cc_src
, cpu_cc_src2
);
449 tcg_gen_sub_tl(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
450 gen_sub_tv(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
451 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
454 static inline void gen_op_mulscc(TCGv dst
, TCGv src1
, TCGv src2
)
459 l1
= gen_new_label();
460 r_temp
= tcg_temp_new();
466 tcg_gen_andi_tl(cpu_cc_src
, src1
, 0xffffffff);
467 tcg_gen_andi_tl(r_temp
, cpu_y
, 0x1);
468 tcg_gen_andi_tl(cpu_cc_src2
, src2
, 0xffffffff);
469 tcg_gen_brcondi_tl(TCG_COND_NE
, r_temp
, 0, l1
);
470 tcg_gen_movi_tl(cpu_cc_src2
, 0);
474 // env->y = (b2 << 31) | (env->y >> 1);
475 tcg_gen_andi_tl(r_temp
, cpu_cc_src
, 0x1);
476 tcg_gen_shli_tl(r_temp
, r_temp
, 31);
477 tcg_gen_shri_tl(cpu_tmp0
, cpu_y
, 1);
478 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, 0x7fffffff);
479 tcg_gen_or_tl(cpu_tmp0
, cpu_tmp0
, r_temp
);
480 tcg_gen_andi_tl(cpu_y
, cpu_tmp0
, 0xffffffff);
483 gen_mov_reg_N(cpu_tmp0
, cpu_psr
);
484 gen_mov_reg_V(r_temp
, cpu_psr
);
485 tcg_gen_xor_tl(cpu_tmp0
, cpu_tmp0
, r_temp
);
486 tcg_temp_free(r_temp
);
488 // T0 = (b1 << 31) | (T0 >> 1);
490 tcg_gen_shli_tl(cpu_tmp0
, cpu_tmp0
, 31);
491 tcg_gen_shri_tl(cpu_cc_src
, cpu_cc_src
, 1);
492 tcg_gen_or_tl(cpu_cc_src
, cpu_cc_src
, cpu_tmp0
);
494 tcg_gen_add_tl(cpu_cc_dst
, cpu_cc_src
, cpu_cc_src2
);
496 tcg_gen_mov_tl(dst
, cpu_cc_dst
);
499 static inline void gen_op_umul(TCGv dst
, TCGv src1
, TCGv src2
)
501 TCGv_i64 r_temp
, r_temp2
;
503 r_temp
= tcg_temp_new_i64();
504 r_temp2
= tcg_temp_new_i64();
506 tcg_gen_extu_tl_i64(r_temp
, src2
);
507 tcg_gen_extu_tl_i64(r_temp2
, src1
);
508 tcg_gen_mul_i64(r_temp2
, r_temp
, r_temp2
);
510 tcg_gen_shri_i64(r_temp
, r_temp2
, 32);
511 tcg_gen_trunc_i64_tl(cpu_tmp0
, r_temp
);
512 tcg_temp_free_i64(r_temp
);
513 tcg_gen_andi_tl(cpu_y
, cpu_tmp0
, 0xffffffff);
514 #ifdef TARGET_SPARC64
515 tcg_gen_mov_i64(dst
, r_temp2
);
517 tcg_gen_trunc_i64_tl(dst
, r_temp2
);
519 tcg_temp_free_i64(r_temp2
);
522 static inline void gen_op_smul(TCGv dst
, TCGv src1
, TCGv src2
)
524 TCGv_i64 r_temp
, r_temp2
;
526 r_temp
= tcg_temp_new_i64();
527 r_temp2
= tcg_temp_new_i64();
529 tcg_gen_ext_tl_i64(r_temp
, src2
);
530 tcg_gen_ext_tl_i64(r_temp2
, src1
);
531 tcg_gen_mul_i64(r_temp2
, r_temp
, r_temp2
);
533 tcg_gen_shri_i64(r_temp
, r_temp2
, 32);
534 tcg_gen_trunc_i64_tl(cpu_tmp0
, r_temp
);
535 tcg_temp_free_i64(r_temp
);
536 tcg_gen_andi_tl(cpu_y
, cpu_tmp0
, 0xffffffff);
537 #ifdef TARGET_SPARC64
538 tcg_gen_mov_i64(dst
, r_temp2
);
540 tcg_gen_trunc_i64_tl(dst
, r_temp2
);
542 tcg_temp_free_i64(r_temp2
);
545 #ifdef TARGET_SPARC64
546 static inline void gen_trap_ifdivzero_tl(TCGv divisor
)
551 l1
= gen_new_label();
552 tcg_gen_brcondi_tl(TCG_COND_NE
, divisor
, 0, l1
);
553 r_const
= tcg_const_i32(TT_DIV_ZERO
);
554 gen_helper_raise_exception(r_const
);
555 tcg_temp_free_i32(r_const
);
559 static inline void gen_op_sdivx(TCGv dst
, TCGv src1
, TCGv src2
)
563 l1
= gen_new_label();
564 l2
= gen_new_label();
565 tcg_gen_mov_tl(cpu_cc_src
, src1
);
566 tcg_gen_mov_tl(cpu_cc_src2
, src2
);
567 gen_trap_ifdivzero_tl(cpu_cc_src2
);
568 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_cc_src
, INT64_MIN
, l1
);
569 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_cc_src2
, -1, l1
);
570 tcg_gen_movi_i64(dst
, INT64_MIN
);
573 tcg_gen_div_i64(dst
, cpu_cc_src
, cpu_cc_src2
);
579 static inline void gen_op_eval_ba(TCGv dst
)
581 tcg_gen_movi_tl(dst
, 1);
585 static inline void gen_op_eval_be(TCGv dst
, TCGv_i32 src
)
587 gen_mov_reg_Z(dst
, src
);
591 static inline void gen_op_eval_ble(TCGv dst
, TCGv_i32 src
)
593 gen_mov_reg_N(cpu_tmp0
, src
);
594 gen_mov_reg_V(dst
, src
);
595 tcg_gen_xor_tl(dst
, dst
, cpu_tmp0
);
596 gen_mov_reg_Z(cpu_tmp0
, src
);
597 tcg_gen_or_tl(dst
, dst
, cpu_tmp0
);
601 static inline void gen_op_eval_bl(TCGv dst
, TCGv_i32 src
)
603 gen_mov_reg_V(cpu_tmp0
, src
);
604 gen_mov_reg_N(dst
, src
);
605 tcg_gen_xor_tl(dst
, dst
, cpu_tmp0
);
609 static inline void gen_op_eval_bleu(TCGv dst
, TCGv_i32 src
)
611 gen_mov_reg_Z(cpu_tmp0
, src
);
612 gen_mov_reg_C(dst
, src
);
613 tcg_gen_or_tl(dst
, dst
, cpu_tmp0
);
617 static inline void gen_op_eval_bcs(TCGv dst
, TCGv_i32 src
)
619 gen_mov_reg_C(dst
, src
);
623 static inline void gen_op_eval_bvs(TCGv dst
, TCGv_i32 src
)
625 gen_mov_reg_V(dst
, src
);
629 static inline void gen_op_eval_bn(TCGv dst
)
631 tcg_gen_movi_tl(dst
, 0);
635 static inline void gen_op_eval_bneg(TCGv dst
, TCGv_i32 src
)
637 gen_mov_reg_N(dst
, src
);
641 static inline void gen_op_eval_bne(TCGv dst
, TCGv_i32 src
)
643 gen_mov_reg_Z(dst
, src
);
644 tcg_gen_xori_tl(dst
, dst
, 0x1);
648 static inline void gen_op_eval_bg(TCGv dst
, TCGv_i32 src
)
650 gen_mov_reg_N(cpu_tmp0
, src
);
651 gen_mov_reg_V(dst
, src
);
652 tcg_gen_xor_tl(dst
, dst
, cpu_tmp0
);
653 gen_mov_reg_Z(cpu_tmp0
, src
);
654 tcg_gen_or_tl(dst
, dst
, cpu_tmp0
);
655 tcg_gen_xori_tl(dst
, dst
, 0x1);
659 static inline void gen_op_eval_bge(TCGv dst
, TCGv_i32 src
)
661 gen_mov_reg_V(cpu_tmp0
, src
);
662 gen_mov_reg_N(dst
, src
);
663 tcg_gen_xor_tl(dst
, dst
, cpu_tmp0
);
664 tcg_gen_xori_tl(dst
, dst
, 0x1);
668 static inline void gen_op_eval_bgu(TCGv dst
, TCGv_i32 src
)
670 gen_mov_reg_Z(cpu_tmp0
, src
);
671 gen_mov_reg_C(dst
, src
);
672 tcg_gen_or_tl(dst
, dst
, cpu_tmp0
);
673 tcg_gen_xori_tl(dst
, dst
, 0x1);
677 static inline void gen_op_eval_bcc(TCGv dst
, TCGv_i32 src
)
679 gen_mov_reg_C(dst
, src
);
680 tcg_gen_xori_tl(dst
, dst
, 0x1);
684 static inline void gen_op_eval_bpos(TCGv dst
, TCGv_i32 src
)
686 gen_mov_reg_N(dst
, src
);
687 tcg_gen_xori_tl(dst
, dst
, 0x1);
691 static inline void gen_op_eval_bvc(TCGv dst
, TCGv_i32 src
)
693 gen_mov_reg_V(dst
, src
);
694 tcg_gen_xori_tl(dst
, dst
, 0x1);
698 FPSR bit field FCC1 | FCC0:
704 static inline void gen_mov_reg_FCC0(TCGv reg
, TCGv src
,
705 unsigned int fcc_offset
)
707 tcg_gen_shri_tl(reg
, src
, FSR_FCC0_SHIFT
+ fcc_offset
);
708 tcg_gen_andi_tl(reg
, reg
, 0x1);
711 static inline void gen_mov_reg_FCC1(TCGv reg
, TCGv src
,
712 unsigned int fcc_offset
)
714 tcg_gen_shri_tl(reg
, src
, FSR_FCC1_SHIFT
+ fcc_offset
);
715 tcg_gen_andi_tl(reg
, reg
, 0x1);
719 static inline void gen_op_eval_fbne(TCGv dst
, TCGv src
,
720 unsigned int fcc_offset
)
722 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
723 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
724 tcg_gen_or_tl(dst
, dst
, cpu_tmp0
);
727 // 1 or 2: FCC0 ^ FCC1
728 static inline void gen_op_eval_fblg(TCGv dst
, TCGv src
,
729 unsigned int fcc_offset
)
731 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
732 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
733 tcg_gen_xor_tl(dst
, dst
, cpu_tmp0
);
737 static inline void gen_op_eval_fbul(TCGv dst
, TCGv src
,
738 unsigned int fcc_offset
)
740 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
744 static inline void gen_op_eval_fbl(TCGv dst
, TCGv src
,
745 unsigned int fcc_offset
)
747 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
748 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
749 tcg_gen_xori_tl(cpu_tmp0
, cpu_tmp0
, 0x1);
750 tcg_gen_and_tl(dst
, dst
, cpu_tmp0
);
754 static inline void gen_op_eval_fbug(TCGv dst
, TCGv src
,
755 unsigned int fcc_offset
)
757 gen_mov_reg_FCC1(dst
, src
, fcc_offset
);
761 static inline void gen_op_eval_fbg(TCGv dst
, TCGv src
,
762 unsigned int fcc_offset
)
764 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
765 tcg_gen_xori_tl(dst
, dst
, 0x1);
766 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
767 tcg_gen_and_tl(dst
, dst
, cpu_tmp0
);
771 static inline void gen_op_eval_fbu(TCGv dst
, TCGv src
,
772 unsigned int fcc_offset
)
774 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
775 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
776 tcg_gen_and_tl(dst
, dst
, cpu_tmp0
);
780 static inline void gen_op_eval_fbe(TCGv dst
, TCGv src
,
781 unsigned int fcc_offset
)
783 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
784 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
785 tcg_gen_or_tl(dst
, dst
, cpu_tmp0
);
786 tcg_gen_xori_tl(dst
, dst
, 0x1);
789 // 0 or 3: !(FCC0 ^ FCC1)
790 static inline void gen_op_eval_fbue(TCGv dst
, TCGv src
,
791 unsigned int fcc_offset
)
793 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
794 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
795 tcg_gen_xor_tl(dst
, dst
, cpu_tmp0
);
796 tcg_gen_xori_tl(dst
, dst
, 0x1);
800 static inline void gen_op_eval_fbge(TCGv dst
, TCGv src
,
801 unsigned int fcc_offset
)
803 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
804 tcg_gen_xori_tl(dst
, dst
, 0x1);
807 // !1: !(FCC0 & !FCC1)
808 static inline void gen_op_eval_fbuge(TCGv dst
, TCGv src
,
809 unsigned int fcc_offset
)
811 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
812 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
813 tcg_gen_xori_tl(cpu_tmp0
, cpu_tmp0
, 0x1);
814 tcg_gen_and_tl(dst
, dst
, cpu_tmp0
);
815 tcg_gen_xori_tl(dst
, dst
, 0x1);
819 static inline void gen_op_eval_fble(TCGv dst
, TCGv src
,
820 unsigned int fcc_offset
)
822 gen_mov_reg_FCC1(dst
, src
, fcc_offset
);
823 tcg_gen_xori_tl(dst
, dst
, 0x1);
826 // !2: !(!FCC0 & FCC1)
827 static inline void gen_op_eval_fbule(TCGv dst
, TCGv src
,
828 unsigned int fcc_offset
)
830 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
831 tcg_gen_xori_tl(dst
, dst
, 0x1);
832 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
833 tcg_gen_and_tl(dst
, dst
, cpu_tmp0
);
834 tcg_gen_xori_tl(dst
, dst
, 0x1);
837 // !3: !(FCC0 & FCC1)
838 static inline void gen_op_eval_fbo(TCGv dst
, TCGv src
,
839 unsigned int fcc_offset
)
841 gen_mov_reg_FCC0(dst
, src
, fcc_offset
);
842 gen_mov_reg_FCC1(cpu_tmp0
, src
, fcc_offset
);
843 tcg_gen_and_tl(dst
, dst
, cpu_tmp0
);
844 tcg_gen_xori_tl(dst
, dst
, 0x1);
847 static inline void gen_branch2(DisasContext
*dc
, target_ulong pc1
,
848 target_ulong pc2
, TCGv r_cond
)
852 l1
= gen_new_label();
854 tcg_gen_brcondi_tl(TCG_COND_EQ
, r_cond
, 0, l1
);
856 gen_goto_tb(dc
, 0, pc1
, pc1
+ 4);
859 gen_goto_tb(dc
, 1, pc2
, pc2
+ 4);
862 static inline void gen_branch_a(DisasContext
*dc
, target_ulong pc1
,
863 target_ulong pc2
, TCGv r_cond
)
867 l1
= gen_new_label();
869 tcg_gen_brcondi_tl(TCG_COND_EQ
, r_cond
, 0, l1
);
871 gen_goto_tb(dc
, 0, pc2
, pc1
);
874 gen_goto_tb(dc
, 1, pc2
+ 4, pc2
+ 8);
877 static inline void gen_generic_branch(target_ulong npc1
, target_ulong npc2
,
882 l1
= gen_new_label();
883 l2
= gen_new_label();
885 tcg_gen_brcondi_tl(TCG_COND_EQ
, r_cond
, 0, l1
);
887 tcg_gen_movi_tl(cpu_npc
, npc1
);
891 tcg_gen_movi_tl(cpu_npc
, npc2
);
895 /* call this function before using the condition register as it may
896 have been set for a jump */
897 static inline void flush_cond(DisasContext
*dc
, TCGv cond
)
899 if (dc
->npc
== JUMP_PC
) {
900 gen_generic_branch(dc
->jump_pc
[0], dc
->jump_pc
[1], cond
);
901 dc
->npc
= DYNAMIC_PC
;
905 static inline void save_npc(DisasContext
*dc
, TCGv cond
)
907 if (dc
->npc
== JUMP_PC
) {
908 gen_generic_branch(dc
->jump_pc
[0], dc
->jump_pc
[1], cond
);
909 dc
->npc
= DYNAMIC_PC
;
910 } else if (dc
->npc
!= DYNAMIC_PC
) {
911 tcg_gen_movi_tl(cpu_npc
, dc
->npc
);
915 static inline void save_state(DisasContext
*dc
, TCGv cond
)
917 tcg_gen_movi_tl(cpu_pc
, dc
->pc
);
918 /* flush pending conditional evaluations before exposing cpu state */
919 if (dc
->cc_op
!= CC_OP_FLAGS
) {
920 dc
->cc_op
= CC_OP_FLAGS
;
921 gen_helper_compute_psr();
926 static inline void gen_mov_pc_npc(DisasContext
*dc
, TCGv cond
)
928 if (dc
->npc
== JUMP_PC
) {
929 gen_generic_branch(dc
->jump_pc
[0], dc
->jump_pc
[1], cond
);
930 tcg_gen_mov_tl(cpu_pc
, cpu_npc
);
932 } else if (dc
->npc
== DYNAMIC_PC
) {
933 tcg_gen_mov_tl(cpu_pc
, cpu_npc
);
940 static inline void gen_op_next_insn(void)
942 tcg_gen_mov_tl(cpu_pc
, cpu_npc
);
943 tcg_gen_addi_tl(cpu_npc
, cpu_npc
, 4);
946 static inline void gen_cond(TCGv r_dst
, unsigned int cc
, unsigned int cond
,
951 #ifdef TARGET_SPARC64
963 gen_helper_compute_psr();
964 dc
->cc_op
= CC_OP_FLAGS
;
969 gen_op_eval_bn(r_dst
);
972 gen_op_eval_be(r_dst
, r_src
);
975 gen_op_eval_ble(r_dst
, r_src
);
978 gen_op_eval_bl(r_dst
, r_src
);
981 gen_op_eval_bleu(r_dst
, r_src
);
984 gen_op_eval_bcs(r_dst
, r_src
);
987 gen_op_eval_bneg(r_dst
, r_src
);
990 gen_op_eval_bvs(r_dst
, r_src
);
993 gen_op_eval_ba(r_dst
);
996 gen_op_eval_bne(r_dst
, r_src
);
999 gen_op_eval_bg(r_dst
, r_src
);
1002 gen_op_eval_bge(r_dst
, r_src
);
1005 gen_op_eval_bgu(r_dst
, r_src
);
1008 gen_op_eval_bcc(r_dst
, r_src
);
1011 gen_op_eval_bpos(r_dst
, r_src
);
1014 gen_op_eval_bvc(r_dst
, r_src
);
1019 static inline void gen_fcond(TCGv r_dst
, unsigned int cc
, unsigned int cond
)
1021 unsigned int offset
;
1041 gen_op_eval_bn(r_dst
);
1044 gen_op_eval_fbne(r_dst
, cpu_fsr
, offset
);
1047 gen_op_eval_fblg(r_dst
, cpu_fsr
, offset
);
1050 gen_op_eval_fbul(r_dst
, cpu_fsr
, offset
);
1053 gen_op_eval_fbl(r_dst
, cpu_fsr
, offset
);
1056 gen_op_eval_fbug(r_dst
, cpu_fsr
, offset
);
1059 gen_op_eval_fbg(r_dst
, cpu_fsr
, offset
);
1062 gen_op_eval_fbu(r_dst
, cpu_fsr
, offset
);
1065 gen_op_eval_ba(r_dst
);
1068 gen_op_eval_fbe(r_dst
, cpu_fsr
, offset
);
1071 gen_op_eval_fbue(r_dst
, cpu_fsr
, offset
);
1074 gen_op_eval_fbge(r_dst
, cpu_fsr
, offset
);
1077 gen_op_eval_fbuge(r_dst
, cpu_fsr
, offset
);
1080 gen_op_eval_fble(r_dst
, cpu_fsr
, offset
);
1083 gen_op_eval_fbule(r_dst
, cpu_fsr
, offset
);
1086 gen_op_eval_fbo(r_dst
, cpu_fsr
, offset
);
1091 #ifdef TARGET_SPARC64
1093 static const int gen_tcg_cond_reg
[8] = {
1104 static inline void gen_cond_reg(TCGv r_dst
, int cond
, TCGv r_src
)
1108 l1
= gen_new_label();
1109 tcg_gen_movi_tl(r_dst
, 0);
1110 tcg_gen_brcondi_tl(gen_tcg_cond_reg
[cond
], r_src
, 0, l1
);
1111 tcg_gen_movi_tl(r_dst
, 1);
1116 /* XXX: potentially incorrect if dynamic npc */
1117 static void do_branch(DisasContext
*dc
, int32_t offset
, uint32_t insn
, int cc
,
1120 unsigned int cond
= GET_FIELD(insn
, 3, 6), a
= (insn
& (1 << 29));
1121 target_ulong target
= dc
->pc
+ offset
;
1124 /* unconditional not taken */
1126 dc
->pc
= dc
->npc
+ 4;
1127 dc
->npc
= dc
->pc
+ 4;
1130 dc
->npc
= dc
->pc
+ 4;
1132 } else if (cond
== 0x8) {
1133 /* unconditional taken */
1136 dc
->npc
= dc
->pc
+ 4;
1140 tcg_gen_mov_tl(cpu_pc
, cpu_npc
);
1143 flush_cond(dc
, r_cond
);
1144 gen_cond(r_cond
, cc
, cond
, dc
);
1146 gen_branch_a(dc
, target
, dc
->npc
, r_cond
);
1150 dc
->jump_pc
[0] = target
;
1151 dc
->jump_pc
[1] = dc
->npc
+ 4;
1157 /* XXX: potentially incorrect if dynamic npc */
1158 static void do_fbranch(DisasContext
*dc
, int32_t offset
, uint32_t insn
, int cc
,
1161 unsigned int cond
= GET_FIELD(insn
, 3, 6), a
= (insn
& (1 << 29));
1162 target_ulong target
= dc
->pc
+ offset
;
1165 /* unconditional not taken */
1167 dc
->pc
= dc
->npc
+ 4;
1168 dc
->npc
= dc
->pc
+ 4;
1171 dc
->npc
= dc
->pc
+ 4;
1173 } else if (cond
== 0x8) {
1174 /* unconditional taken */
1177 dc
->npc
= dc
->pc
+ 4;
1181 tcg_gen_mov_tl(cpu_pc
, cpu_npc
);
1184 flush_cond(dc
, r_cond
);
1185 gen_fcond(r_cond
, cc
, cond
);
1187 gen_branch_a(dc
, target
, dc
->npc
, r_cond
);
1191 dc
->jump_pc
[0] = target
;
1192 dc
->jump_pc
[1] = dc
->npc
+ 4;
1198 #ifdef TARGET_SPARC64
1199 /* XXX: potentially incorrect if dynamic npc */
1200 static void do_branch_reg(DisasContext
*dc
, int32_t offset
, uint32_t insn
,
1201 TCGv r_cond
, TCGv r_reg
)
1203 unsigned int cond
= GET_FIELD_SP(insn
, 25, 27), a
= (insn
& (1 << 29));
1204 target_ulong target
= dc
->pc
+ offset
;
1206 flush_cond(dc
, r_cond
);
1207 gen_cond_reg(r_cond
, cond
, r_reg
);
1209 gen_branch_a(dc
, target
, dc
->npc
, r_cond
);
1213 dc
->jump_pc
[0] = target
;
1214 dc
->jump_pc
[1] = dc
->npc
+ 4;
1219 static inline void gen_op_fcmps(int fccno
, TCGv_i32 r_rs1
, TCGv_i32 r_rs2
)
1223 gen_helper_fcmps(r_rs1
, r_rs2
);
1226 gen_helper_fcmps_fcc1(r_rs1
, r_rs2
);
1229 gen_helper_fcmps_fcc2(r_rs1
, r_rs2
);
1232 gen_helper_fcmps_fcc3(r_rs1
, r_rs2
);
1237 static inline void gen_op_fcmpd(int fccno
)
1244 gen_helper_fcmpd_fcc1();
1247 gen_helper_fcmpd_fcc2();
1250 gen_helper_fcmpd_fcc3();
1255 static inline void gen_op_fcmpq(int fccno
)
1262 gen_helper_fcmpq_fcc1();
1265 gen_helper_fcmpq_fcc2();
1268 gen_helper_fcmpq_fcc3();
1273 static inline void gen_op_fcmpes(int fccno
, TCGv_i32 r_rs1
, TCGv_i32 r_rs2
)
1277 gen_helper_fcmpes(r_rs1
, r_rs2
);
1280 gen_helper_fcmpes_fcc1(r_rs1
, r_rs2
);
1283 gen_helper_fcmpes_fcc2(r_rs1
, r_rs2
);
1286 gen_helper_fcmpes_fcc3(r_rs1
, r_rs2
);
1291 static inline void gen_op_fcmped(int fccno
)
1295 gen_helper_fcmped();
1298 gen_helper_fcmped_fcc1();
1301 gen_helper_fcmped_fcc2();
1304 gen_helper_fcmped_fcc3();
1309 static inline void gen_op_fcmpeq(int fccno
)
1313 gen_helper_fcmpeq();
1316 gen_helper_fcmpeq_fcc1();
1319 gen_helper_fcmpeq_fcc2();
1322 gen_helper_fcmpeq_fcc3();
1329 static inline void gen_op_fcmps(int fccno
, TCGv r_rs1
, TCGv r_rs2
)
1331 gen_helper_fcmps(r_rs1
, r_rs2
);
1334 static inline void gen_op_fcmpd(int fccno
)
1339 static inline void gen_op_fcmpq(int fccno
)
1344 static inline void gen_op_fcmpes(int fccno
, TCGv r_rs1
, TCGv r_rs2
)
1346 gen_helper_fcmpes(r_rs1
, r_rs2
);
1349 static inline void gen_op_fcmped(int fccno
)
1351 gen_helper_fcmped();
1354 static inline void gen_op_fcmpeq(int fccno
)
1356 gen_helper_fcmpeq();
1360 static inline void gen_op_fpexception_im(int fsr_flags
)
1364 tcg_gen_andi_tl(cpu_fsr
, cpu_fsr
, FSR_FTT_NMASK
);
1365 tcg_gen_ori_tl(cpu_fsr
, cpu_fsr
, fsr_flags
);
1366 r_const
= tcg_const_i32(TT_FP_EXCP
);
1367 gen_helper_raise_exception(r_const
);
1368 tcg_temp_free_i32(r_const
);
1371 static int gen_trap_ifnofpu(DisasContext
*dc
, TCGv r_cond
)
1373 #if !defined(CONFIG_USER_ONLY)
1374 if (!dc
->fpu_enabled
) {
1377 save_state(dc
, r_cond
);
1378 r_const
= tcg_const_i32(TT_NFPU_INSN
);
1379 gen_helper_raise_exception(r_const
);
1380 tcg_temp_free_i32(r_const
);
1388 static inline void gen_op_clear_ieee_excp_and_FTT(void)
1390 tcg_gen_andi_tl(cpu_fsr
, cpu_fsr
, FSR_FTT_CEXC_NMASK
);
1393 static inline void gen_clear_float_exceptions(void)
1395 gen_helper_clear_float_exceptions();
1399 #ifdef TARGET_SPARC64
1400 static inline TCGv_i32
gen_get_asi(int insn
, TCGv r_addr
)
1406 r_asi
= tcg_temp_new_i32();
1407 tcg_gen_mov_i32(r_asi
, cpu_asi
);
1409 asi
= GET_FIELD(insn
, 19, 26);
1410 r_asi
= tcg_const_i32(asi
);
1415 static inline void gen_ld_asi(TCGv dst
, TCGv addr
, int insn
, int size
,
1418 TCGv_i32 r_asi
, r_size
, r_sign
;
1420 r_asi
= gen_get_asi(insn
, addr
);
1421 r_size
= tcg_const_i32(size
);
1422 r_sign
= tcg_const_i32(sign
);
1423 gen_helper_ld_asi(dst
, addr
, r_asi
, r_size
, r_sign
);
1424 tcg_temp_free_i32(r_sign
);
1425 tcg_temp_free_i32(r_size
);
1426 tcg_temp_free_i32(r_asi
);
1429 static inline void gen_st_asi(TCGv src
, TCGv addr
, int insn
, int size
)
1431 TCGv_i32 r_asi
, r_size
;
1433 r_asi
= gen_get_asi(insn
, addr
);
1434 r_size
= tcg_const_i32(size
);
1435 gen_helper_st_asi(addr
, src
, r_asi
, r_size
);
1436 tcg_temp_free_i32(r_size
);
1437 tcg_temp_free_i32(r_asi
);
1440 static inline void gen_ldf_asi(TCGv addr
, int insn
, int size
, int rd
)
1442 TCGv_i32 r_asi
, r_size
, r_rd
;
1444 r_asi
= gen_get_asi(insn
, addr
);
1445 r_size
= tcg_const_i32(size
);
1446 r_rd
= tcg_const_i32(rd
);
1447 gen_helper_ldf_asi(addr
, r_asi
, r_size
, r_rd
);
1448 tcg_temp_free_i32(r_rd
);
1449 tcg_temp_free_i32(r_size
);
1450 tcg_temp_free_i32(r_asi
);
1453 static inline void gen_stf_asi(TCGv addr
, int insn
, int size
, int rd
)
1455 TCGv_i32 r_asi
, r_size
, r_rd
;
1457 r_asi
= gen_get_asi(insn
, addr
);
1458 r_size
= tcg_const_i32(size
);
1459 r_rd
= tcg_const_i32(rd
);
1460 gen_helper_stf_asi(addr
, r_asi
, r_size
, r_rd
);
1461 tcg_temp_free_i32(r_rd
);
1462 tcg_temp_free_i32(r_size
);
1463 tcg_temp_free_i32(r_asi
);
1466 static inline void gen_swap_asi(TCGv dst
, TCGv addr
, int insn
)
1468 TCGv_i32 r_asi
, r_size
, r_sign
;
1470 r_asi
= gen_get_asi(insn
, addr
);
1471 r_size
= tcg_const_i32(4);
1472 r_sign
= tcg_const_i32(0);
1473 gen_helper_ld_asi(cpu_tmp64
, addr
, r_asi
, r_size
, r_sign
);
1474 tcg_temp_free_i32(r_sign
);
1475 gen_helper_st_asi(addr
, dst
, r_asi
, r_size
);
1476 tcg_temp_free_i32(r_size
);
1477 tcg_temp_free_i32(r_asi
);
1478 tcg_gen_trunc_i64_tl(dst
, cpu_tmp64
);
1481 static inline void gen_ldda_asi(TCGv hi
, TCGv addr
, int insn
, int rd
)
1483 TCGv_i32 r_asi
, r_rd
;
1485 r_asi
= gen_get_asi(insn
, addr
);
1486 r_rd
= tcg_const_i32(rd
);
1487 gen_helper_ldda_asi(addr
, r_asi
, r_rd
);
1488 tcg_temp_free_i32(r_rd
);
1489 tcg_temp_free_i32(r_asi
);
1492 static inline void gen_stda_asi(TCGv hi
, TCGv addr
, int insn
, int rd
)
1494 TCGv_i32 r_asi
, r_size
;
1496 gen_movl_reg_TN(rd
+ 1, cpu_tmp0
);
1497 tcg_gen_concat_tl_i64(cpu_tmp64
, cpu_tmp0
, hi
);
1498 r_asi
= gen_get_asi(insn
, addr
);
1499 r_size
= tcg_const_i32(8);
1500 gen_helper_st_asi(addr
, cpu_tmp64
, r_asi
, r_size
);
1501 tcg_temp_free_i32(r_size
);
1502 tcg_temp_free_i32(r_asi
);
1505 static inline void gen_cas_asi(TCGv dst
, TCGv addr
, TCGv val2
, int insn
,
1511 r_val1
= tcg_temp_new();
1512 gen_movl_reg_TN(rd
, r_val1
);
1513 r_asi
= gen_get_asi(insn
, addr
);
1514 gen_helper_cas_asi(dst
, addr
, r_val1
, val2
, r_asi
);
1515 tcg_temp_free_i32(r_asi
);
1516 tcg_temp_free(r_val1
);
1519 static inline void gen_casx_asi(TCGv dst
, TCGv addr
, TCGv val2
, int insn
,
1524 gen_movl_reg_TN(rd
, cpu_tmp64
);
1525 r_asi
= gen_get_asi(insn
, addr
);
1526 gen_helper_casx_asi(dst
, addr
, cpu_tmp64
, val2
, r_asi
);
1527 tcg_temp_free_i32(r_asi
);
1530 #elif !defined(CONFIG_USER_ONLY)
1532 static inline void gen_ld_asi(TCGv dst
, TCGv addr
, int insn
, int size
,
1535 TCGv_i32 r_asi
, r_size
, r_sign
;
1537 r_asi
= tcg_const_i32(GET_FIELD(insn
, 19, 26));
1538 r_size
= tcg_const_i32(size
);
1539 r_sign
= tcg_const_i32(sign
);
1540 gen_helper_ld_asi(cpu_tmp64
, addr
, r_asi
, r_size
, r_sign
);
1541 tcg_temp_free(r_sign
);
1542 tcg_temp_free(r_size
);
1543 tcg_temp_free(r_asi
);
1544 tcg_gen_trunc_i64_tl(dst
, cpu_tmp64
);
1547 static inline void gen_st_asi(TCGv src
, TCGv addr
, int insn
, int size
)
1549 TCGv_i32 r_asi
, r_size
;
1551 tcg_gen_extu_tl_i64(cpu_tmp64
, src
);
1552 r_asi
= tcg_const_i32(GET_FIELD(insn
, 19, 26));
1553 r_size
= tcg_const_i32(size
);
1554 gen_helper_st_asi(addr
, cpu_tmp64
, r_asi
, r_size
);
1555 tcg_temp_free(r_size
);
1556 tcg_temp_free(r_asi
);
1559 static inline void gen_swap_asi(TCGv dst
, TCGv addr
, int insn
)
1561 TCGv_i32 r_asi
, r_size
, r_sign
;
1564 r_asi
= tcg_const_i32(GET_FIELD(insn
, 19, 26));
1565 r_size
= tcg_const_i32(4);
1566 r_sign
= tcg_const_i32(0);
1567 gen_helper_ld_asi(cpu_tmp64
, addr
, r_asi
, r_size
, r_sign
);
1568 tcg_temp_free(r_sign
);
1569 r_val
= tcg_temp_new_i64();
1570 tcg_gen_extu_tl_i64(r_val
, dst
);
1571 gen_helper_st_asi(addr
, r_val
, r_asi
, r_size
);
1572 tcg_temp_free_i64(r_val
);
1573 tcg_temp_free(r_size
);
1574 tcg_temp_free(r_asi
);
1575 tcg_gen_trunc_i64_tl(dst
, cpu_tmp64
);
1578 static inline void gen_ldda_asi(TCGv hi
, TCGv addr
, int insn
, int rd
)
1580 TCGv_i32 r_asi
, r_size
, r_sign
;
1582 r_asi
= tcg_const_i32(GET_FIELD(insn
, 19, 26));
1583 r_size
= tcg_const_i32(8);
1584 r_sign
= tcg_const_i32(0);
1585 gen_helper_ld_asi(cpu_tmp64
, addr
, r_asi
, r_size
, r_sign
);
1586 tcg_temp_free(r_sign
);
1587 tcg_temp_free(r_size
);
1588 tcg_temp_free(r_asi
);
1589 tcg_gen_trunc_i64_tl(cpu_tmp0
, cpu_tmp64
);
1590 gen_movl_TN_reg(rd
+ 1, cpu_tmp0
);
1591 tcg_gen_shri_i64(cpu_tmp64
, cpu_tmp64
, 32);
1592 tcg_gen_trunc_i64_tl(hi
, cpu_tmp64
);
1593 gen_movl_TN_reg(rd
, hi
);
1596 static inline void gen_stda_asi(TCGv hi
, TCGv addr
, int insn
, int rd
)
1598 TCGv_i32 r_asi
, r_size
;
1600 gen_movl_reg_TN(rd
+ 1, cpu_tmp0
);
1601 tcg_gen_concat_tl_i64(cpu_tmp64
, cpu_tmp0
, hi
);
1602 r_asi
= tcg_const_i32(GET_FIELD(insn
, 19, 26));
1603 r_size
= tcg_const_i32(8);
1604 gen_helper_st_asi(addr
, cpu_tmp64
, r_asi
, r_size
);
1605 tcg_temp_free(r_size
);
1606 tcg_temp_free(r_asi
);
1610 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1611 static inline void gen_ldstub_asi(TCGv dst
, TCGv addr
, int insn
)
1614 TCGv_i32 r_asi
, r_size
;
1616 gen_ld_asi(dst
, addr
, insn
, 1, 0);
1618 r_val
= tcg_const_i64(0xffULL
);
1619 r_asi
= tcg_const_i32(GET_FIELD(insn
, 19, 26));
1620 r_size
= tcg_const_i32(1);
1621 gen_helper_st_asi(addr
, r_val
, r_asi
, r_size
);
1622 tcg_temp_free_i32(r_size
);
1623 tcg_temp_free_i32(r_asi
);
1624 tcg_temp_free_i64(r_val
);
1628 static inline TCGv
get_src1(unsigned int insn
, TCGv def
)
1633 rs1
= GET_FIELD(insn
, 13, 17);
1635 r_rs1
= tcg_const_tl(0); // XXX how to free?
1637 r_rs1
= cpu_gregs
[rs1
];
1639 tcg_gen_ld_tl(def
, cpu_regwptr
, (rs1
- 8) * sizeof(target_ulong
));
1643 static inline TCGv
get_src2(unsigned int insn
, TCGv def
)
1647 if (IS_IMM
) { /* immediate */
1650 simm
= GET_FIELDs(insn
, 19, 31);
1651 r_rs2
= tcg_const_tl(simm
); // XXX how to free?
1652 } else { /* register */
1655 rs2
= GET_FIELD(insn
, 27, 31);
1657 r_rs2
= tcg_const_tl(0); // XXX how to free?
1659 r_rs2
= cpu_gregs
[rs2
];
1661 tcg_gen_ld_tl(def
, cpu_regwptr
, (rs2
- 8) * sizeof(target_ulong
));
1666 #ifdef TARGET_SPARC64
1667 static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr
, TCGv_ptr cpu_env
)
1669 TCGv_i32 r_tl
= tcg_temp_new_i32();
1671 /* load env->tl into r_tl */
1672 tcg_gen_ld_i32(r_tl
, cpu_env
, offsetof(CPUSPARCState
, tl
));
1674 /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
1675 tcg_gen_andi_i32(r_tl
, r_tl
, MAXTL_MASK
);
1677 /* calculate offset to current trap state from env->ts, reuse r_tl */
1678 tcg_gen_muli_i32(r_tl
, r_tl
, sizeof (trap_state
));
1679 tcg_gen_addi_ptr(r_tsptr
, cpu_env
, offsetof(CPUState
, ts
));
1681 /* tsptr = env->ts[env->tl & MAXTL_MASK] */
1683 TCGv_ptr r_tl_tmp
= tcg_temp_new_ptr();
1684 tcg_gen_ext_i32_ptr(r_tl_tmp
, r_tl
);
1685 tcg_gen_add_ptr(r_tsptr
, r_tsptr
, r_tl_tmp
);
1686 tcg_temp_free_ptr(r_tl_tmp
);
1689 tcg_temp_free_i32(r_tl
);
1693 #define CHECK_IU_FEATURE(dc, FEATURE) \
1694 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
1696 #define CHECK_FPU_FEATURE(dc, FEATURE) \
1697 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
1700 /* before an instruction, dc->pc must be static */
1701 static void disas_sparc_insn(DisasContext
* dc
)
1703 unsigned int insn
, opc
, rs1
, rs2
, rd
;
1706 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
)))
1707 tcg_gen_debug_insn_start(dc
->pc
);
1708 insn
= ldl_code(dc
->pc
);
1709 opc
= GET_FIELD(insn
, 0, 1);
1711 rd
= GET_FIELD(insn
, 2, 6);
1713 cpu_src1
= tcg_temp_new(); // const
1714 cpu_src2
= tcg_temp_new(); // const
1717 case 0: /* branches/sethi */
1719 unsigned int xop
= GET_FIELD(insn
, 7, 9);
1722 #ifdef TARGET_SPARC64
1723 case 0x1: /* V9 BPcc */
1727 target
= GET_FIELD_SP(insn
, 0, 18);
1728 target
= sign_extend(target
, 18);
1730 cc
= GET_FIELD_SP(insn
, 20, 21);
1732 do_branch(dc
, target
, insn
, 0, cpu_cond
);
1734 do_branch(dc
, target
, insn
, 1, cpu_cond
);
1739 case 0x3: /* V9 BPr */
1741 target
= GET_FIELD_SP(insn
, 0, 13) |
1742 (GET_FIELD_SP(insn
, 20, 21) << 14);
1743 target
= sign_extend(target
, 16);
1745 cpu_src1
= get_src1(insn
, cpu_src1
);
1746 do_branch_reg(dc
, target
, insn
, cpu_cond
, cpu_src1
);
1749 case 0x5: /* V9 FBPcc */
1751 int cc
= GET_FIELD_SP(insn
, 20, 21);
1752 if (gen_trap_ifnofpu(dc
, cpu_cond
))
1754 target
= GET_FIELD_SP(insn
, 0, 18);
1755 target
= sign_extend(target
, 19);
1757 do_fbranch(dc
, target
, insn
, cc
, cpu_cond
);
1761 case 0x7: /* CBN+x */
1766 case 0x2: /* BN+x */
1768 target
= GET_FIELD(insn
, 10, 31);
1769 target
= sign_extend(target
, 22);
1771 do_branch(dc
, target
, insn
, 0, cpu_cond
);
1774 case 0x6: /* FBN+x */
1776 if (gen_trap_ifnofpu(dc
, cpu_cond
))
1778 target
= GET_FIELD(insn
, 10, 31);
1779 target
= sign_extend(target
, 22);
1781 do_fbranch(dc
, target
, insn
, 0, cpu_cond
);
1784 case 0x4: /* SETHI */
1786 uint32_t value
= GET_FIELD(insn
, 10, 31);
1789 r_const
= tcg_const_tl(value
<< 10);
1790 gen_movl_TN_reg(rd
, r_const
);
1791 tcg_temp_free(r_const
);
1794 case 0x0: /* UNIMPL */
1803 target_long target
= GET_FIELDs(insn
, 2, 31) << 2;
1806 r_const
= tcg_const_tl(dc
->pc
);
1807 gen_movl_TN_reg(15, r_const
);
1808 tcg_temp_free(r_const
);
1810 gen_mov_pc_npc(dc
, cpu_cond
);
1814 case 2: /* FPU & Logical Operations */
1816 unsigned int xop
= GET_FIELD(insn
, 7, 12);
1817 if (xop
== 0x3a) { /* generate trap */
1820 cpu_src1
= get_src1(insn
, cpu_src1
);
1822 rs2
= GET_FIELD(insn
, 25, 31);
1823 tcg_gen_addi_tl(cpu_dst
, cpu_src1
, rs2
);
1825 rs2
= GET_FIELD(insn
, 27, 31);
1827 gen_movl_reg_TN(rs2
, cpu_src2
);
1828 tcg_gen_add_tl(cpu_dst
, cpu_src1
, cpu_src2
);
1830 tcg_gen_mov_tl(cpu_dst
, cpu_src1
);
1832 cond
= GET_FIELD(insn
, 3, 6);
1834 save_state(dc
, cpu_cond
);
1835 if ((dc
->def
->features
& CPU_FEATURE_HYPV
) &&
1837 tcg_gen_andi_tl(cpu_dst
, cpu_dst
, UA2005_HTRAP_MASK
);
1839 tcg_gen_andi_tl(cpu_dst
, cpu_dst
, V8_TRAP_MASK
);
1840 tcg_gen_addi_tl(cpu_dst
, cpu_dst
, TT_TRAP
);
1841 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_dst
);
1842 gen_helper_raise_exception(cpu_tmp32
);
1843 } else if (cond
!= 0) {
1844 TCGv r_cond
= tcg_temp_new();
1846 #ifdef TARGET_SPARC64
1848 int cc
= GET_FIELD_SP(insn
, 11, 12);
1850 save_state(dc
, cpu_cond
);
1852 gen_cond(r_cond
, 0, cond
, dc
);
1854 gen_cond(r_cond
, 1, cond
, dc
);
1858 save_state(dc
, cpu_cond
);
1859 gen_cond(r_cond
, 0, cond
, dc
);
1861 l1
= gen_new_label();
1862 tcg_gen_brcondi_tl(TCG_COND_EQ
, r_cond
, 0, l1
);
1864 if ((dc
->def
->features
& CPU_FEATURE_HYPV
) &&
1866 tcg_gen_andi_tl(cpu_dst
, cpu_dst
, UA2005_HTRAP_MASK
);
1868 tcg_gen_andi_tl(cpu_dst
, cpu_dst
, V8_TRAP_MASK
);
1869 tcg_gen_addi_tl(cpu_dst
, cpu_dst
, TT_TRAP
);
1870 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_dst
);
1871 gen_helper_raise_exception(cpu_tmp32
);
1874 tcg_temp_free(r_cond
);
1880 } else if (xop
== 0x28) {
1881 rs1
= GET_FIELD(insn
, 13, 17);
1884 #ifndef TARGET_SPARC64
1885 case 0x01 ... 0x0e: /* undefined in the SPARCv8
1886 manual, rdy on the microSPARC
1888 case 0x0f: /* stbar in the SPARCv8 manual,
1889 rdy on the microSPARC II */
1890 case 0x10 ... 0x1f: /* implementation-dependent in the
1891 SPARCv8 manual, rdy on the
1894 gen_movl_TN_reg(rd
, cpu_y
);
1896 #ifdef TARGET_SPARC64
1897 case 0x2: /* V9 rdccr */
1898 gen_helper_compute_psr();
1899 gen_helper_rdccr(cpu_dst
);
1900 gen_movl_TN_reg(rd
, cpu_dst
);
1902 case 0x3: /* V9 rdasi */
1903 tcg_gen_ext_i32_tl(cpu_dst
, cpu_asi
);
1904 gen_movl_TN_reg(rd
, cpu_dst
);
1906 case 0x4: /* V9 rdtick */
1910 r_tickptr
= tcg_temp_new_ptr();
1911 tcg_gen_ld_ptr(r_tickptr
, cpu_env
,
1912 offsetof(CPUState
, tick
));
1913 gen_helper_tick_get_count(cpu_dst
, r_tickptr
);
1914 tcg_temp_free_ptr(r_tickptr
);
1915 gen_movl_TN_reg(rd
, cpu_dst
);
1918 case 0x5: /* V9 rdpc */
1922 r_const
= tcg_const_tl(dc
->pc
);
1923 gen_movl_TN_reg(rd
, r_const
);
1924 tcg_temp_free(r_const
);
1927 case 0x6: /* V9 rdfprs */
1928 tcg_gen_ext_i32_tl(cpu_dst
, cpu_fprs
);
1929 gen_movl_TN_reg(rd
, cpu_dst
);
1931 case 0xf: /* V9 membar */
1932 break; /* no effect */
1933 case 0x13: /* Graphics Status */
1934 if (gen_trap_ifnofpu(dc
, cpu_cond
))
1936 gen_movl_TN_reg(rd
, cpu_gsr
);
1938 case 0x16: /* Softint */
1939 tcg_gen_ext_i32_tl(cpu_dst
, cpu_softint
);
1940 gen_movl_TN_reg(rd
, cpu_dst
);
1942 case 0x17: /* Tick compare */
1943 gen_movl_TN_reg(rd
, cpu_tick_cmpr
);
1945 case 0x18: /* System tick */
1949 r_tickptr
= tcg_temp_new_ptr();
1950 tcg_gen_ld_ptr(r_tickptr
, cpu_env
,
1951 offsetof(CPUState
, stick
));
1952 gen_helper_tick_get_count(cpu_dst
, r_tickptr
);
1953 tcg_temp_free_ptr(r_tickptr
);
1954 gen_movl_TN_reg(rd
, cpu_dst
);
1957 case 0x19: /* System tick compare */
1958 gen_movl_TN_reg(rd
, cpu_stick_cmpr
);
1960 case 0x10: /* Performance Control */
1961 case 0x11: /* Performance Instrumentation Counter */
1962 case 0x12: /* Dispatch Control */
1963 case 0x14: /* Softint set, WO */
1964 case 0x15: /* Softint clear, WO */
1969 #if !defined(CONFIG_USER_ONLY)
1970 } else if (xop
== 0x29) { /* rdpsr / UA2005 rdhpr */
1971 #ifndef TARGET_SPARC64
1972 if (!supervisor(dc
))
1974 gen_helper_compute_psr();
1975 dc
->cc_op
= CC_OP_FLAGS
;
1976 gen_helper_rdpsr(cpu_dst
);
1978 CHECK_IU_FEATURE(dc
, HYPV
);
1979 if (!hypervisor(dc
))
1981 rs1
= GET_FIELD(insn
, 13, 17);
1984 // gen_op_rdhpstate();
1987 // gen_op_rdhtstate();
1990 tcg_gen_mov_tl(cpu_dst
, cpu_hintp
);
1993 tcg_gen_mov_tl(cpu_dst
, cpu_htba
);
1996 tcg_gen_mov_tl(cpu_dst
, cpu_hver
);
1998 case 31: // hstick_cmpr
1999 tcg_gen_mov_tl(cpu_dst
, cpu_hstick_cmpr
);
2005 gen_movl_TN_reg(rd
, cpu_dst
);
2007 } else if (xop
== 0x2a) { /* rdwim / V9 rdpr */
2008 if (!supervisor(dc
))
2010 #ifdef TARGET_SPARC64
2011 rs1
= GET_FIELD(insn
, 13, 17);
2017 r_tsptr
= tcg_temp_new_ptr();
2018 gen_load_trap_state_at_tl(r_tsptr
, cpu_env
);
2019 tcg_gen_ld_tl(cpu_tmp0
, r_tsptr
,
2020 offsetof(trap_state
, tpc
));
2021 tcg_temp_free_ptr(r_tsptr
);
2028 r_tsptr
= tcg_temp_new_ptr();
2029 gen_load_trap_state_at_tl(r_tsptr
, cpu_env
);
2030 tcg_gen_ld_tl(cpu_tmp0
, r_tsptr
,
2031 offsetof(trap_state
, tnpc
));
2032 tcg_temp_free_ptr(r_tsptr
);
2039 r_tsptr
= tcg_temp_new_ptr();
2040 gen_load_trap_state_at_tl(r_tsptr
, cpu_env
);
2041 tcg_gen_ld_tl(cpu_tmp0
, r_tsptr
,
2042 offsetof(trap_state
, tstate
));
2043 tcg_temp_free_ptr(r_tsptr
);
2050 r_tsptr
= tcg_temp_new_ptr();
2051 gen_load_trap_state_at_tl(r_tsptr
, cpu_env
);
2052 tcg_gen_ld_i32(cpu_tmp32
, r_tsptr
,
2053 offsetof(trap_state
, tt
));
2054 tcg_temp_free_ptr(r_tsptr
);
2055 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2062 r_tickptr
= tcg_temp_new_ptr();
2063 tcg_gen_ld_ptr(r_tickptr
, cpu_env
,
2064 offsetof(CPUState
, tick
));
2065 gen_helper_tick_get_count(cpu_tmp0
, r_tickptr
);
2066 gen_movl_TN_reg(rd
, cpu_tmp0
);
2067 tcg_temp_free_ptr(r_tickptr
);
2071 tcg_gen_mov_tl(cpu_tmp0
, cpu_tbr
);
2074 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2075 offsetof(CPUSPARCState
, pstate
));
2076 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2079 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2080 offsetof(CPUSPARCState
, tl
));
2081 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2084 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2085 offsetof(CPUSPARCState
, psrpil
));
2086 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2089 gen_helper_rdcwp(cpu_tmp0
);
2092 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2093 offsetof(CPUSPARCState
, cansave
));
2094 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2096 case 11: // canrestore
2097 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2098 offsetof(CPUSPARCState
, canrestore
));
2099 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2101 case 12: // cleanwin
2102 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2103 offsetof(CPUSPARCState
, cleanwin
));
2104 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2106 case 13: // otherwin
2107 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2108 offsetof(CPUSPARCState
, otherwin
));
2109 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2112 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2113 offsetof(CPUSPARCState
, wstate
));
2114 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2116 case 16: // UA2005 gl
2117 CHECK_IU_FEATURE(dc
, GL
);
2118 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
,
2119 offsetof(CPUSPARCState
, gl
));
2120 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_tmp32
);
2122 case 26: // UA2005 strand status
2123 CHECK_IU_FEATURE(dc
, HYPV
);
2124 if (!hypervisor(dc
))
2126 tcg_gen_mov_tl(cpu_tmp0
, cpu_ssr
);
2129 tcg_gen_mov_tl(cpu_tmp0
, cpu_ver
);
2136 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_wim
);
2138 gen_movl_TN_reg(rd
, cpu_tmp0
);
2140 } else if (xop
== 0x2b) { /* rdtbr / V9 flushw */
2141 #ifdef TARGET_SPARC64
2142 save_state(dc
, cpu_cond
);
2143 gen_helper_flushw();
2145 if (!supervisor(dc
))
2147 gen_movl_TN_reg(rd
, cpu_tbr
);
2151 } else if (xop
== 0x34) { /* FPU Operations */
2152 if (gen_trap_ifnofpu(dc
, cpu_cond
))
2154 gen_op_clear_ieee_excp_and_FTT();
2155 rs1
= GET_FIELD(insn
, 13, 17);
2156 rs2
= GET_FIELD(insn
, 27, 31);
2157 xop
= GET_FIELD(insn
, 18, 26);
2159 case 0x1: /* fmovs */
2160 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_fpr
[rs2
]);
2162 case 0x5: /* fnegs */
2163 gen_helper_fnegs(cpu_fpr
[rd
], cpu_fpr
[rs2
]);
2165 case 0x9: /* fabss */
2166 gen_helper_fabss(cpu_fpr
[rd
], cpu_fpr
[rs2
]);
2168 case 0x29: /* fsqrts */
2169 CHECK_FPU_FEATURE(dc
, FSQRT
);
2170 gen_clear_float_exceptions();
2171 gen_helper_fsqrts(cpu_tmp32
, cpu_fpr
[rs2
]);
2172 gen_helper_check_ieee_exceptions();
2173 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2175 case 0x2a: /* fsqrtd */
2176 CHECK_FPU_FEATURE(dc
, FSQRT
);
2177 gen_op_load_fpr_DT1(DFPREG(rs2
));
2178 gen_clear_float_exceptions();
2179 gen_helper_fsqrtd();
2180 gen_helper_check_ieee_exceptions();
2181 gen_op_store_DT0_fpr(DFPREG(rd
));
2183 case 0x2b: /* fsqrtq */
2184 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2185 gen_op_load_fpr_QT1(QFPREG(rs2
));
2186 gen_clear_float_exceptions();
2187 gen_helper_fsqrtq();
2188 gen_helper_check_ieee_exceptions();
2189 gen_op_store_QT0_fpr(QFPREG(rd
));
2191 case 0x41: /* fadds */
2192 gen_clear_float_exceptions();
2193 gen_helper_fadds(cpu_tmp32
, cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
2194 gen_helper_check_ieee_exceptions();
2195 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2197 case 0x42: /* faddd */
2198 gen_op_load_fpr_DT0(DFPREG(rs1
));
2199 gen_op_load_fpr_DT1(DFPREG(rs2
));
2200 gen_clear_float_exceptions();
2202 gen_helper_check_ieee_exceptions();
2203 gen_op_store_DT0_fpr(DFPREG(rd
));
2205 case 0x43: /* faddq */
2206 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2207 gen_op_load_fpr_QT0(QFPREG(rs1
));
2208 gen_op_load_fpr_QT1(QFPREG(rs2
));
2209 gen_clear_float_exceptions();
2211 gen_helper_check_ieee_exceptions();
2212 gen_op_store_QT0_fpr(QFPREG(rd
));
2214 case 0x45: /* fsubs */
2215 gen_clear_float_exceptions();
2216 gen_helper_fsubs(cpu_tmp32
, cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
2217 gen_helper_check_ieee_exceptions();
2218 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2220 case 0x46: /* fsubd */
2221 gen_op_load_fpr_DT0(DFPREG(rs1
));
2222 gen_op_load_fpr_DT1(DFPREG(rs2
));
2223 gen_clear_float_exceptions();
2225 gen_helper_check_ieee_exceptions();
2226 gen_op_store_DT0_fpr(DFPREG(rd
));
2228 case 0x47: /* fsubq */
2229 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2230 gen_op_load_fpr_QT0(QFPREG(rs1
));
2231 gen_op_load_fpr_QT1(QFPREG(rs2
));
2232 gen_clear_float_exceptions();
2234 gen_helper_check_ieee_exceptions();
2235 gen_op_store_QT0_fpr(QFPREG(rd
));
2237 case 0x49: /* fmuls */
2238 CHECK_FPU_FEATURE(dc
, FMUL
);
2239 gen_clear_float_exceptions();
2240 gen_helper_fmuls(cpu_tmp32
, cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
2241 gen_helper_check_ieee_exceptions();
2242 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2244 case 0x4a: /* fmuld */
2245 CHECK_FPU_FEATURE(dc
, FMUL
);
2246 gen_op_load_fpr_DT0(DFPREG(rs1
));
2247 gen_op_load_fpr_DT1(DFPREG(rs2
));
2248 gen_clear_float_exceptions();
2250 gen_helper_check_ieee_exceptions();
2251 gen_op_store_DT0_fpr(DFPREG(rd
));
2253 case 0x4b: /* fmulq */
2254 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2255 CHECK_FPU_FEATURE(dc
, FMUL
);
2256 gen_op_load_fpr_QT0(QFPREG(rs1
));
2257 gen_op_load_fpr_QT1(QFPREG(rs2
));
2258 gen_clear_float_exceptions();
2260 gen_helper_check_ieee_exceptions();
2261 gen_op_store_QT0_fpr(QFPREG(rd
));
2263 case 0x4d: /* fdivs */
2264 gen_clear_float_exceptions();
2265 gen_helper_fdivs(cpu_tmp32
, cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
2266 gen_helper_check_ieee_exceptions();
2267 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2269 case 0x4e: /* fdivd */
2270 gen_op_load_fpr_DT0(DFPREG(rs1
));
2271 gen_op_load_fpr_DT1(DFPREG(rs2
));
2272 gen_clear_float_exceptions();
2274 gen_helper_check_ieee_exceptions();
2275 gen_op_store_DT0_fpr(DFPREG(rd
));
2277 case 0x4f: /* fdivq */
2278 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2279 gen_op_load_fpr_QT0(QFPREG(rs1
));
2280 gen_op_load_fpr_QT1(QFPREG(rs2
));
2281 gen_clear_float_exceptions();
2283 gen_helper_check_ieee_exceptions();
2284 gen_op_store_QT0_fpr(QFPREG(rd
));
2286 case 0x69: /* fsmuld */
2287 CHECK_FPU_FEATURE(dc
, FSMULD
);
2288 gen_clear_float_exceptions();
2289 gen_helper_fsmuld(cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
2290 gen_helper_check_ieee_exceptions();
2291 gen_op_store_DT0_fpr(DFPREG(rd
));
2293 case 0x6e: /* fdmulq */
2294 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2295 gen_op_load_fpr_DT0(DFPREG(rs1
));
2296 gen_op_load_fpr_DT1(DFPREG(rs2
));
2297 gen_clear_float_exceptions();
2298 gen_helper_fdmulq();
2299 gen_helper_check_ieee_exceptions();
2300 gen_op_store_QT0_fpr(QFPREG(rd
));
2302 case 0xc4: /* fitos */
2303 gen_clear_float_exceptions();
2304 gen_helper_fitos(cpu_tmp32
, cpu_fpr
[rs2
]);
2305 gen_helper_check_ieee_exceptions();
2306 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2308 case 0xc6: /* fdtos */
2309 gen_op_load_fpr_DT1(DFPREG(rs2
));
2310 gen_clear_float_exceptions();
2311 gen_helper_fdtos(cpu_tmp32
);
2312 gen_helper_check_ieee_exceptions();
2313 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2315 case 0xc7: /* fqtos */
2316 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2317 gen_op_load_fpr_QT1(QFPREG(rs2
));
2318 gen_clear_float_exceptions();
2319 gen_helper_fqtos(cpu_tmp32
);
2320 gen_helper_check_ieee_exceptions();
2321 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2323 case 0xc8: /* fitod */
2324 gen_helper_fitod(cpu_fpr
[rs2
]);
2325 gen_op_store_DT0_fpr(DFPREG(rd
));
2327 case 0xc9: /* fstod */
2328 gen_helper_fstod(cpu_fpr
[rs2
]);
2329 gen_op_store_DT0_fpr(DFPREG(rd
));
2331 case 0xcb: /* fqtod */
2332 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2333 gen_op_load_fpr_QT1(QFPREG(rs2
));
2334 gen_clear_float_exceptions();
2336 gen_helper_check_ieee_exceptions();
2337 gen_op_store_DT0_fpr(DFPREG(rd
));
2339 case 0xcc: /* fitoq */
2340 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2341 gen_helper_fitoq(cpu_fpr
[rs2
]);
2342 gen_op_store_QT0_fpr(QFPREG(rd
));
2344 case 0xcd: /* fstoq */
2345 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2346 gen_helper_fstoq(cpu_fpr
[rs2
]);
2347 gen_op_store_QT0_fpr(QFPREG(rd
));
2349 case 0xce: /* fdtoq */
2350 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2351 gen_op_load_fpr_DT1(DFPREG(rs2
));
2353 gen_op_store_QT0_fpr(QFPREG(rd
));
2355 case 0xd1: /* fstoi */
2356 gen_clear_float_exceptions();
2357 gen_helper_fstoi(cpu_tmp32
, cpu_fpr
[rs2
]);
2358 gen_helper_check_ieee_exceptions();
2359 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2361 case 0xd2: /* fdtoi */
2362 gen_op_load_fpr_DT1(DFPREG(rs2
));
2363 gen_clear_float_exceptions();
2364 gen_helper_fdtoi(cpu_tmp32
);
2365 gen_helper_check_ieee_exceptions();
2366 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2368 case 0xd3: /* fqtoi */
2369 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2370 gen_op_load_fpr_QT1(QFPREG(rs2
));
2371 gen_clear_float_exceptions();
2372 gen_helper_fqtoi(cpu_tmp32
);
2373 gen_helper_check_ieee_exceptions();
2374 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2376 #ifdef TARGET_SPARC64
2377 case 0x2: /* V9 fmovd */
2378 tcg_gen_mov_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs2
)]);
2379 tcg_gen_mov_i32(cpu_fpr
[DFPREG(rd
) + 1],
2380 cpu_fpr
[DFPREG(rs2
) + 1]);
2382 case 0x3: /* V9 fmovq */
2383 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2384 tcg_gen_mov_i32(cpu_fpr
[QFPREG(rd
)], cpu_fpr
[QFPREG(rs2
)]);
2385 tcg_gen_mov_i32(cpu_fpr
[QFPREG(rd
) + 1],
2386 cpu_fpr
[QFPREG(rs2
) + 1]);
2387 tcg_gen_mov_i32(cpu_fpr
[QFPREG(rd
) + 2],
2388 cpu_fpr
[QFPREG(rs2
) + 2]);
2389 tcg_gen_mov_i32(cpu_fpr
[QFPREG(rd
) + 3],
2390 cpu_fpr
[QFPREG(rs2
) + 3]);
2392 case 0x6: /* V9 fnegd */
2393 gen_op_load_fpr_DT1(DFPREG(rs2
));
2395 gen_op_store_DT0_fpr(DFPREG(rd
));
2397 case 0x7: /* V9 fnegq */
2398 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2399 gen_op_load_fpr_QT1(QFPREG(rs2
));
2401 gen_op_store_QT0_fpr(QFPREG(rd
));
2403 case 0xa: /* V9 fabsd */
2404 gen_op_load_fpr_DT1(DFPREG(rs2
));
2406 gen_op_store_DT0_fpr(DFPREG(rd
));
2408 case 0xb: /* V9 fabsq */
2409 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2410 gen_op_load_fpr_QT1(QFPREG(rs2
));
2412 gen_op_store_QT0_fpr(QFPREG(rd
));
2414 case 0x81: /* V9 fstox */
2415 gen_clear_float_exceptions();
2416 gen_helper_fstox(cpu_fpr
[rs2
]);
2417 gen_helper_check_ieee_exceptions();
2418 gen_op_store_DT0_fpr(DFPREG(rd
));
2420 case 0x82: /* V9 fdtox */
2421 gen_op_load_fpr_DT1(DFPREG(rs2
));
2422 gen_clear_float_exceptions();
2424 gen_helper_check_ieee_exceptions();
2425 gen_op_store_DT0_fpr(DFPREG(rd
));
2427 case 0x83: /* V9 fqtox */
2428 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2429 gen_op_load_fpr_QT1(QFPREG(rs2
));
2430 gen_clear_float_exceptions();
2432 gen_helper_check_ieee_exceptions();
2433 gen_op_store_DT0_fpr(DFPREG(rd
));
2435 case 0x84: /* V9 fxtos */
2436 gen_op_load_fpr_DT1(DFPREG(rs2
));
2437 gen_clear_float_exceptions();
2438 gen_helper_fxtos(cpu_tmp32
);
2439 gen_helper_check_ieee_exceptions();
2440 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_tmp32
);
2442 case 0x88: /* V9 fxtod */
2443 gen_op_load_fpr_DT1(DFPREG(rs2
));
2444 gen_clear_float_exceptions();
2446 gen_helper_check_ieee_exceptions();
2447 gen_op_store_DT0_fpr(DFPREG(rd
));
2449 case 0x8c: /* V9 fxtoq */
2450 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2451 gen_op_load_fpr_DT1(DFPREG(rs2
));
2452 gen_clear_float_exceptions();
2454 gen_helper_check_ieee_exceptions();
2455 gen_op_store_QT0_fpr(QFPREG(rd
));
2461 } else if (xop
== 0x35) { /* FPU Operations */
2462 #ifdef TARGET_SPARC64
2465 if (gen_trap_ifnofpu(dc
, cpu_cond
))
2467 gen_op_clear_ieee_excp_and_FTT();
2468 rs1
= GET_FIELD(insn
, 13, 17);
2469 rs2
= GET_FIELD(insn
, 27, 31);
2470 xop
= GET_FIELD(insn
, 18, 26);
2471 #ifdef TARGET_SPARC64
2472 if ((xop
& 0x11f) == 0x005) { // V9 fmovsr
2475 l1
= gen_new_label();
2476 cond
= GET_FIELD_SP(insn
, 14, 17);
2477 cpu_src1
= get_src1(insn
, cpu_src1
);
2478 tcg_gen_brcondi_tl(gen_tcg_cond_reg
[cond
], cpu_src1
,
2480 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_fpr
[rs2
]);
2483 } else if ((xop
& 0x11f) == 0x006) { // V9 fmovdr
2486 l1
= gen_new_label();
2487 cond
= GET_FIELD_SP(insn
, 14, 17);
2488 cpu_src1
= get_src1(insn
, cpu_src1
);
2489 tcg_gen_brcondi_tl(gen_tcg_cond_reg
[cond
], cpu_src1
,
2491 tcg_gen_mov_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs2
)]);
2492 tcg_gen_mov_i32(cpu_fpr
[DFPREG(rd
) + 1], cpu_fpr
[DFPREG(rs2
) + 1]);
2495 } else if ((xop
& 0x11f) == 0x007) { // V9 fmovqr
2498 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2499 l1
= gen_new_label();
2500 cond
= GET_FIELD_SP(insn
, 14, 17);
2501 cpu_src1
= get_src1(insn
, cpu_src1
);
2502 tcg_gen_brcondi_tl(gen_tcg_cond_reg
[cond
], cpu_src1
,
2504 tcg_gen_mov_i32(cpu_fpr
[QFPREG(rd
)], cpu_fpr
[QFPREG(rs2
)]);
2505 tcg_gen_mov_i32(cpu_fpr
[QFPREG(rd
) + 1], cpu_fpr
[QFPREG(rs2
) + 1]);
2506 tcg_gen_mov_i32(cpu_fpr
[QFPREG(rd
) + 2], cpu_fpr
[QFPREG(rs2
) + 2]);
2507 tcg_gen_mov_i32(cpu_fpr
[QFPREG(rd
) + 3], cpu_fpr
[QFPREG(rs2
) + 3]);
2513 #ifdef TARGET_SPARC64
2514 #define FMOVSCC(fcc) \
2519 l1 = gen_new_label(); \
2520 r_cond = tcg_temp_new(); \
2521 cond = GET_FIELD_SP(insn, 14, 17); \
2522 gen_fcond(r_cond, fcc, cond); \
2523 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2525 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \
2526 gen_set_label(l1); \
2527 tcg_temp_free(r_cond); \
2529 #define FMOVDCC(fcc) \
2534 l1 = gen_new_label(); \
2535 r_cond = tcg_temp_new(); \
2536 cond = GET_FIELD_SP(insn, 14, 17); \
2537 gen_fcond(r_cond, fcc, cond); \
2538 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2540 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \
2541 cpu_fpr[DFPREG(rs2)]); \
2542 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \
2543 cpu_fpr[DFPREG(rs2) + 1]); \
2544 gen_set_label(l1); \
2545 tcg_temp_free(r_cond); \
2547 #define FMOVQCC(fcc) \
2552 l1 = gen_new_label(); \
2553 r_cond = tcg_temp_new(); \
2554 cond = GET_FIELD_SP(insn, 14, 17); \
2555 gen_fcond(r_cond, fcc, cond); \
2556 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2558 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \
2559 cpu_fpr[QFPREG(rs2)]); \
2560 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \
2561 cpu_fpr[QFPREG(rs2) + 1]); \
2562 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \
2563 cpu_fpr[QFPREG(rs2) + 2]); \
2564 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \
2565 cpu_fpr[QFPREG(rs2) + 3]); \
2566 gen_set_label(l1); \
2567 tcg_temp_free(r_cond); \
2569 case 0x001: /* V9 fmovscc %fcc0 */
2572 case 0x002: /* V9 fmovdcc %fcc0 */
2575 case 0x003: /* V9 fmovqcc %fcc0 */
2576 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2579 case 0x041: /* V9 fmovscc %fcc1 */
2582 case 0x042: /* V9 fmovdcc %fcc1 */
2585 case 0x043: /* V9 fmovqcc %fcc1 */
2586 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2589 case 0x081: /* V9 fmovscc %fcc2 */
2592 case 0x082: /* V9 fmovdcc %fcc2 */
2595 case 0x083: /* V9 fmovqcc %fcc2 */
2596 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2599 case 0x0c1: /* V9 fmovscc %fcc3 */
2602 case 0x0c2: /* V9 fmovdcc %fcc3 */
2605 case 0x0c3: /* V9 fmovqcc %fcc3 */
2606 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2612 #define FMOVSCC(icc) \
2617 l1 = gen_new_label(); \
2618 r_cond = tcg_temp_new(); \
2619 cond = GET_FIELD_SP(insn, 14, 17); \
2620 gen_cond(r_cond, icc, cond, dc); \
2621 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2623 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \
2624 gen_set_label(l1); \
2625 tcg_temp_free(r_cond); \
2627 #define FMOVDCC(icc) \
2632 l1 = gen_new_label(); \
2633 r_cond = tcg_temp_new(); \
2634 cond = GET_FIELD_SP(insn, 14, 17); \
2635 gen_cond(r_cond, icc, cond, dc); \
2636 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2638 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \
2639 cpu_fpr[DFPREG(rs2)]); \
2640 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \
2641 cpu_fpr[DFPREG(rs2) + 1]); \
2642 gen_set_label(l1); \
2643 tcg_temp_free(r_cond); \
2645 #define FMOVQCC(icc) \
2650 l1 = gen_new_label(); \
2651 r_cond = tcg_temp_new(); \
2652 cond = GET_FIELD_SP(insn, 14, 17); \
2653 gen_cond(r_cond, icc, cond, dc); \
2654 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2656 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \
2657 cpu_fpr[QFPREG(rs2)]); \
2658 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \
2659 cpu_fpr[QFPREG(rs2) + 1]); \
2660 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \
2661 cpu_fpr[QFPREG(rs2) + 2]); \
2662 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \
2663 cpu_fpr[QFPREG(rs2) + 3]); \
2664 gen_set_label(l1); \
2665 tcg_temp_free(r_cond); \
2668 case 0x101: /* V9 fmovscc %icc */
2671 case 0x102: /* V9 fmovdcc %icc */
2673 case 0x103: /* V9 fmovqcc %icc */
2674 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2677 case 0x181: /* V9 fmovscc %xcc */
2680 case 0x182: /* V9 fmovdcc %xcc */
2683 case 0x183: /* V9 fmovqcc %xcc */
2684 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2691 case 0x51: /* fcmps, V9 %fcc */
2692 gen_op_fcmps(rd
& 3, cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
2694 case 0x52: /* fcmpd, V9 %fcc */
2695 gen_op_load_fpr_DT0(DFPREG(rs1
));
2696 gen_op_load_fpr_DT1(DFPREG(rs2
));
2697 gen_op_fcmpd(rd
& 3);
2699 case 0x53: /* fcmpq, V9 %fcc */
2700 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2701 gen_op_load_fpr_QT0(QFPREG(rs1
));
2702 gen_op_load_fpr_QT1(QFPREG(rs2
));
2703 gen_op_fcmpq(rd
& 3);
2705 case 0x55: /* fcmpes, V9 %fcc */
2706 gen_op_fcmpes(rd
& 3, cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
2708 case 0x56: /* fcmped, V9 %fcc */
2709 gen_op_load_fpr_DT0(DFPREG(rs1
));
2710 gen_op_load_fpr_DT1(DFPREG(rs2
));
2711 gen_op_fcmped(rd
& 3);
2713 case 0x57: /* fcmpeq, V9 %fcc */
2714 CHECK_FPU_FEATURE(dc
, FLOAT128
);
2715 gen_op_load_fpr_QT0(QFPREG(rs1
));
2716 gen_op_load_fpr_QT1(QFPREG(rs2
));
2717 gen_op_fcmpeq(rd
& 3);
2722 } else if (xop
== 0x2) {
2725 rs1
= GET_FIELD(insn
, 13, 17);
2727 // or %g0, x, y -> mov T0, x; mov y, T0
2728 if (IS_IMM
) { /* immediate */
2731 simm
= GET_FIELDs(insn
, 19, 31);
2732 r_const
= tcg_const_tl(simm
);
2733 gen_movl_TN_reg(rd
, r_const
);
2734 tcg_temp_free(r_const
);
2735 } else { /* register */
2736 rs2
= GET_FIELD(insn
, 27, 31);
2737 gen_movl_reg_TN(rs2
, cpu_dst
);
2738 gen_movl_TN_reg(rd
, cpu_dst
);
2741 cpu_src1
= get_src1(insn
, cpu_src1
);
2742 if (IS_IMM
) { /* immediate */
2743 simm
= GET_FIELDs(insn
, 19, 31);
2744 tcg_gen_ori_tl(cpu_dst
, cpu_src1
, simm
);
2745 gen_movl_TN_reg(rd
, cpu_dst
);
2746 } else { /* register */
2747 // or x, %g0, y -> mov T1, x; mov y, T1
2748 rs2
= GET_FIELD(insn
, 27, 31);
2750 gen_movl_reg_TN(rs2
, cpu_src2
);
2751 tcg_gen_or_tl(cpu_dst
, cpu_src1
, cpu_src2
);
2752 gen_movl_TN_reg(rd
, cpu_dst
);
2754 gen_movl_TN_reg(rd
, cpu_src1
);
2757 #ifdef TARGET_SPARC64
2758 } else if (xop
== 0x25) { /* sll, V9 sllx */
2759 cpu_src1
= get_src1(insn
, cpu_src1
);
2760 if (IS_IMM
) { /* immediate */
2761 simm
= GET_FIELDs(insn
, 20, 31);
2762 if (insn
& (1 << 12)) {
2763 tcg_gen_shli_i64(cpu_dst
, cpu_src1
, simm
& 0x3f);
2765 tcg_gen_shli_i64(cpu_dst
, cpu_src1
, simm
& 0x1f);
2767 } else { /* register */
2768 rs2
= GET_FIELD(insn
, 27, 31);
2769 gen_movl_reg_TN(rs2
, cpu_src2
);
2770 if (insn
& (1 << 12)) {
2771 tcg_gen_andi_i64(cpu_tmp0
, cpu_src2
, 0x3f);
2773 tcg_gen_andi_i64(cpu_tmp0
, cpu_src2
, 0x1f);
2775 tcg_gen_shl_i64(cpu_dst
, cpu_src1
, cpu_tmp0
);
2777 gen_movl_TN_reg(rd
, cpu_dst
);
2778 } else if (xop
== 0x26) { /* srl, V9 srlx */
2779 cpu_src1
= get_src1(insn
, cpu_src1
);
2780 if (IS_IMM
) { /* immediate */
2781 simm
= GET_FIELDs(insn
, 20, 31);
2782 if (insn
& (1 << 12)) {
2783 tcg_gen_shri_i64(cpu_dst
, cpu_src1
, simm
& 0x3f);
2785 tcg_gen_andi_i64(cpu_dst
, cpu_src1
, 0xffffffffULL
);
2786 tcg_gen_shri_i64(cpu_dst
, cpu_dst
, simm
& 0x1f);
2788 } else { /* register */
2789 rs2
= GET_FIELD(insn
, 27, 31);
2790 gen_movl_reg_TN(rs2
, cpu_src2
);
2791 if (insn
& (1 << 12)) {
2792 tcg_gen_andi_i64(cpu_tmp0
, cpu_src2
, 0x3f);
2793 tcg_gen_shr_i64(cpu_dst
, cpu_src1
, cpu_tmp0
);
2795 tcg_gen_andi_i64(cpu_tmp0
, cpu_src2
, 0x1f);
2796 tcg_gen_andi_i64(cpu_dst
, cpu_src1
, 0xffffffffULL
);
2797 tcg_gen_shr_i64(cpu_dst
, cpu_dst
, cpu_tmp0
);
2800 gen_movl_TN_reg(rd
, cpu_dst
);
2801 } else if (xop
== 0x27) { /* sra, V9 srax */
2802 cpu_src1
= get_src1(insn
, cpu_src1
);
2803 if (IS_IMM
) { /* immediate */
2804 simm
= GET_FIELDs(insn
, 20, 31);
2805 if (insn
& (1 << 12)) {
2806 tcg_gen_sari_i64(cpu_dst
, cpu_src1
, simm
& 0x3f);
2808 tcg_gen_andi_i64(cpu_dst
, cpu_src1
, 0xffffffffULL
);
2809 tcg_gen_ext32s_i64(cpu_dst
, cpu_dst
);
2810 tcg_gen_sari_i64(cpu_dst
, cpu_dst
, simm
& 0x1f);
2812 } else { /* register */
2813 rs2
= GET_FIELD(insn
, 27, 31);
2814 gen_movl_reg_TN(rs2
, cpu_src2
);
2815 if (insn
& (1 << 12)) {
2816 tcg_gen_andi_i64(cpu_tmp0
, cpu_src2
, 0x3f);
2817 tcg_gen_sar_i64(cpu_dst
, cpu_src1
, cpu_tmp0
);
2819 tcg_gen_andi_i64(cpu_tmp0
, cpu_src2
, 0x1f);
2820 tcg_gen_andi_i64(cpu_dst
, cpu_src1
, 0xffffffffULL
);
2821 tcg_gen_ext32s_i64(cpu_dst
, cpu_dst
);
2822 tcg_gen_sar_i64(cpu_dst
, cpu_dst
, cpu_tmp0
);
2825 gen_movl_TN_reg(rd
, cpu_dst
);
2827 } else if (xop
< 0x36) {
2829 cpu_src1
= get_src1(insn
, cpu_src1
);
2830 cpu_src2
= get_src2(insn
, cpu_src2
);
2831 switch (xop
& ~0x10) {
2834 simm
= GET_FIELDs(insn
, 19, 31);
2836 gen_op_addi_cc(cpu_dst
, cpu_src1
, simm
);
2837 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_ADD
);
2838 dc
->cc_op
= CC_OP_ADD
;
2840 tcg_gen_addi_tl(cpu_dst
, cpu_src1
, simm
);
2844 gen_op_add_cc(cpu_dst
, cpu_src1
, cpu_src2
);
2845 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_ADD
);
2846 dc
->cc_op
= CC_OP_ADD
;
2848 tcg_gen_add_tl(cpu_dst
, cpu_src1
, cpu_src2
);
2854 simm
= GET_FIELDs(insn
, 19, 31);
2855 tcg_gen_andi_tl(cpu_dst
, cpu_src1
, simm
);
2857 tcg_gen_and_tl(cpu_dst
, cpu_src1
, cpu_src2
);
2860 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
2861 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
2862 dc
->cc_op
= CC_OP_LOGIC
;
2867 simm
= GET_FIELDs(insn
, 19, 31);
2868 tcg_gen_ori_tl(cpu_dst
, cpu_src1
, simm
);
2870 tcg_gen_or_tl(cpu_dst
, cpu_src1
, cpu_src2
);
2873 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
2874 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
2875 dc
->cc_op
= CC_OP_LOGIC
;
2880 simm
= GET_FIELDs(insn
, 19, 31);
2881 tcg_gen_xori_tl(cpu_dst
, cpu_src1
, simm
);
2883 tcg_gen_xor_tl(cpu_dst
, cpu_src1
, cpu_src2
);
2886 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
2887 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
2888 dc
->cc_op
= CC_OP_LOGIC
;
2893 simm
= GET_FIELDs(insn
, 19, 31);
2895 gen_op_subi_cc(cpu_dst
, cpu_src1
, simm
, dc
);
2897 tcg_gen_subi_tl(cpu_dst
, cpu_src1
, simm
);
2901 gen_op_sub_cc(cpu_dst
, cpu_src1
, cpu_src2
);
2902 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SUB
);
2903 dc
->cc_op
= CC_OP_SUB
;
2905 tcg_gen_sub_tl(cpu_dst
, cpu_src1
, cpu_src2
);
2909 case 0x5: /* andn */
2911 simm
= GET_FIELDs(insn
, 19, 31);
2912 tcg_gen_andi_tl(cpu_dst
, cpu_src1
, ~simm
);
2914 tcg_gen_andc_tl(cpu_dst
, cpu_src1
, cpu_src2
);
2917 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
2918 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
2919 dc
->cc_op
= CC_OP_LOGIC
;
2924 simm
= GET_FIELDs(insn
, 19, 31);
2925 tcg_gen_ori_tl(cpu_dst
, cpu_src1
, ~simm
);
2927 tcg_gen_orc_tl(cpu_dst
, cpu_src1
, cpu_src2
);
2930 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
2931 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
2932 dc
->cc_op
= CC_OP_LOGIC
;
2935 case 0x7: /* xorn */
2937 simm
= GET_FIELDs(insn
, 19, 31);
2938 tcg_gen_xori_tl(cpu_dst
, cpu_src1
, ~simm
);
2940 tcg_gen_not_tl(cpu_tmp0
, cpu_src2
);
2941 tcg_gen_xor_tl(cpu_dst
, cpu_src1
, cpu_tmp0
);
2944 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
2945 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
2946 dc
->cc_op
= CC_OP_LOGIC
;
2949 case 0x8: /* addx, V9 addc */
2951 simm
= GET_FIELDs(insn
, 19, 31);
2953 gen_helper_compute_psr();
2954 gen_op_addxi_cc(cpu_dst
, cpu_src1
, simm
);
2955 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_ADDX
);
2956 dc
->cc_op
= CC_OP_ADDX
;
2958 gen_helper_compute_psr();
2959 gen_mov_reg_C(cpu_tmp0
, cpu_psr
);
2960 tcg_gen_addi_tl(cpu_tmp0
, cpu_tmp0
, simm
);
2961 tcg_gen_add_tl(cpu_dst
, cpu_src1
, cpu_tmp0
);
2965 gen_helper_compute_psr();
2966 gen_op_addx_cc(cpu_dst
, cpu_src1
, cpu_src2
);
2967 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_ADDX
);
2968 dc
->cc_op
= CC_OP_ADDX
;
2970 gen_helper_compute_psr();
2971 gen_mov_reg_C(cpu_tmp0
, cpu_psr
);
2972 tcg_gen_add_tl(cpu_tmp0
, cpu_src2
, cpu_tmp0
);
2973 tcg_gen_add_tl(cpu_dst
, cpu_src1
, cpu_tmp0
);
2977 #ifdef TARGET_SPARC64
2978 case 0x9: /* V9 mulx */
2980 simm
= GET_FIELDs(insn
, 19, 31);
2981 tcg_gen_muli_i64(cpu_dst
, cpu_src1
, simm
);
2983 tcg_gen_mul_i64(cpu_dst
, cpu_src1
, cpu_src2
);
2987 case 0xa: /* umul */
2988 CHECK_IU_FEATURE(dc
, MUL
);
2989 gen_op_umul(cpu_dst
, cpu_src1
, cpu_src2
);
2991 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
2992 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
2993 dc
->cc_op
= CC_OP_LOGIC
;
2996 case 0xb: /* smul */
2997 CHECK_IU_FEATURE(dc
, MUL
);
2998 gen_op_smul(cpu_dst
, cpu_src1
, cpu_src2
);
3000 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
3001 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_LOGIC
);
3002 dc
->cc_op
= CC_OP_LOGIC
;
3005 case 0xc: /* subx, V9 subc */
3007 simm
= GET_FIELDs(insn
, 19, 31);
3009 gen_helper_compute_psr();
3010 gen_op_subxi_cc(cpu_dst
, cpu_src1
, simm
);
3011 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SUBX
);
3012 dc
->cc_op
= CC_OP_SUBX
;
3014 gen_helper_compute_psr();
3015 gen_mov_reg_C(cpu_tmp0
, cpu_psr
);
3016 tcg_gen_addi_tl(cpu_tmp0
, cpu_tmp0
, simm
);
3017 tcg_gen_sub_tl(cpu_dst
, cpu_src1
, cpu_tmp0
);
3021 gen_helper_compute_psr();
3022 gen_op_subx_cc(cpu_dst
, cpu_src1
, cpu_src2
);
3023 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_SUBX
);
3024 dc
->cc_op
= CC_OP_SUBX
;
3026 gen_helper_compute_psr();
3027 gen_mov_reg_C(cpu_tmp0
, cpu_psr
);
3028 tcg_gen_add_tl(cpu_tmp0
, cpu_src2
, cpu_tmp0
);
3029 tcg_gen_sub_tl(cpu_dst
, cpu_src1
, cpu_tmp0
);
3033 #ifdef TARGET_SPARC64
3034 case 0xd: /* V9 udivx */
3035 tcg_gen_mov_tl(cpu_cc_src
, cpu_src1
);
3036 tcg_gen_mov_tl(cpu_cc_src2
, cpu_src2
);
3037 gen_trap_ifdivzero_tl(cpu_cc_src2
);
3038 tcg_gen_divu_i64(cpu_dst
, cpu_cc_src
, cpu_cc_src2
);
3041 case 0xe: /* udiv */
3042 CHECK_IU_FEATURE(dc
, DIV
);
3043 gen_helper_udiv(cpu_dst
, cpu_src1
, cpu_src2
);
3045 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
3046 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_DIV
);
3047 dc
->cc_op
= CC_OP_DIV
;
3050 case 0xf: /* sdiv */
3051 CHECK_IU_FEATURE(dc
, DIV
);
3052 gen_helper_sdiv(cpu_dst
, cpu_src1
, cpu_src2
);
3054 tcg_gen_mov_tl(cpu_cc_dst
, cpu_dst
);
3055 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_DIV
);
3056 dc
->cc_op
= CC_OP_DIV
;
3062 gen_movl_TN_reg(rd
, cpu_dst
);
3064 cpu_src1
= get_src1(insn
, cpu_src1
);
3065 cpu_src2
= get_src2(insn
, cpu_src2
);
3067 case 0x20: /* taddcc */
3068 gen_op_tadd_cc(cpu_dst
, cpu_src1
, cpu_src2
);
3069 gen_movl_TN_reg(rd
, cpu_dst
);
3070 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_TADD
);
3071 dc
->cc_op
= CC_OP_TADD
;
3073 case 0x21: /* tsubcc */
3074 gen_op_tsub_cc(cpu_dst
, cpu_src1
, cpu_src2
);
3075 gen_movl_TN_reg(rd
, cpu_dst
);
3076 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_TSUB
);
3077 dc
->cc_op
= CC_OP_TSUB
;
3079 case 0x22: /* taddcctv */
3080 save_state(dc
, cpu_cond
);
3081 gen_op_tadd_ccTV(cpu_dst
, cpu_src1
, cpu_src2
);
3082 gen_movl_TN_reg(rd
, cpu_dst
);
3083 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_TADDTV
);
3084 dc
->cc_op
= CC_OP_TADDTV
;
3086 case 0x23: /* tsubcctv */
3087 save_state(dc
, cpu_cond
);
3088 gen_op_tsub_ccTV(cpu_dst
, cpu_src1
, cpu_src2
);
3089 gen_movl_TN_reg(rd
, cpu_dst
);
3090 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_TSUBTV
);
3091 dc
->cc_op
= CC_OP_TSUBTV
;
3093 case 0x24: /* mulscc */
3094 gen_helper_compute_psr();
3095 gen_op_mulscc(cpu_dst
, cpu_src1
, cpu_src2
);
3096 gen_movl_TN_reg(rd
, cpu_dst
);
3097 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_ADD
);
3098 dc
->cc_op
= CC_OP_ADD
;
3100 #ifndef TARGET_SPARC64
3101 case 0x25: /* sll */
3102 if (IS_IMM
) { /* immediate */
3103 simm
= GET_FIELDs(insn
, 20, 31);
3104 tcg_gen_shli_tl(cpu_dst
, cpu_src1
, simm
& 0x1f);
3105 } else { /* register */
3106 tcg_gen_andi_tl(cpu_tmp0
, cpu_src2
, 0x1f);
3107 tcg_gen_shl_tl(cpu_dst
, cpu_src1
, cpu_tmp0
);
3109 gen_movl_TN_reg(rd
, cpu_dst
);
3111 case 0x26: /* srl */
3112 if (IS_IMM
) { /* immediate */
3113 simm
= GET_FIELDs(insn
, 20, 31);
3114 tcg_gen_shri_tl(cpu_dst
, cpu_src1
, simm
& 0x1f);
3115 } else { /* register */
3116 tcg_gen_andi_tl(cpu_tmp0
, cpu_src2
, 0x1f);
3117 tcg_gen_shr_tl(cpu_dst
, cpu_src1
, cpu_tmp0
);
3119 gen_movl_TN_reg(rd
, cpu_dst
);
3121 case 0x27: /* sra */
3122 if (IS_IMM
) { /* immediate */
3123 simm
= GET_FIELDs(insn
, 20, 31);
3124 tcg_gen_sari_tl(cpu_dst
, cpu_src1
, simm
& 0x1f);
3125 } else { /* register */
3126 tcg_gen_andi_tl(cpu_tmp0
, cpu_src2
, 0x1f);
3127 tcg_gen_sar_tl(cpu_dst
, cpu_src1
, cpu_tmp0
);
3129 gen_movl_TN_reg(rd
, cpu_dst
);
3136 tcg_gen_xor_tl(cpu_tmp0
, cpu_src1
, cpu_src2
);
3137 tcg_gen_andi_tl(cpu_y
, cpu_tmp0
, 0xffffffff);
3139 #ifndef TARGET_SPARC64
3140 case 0x01 ... 0x0f: /* undefined in the
3144 case 0x10 ... 0x1f: /* implementation-dependent
3150 case 0x2: /* V9 wrccr */
3151 tcg_gen_xor_tl(cpu_dst
, cpu_src1
, cpu_src2
);
3152 gen_helper_wrccr(cpu_dst
);
3153 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_FLAGS
);
3154 dc
->cc_op
= CC_OP_FLAGS
;
3156 case 0x3: /* V9 wrasi */
3157 tcg_gen_xor_tl(cpu_dst
, cpu_src1
, cpu_src2
);
3158 tcg_gen_andi_tl(cpu_dst
, cpu_dst
, 0xff);
3159 tcg_gen_trunc_tl_i32(cpu_asi
, cpu_dst
);
3161 case 0x6: /* V9 wrfprs */
3162 tcg_gen_xor_tl(cpu_dst
, cpu_src1
, cpu_src2
);
3163 tcg_gen_trunc_tl_i32(cpu_fprs
, cpu_dst
);
3164 save_state(dc
, cpu_cond
);
3169 case 0xf: /* V9 sir, nop if user */
3170 #if !defined(CONFIG_USER_ONLY)
3175 case 0x13: /* Graphics Status */
3176 if (gen_trap_ifnofpu(dc
, cpu_cond
))
3178 tcg_gen_xor_tl(cpu_gsr
, cpu_src1
, cpu_src2
);
3180 case 0x14: /* Softint set */
3181 if (!supervisor(dc
))
3183 tcg_gen_xor_tl(cpu_tmp64
, cpu_src1
, cpu_src2
);
3184 gen_helper_set_softint(cpu_tmp64
);
3186 case 0x15: /* Softint clear */
3187 if (!supervisor(dc
))
3189 tcg_gen_xor_tl(cpu_tmp64
, cpu_src1
, cpu_src2
);
3190 gen_helper_clear_softint(cpu_tmp64
);
3192 case 0x16: /* Softint write */
3193 if (!supervisor(dc
))
3195 tcg_gen_xor_tl(cpu_tmp64
, cpu_src1
, cpu_src2
);
3196 gen_helper_write_softint(cpu_tmp64
);
3198 case 0x17: /* Tick compare */
3199 #if !defined(CONFIG_USER_ONLY)
3200 if (!supervisor(dc
))
3206 tcg_gen_xor_tl(cpu_tick_cmpr
, cpu_src1
,
3208 r_tickptr
= tcg_temp_new_ptr();
3209 tcg_gen_ld_ptr(r_tickptr
, cpu_env
,
3210 offsetof(CPUState
, tick
));
3211 gen_helper_tick_set_limit(r_tickptr
,
3213 tcg_temp_free_ptr(r_tickptr
);
3216 case 0x18: /* System tick */
3217 #if !defined(CONFIG_USER_ONLY)
3218 if (!supervisor(dc
))
3224 tcg_gen_xor_tl(cpu_dst
, cpu_src1
,
3226 r_tickptr
= tcg_temp_new_ptr();
3227 tcg_gen_ld_ptr(r_tickptr
, cpu_env
,
3228 offsetof(CPUState
, stick
));
3229 gen_helper_tick_set_count(r_tickptr
,
3231 tcg_temp_free_ptr(r_tickptr
);
3234 case 0x19: /* System tick compare */
3235 #if !defined(CONFIG_USER_ONLY)
3236 if (!supervisor(dc
))
3242 tcg_gen_xor_tl(cpu_stick_cmpr
, cpu_src1
,
3244 r_tickptr
= tcg_temp_new_ptr();
3245 tcg_gen_ld_ptr(r_tickptr
, cpu_env
,
3246 offsetof(CPUState
, stick
));
3247 gen_helper_tick_set_limit(r_tickptr
,
3249 tcg_temp_free_ptr(r_tickptr
);
3253 case 0x10: /* Performance Control */
3254 case 0x11: /* Performance Instrumentation
3256 case 0x12: /* Dispatch Control */
3263 #if !defined(CONFIG_USER_ONLY)
3264 case 0x31: /* wrpsr, V9 saved, restored */
3266 if (!supervisor(dc
))
3268 #ifdef TARGET_SPARC64
3274 gen_helper_restored();
3276 case 2: /* UA2005 allclean */
3277 case 3: /* UA2005 otherw */
3278 case 4: /* UA2005 normalw */
3279 case 5: /* UA2005 invalw */
3285 tcg_gen_xor_tl(cpu_dst
, cpu_src1
, cpu_src2
);
3286 gen_helper_wrpsr(cpu_dst
);
3287 tcg_gen_movi_i32(cpu_cc_op
, CC_OP_FLAGS
);
3288 dc
->cc_op
= CC_OP_FLAGS
;
3289 save_state(dc
, cpu_cond
);
3296 case 0x32: /* wrwim, V9 wrpr */
3298 if (!supervisor(dc
))
3300 tcg_gen_xor_tl(cpu_tmp0
, cpu_src1
, cpu_src2
);
3301 #ifdef TARGET_SPARC64
3307 r_tsptr
= tcg_temp_new_ptr();
3308 gen_load_trap_state_at_tl(r_tsptr
, cpu_env
);
3309 tcg_gen_st_tl(cpu_tmp0
, r_tsptr
,
3310 offsetof(trap_state
, tpc
));
3311 tcg_temp_free_ptr(r_tsptr
);
3318 r_tsptr
= tcg_temp_new_ptr();
3319 gen_load_trap_state_at_tl(r_tsptr
, cpu_env
);
3320 tcg_gen_st_tl(cpu_tmp0
, r_tsptr
,
3321 offsetof(trap_state
, tnpc
));
3322 tcg_temp_free_ptr(r_tsptr
);
3329 r_tsptr
= tcg_temp_new_ptr();
3330 gen_load_trap_state_at_tl(r_tsptr
, cpu_env
);
3331 tcg_gen_st_tl(cpu_tmp0
, r_tsptr
,
3332 offsetof(trap_state
,
3334 tcg_temp_free_ptr(r_tsptr
);
3341 r_tsptr
= tcg_temp_new_ptr();
3342 gen_load_trap_state_at_tl(r_tsptr
, cpu_env
);
3343 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3344 tcg_gen_st_i32(cpu_tmp32
, r_tsptr
,
3345 offsetof(trap_state
, tt
));
3346 tcg_temp_free_ptr(r_tsptr
);
3353 r_tickptr
= tcg_temp_new_ptr();
3354 tcg_gen_ld_ptr(r_tickptr
, cpu_env
,
3355 offsetof(CPUState
, tick
));
3356 gen_helper_tick_set_count(r_tickptr
,
3358 tcg_temp_free_ptr(r_tickptr
);
3362 tcg_gen_mov_tl(cpu_tbr
, cpu_tmp0
);
3365 save_state(dc
, cpu_cond
);
3366 gen_helper_wrpstate(cpu_tmp0
);
3372 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3373 tcg_gen_st_i32(cpu_tmp32
, cpu_env
,
3374 offsetof(CPUSPARCState
, tl
));
3377 gen_helper_wrpil(cpu_tmp0
);
3380 gen_helper_wrcwp(cpu_tmp0
);
3383 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3384 tcg_gen_st_i32(cpu_tmp32
, cpu_env
,
3385 offsetof(CPUSPARCState
,
3388 case 11: // canrestore
3389 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3390 tcg_gen_st_i32(cpu_tmp32
, cpu_env
,
3391 offsetof(CPUSPARCState
,
3394 case 12: // cleanwin
3395 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3396 tcg_gen_st_i32(cpu_tmp32
, cpu_env
,
3397 offsetof(CPUSPARCState
,
3400 case 13: // otherwin
3401 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3402 tcg_gen_st_i32(cpu_tmp32
, cpu_env
,
3403 offsetof(CPUSPARCState
,
3407 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3408 tcg_gen_st_i32(cpu_tmp32
, cpu_env
,
3409 offsetof(CPUSPARCState
,
3412 case 16: // UA2005 gl
3413 CHECK_IU_FEATURE(dc
, GL
);
3414 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3415 tcg_gen_st_i32(cpu_tmp32
, cpu_env
,
3416 offsetof(CPUSPARCState
, gl
));
3418 case 26: // UA2005 strand status
3419 CHECK_IU_FEATURE(dc
, HYPV
);
3420 if (!hypervisor(dc
))
3422 tcg_gen_mov_tl(cpu_ssr
, cpu_tmp0
);
3428 tcg_gen_trunc_tl_i32(cpu_tmp32
, cpu_tmp0
);
3429 if (dc
->def
->nwindows
!= 32)
3430 tcg_gen_andi_tl(cpu_tmp32
, cpu_tmp32
,
3431 (1 << dc
->def
->nwindows
) - 1);
3432 tcg_gen_mov_i32(cpu_wim
, cpu_tmp32
);
3436 case 0x33: /* wrtbr, UA2005 wrhpr */
3438 #ifndef TARGET_SPARC64
3439 if (!supervisor(dc
))
3441 tcg_gen_xor_tl(cpu_tbr
, cpu_src1
, cpu_src2
);
3443 CHECK_IU_FEATURE(dc
, HYPV
);
3444 if (!hypervisor(dc
))
3446 tcg_gen_xor_tl(cpu_tmp0
, cpu_src1
, cpu_src2
);
3449 // XXX gen_op_wrhpstate();
3450 save_state(dc
, cpu_cond
);
3456 // XXX gen_op_wrhtstate();
3459 tcg_gen_mov_tl(cpu_hintp
, cpu_tmp0
);
3462 tcg_gen_mov_tl(cpu_htba
, cpu_tmp0
);
3464 case 31: // hstick_cmpr
3468 tcg_gen_mov_tl(cpu_hstick_cmpr
, cpu_tmp0
);
3469 r_tickptr
= tcg_temp_new_ptr();
3470 tcg_gen_ld_ptr(r_tickptr
, cpu_env
,
3471 offsetof(CPUState
, hstick
));
3472 gen_helper_tick_set_limit(r_tickptr
,
3474 tcg_temp_free_ptr(r_tickptr
);
3477 case 6: // hver readonly
3485 #ifdef TARGET_SPARC64
3486 case 0x2c: /* V9 movcc */
3488 int cc
= GET_FIELD_SP(insn
, 11, 12);
3489 int cond
= GET_FIELD_SP(insn
, 14, 17);
3493 r_cond
= tcg_temp_new();
3494 if (insn
& (1 << 18)) {
3496 gen_cond(r_cond
, 0, cond
, dc
);
3498 gen_cond(r_cond
, 1, cond
, dc
);
3502 gen_fcond(r_cond
, cc
, cond
);
3505 l1
= gen_new_label();
3507 tcg_gen_brcondi_tl(TCG_COND_EQ
, r_cond
, 0, l1
);
3508 if (IS_IMM
) { /* immediate */
3511 simm
= GET_FIELD_SPs(insn
, 0, 10);
3512 r_const
= tcg_const_tl(simm
);
3513 gen_movl_TN_reg(rd
, r_const
);
3514 tcg_temp_free(r_const
);
3516 rs2
= GET_FIELD_SP(insn
, 0, 4);
3517 gen_movl_reg_TN(rs2
, cpu_tmp0
);
3518 gen_movl_TN_reg(rd
, cpu_tmp0
);
3521 tcg_temp_free(r_cond
);
3524 case 0x2d: /* V9 sdivx */
3525 gen_op_sdivx(cpu_dst
, cpu_src1
, cpu_src2
);
3526 gen_movl_TN_reg(rd
, cpu_dst
);
3528 case 0x2e: /* V9 popc */
3530 cpu_src2
= get_src2(insn
, cpu_src2
);
3531 gen_helper_popc(cpu_dst
, cpu_src2
);
3532 gen_movl_TN_reg(rd
, cpu_dst
);
3534 case 0x2f: /* V9 movr */
3536 int cond
= GET_FIELD_SP(insn
, 10, 12);
3539 cpu_src1
= get_src1(insn
, cpu_src1
);
3541 l1
= gen_new_label();
3543 tcg_gen_brcondi_tl(gen_tcg_cond_reg
[cond
],
3545 if (IS_IMM
) { /* immediate */
3548 simm
= GET_FIELD_SPs(insn
, 0, 9);
3549 r_const
= tcg_const_tl(simm
);
3550 gen_movl_TN_reg(rd
, r_const
);
3551 tcg_temp_free(r_const
);
3553 rs2
= GET_FIELD_SP(insn
, 0, 4);
3554 gen_movl_reg_TN(rs2
, cpu_tmp0
);
3555 gen_movl_TN_reg(rd
, cpu_tmp0
);
3565 } else if (xop
== 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3566 #ifdef TARGET_SPARC64
3567 int opf
= GET_FIELD_SP(insn
, 5, 13);
3568 rs1
= GET_FIELD(insn
, 13, 17);
3569 rs2
= GET_FIELD(insn
, 27, 31);
3570 if (gen_trap_ifnofpu(dc
, cpu_cond
))
3574 case 0x000: /* VIS I edge8cc */
3575 case 0x001: /* VIS II edge8n */
3576 case 0x002: /* VIS I edge8lcc */
3577 case 0x003: /* VIS II edge8ln */
3578 case 0x004: /* VIS I edge16cc */
3579 case 0x005: /* VIS II edge16n */
3580 case 0x006: /* VIS I edge16lcc */
3581 case 0x007: /* VIS II edge16ln */
3582 case 0x008: /* VIS I edge32cc */
3583 case 0x009: /* VIS II edge32n */
3584 case 0x00a: /* VIS I edge32lcc */
3585 case 0x00b: /* VIS II edge32ln */
3588 case 0x010: /* VIS I array8 */
3589 CHECK_FPU_FEATURE(dc
, VIS1
);
3590 cpu_src1
= get_src1(insn
, cpu_src1
);
3591 gen_movl_reg_TN(rs2
, cpu_src2
);
3592 gen_helper_array8(cpu_dst
, cpu_src1
, cpu_src2
);
3593 gen_movl_TN_reg(rd
, cpu_dst
);
3595 case 0x012: /* VIS I array16 */
3596 CHECK_FPU_FEATURE(dc
, VIS1
);
3597 cpu_src1
= get_src1(insn
, cpu_src1
);
3598 gen_movl_reg_TN(rs2
, cpu_src2
);
3599 gen_helper_array8(cpu_dst
, cpu_src1
, cpu_src2
);
3600 tcg_gen_shli_i64(cpu_dst
, cpu_dst
, 1);
3601 gen_movl_TN_reg(rd
, cpu_dst
);
3603 case 0x014: /* VIS I array32 */
3604 CHECK_FPU_FEATURE(dc
, VIS1
);
3605 cpu_src1
= get_src1(insn
, cpu_src1
);
3606 gen_movl_reg_TN(rs2
, cpu_src2
);
3607 gen_helper_array8(cpu_dst
, cpu_src1
, cpu_src2
);
3608 tcg_gen_shli_i64(cpu_dst
, cpu_dst
, 2);
3609 gen_movl_TN_reg(rd
, cpu_dst
);
3611 case 0x018: /* VIS I alignaddr */
3612 CHECK_FPU_FEATURE(dc
, VIS1
);
3613 cpu_src1
= get_src1(insn
, cpu_src1
);
3614 gen_movl_reg_TN(rs2
, cpu_src2
);
3615 gen_helper_alignaddr(cpu_dst
, cpu_src1
, cpu_src2
);
3616 gen_movl_TN_reg(rd
, cpu_dst
);
3618 case 0x019: /* VIS II bmask */
3619 case 0x01a: /* VIS I alignaddrl */
3622 case 0x020: /* VIS I fcmple16 */
3623 CHECK_FPU_FEATURE(dc
, VIS1
);
3624 gen_op_load_fpr_DT0(DFPREG(rs1
));
3625 gen_op_load_fpr_DT1(DFPREG(rs2
));
3626 gen_helper_fcmple16();
3627 gen_op_store_DT0_fpr(DFPREG(rd
));
3629 case 0x022: /* VIS I fcmpne16 */
3630 CHECK_FPU_FEATURE(dc
, VIS1
);
3631 gen_op_load_fpr_DT0(DFPREG(rs1
));
3632 gen_op_load_fpr_DT1(DFPREG(rs2
));
3633 gen_helper_fcmpne16();
3634 gen_op_store_DT0_fpr(DFPREG(rd
));
3636 case 0x024: /* VIS I fcmple32 */
3637 CHECK_FPU_FEATURE(dc
, VIS1
);
3638 gen_op_load_fpr_DT0(DFPREG(rs1
));
3639 gen_op_load_fpr_DT1(DFPREG(rs2
));
3640 gen_helper_fcmple32();
3641 gen_op_store_DT0_fpr(DFPREG(rd
));
3643 case 0x026: /* VIS I fcmpne32 */
3644 CHECK_FPU_FEATURE(dc
, VIS1
);
3645 gen_op_load_fpr_DT0(DFPREG(rs1
));
3646 gen_op_load_fpr_DT1(DFPREG(rs2
));
3647 gen_helper_fcmpne32();
3648 gen_op_store_DT0_fpr(DFPREG(rd
));
3650 case 0x028: /* VIS I fcmpgt16 */
3651 CHECK_FPU_FEATURE(dc
, VIS1
);
3652 gen_op_load_fpr_DT0(DFPREG(rs1
));
3653 gen_op_load_fpr_DT1(DFPREG(rs2
));
3654 gen_helper_fcmpgt16();
3655 gen_op_store_DT0_fpr(DFPREG(rd
));
3657 case 0x02a: /* VIS I fcmpeq16 */
3658 CHECK_FPU_FEATURE(dc
, VIS1
);
3659 gen_op_load_fpr_DT0(DFPREG(rs1
));
3660 gen_op_load_fpr_DT1(DFPREG(rs2
));
3661 gen_helper_fcmpeq16();
3662 gen_op_store_DT0_fpr(DFPREG(rd
));
3664 case 0x02c: /* VIS I fcmpgt32 */
3665 CHECK_FPU_FEATURE(dc
, VIS1
);
3666 gen_op_load_fpr_DT0(DFPREG(rs1
));
3667 gen_op_load_fpr_DT1(DFPREG(rs2
));
3668 gen_helper_fcmpgt32();
3669 gen_op_store_DT0_fpr(DFPREG(rd
));
3671 case 0x02e: /* VIS I fcmpeq32 */
3672 CHECK_FPU_FEATURE(dc
, VIS1
);
3673 gen_op_load_fpr_DT0(DFPREG(rs1
));
3674 gen_op_load_fpr_DT1(DFPREG(rs2
));
3675 gen_helper_fcmpeq32();
3676 gen_op_store_DT0_fpr(DFPREG(rd
));
3678 case 0x031: /* VIS I fmul8x16 */
3679 CHECK_FPU_FEATURE(dc
, VIS1
);
3680 gen_op_load_fpr_DT0(DFPREG(rs1
));
3681 gen_op_load_fpr_DT1(DFPREG(rs2
));
3682 gen_helper_fmul8x16();
3683 gen_op_store_DT0_fpr(DFPREG(rd
));
3685 case 0x033: /* VIS I fmul8x16au */
3686 CHECK_FPU_FEATURE(dc
, VIS1
);
3687 gen_op_load_fpr_DT0(DFPREG(rs1
));
3688 gen_op_load_fpr_DT1(DFPREG(rs2
));
3689 gen_helper_fmul8x16au();
3690 gen_op_store_DT0_fpr(DFPREG(rd
));
3692 case 0x035: /* VIS I fmul8x16al */
3693 CHECK_FPU_FEATURE(dc
, VIS1
);
3694 gen_op_load_fpr_DT0(DFPREG(rs1
));
3695 gen_op_load_fpr_DT1(DFPREG(rs2
));
3696 gen_helper_fmul8x16al();
3697 gen_op_store_DT0_fpr(DFPREG(rd
));
3699 case 0x036: /* VIS I fmul8sux16 */
3700 CHECK_FPU_FEATURE(dc
, VIS1
);
3701 gen_op_load_fpr_DT0(DFPREG(rs1
));
3702 gen_op_load_fpr_DT1(DFPREG(rs2
));
3703 gen_helper_fmul8sux16();
3704 gen_op_store_DT0_fpr(DFPREG(rd
));
3706 case 0x037: /* VIS I fmul8ulx16 */
3707 CHECK_FPU_FEATURE(dc
, VIS1
);
3708 gen_op_load_fpr_DT0(DFPREG(rs1
));
3709 gen_op_load_fpr_DT1(DFPREG(rs2
));
3710 gen_helper_fmul8ulx16();
3711 gen_op_store_DT0_fpr(DFPREG(rd
));
3713 case 0x038: /* VIS I fmuld8sux16 */
3714 CHECK_FPU_FEATURE(dc
, VIS1
);
3715 gen_op_load_fpr_DT0(DFPREG(rs1
));
3716 gen_op_load_fpr_DT1(DFPREG(rs2
));
3717 gen_helper_fmuld8sux16();
3718 gen_op_store_DT0_fpr(DFPREG(rd
));
3720 case 0x039: /* VIS I fmuld8ulx16 */
3721 CHECK_FPU_FEATURE(dc
, VIS1
);
3722 gen_op_load_fpr_DT0(DFPREG(rs1
));
3723 gen_op_load_fpr_DT1(DFPREG(rs2
));
3724 gen_helper_fmuld8ulx16();
3725 gen_op_store_DT0_fpr(DFPREG(rd
));
3727 case 0x03a: /* VIS I fpack32 */
3728 case 0x03b: /* VIS I fpack16 */
3729 case 0x03d: /* VIS I fpackfix */
3730 case 0x03e: /* VIS I pdist */
3733 case 0x048: /* VIS I faligndata */
3734 CHECK_FPU_FEATURE(dc
, VIS1
);
3735 gen_op_load_fpr_DT0(DFPREG(rs1
));
3736 gen_op_load_fpr_DT1(DFPREG(rs2
));
3737 gen_helper_faligndata();
3738 gen_op_store_DT0_fpr(DFPREG(rd
));
3740 case 0x04b: /* VIS I fpmerge */
3741 CHECK_FPU_FEATURE(dc
, VIS1
);
3742 gen_op_load_fpr_DT0(DFPREG(rs1
));
3743 gen_op_load_fpr_DT1(DFPREG(rs2
));
3744 gen_helper_fpmerge();
3745 gen_op_store_DT0_fpr(DFPREG(rd
));
3747 case 0x04c: /* VIS II bshuffle */
3750 case 0x04d: /* VIS I fexpand */
3751 CHECK_FPU_FEATURE(dc
, VIS1
);
3752 gen_op_load_fpr_DT0(DFPREG(rs1
));
3753 gen_op_load_fpr_DT1(DFPREG(rs2
));
3754 gen_helper_fexpand();
3755 gen_op_store_DT0_fpr(DFPREG(rd
));
3757 case 0x050: /* VIS I fpadd16 */
3758 CHECK_FPU_FEATURE(dc
, VIS1
);
3759 gen_op_load_fpr_DT0(DFPREG(rs1
));
3760 gen_op_load_fpr_DT1(DFPREG(rs2
));
3761 gen_helper_fpadd16();
3762 gen_op_store_DT0_fpr(DFPREG(rd
));
3764 case 0x051: /* VIS I fpadd16s */
3765 CHECK_FPU_FEATURE(dc
, VIS1
);
3766 gen_helper_fpadd16s(cpu_fpr
[rd
],
3767 cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3769 case 0x052: /* VIS I fpadd32 */
3770 CHECK_FPU_FEATURE(dc
, VIS1
);
3771 gen_op_load_fpr_DT0(DFPREG(rs1
));
3772 gen_op_load_fpr_DT1(DFPREG(rs2
));
3773 gen_helper_fpadd32();
3774 gen_op_store_DT0_fpr(DFPREG(rd
));
3776 case 0x053: /* VIS I fpadd32s */
3777 CHECK_FPU_FEATURE(dc
, VIS1
);
3778 gen_helper_fpadd32s(cpu_fpr
[rd
],
3779 cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3781 case 0x054: /* VIS I fpsub16 */
3782 CHECK_FPU_FEATURE(dc
, VIS1
);
3783 gen_op_load_fpr_DT0(DFPREG(rs1
));
3784 gen_op_load_fpr_DT1(DFPREG(rs2
));
3785 gen_helper_fpsub16();
3786 gen_op_store_DT0_fpr(DFPREG(rd
));
3788 case 0x055: /* VIS I fpsub16s */
3789 CHECK_FPU_FEATURE(dc
, VIS1
);
3790 gen_helper_fpsub16s(cpu_fpr
[rd
],
3791 cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3793 case 0x056: /* VIS I fpsub32 */
3794 CHECK_FPU_FEATURE(dc
, VIS1
);
3795 gen_op_load_fpr_DT0(DFPREG(rs1
));
3796 gen_op_load_fpr_DT1(DFPREG(rs2
));
3797 gen_helper_fpsub32();
3798 gen_op_store_DT0_fpr(DFPREG(rd
));
3800 case 0x057: /* VIS I fpsub32s */
3801 CHECK_FPU_FEATURE(dc
, VIS1
);
3802 gen_helper_fpsub32s(cpu_fpr
[rd
],
3803 cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3805 case 0x060: /* VIS I fzero */
3806 CHECK_FPU_FEATURE(dc
, VIS1
);
3807 tcg_gen_movi_i32(cpu_fpr
[DFPREG(rd
)], 0);
3808 tcg_gen_movi_i32(cpu_fpr
[DFPREG(rd
) + 1], 0);
3810 case 0x061: /* VIS I fzeros */
3811 CHECK_FPU_FEATURE(dc
, VIS1
);
3812 tcg_gen_movi_i32(cpu_fpr
[rd
], 0);
3814 case 0x062: /* VIS I fnor */
3815 CHECK_FPU_FEATURE(dc
, VIS1
);
3816 tcg_gen_nor_i32(cpu_tmp32
, cpu_fpr
[DFPREG(rs1
)],
3817 cpu_fpr
[DFPREG(rs2
)]);
3818 tcg_gen_nor_i32(cpu_tmp32
, cpu_fpr
[DFPREG(rs1
) + 1],
3819 cpu_fpr
[DFPREG(rs2
) + 1]);
3821 case 0x063: /* VIS I fnors */
3822 CHECK_FPU_FEATURE(dc
, VIS1
);
3823 tcg_gen_nor_i32(cpu_tmp32
, cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3825 case 0x064: /* VIS I fandnot2 */
3826 CHECK_FPU_FEATURE(dc
, VIS1
);
3827 tcg_gen_andc_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs1
)],
3828 cpu_fpr
[DFPREG(rs2
)]);
3829 tcg_gen_andc_i32(cpu_fpr
[DFPREG(rd
) + 1],
3830 cpu_fpr
[DFPREG(rs1
) + 1],
3831 cpu_fpr
[DFPREG(rs2
) + 1]);
3833 case 0x065: /* VIS I fandnot2s */
3834 CHECK_FPU_FEATURE(dc
, VIS1
);
3835 tcg_gen_andc_i32(cpu_fpr
[rd
], cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3837 case 0x066: /* VIS I fnot2 */
3838 CHECK_FPU_FEATURE(dc
, VIS1
);
3839 tcg_gen_not_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs2
)]);
3840 tcg_gen_not_i32(cpu_fpr
[DFPREG(rd
) + 1],
3841 cpu_fpr
[DFPREG(rs2
) + 1]);
3843 case 0x067: /* VIS I fnot2s */
3844 CHECK_FPU_FEATURE(dc
, VIS1
);
3845 tcg_gen_not_i32(cpu_fpr
[rd
], cpu_fpr
[rs2
]);
3847 case 0x068: /* VIS I fandnot1 */
3848 CHECK_FPU_FEATURE(dc
, VIS1
);
3849 tcg_gen_andc_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs2
)],
3850 cpu_fpr
[DFPREG(rs1
)]);
3851 tcg_gen_andc_i32(cpu_fpr
[DFPREG(rd
) + 1],
3852 cpu_fpr
[DFPREG(rs2
) + 1],
3853 cpu_fpr
[DFPREG(rs1
) + 1]);
3855 case 0x069: /* VIS I fandnot1s */
3856 CHECK_FPU_FEATURE(dc
, VIS1
);
3857 tcg_gen_andc_i32(cpu_fpr
[rd
], cpu_fpr
[rs2
], cpu_fpr
[rs1
]);
3859 case 0x06a: /* VIS I fnot1 */
3860 CHECK_FPU_FEATURE(dc
, VIS1
);
3861 tcg_gen_not_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs1
)]);
3862 tcg_gen_not_i32(cpu_fpr
[DFPREG(rd
) + 1],
3863 cpu_fpr
[DFPREG(rs1
) + 1]);
3865 case 0x06b: /* VIS I fnot1s */
3866 CHECK_FPU_FEATURE(dc
, VIS1
);
3867 tcg_gen_not_i32(cpu_fpr
[rd
], cpu_fpr
[rs1
]);
3869 case 0x06c: /* VIS I fxor */
3870 CHECK_FPU_FEATURE(dc
, VIS1
);
3871 tcg_gen_xor_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs1
)],
3872 cpu_fpr
[DFPREG(rs2
)]);
3873 tcg_gen_xor_i32(cpu_fpr
[DFPREG(rd
) + 1],
3874 cpu_fpr
[DFPREG(rs1
) + 1],
3875 cpu_fpr
[DFPREG(rs2
) + 1]);
3877 case 0x06d: /* VIS I fxors */
3878 CHECK_FPU_FEATURE(dc
, VIS1
);
3879 tcg_gen_xor_i32(cpu_fpr
[rd
], cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3881 case 0x06e: /* VIS I fnand */
3882 CHECK_FPU_FEATURE(dc
, VIS1
);
3883 tcg_gen_nand_i32(cpu_tmp32
, cpu_fpr
[DFPREG(rs1
)],
3884 cpu_fpr
[DFPREG(rs2
)]);
3885 tcg_gen_nand_i32(cpu_tmp32
, cpu_fpr
[DFPREG(rs1
) + 1],
3886 cpu_fpr
[DFPREG(rs2
) + 1]);
3888 case 0x06f: /* VIS I fnands */
3889 CHECK_FPU_FEATURE(dc
, VIS1
);
3890 tcg_gen_nand_i32(cpu_tmp32
, cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3892 case 0x070: /* VIS I fand */
3893 CHECK_FPU_FEATURE(dc
, VIS1
);
3894 tcg_gen_and_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs1
)],
3895 cpu_fpr
[DFPREG(rs2
)]);
3896 tcg_gen_and_i32(cpu_fpr
[DFPREG(rd
) + 1],
3897 cpu_fpr
[DFPREG(rs1
) + 1],
3898 cpu_fpr
[DFPREG(rs2
) + 1]);
3900 case 0x071: /* VIS I fands */
3901 CHECK_FPU_FEATURE(dc
, VIS1
);
3902 tcg_gen_and_i32(cpu_fpr
[rd
], cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3904 case 0x072: /* VIS I fxnor */
3905 CHECK_FPU_FEATURE(dc
, VIS1
);
3906 tcg_gen_xori_i32(cpu_tmp32
, cpu_fpr
[DFPREG(rs2
)], -1);
3907 tcg_gen_xor_i32(cpu_fpr
[DFPREG(rd
)], cpu_tmp32
,
3908 cpu_fpr
[DFPREG(rs1
)]);
3909 tcg_gen_xori_i32(cpu_tmp32
, cpu_fpr
[DFPREG(rs2
) + 1], -1);
3910 tcg_gen_xor_i32(cpu_fpr
[DFPREG(rd
) + 1], cpu_tmp32
,
3911 cpu_fpr
[DFPREG(rs1
) + 1]);
3913 case 0x073: /* VIS I fxnors */
3914 CHECK_FPU_FEATURE(dc
, VIS1
);
3915 tcg_gen_xori_i32(cpu_tmp32
, cpu_fpr
[rs2
], -1);
3916 tcg_gen_xor_i32(cpu_fpr
[rd
], cpu_tmp32
, cpu_fpr
[rs1
]);
3918 case 0x074: /* VIS I fsrc1 */
3919 CHECK_FPU_FEATURE(dc
, VIS1
);
3920 tcg_gen_mov_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs1
)]);
3921 tcg_gen_mov_i32(cpu_fpr
[DFPREG(rd
) + 1],
3922 cpu_fpr
[DFPREG(rs1
) + 1]);
3924 case 0x075: /* VIS I fsrc1s */
3925 CHECK_FPU_FEATURE(dc
, VIS1
);
3926 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_fpr
[rs1
]);
3928 case 0x076: /* VIS I fornot2 */
3929 CHECK_FPU_FEATURE(dc
, VIS1
);
3930 tcg_gen_orc_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs1
)],
3931 cpu_fpr
[DFPREG(rs2
)]);
3932 tcg_gen_orc_i32(cpu_fpr
[DFPREG(rd
) + 1],
3933 cpu_fpr
[DFPREG(rs1
) + 1],
3934 cpu_fpr
[DFPREG(rs2
) + 1]);
3936 case 0x077: /* VIS I fornot2s */
3937 CHECK_FPU_FEATURE(dc
, VIS1
);
3938 tcg_gen_orc_i32(cpu_fpr
[rd
], cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3940 case 0x078: /* VIS I fsrc2 */
3941 CHECK_FPU_FEATURE(dc
, VIS1
);
3942 gen_op_load_fpr_DT0(DFPREG(rs2
));
3943 gen_op_store_DT0_fpr(DFPREG(rd
));
3945 case 0x079: /* VIS I fsrc2s */
3946 CHECK_FPU_FEATURE(dc
, VIS1
);
3947 tcg_gen_mov_i32(cpu_fpr
[rd
], cpu_fpr
[rs2
]);
3949 case 0x07a: /* VIS I fornot1 */
3950 CHECK_FPU_FEATURE(dc
, VIS1
);
3951 tcg_gen_orc_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs2
)],
3952 cpu_fpr
[DFPREG(rs1
)]);
3953 tcg_gen_orc_i32(cpu_fpr
[DFPREG(rd
) + 1],
3954 cpu_fpr
[DFPREG(rs2
) + 1],
3955 cpu_fpr
[DFPREG(rs1
) + 1]);
3957 case 0x07b: /* VIS I fornot1s */
3958 CHECK_FPU_FEATURE(dc
, VIS1
);
3959 tcg_gen_orc_i32(cpu_fpr
[rd
], cpu_fpr
[rs2
], cpu_fpr
[rs1
]);
3961 case 0x07c: /* VIS I for */
3962 CHECK_FPU_FEATURE(dc
, VIS1
);
3963 tcg_gen_or_i32(cpu_fpr
[DFPREG(rd
)], cpu_fpr
[DFPREG(rs1
)],
3964 cpu_fpr
[DFPREG(rs2
)]);
3965 tcg_gen_or_i32(cpu_fpr
[DFPREG(rd
) + 1],
3966 cpu_fpr
[DFPREG(rs1
) + 1],
3967 cpu_fpr
[DFPREG(rs2
) + 1]);
3969 case 0x07d: /* VIS I fors */
3970 CHECK_FPU_FEATURE(dc
, VIS1
);
3971 tcg_gen_or_i32(cpu_fpr
[rd
], cpu_fpr
[rs1
], cpu_fpr
[rs2
]);
3973 case 0x07e: /* VIS I fone */
3974 CHECK_FPU_FEATURE(dc
, VIS1
);
3975 tcg_gen_movi_i32(cpu_fpr
[DFPREG(rd
)], -1);
3976 tcg_gen_movi_i32(cpu_fpr
[DFPREG(rd
) + 1], -1);
3978 case 0x07f: /* VIS I fones */
3979 CHECK_FPU_FEATURE(dc
, VIS1
);
3980 tcg_gen_movi_i32(cpu_fpr
[rd
], -1);
3982 case 0x080: /* VIS I shutdown */
3983 case 0x081: /* VIS II siam */
3992 } else if (xop
== 0x37) { /* V8 CPop2, V9 impdep2 */
3993 #ifdef TARGET_SPARC64
3998 #ifdef TARGET_SPARC64
3999 } else if (xop
== 0x39) { /* V9 return */
4002 save_state(dc
, cpu_cond
);
4003 cpu_src1
= get_src1(insn
, cpu_src1
);
4004 if (IS_IMM
) { /* immediate */
4005 simm
= GET_FIELDs(insn
, 19, 31);
4006 tcg_gen_addi_tl(cpu_dst
, cpu_src1
, simm
);
4007 } else { /* register */
4008 rs2
= GET_FIELD(insn
, 27, 31);
4010 gen_movl_reg_TN(rs2
, cpu_src2
);
4011 tcg_gen_add_tl(cpu_dst
, cpu_src1
, cpu_src2
);
4013 tcg_gen_mov_tl(cpu_dst
, cpu_src1
);
4015 gen_helper_restore();
4016 gen_mov_pc_npc(dc
, cpu_cond
);
4017 r_const
= tcg_const_i32(3);
4018 gen_helper_check_align(cpu_dst
, r_const
);
4019 tcg_temp_free_i32(r_const
);
4020 tcg_gen_mov_tl(cpu_npc
, cpu_dst
);
4021 dc
->npc
= DYNAMIC_PC
;
4025 cpu_src1
= get_src1(insn
, cpu_src1
);
4026 if (IS_IMM
) { /* immediate */
4027 simm
= GET_FIELDs(insn
, 19, 31);
4028 tcg_gen_addi_tl(cpu_dst
, cpu_src1
, simm
);
4029 } else { /* register */
4030 rs2
= GET_FIELD(insn
, 27, 31);
4032 gen_movl_reg_TN(rs2
, cpu_src2
);
4033 tcg_gen_add_tl(cpu_dst
, cpu_src1
, cpu_src2
);
4035 tcg_gen_mov_tl(cpu_dst
, cpu_src1
);
4038 case 0x38: /* jmpl */
4043 r_pc
= tcg_const_tl(dc
->pc
);
4044 gen_movl_TN_reg(rd
, r_pc
);
4045 tcg_temp_free(r_pc
);
4046 gen_mov_pc_npc(dc
, cpu_cond
);
4047 r_const
= tcg_const_i32(3);
4048 gen_helper_check_align(cpu_dst
, r_const
);
4049 tcg_temp_free_i32(r_const
);
4050 tcg_gen_mov_tl(cpu_npc
, cpu_dst
);
4051 dc
->npc
= DYNAMIC_PC
;
4054 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4055 case 0x39: /* rett, V9 return */
4059 if (!supervisor(dc
))
4061 gen_mov_pc_npc(dc
, cpu_cond
);
4062 r_const
= tcg_const_i32(3);
4063 gen_helper_check_align(cpu_dst
, r_const
);
4064 tcg_temp_free_i32(r_const
);
4065 tcg_gen_mov_tl(cpu_npc
, cpu_dst
);
4066 dc
->npc
= DYNAMIC_PC
;
4071 case 0x3b: /* flush */
4072 if (!((dc
)->def
->features
& CPU_FEATURE_FLUSH
))
4074 gen_helper_flush(cpu_dst
);
4076 case 0x3c: /* save */
4077 save_state(dc
, cpu_cond
);
4079 gen_movl_TN_reg(rd
, cpu_dst
);
4081 case 0x3d: /* restore */
4082 save_state(dc
, cpu_cond
);
4083 gen_helper_restore();
4084 gen_movl_TN_reg(rd
, cpu_dst
);
4086 #if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
4087 case 0x3e: /* V9 done/retry */
4091 if (!supervisor(dc
))
4093 dc
->npc
= DYNAMIC_PC
;
4094 dc
->pc
= DYNAMIC_PC
;
4098 if (!supervisor(dc
))
4100 dc
->npc
= DYNAMIC_PC
;
4101 dc
->pc
= DYNAMIC_PC
;
4117 case 3: /* load/store instructions */
4119 unsigned int xop
= GET_FIELD(insn
, 7, 12);
4121 /* flush pending conditional evaluations before exposing
4123 if (dc
->cc_op
!= CC_OP_FLAGS
) {
4124 dc
->cc_op
= CC_OP_FLAGS
;
4125 gen_helper_compute_psr();
4127 cpu_src1
= get_src1(insn
, cpu_src1
);
4128 if (xop
== 0x3c || xop
== 0x3e) { // V9 casa/casxa
4129 rs2
= GET_FIELD(insn
, 27, 31);
4130 gen_movl_reg_TN(rs2
, cpu_src2
);
4131 tcg_gen_mov_tl(cpu_addr
, cpu_src1
);
4132 } else if (IS_IMM
) { /* immediate */
4133 simm
= GET_FIELDs(insn
, 19, 31);
4134 tcg_gen_addi_tl(cpu_addr
, cpu_src1
, simm
);
4135 } else { /* register */
4136 rs2
= GET_FIELD(insn
, 27, 31);
4138 gen_movl_reg_TN(rs2
, cpu_src2
);
4139 tcg_gen_add_tl(cpu_addr
, cpu_src1
, cpu_src2
);
4141 tcg_gen_mov_tl(cpu_addr
, cpu_src1
);
4143 if (xop
< 4 || (xop
> 7 && xop
< 0x14 && xop
!= 0x0e) ||
4144 (xop
> 0x17 && xop
<= 0x1d ) ||
4145 (xop
> 0x2c && xop
<= 0x33) || xop
== 0x1f || xop
== 0x3d) {
4147 case 0x0: /* ld, V9 lduw, load unsigned word */
4148 gen_address_mask(dc
, cpu_addr
);
4149 tcg_gen_qemu_ld32u(cpu_val
, cpu_addr
, dc
->mem_idx
);
4151 case 0x1: /* ldub, load unsigned byte */
4152 gen_address_mask(dc
, cpu_addr
);
4153 tcg_gen_qemu_ld8u(cpu_val
, cpu_addr
, dc
->mem_idx
);
4155 case 0x2: /* lduh, load unsigned halfword */
4156 gen_address_mask(dc
, cpu_addr
);
4157 tcg_gen_qemu_ld16u(cpu_val
, cpu_addr
, dc
->mem_idx
);
4159 case 0x3: /* ldd, load double word */
4165 save_state(dc
, cpu_cond
);
4166 r_const
= tcg_const_i32(7);
4167 gen_helper_check_align(cpu_addr
, r_const
); // XXX remove
4168 tcg_temp_free_i32(r_const
);
4169 gen_address_mask(dc
, cpu_addr
);
4170 tcg_gen_qemu_ld64(cpu_tmp64
, cpu_addr
, dc
->mem_idx
);
4171 tcg_gen_trunc_i64_tl(cpu_tmp0
, cpu_tmp64
);
4172 tcg_gen_andi_tl(cpu_tmp0
, cpu_tmp0
, 0xffffffffULL
);
4173 gen_movl_TN_reg(rd
+ 1, cpu_tmp0
);
4174 tcg_gen_shri_i64(cpu_tmp64
, cpu_tmp64
, 32);
4175 tcg_gen_trunc_i64_tl(cpu_val
, cpu_tmp64
);
4176 tcg_gen_andi_tl(cpu_val
, cpu_val
, 0xffffffffULL
);
4179 case 0x9: /* ldsb, load signed byte */
4180 gen_address_mask(dc
, cpu_addr
);
4181 tcg_gen_qemu_ld8s(cpu_val
, cpu_addr
, dc
->mem_idx
);
4183 case 0xa: /* ldsh, load signed halfword */
4184 gen_address_mask(dc
, cpu_addr
);
4185 tcg_gen_qemu_ld16s(cpu_val
, cpu_addr
, dc
->mem_idx
);
4187 case 0xd: /* ldstub -- XXX: should be atomically */
4191 gen_address_mask(dc
, cpu_addr
);
4192 tcg_gen_qemu_ld8s(cpu_val
, cpu_addr
, dc
->mem_idx
);
4193 r_const
= tcg_const_tl(0xff);
4194 tcg_gen_qemu_st8(r_const
, cpu_addr
, dc
->mem_idx
);
4195 tcg_temp_free(r_const
);
4198 case 0x0f: /* swap, swap register with memory. Also
4200 CHECK_IU_FEATURE(dc
, SWAP
);
4201 gen_movl_reg_TN(rd
, cpu_val
);
4202 gen_address_mask(dc
, cpu_addr
);
4203 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_addr
, dc
->mem_idx
);
4204 tcg_gen_qemu_st32(cpu_val
, cpu_addr
, dc
->mem_idx
);
4205 tcg_gen_mov_tl(cpu_val
, cpu_tmp0
);
4207 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4208 case 0x10: /* lda, V9 lduwa, load word alternate */
4209 #ifndef TARGET_SPARC64
4212 if (!supervisor(dc
))
4215 save_state(dc
, cpu_cond
);
4216 gen_ld_asi(cpu_val
, cpu_addr
, insn
, 4, 0);
4218 case 0x11: /* lduba, load unsigned byte alternate */
4219 #ifndef TARGET_SPARC64
4222 if (!supervisor(dc
))
4225 save_state(dc
, cpu_cond
);
4226 gen_ld_asi(cpu_val
, cpu_addr
, insn
, 1, 0);
4228 case 0x12: /* lduha, load unsigned halfword alternate */
4229 #ifndef TARGET_SPARC64
4232 if (!supervisor(dc
))
4235 save_state(dc
, cpu_cond
);
4236 gen_ld_asi(cpu_val
, cpu_addr
, insn
, 2, 0);
4238 case 0x13: /* ldda, load double word alternate */
4239 #ifndef TARGET_SPARC64
4242 if (!supervisor(dc
))
4247 save_state(dc
, cpu_cond
);
4248 gen_ldda_asi(cpu_val
, cpu_addr
, insn
, rd
);
4250 case 0x19: /* ldsba, load signed byte alternate */
4251 #ifndef TARGET_SPARC64
4254 if (!supervisor(dc
))
4257 save_state(dc
, cpu_cond
);
4258 gen_ld_asi(cpu_val
, cpu_addr
, insn
, 1, 1);
4260 case 0x1a: /* ldsha, load signed halfword alternate */
4261 #ifndef TARGET_SPARC64
4264 if (!supervisor(dc
))
4267 save_state(dc
, cpu_cond
);
4268 gen_ld_asi(cpu_val
, cpu_addr
, insn
, 2, 1);
4270 case 0x1d: /* ldstuba -- XXX: should be atomically */
4271 #ifndef TARGET_SPARC64
4274 if (!supervisor(dc
))
4277 save_state(dc
, cpu_cond
);
4278 gen_ldstub_asi(cpu_val
, cpu_addr
, insn
);
4280 case 0x1f: /* swapa, swap reg with alt. memory. Also
4282 CHECK_IU_FEATURE(dc
, SWAP
);
4283 #ifndef TARGET_SPARC64
4286 if (!supervisor(dc
))
4289 save_state(dc
, cpu_cond
);
4290 gen_movl_reg_TN(rd
, cpu_val
);
4291 gen_swap_asi(cpu_val
, cpu_addr
, insn
);
4294 #ifndef TARGET_SPARC64
4295 case 0x30: /* ldc */
4296 case 0x31: /* ldcsr */
4297 case 0x33: /* lddc */
4301 #ifdef TARGET_SPARC64
4302 case 0x08: /* V9 ldsw */
4303 gen_address_mask(dc
, cpu_addr
);
4304 tcg_gen_qemu_ld32s(cpu_val
, cpu_addr
, dc
->mem_idx
);
4306 case 0x0b: /* V9 ldx */
4307 gen_address_mask(dc
, cpu_addr
);
4308 tcg_gen_qemu_ld64(cpu_val
, cpu_addr
, dc
->mem_idx
);
4310 case 0x18: /* V9 ldswa */
4311 save_state(dc
, cpu_cond
);
4312 gen_ld_asi(cpu_val
, cpu_addr
, insn
, 4, 1);
4314 case 0x1b: /* V9 ldxa */
4315 save_state(dc
, cpu_cond
);
4316 gen_ld_asi(cpu_val
, cpu_addr
, insn
, 8, 0);
4318 case 0x2d: /* V9 prefetch, no effect */
4320 case 0x30: /* V9 ldfa */
4321 save_state(dc
, cpu_cond
);
4322 gen_ldf_asi(cpu_addr
, insn
, 4, rd
);
4324 case 0x33: /* V9 lddfa */
4325 save_state(dc
, cpu_cond
);
4326 gen_ldf_asi(cpu_addr
, insn
, 8, DFPREG(rd
));
4328 case 0x3d: /* V9 prefetcha, no effect */
4330 case 0x32: /* V9 ldqfa */
4331 CHECK_FPU_FEATURE(dc
, FLOAT128
);
4332 save_state(dc
, cpu_cond
);
4333 gen_ldf_asi(cpu_addr
, insn
, 16, QFPREG(rd
));
4339 gen_movl_TN_reg(rd
, cpu_val
);
4340 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4343 } else if (xop
>= 0x20 && xop
< 0x24) {
4344 if (gen_trap_ifnofpu(dc
, cpu_cond
))
4346 save_state(dc
, cpu_cond
);
4348 case 0x20: /* ldf, load fpreg */
4349 gen_address_mask(dc
, cpu_addr
);
4350 tcg_gen_qemu_ld32u(cpu_tmp0
, cpu_addr
, dc
->mem_idx
);
4351 tcg_gen_trunc_tl_i32(cpu_fpr
[rd
], cpu_tmp0
);
4353 case 0x21: /* ldfsr, V9 ldxfsr */
4354 #ifdef TARGET_SPARC64
4355 gen_address_mask(dc
, cpu_addr
);
4357 tcg_gen_qemu_ld64(cpu_tmp64
, cpu_addr
, dc
->mem_idx
);
4358 gen_helper_ldxfsr(cpu_tmp64
);
4362 tcg_gen_qemu_ld32u(cpu_tmp32
, cpu_addr
, dc
->mem_idx
);
4363 gen_helper_ldfsr(cpu_tmp32
);
4367 case 0x22: /* ldqf, load quad fpreg */
4371 CHECK_FPU_FEATURE(dc
, FLOAT128
);
4372 r_const
= tcg_const_i32(dc
->mem_idx
);
4373 gen_helper_ldqf(cpu_addr
, r_const
);
4374 tcg_temp_free_i32(r_const
);
4375 gen_op_store_QT0_fpr(QFPREG(rd
));
4378 case 0x23: /* lddf, load double fpreg */
4382 r_const
= tcg_const_i32(dc
->mem_idx
);
4383 gen_helper_lddf(cpu_addr
, r_const
);
4384 tcg_temp_free_i32(r_const
);
4385 gen_op_store_DT0_fpr(DFPREG(rd
));
4391 } else if (xop
< 8 || (xop
>= 0x14 && xop
< 0x18) ||
4392 xop
== 0xe || xop
== 0x1e) {
4393 gen_movl_reg_TN(rd
, cpu_val
);
4395 case 0x4: /* st, store word */
4396 gen_address_mask(dc
, cpu_addr
);
4397 tcg_gen_qemu_st32(cpu_val
, cpu_addr
, dc
->mem_idx
);
4399 case 0x5: /* stb, store byte */
4400 gen_address_mask(dc
, cpu_addr
);
4401 tcg_gen_qemu_st8(cpu_val
, cpu_addr
, dc
->mem_idx
);
4403 case 0x6: /* sth, store halfword */
4404 gen_address_mask(dc
, cpu_addr
);
4405 tcg_gen_qemu_st16(cpu_val
, cpu_addr
, dc
->mem_idx
);
4407 case 0x7: /* std, store double word */
4413 save_state(dc
, cpu_cond
);
4414 gen_address_mask(dc
, cpu_addr
);
4415 r_const
= tcg_const_i32(7);
4416 gen_helper_check_align(cpu_addr
, r_const
); // XXX remove
4417 tcg_temp_free_i32(r_const
);
4418 gen_movl_reg_TN(rd
+ 1, cpu_tmp0
);
4419 tcg_gen_concat_tl_i64(cpu_tmp64
, cpu_tmp0
, cpu_val
);
4420 tcg_gen_qemu_st64(cpu_tmp64
, cpu_addr
, dc
->mem_idx
);
4423 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4424 case 0x14: /* sta, V9 stwa, store word alternate */
4425 #ifndef TARGET_SPARC64
4428 if (!supervisor(dc
))
4431 save_state(dc
, cpu_cond
);
4432 gen_st_asi(cpu_val
, cpu_addr
, insn
, 4);
4434 case 0x15: /* stba, store byte alternate */
4435 #ifndef TARGET_SPARC64
4438 if (!supervisor(dc
))
4441 save_state(dc
, cpu_cond
);
4442 gen_st_asi(cpu_val
, cpu_addr
, insn
, 1);
4444 case 0x16: /* stha, store halfword alternate */
4445 #ifndef TARGET_SPARC64
4448 if (!supervisor(dc
))
4451 save_state(dc
, cpu_cond
);
4452 gen_st_asi(cpu_val
, cpu_addr
, insn
, 2);
4454 case 0x17: /* stda, store double word alternate */
4455 #ifndef TARGET_SPARC64
4458 if (!supervisor(dc
))
4464 save_state(dc
, cpu_cond
);
4465 gen_stda_asi(cpu_val
, cpu_addr
, insn
, rd
);
4469 #ifdef TARGET_SPARC64
4470 case 0x0e: /* V9 stx */
4471 gen_address_mask(dc
, cpu_addr
);
4472 tcg_gen_qemu_st64(cpu_val
, cpu_addr
, dc
->mem_idx
);
4474 case 0x1e: /* V9 stxa */
4475 save_state(dc
, cpu_cond
);
4476 gen_st_asi(cpu_val
, cpu_addr
, insn
, 8);
4482 } else if (xop
> 0x23 && xop
< 0x28) {
4483 if (gen_trap_ifnofpu(dc
, cpu_cond
))
4485 save_state(dc
, cpu_cond
);
4487 case 0x24: /* stf, store fpreg */
4488 gen_address_mask(dc
, cpu_addr
);
4489 tcg_gen_ext_i32_tl(cpu_tmp0
, cpu_fpr
[rd
]);
4490 tcg_gen_qemu_st32(cpu_tmp0
, cpu_addr
, dc
->mem_idx
);
4492 case 0x25: /* stfsr, V9 stxfsr */
4493 #ifdef TARGET_SPARC64
4494 gen_address_mask(dc
, cpu_addr
);
4495 tcg_gen_ld_i64(cpu_tmp64
, cpu_env
, offsetof(CPUState
, fsr
));
4497 tcg_gen_qemu_st64(cpu_tmp64
, cpu_addr
, dc
->mem_idx
);
4499 tcg_gen_qemu_st32(cpu_tmp64
, cpu_addr
, dc
->mem_idx
);
4501 tcg_gen_ld_i32(cpu_tmp32
, cpu_env
, offsetof(CPUState
, fsr
));
4502 tcg_gen_qemu_st32(cpu_tmp32
, cpu_addr
, dc
->mem_idx
);
4506 #ifdef TARGET_SPARC64
4507 /* V9 stqf, store quad fpreg */
4511 CHECK_FPU_FEATURE(dc
, FLOAT128
);
4512 gen_op_load_fpr_QT0(QFPREG(rd
));
4513 r_const
= tcg_const_i32(dc
->mem_idx
);
4514 gen_helper_stqf(cpu_addr
, r_const
);
4515 tcg_temp_free_i32(r_const
);
4518 #else /* !TARGET_SPARC64 */
4519 /* stdfq, store floating point queue */
4520 #if defined(CONFIG_USER_ONLY)
4523 if (!supervisor(dc
))
4525 if (gen_trap_ifnofpu(dc
, cpu_cond
))
4530 case 0x27: /* stdf, store double fpreg */
4534 gen_op_load_fpr_DT0(DFPREG(rd
));
4535 r_const
= tcg_const_i32(dc
->mem_idx
);
4536 gen_helper_stdf(cpu_addr
, r_const
);
4537 tcg_temp_free_i32(r_const
);
4543 } else if (xop
> 0x33 && xop
< 0x3f) {
4544 save_state(dc
, cpu_cond
);
4546 #ifdef TARGET_SPARC64
4547 case 0x34: /* V9 stfa */
4548 gen_stf_asi(cpu_addr
, insn
, 4, rd
);
4550 case 0x36: /* V9 stqfa */
4554 CHECK_FPU_FEATURE(dc
, FLOAT128
);
4555 r_const
= tcg_const_i32(7);
4556 gen_helper_check_align(cpu_addr
, r_const
);
4557 tcg_temp_free_i32(r_const
);
4558 gen_op_load_fpr_QT0(QFPREG(rd
));
4559 gen_stf_asi(cpu_addr
, insn
, 16, QFPREG(rd
));
4562 case 0x37: /* V9 stdfa */
4563 gen_op_load_fpr_DT0(DFPREG(rd
));
4564 gen_stf_asi(cpu_addr
, insn
, 8, DFPREG(rd
));
4566 case 0x3c: /* V9 casa */
4567 gen_cas_asi(cpu_val
, cpu_addr
, cpu_src2
, insn
, rd
);
4568 gen_movl_TN_reg(rd
, cpu_val
);
4570 case 0x3e: /* V9 casxa */
4571 gen_casx_asi(cpu_val
, cpu_addr
, cpu_src2
, insn
, rd
);
4572 gen_movl_TN_reg(rd
, cpu_val
);
4575 case 0x34: /* stc */
4576 case 0x35: /* stcsr */
4577 case 0x36: /* stdcq */
4578 case 0x37: /* stdc */
4589 /* default case for non jump instructions */
4590 if (dc
->npc
== DYNAMIC_PC
) {
4591 dc
->pc
= DYNAMIC_PC
;
4593 } else if (dc
->npc
== JUMP_PC
) {
4594 /* we can do a static jump */
4595 gen_branch2(dc
, dc
->jump_pc
[0], dc
->jump_pc
[1], cpu_cond
);
4599 dc
->npc
= dc
->npc
+ 4;
4607 save_state(dc
, cpu_cond
);
4608 r_const
= tcg_const_i32(TT_ILL_INSN
);
4609 gen_helper_raise_exception(r_const
);
4610 tcg_temp_free_i32(r_const
);
4618 save_state(dc
, cpu_cond
);
4619 r_const
= tcg_const_i32(TT_UNIMP_FLUSH
);
4620 gen_helper_raise_exception(r_const
);
4621 tcg_temp_free_i32(r_const
);
4625 #if !defined(CONFIG_USER_ONLY)
4630 save_state(dc
, cpu_cond
);
4631 r_const
= tcg_const_i32(TT_PRIV_INSN
);
4632 gen_helper_raise_exception(r_const
);
4633 tcg_temp_free_i32(r_const
);
4639 save_state(dc
, cpu_cond
);
4640 gen_op_fpexception_im(FSR_FTT_UNIMPFPOP
);
4643 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4645 save_state(dc
, cpu_cond
);
4646 gen_op_fpexception_im(FSR_FTT_SEQ_ERROR
);
4650 #ifndef TARGET_SPARC64
4655 save_state(dc
, cpu_cond
);
4656 r_const
= tcg_const_i32(TT_NCP_INSN
);
4657 gen_helper_raise_exception(r_const
);
4658 tcg_temp_free(r_const
);
4665 static inline void gen_intermediate_code_internal(TranslationBlock
* tb
,
4666 int spc
, CPUSPARCState
*env
)
4668 target_ulong pc_start
, last_pc
;
4669 uint16_t *gen_opc_end
;
4670 DisasContext dc1
, *dc
= &dc1
;
4676 memset(dc
, 0, sizeof(DisasContext
));
4681 dc
->npc
= (target_ulong
) tb
->cs_base
;
4682 dc
->cc_op
= CC_OP_DYNAMIC
;
4683 dc
->mem_idx
= cpu_mmu_index(env
);
4685 if ((dc
->def
->features
& CPU_FEATURE_FLOAT
))
4686 dc
->fpu_enabled
= cpu_fpu_enabled(env
);
4688 dc
->fpu_enabled
= 0;
4689 #ifdef TARGET_SPARC64
4690 dc
->address_mask_32bit
= env
->pstate
& PS_AM
;
4692 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
4694 cpu_tmp0
= tcg_temp_new();
4695 cpu_tmp32
= tcg_temp_new_i32();
4696 cpu_tmp64
= tcg_temp_new_i64();
4698 cpu_dst
= tcg_temp_local_new();
4701 cpu_val
= tcg_temp_local_new();
4702 cpu_addr
= tcg_temp_local_new();
4705 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
4707 max_insns
= CF_COUNT_MASK
;
4710 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
4711 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
4712 if (bp
->pc
== dc
->pc
) {
4713 if (dc
->pc
!= pc_start
)
4714 save_state(dc
, cpu_cond
);
4723 qemu_log("Search PC...\n");
4724 j
= gen_opc_ptr
- gen_opc_buf
;
4728 gen_opc_instr_start
[lj
++] = 0;
4729 gen_opc_pc
[lj
] = dc
->pc
;
4730 gen_opc_npc
[lj
] = dc
->npc
;
4731 gen_opc_instr_start
[lj
] = 1;
4732 gen_opc_icount
[lj
] = num_insns
;
4735 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
4738 disas_sparc_insn(dc
);
4743 /* if the next PC is different, we abort now */
4744 if (dc
->pc
!= (last_pc
+ 4))
4746 /* if we reach a page boundary, we stop generation so that the
4747 PC of a TT_TFAULT exception is always in the right page */
4748 if ((dc
->pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
4750 /* if single step mode, we generate only one instruction and
4751 generate an exception */
4752 if (env
->singlestep_enabled
|| singlestep
) {
4753 tcg_gen_movi_tl(cpu_pc
, dc
->pc
);
4757 } while ((gen_opc_ptr
< gen_opc_end
) &&
4758 (dc
->pc
- pc_start
) < (TARGET_PAGE_SIZE
- 32) &&
4759 num_insns
< max_insns
);
4762 tcg_temp_free(cpu_addr
);
4763 tcg_temp_free(cpu_val
);
4764 tcg_temp_free(cpu_dst
);
4765 tcg_temp_free_i64(cpu_tmp64
);
4766 tcg_temp_free_i32(cpu_tmp32
);
4767 tcg_temp_free(cpu_tmp0
);
4768 if (tb
->cflags
& CF_LAST_IO
)
4771 if (dc
->pc
!= DYNAMIC_PC
&&
4772 (dc
->npc
!= DYNAMIC_PC
&& dc
->npc
!= JUMP_PC
)) {
4773 /* static PC and NPC: we can use direct chaining */
4774 gen_goto_tb(dc
, 0, dc
->pc
, dc
->npc
);
4776 if (dc
->pc
!= DYNAMIC_PC
)
4777 tcg_gen_movi_tl(cpu_pc
, dc
->pc
);
4778 save_npc(dc
, cpu_cond
);
4782 gen_icount_end(tb
, num_insns
);
4783 *gen_opc_ptr
= INDEX_op_end
;
4785 j
= gen_opc_ptr
- gen_opc_buf
;
4788 gen_opc_instr_start
[lj
++] = 0;
4792 gen_opc_jump_pc
[0] = dc
->jump_pc
[0];
4793 gen_opc_jump_pc
[1] = dc
->jump_pc
[1];
4795 tb
->size
= last_pc
+ 4 - pc_start
;
4796 tb
->icount
= num_insns
;
4799 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
4800 qemu_log("--------------\n");
4801 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
4802 log_target_disas(pc_start
, last_pc
+ 4 - pc_start
, 0);
4808 void gen_intermediate_code(CPUSPARCState
* env
, TranslationBlock
* tb
)
4810 gen_intermediate_code_internal(tb
, 0, env
);
4813 void gen_intermediate_code_pc(CPUSPARCState
* env
, TranslationBlock
* tb
)
4815 gen_intermediate_code_internal(tb
, 1, env
);
4818 void gen_intermediate_code_init(CPUSPARCState
*env
)
4822 static const char * const gregnames
[8] = {
4823 NULL
, // g0 not used
4832 static const char * const fregnames
[64] = {
4833 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
4834 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
4835 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
4836 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
4837 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
4838 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
4839 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
4840 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
4843 /* init various static tables */
4847 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
4848 cpu_regwptr
= tcg_global_mem_new_ptr(TCG_AREG0
,
4849 offsetof(CPUState
, regwptr
),
4851 #ifdef TARGET_SPARC64
4852 cpu_xcc
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUState
, xcc
),
4854 cpu_asi
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUState
, asi
),
4856 cpu_fprs
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUState
, fprs
),
4858 cpu_gsr
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, gsr
),
4860 cpu_tick_cmpr
= tcg_global_mem_new(TCG_AREG0
,
4861 offsetof(CPUState
, tick_cmpr
),
4863 cpu_stick_cmpr
= tcg_global_mem_new(TCG_AREG0
,
4864 offsetof(CPUState
, stick_cmpr
),
4866 cpu_hstick_cmpr
= tcg_global_mem_new(TCG_AREG0
,
4867 offsetof(CPUState
, hstick_cmpr
),
4869 cpu_hintp
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, hintp
),
4871 cpu_htba
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, htba
),
4873 cpu_hver
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, hver
),
4875 cpu_ssr
= tcg_global_mem_new(TCG_AREG0
,
4876 offsetof(CPUState
, ssr
), "ssr");
4877 cpu_ver
= tcg_global_mem_new(TCG_AREG0
,
4878 offsetof(CPUState
, version
), "ver");
4879 cpu_softint
= tcg_global_mem_new_i32(TCG_AREG0
,
4880 offsetof(CPUState
, softint
),
4883 cpu_wim
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, wim
),
4886 cpu_cond
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, cond
),
4888 cpu_cc_src
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, cc_src
),
4890 cpu_cc_src2
= tcg_global_mem_new(TCG_AREG0
,
4891 offsetof(CPUState
, cc_src2
),
4893 cpu_cc_dst
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, cc_dst
),
4895 cpu_cc_op
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUState
, cc_op
),
4897 cpu_psr
= tcg_global_mem_new_i32(TCG_AREG0
, offsetof(CPUState
, psr
),
4899 cpu_fsr
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, fsr
),
4901 cpu_pc
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, pc
),
4903 cpu_npc
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, npc
),
4905 cpu_y
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, y
), "y");
4906 #ifndef CONFIG_USER_ONLY
4907 cpu_tbr
= tcg_global_mem_new(TCG_AREG0
, offsetof(CPUState
, tbr
),
4910 for (i
= 1; i
< 8; i
++)
4911 cpu_gregs
[i
] = tcg_global_mem_new(TCG_AREG0
,
4912 offsetof(CPUState
, gregs
[i
]),
4914 for (i
= 0; i
< TARGET_FPREGS
; i
++)
4915 cpu_fpr
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
4916 offsetof(CPUState
, fpr
[i
]),
4919 /* register helpers */
4921 #define GEN_HELPER 2
4926 void gen_pc_load(CPUState
*env
, TranslationBlock
*tb
,
4927 unsigned long searched_pc
, int pc_pos
, void *puc
)
4930 env
->pc
= gen_opc_pc
[pc_pos
];
4931 npc
= gen_opc_npc
[pc_pos
];
4933 /* dynamic NPC: already stored */
4934 } else if (npc
== 2) {
4935 target_ulong t2
= (target_ulong
)(unsigned long)puc
;
4936 /* jump PC: use T2 and the jump targets of the translation */
4938 env
->npc
= gen_opc_jump_pc
[0];
4940 env
->npc
= gen_opc_jump_pc
[1];
4945 /* flush pending conditional evaluations before exposing cpu state */
4946 if (CC_OP
!= CC_OP_FLAGS
) {
4947 helper_compute_psr();