#include <inttypes.h>
#include "cpu.h"
-#include "exec-all.h"
#include "disas.h"
#include "helper.h"
#include "tcg-op.h"
tcg_gen_goto_tb(tb_num);
tcg_gen_movi_tl(cpu_pc, pc);
tcg_gen_movi_tl(cpu_npc, npc);
- tcg_gen_exit_tb((long)tb + tb_num);
+ tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
} else {
/* jump to another page: currently not optimized */
tcg_gen_movi_tl(cpu_pc, pc);
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
{
int l1, l2;
+ TCGv r_temp1, r_temp2;
l1 = gen_new_label();
l2 = gen_new_label();
- tcg_gen_mov_tl(cpu_cc_src, src1);
- tcg_gen_mov_tl(cpu_cc_src2, src2);
- gen_trap_ifdivzero_tl(cpu_cc_src2);
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
+ r_temp1 = tcg_temp_local_new();
+ r_temp2 = tcg_temp_local_new();
+ tcg_gen_mov_tl(r_temp1, src1);
+ tcg_gen_mov_tl(r_temp2, src2);
+ gen_trap_ifdivzero_tl(r_temp2);
+ tcg_gen_brcondi_tl(TCG_COND_NE, r_temp1, INT64_MIN, l1);
+ tcg_gen_brcondi_tl(TCG_COND_NE, r_temp2, -1, l1);
tcg_gen_movi_i64(dst, INT64_MIN);
tcg_gen_br(l2);
gen_set_label(l1);
- tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
+ tcg_gen_div_i64(dst, r_temp1, r_temp2);
gen_set_label(l2);
+ tcg_temp_free(r_temp1);
+ tcg_temp_free(r_temp2);
}
#endif
int cc;
target = GET_FIELD_SP(insn, 0, 18);
- target = sign_extend(target, 18);
+ target = sign_extend(target, 19);
target <<= 2;
cc = GET_FIELD_SP(insn, 20, 21);
if (cc == 0)
} else
tcg_gen_mov_tl(cpu_dst, cpu_src1);
}
+
cond = GET_FIELD(insn, 3, 6);
- if (cond == 0x8) {
+ if (cond == 0x8) { /* Trap Always */
save_state(dc, cpu_cond);
if ((dc->def->features & CPU_FEATURE_HYPV) &&
supervisor(dc))
tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
- gen_helper_raise_exception(cpu_tmp32);
+
+ if (rs2 == 0 &&
+ dc->def->features & CPU_FEATURE_TA0_SHUTDOWN) {
+
+ gen_helper_shutdown();
+
+ } else {
+ gen_helper_raise_exception(cpu_tmp32);
+ }
} else if (cond != 0) {
TCGv r_cond = tcg_temp_new();
int l1;
case 0x10 ... 0x1f: /* implementation-dependent in the
SPARCv8 manual, rdy on the
microSPARC II */
+ /* Read Asr17 */
+ if (rs1 == 0x11 && dc->def->features & CPU_FEATURE_ASR17) {
+ TCGv r_const;
+
+ /* Read Asr17 for a Leon3 monoprocessor */
+ r_const = tcg_const_tl((1 << 8)
+ | (dc->def->nwindows - 1));
+ gen_movl_TN_reg(rd, r_const);
+ tcg_temp_free(r_const);
+ break;
+ }
#endif
gen_movl_TN_reg(rd, cpu_y);
break;
break;
#ifdef TARGET_SPARC64
case 0xd: /* V9 udivx */
- tcg_gen_mov_tl(cpu_cc_src, cpu_src1);
- tcg_gen_mov_tl(cpu_cc_src2, cpu_src2);
- gen_trap_ifdivzero_tl(cpu_cc_src2);
- tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2);
+ {
+ TCGv r_temp1, r_temp2;
+ r_temp1 = tcg_temp_local_new();
+ r_temp2 = tcg_temp_local_new();
+ tcg_gen_mov_tl(r_temp1, cpu_src1);
+ tcg_gen_mov_tl(r_temp2, cpu_src2);
+ gen_trap_ifdivzero_tl(r_temp2);
+ tcg_gen_divu_i64(cpu_dst, r_temp1, r_temp2);
+ tcg_temp_free(r_temp1);
+ tcg_temp_free(r_temp2);
+ }
break;
#endif
case 0xe: /* udiv */
CHECK_IU_FEATURE(dc, DIV);
- gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_DIV);
+ gen_helper_udiv_cc(cpu_dst, cpu_src1, cpu_src2);
dc->cc_op = CC_OP_DIV;
+ } else {
+ gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
}
break;
case 0xf: /* sdiv */
CHECK_IU_FEATURE(dc, DIV);
- gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
if (xop & 0x10) {
- tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
- tcg_gen_movi_i32(cpu_cc_op, CC_OP_DIV);
+ gen_helper_sdiv_cc(cpu_dst, cpu_src1, cpu_src2);
dc->cc_op = CC_OP_DIV;
+ } else {
+ gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
}
break;
default:
tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
break;
case 6: // pstate
- save_state(dc, cpu_cond);
- gen_helper_wrpstate(cpu_tmp0);
- dc->npc = DYNAMIC_PC;
+ {
+ TCGv r_tmp = tcg_temp_local_new();
+
+ tcg_gen_mov_tl(r_tmp, cpu_tmp0);
+ save_state(dc, cpu_cond);
+ gen_helper_wrpstate(r_tmp);
+ tcg_temp_free(r_tmp);
+ dc->npc = DYNAMIC_PC;
+ }
break;
case 7: // tl
- save_state(dc, cpu_cond);
- tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
- tcg_gen_st_i32(cpu_tmp32, cpu_env,
- offsetof(CPUSPARCState, tl));
- dc->npc = DYNAMIC_PC;
+ {
+ TCGv r_tmp = tcg_temp_local_new();
+
+ tcg_gen_mov_tl(r_tmp, cpu_tmp0);
+ save_state(dc, cpu_cond);
+ tcg_gen_trunc_tl_i32(cpu_tmp32, r_tmp);
+ tcg_temp_free(r_tmp);
+ tcg_gen_st_i32(cpu_tmp32, cpu_env,
+ offsetof(CPUSPARCState, tl));
+ dc->npc = DYNAMIC_PC;
+ }
break;
case 8: // pil
gen_helper_wrpil(cpu_tmp0);
case 0x3b: /* flush */
if (!((dc)->def->features & CPU_FEATURE_FLUSH))
goto unimp_flush;
- gen_helper_flush(cpu_dst);
+ /* nop */
break;
case 0x3c: /* save */
save_state(dc, cpu_cond);
case 0x2d: /* V9 prefetch, no effect */
goto skip_move;
case 0x30: /* V9 ldfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 4, rd);
goto skip_move;
case 0x33: /* V9 lddfa */
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
goto skip_move;
goto skip_move;
case 0x32: /* V9 ldqfa */
CHECK_FPU_FEATURE(dc, FLOAT128);
+ if (gen_trap_ifnofpu(dc, cpu_cond)) {
+ goto jmp_insn;
+ }
save_state(dc, cpu_cond);
gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
goto skip_move;
r_const = tcg_const_i32(7);
gen_helper_check_align(cpu_addr, r_const);
tcg_temp_free_i32(r_const);
- gen_op_load_fpr_QT0(QFPREG(rd));
gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
}
break;
case 0x37: /* V9 stdfa */
- gen_op_load_fpr_DT0(DFPREG(rd));
gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
break;
case 0x3c: /* V9 casa */
}
}
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
- unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
{
target_ulong npc;
env->pc = gen_opc_pc[pc_pos];