diff options
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r-- | target-mips/translate.c | 3801 |
1 files changed, 2219 insertions, 1582 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index f0dc14d82..41a27b4e2 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -423,24 +423,87 @@ enum { }; /* global register indices */ -static TCGv cpu_env, current_tc_gprs, current_tc_hi, cpu_T[2]; +static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu; -static inline void tcg_gen_helper_0_1i(void *func, TCGv arg) +/* FPU TNs, global for now. */ +static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3]; + +static inline void tcg_gen_helper_0_i(void *func, TCGv arg) { - TCGv t = tcg_const_i32(arg); + TCGv tmp = tcg_const_i32(arg); - tcg_gen_helper_0_1(func, t); - tcg_temp_free(t); + tcg_gen_helper_0_1(func, tmp); + tcg_temp_free(tmp); } -static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2) +static inline void tcg_gen_helper_0_ii(void *func, TCGv arg1, TCGv arg2) { - TCGv t1 = tcg_const_i32(arg1); - TCGv t2 = tcg_const_i32(arg2); + TCGv tmp1 = tcg_const_i32(arg1); + TCGv tmp2 = tcg_const_i32(arg2); - tcg_gen_helper_0_2(func, t1, t2); - tcg_temp_free(t1); - tcg_temp_free(t2); + tcg_gen_helper_0_2(func, tmp1, tmp2); + tcg_temp_free(tmp1); + tcg_temp_free(tmp2); +} + +static inline void tcg_gen_helper_0_1i(void *func, TCGv arg1, TCGv arg2) +{ + TCGv tmp = tcg_const_i32(arg2); + + tcg_gen_helper_0_2(func, arg1, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_0_2i(void *func, TCGv arg1, TCGv arg2, TCGv arg3) +{ + TCGv tmp = tcg_const_i32(arg3); + + tcg_gen_helper_0_3(func, arg1, arg2, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4) +{ + TCGv tmp1 = tcg_const_i32(arg3); + TCGv tmp2 = tcg_const_i32(arg3); + + tcg_gen_helper_0_4(func, arg1, arg2, tmp1, tmp2); + tcg_temp_free(tmp1); + tcg_temp_free(tmp2); +} + +static inline void tcg_gen_helper_1_i(void *func, TCGv ret, TCGv arg) +{ + TCGv tmp = tcg_const_i32(arg); + + tcg_gen_helper_1_1(func, ret, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_1_1i(void *func, TCGv ret, TCGv arg1, TCGv arg2) +{ + TCGv tmp = tcg_const_i32(arg2); + + tcg_gen_helper_1_2(func, ret, arg1, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_1_2i(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3) +{ + TCGv tmp = tcg_const_i32(arg3); + + tcg_gen_helper_1_3(func, ret, arg1, arg2, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_1_2ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4) +{ + TCGv tmp1 = tcg_const_i32(arg3); + TCGv tmp2 = tcg_const_i32(arg3); + + tcg_gen_helper_1_4(func, ret, arg1, arg2, tmp1, tmp2); + tcg_temp_free(tmp1); + tcg_temp_free(tmp2); } typedef struct DisasContext { @@ -537,116 +600,140 @@ static inline void gen_store_HI (TCGv t, int reg) } /* Moves to/from shadow registers. */ -static inline void gen_load_srsgpr (TCGv t, int reg) +static inline void gen_load_srsgpr (int from, int to) { - if (reg == 0) - tcg_gen_movi_tl(t, 0); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); + + if (from == 0) + tcg_gen_movi_tl(r_tmp1, 0); else { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl)); - tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS); - tcg_gen_andi_i32(r_tmp, r_tmp, 0xf); - tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32); - tcg_gen_add_i32(r_tmp, cpu_env, r_tmp); + tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl)); + tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS); + tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf); + tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32); + tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2); - tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg); - tcg_temp_free(r_tmp); + tcg_gen_ld_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * from); + tcg_temp_free(r_tmp2); } + gen_store_gpr(r_tmp1, to); + tcg_temp_free(r_tmp1); } -static inline void gen_store_srsgpr (TCGv t, int reg) +static inline void gen_store_srsgpr (int from, int to) { - if (reg != 0) { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); - - tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl)); - tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS); - tcg_gen_andi_i32(r_tmp, r_tmp, 0xf); - tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32); - tcg_gen_add_i32(r_tmp, cpu_env, r_tmp); - - tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg); - tcg_temp_free(r_tmp); + if (to != 0) { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); + + gen_load_gpr(r_tmp1, from); + tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl)); + tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS); + tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf); + tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32); + tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2); + + tcg_gen_st_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * to); + tcg_temp_free(r_tmp1); + tcg_temp_free(r_tmp2); } } /* Floating point register moves. */ -#define FGEN32(func, NAME) \ -static GenOpFunc *NAME ## _table [32] = { \ -NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \ -NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \ -NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \ -NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \ -NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \ -NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \ -NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \ -NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \ -}; \ -static always_inline void func(int n) \ -{ \ - NAME ## _table[n](); \ +static inline void gen_load_fpr32 (TCGv t, int reg) +{ + tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX); } -FGEN32(gen_op_load_fpr_WT0, gen_op_load_fpr_WT0_fpr); -FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr); - -FGEN32(gen_op_load_fpr_WT1, gen_op_load_fpr_WT1_fpr); -FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr); - -FGEN32(gen_op_load_fpr_WT2, gen_op_load_fpr_WT2_fpr); -FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr); - -FGEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fpr); -FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr); - -FGEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fpr); -FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr); +static inline void gen_store_fpr32 (TCGv t, int reg) +{ + tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX); +} -FGEN32(gen_op_load_fpr_DT2, gen_op_load_fpr_DT2_fpr); -FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr); +static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg) +{ + if (ctx->hflags & MIPS_HFLAG_F64) { + tcg_gen_ld_i64(t, current_fpu, 8 * reg); + } else { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX); + tcg_gen_extu_i32_i64(t, r_tmp1); + tcg_gen_shli_i64(t, t, 32); + tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX); + tcg_gen_extu_i32_i64(r_tmp2, r_tmp1); + tcg_gen_or_i64(t, t, r_tmp2); + tcg_temp_free(r_tmp1); + tcg_temp_free(r_tmp2); + } +} -FGEN32(gen_op_load_fpr_WTH0, gen_op_load_fpr_WTH0_fpr); -FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr); +static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg) +{ + if (ctx->hflags & MIPS_HFLAG_F64) { + tcg_gen_st_i64(t, current_fpu, 8 * reg); + } else { + TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); -FGEN32(gen_op_load_fpr_WTH1, gen_op_load_fpr_WTH1_fpr); -FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr); + tcg_gen_trunc_i64_i32(r_tmp, t); + tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX); + tcg_gen_shri_i64(t, t, 32); + tcg_gen_trunc_i64_i32(r_tmp, t); + tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX); + tcg_temp_free(r_tmp); + } +} -FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr); -FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr); +static inline void gen_load_fpr32h (TCGv t, int reg) +{ + tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX); +} -#define GEN_LOAD_FREG_FTN(FTn, Fn) \ -do { \ - glue(gen_op_load_fpr_, FTn)(Fn); \ -} while (0) +static inline void gen_store_fpr32h (TCGv t, int reg) +{ + tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX); +} -#define GEN_STORE_FTN_FREG(Fn, FTn) \ -do { \ - glue(gen_op_store_fpr_, FTn)(Fn); \ -} while (0) +static inline void get_fp_cond (TCGv t) +{ + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); + + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); + tcg_gen_shri_i32(r_tmp2, r_tmp1, 24); + tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe); + tcg_gen_shri_i32(r_tmp1, r_tmp1, 23); + tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1); + tcg_gen_or_i32(t, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp1); + tcg_temp_free(r_tmp2); +} -#define FOP_CONDS(type, fmt) \ -static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = { \ - gen_op_cmp ## type ## _ ## fmt ## _f, \ - gen_op_cmp ## type ## _ ## fmt ## _un, \ - gen_op_cmp ## type ## _ ## fmt ## _eq, \ - gen_op_cmp ## type ## _ ## fmt ## _ueq, \ - gen_op_cmp ## type ## _ ## fmt ## _olt, \ - gen_op_cmp ## type ## _ ## fmt ## _ult, \ - gen_op_cmp ## type ## _ ## fmt ## _ole, \ - gen_op_cmp ## type ## _ ## fmt ## _ule, \ - gen_op_cmp ## type ## _ ## fmt ## _sf, \ - gen_op_cmp ## type ## _ ## fmt ## _ngle, \ - gen_op_cmp ## type ## _ ## fmt ## _seq, \ - gen_op_cmp ## type ## _ ## fmt ## _ngl, \ - gen_op_cmp ## type ## _ ## fmt ## _lt, \ - gen_op_cmp ## type ## _ ## fmt ## _nge, \ - gen_op_cmp ## type ## _ ## fmt ## _le, \ - gen_op_cmp ## type ## _ ## fmt ## _ngt, \ -}; \ -static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \ -{ \ - gen_op_cmp ## type ## _ ## fmt ## _table[n](cc); \ +#define FOP_CONDS(type, fmt) \ +static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = { \ + do_cmp ## type ## _ ## fmt ## _f, \ + do_cmp ## type ## _ ## fmt ## _un, \ + do_cmp ## type ## _ ## fmt ## _eq, \ + do_cmp ## type ## _ ## fmt ## _ueq, \ + do_cmp ## type ## _ ## fmt ## _olt, \ + do_cmp ## type ## _ ## fmt ## _ult, \ + do_cmp ## type ## _ ## fmt ## _ole, \ + do_cmp ## type ## _ ## fmt ## _ule, \ + do_cmp ## type ## _ ## fmt ## _sf, \ + do_cmp ## type ## _ ## fmt ## _ngle, \ + do_cmp ## type ## _ ## fmt ## _seq, \ + do_cmp ## type ## _ ## fmt ## _ngl, \ + do_cmp ## type ## _ ## fmt ## _lt, \ + do_cmp ## type ## _ ## fmt ## _nge, \ + do_cmp ## type ## _ ## fmt ## _le, \ + do_cmp ## type ## _ ## fmt ## _ngt, \ +}; \ +static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \ +{ \ + tcg_gen_helper_0_i(fcmp ## type ## _ ## fmt ## _table[n], cc); \ } FOP_CONDS(, d) @@ -655,19 +742,20 @@ FOP_CONDS(, s) FOP_CONDS(abs, s) FOP_CONDS(, ps) FOP_CONDS(abs, ps) +#undef FOP_CONDS /* Tests */ #define OP_COND(name, cond) \ -void glue(gen_op_, name) (void) \ +void glue(gen_op_, name) (TCGv t0, TCGv t1) \ { \ int l1 = gen_new_label(); \ int l2 = gen_new_label(); \ \ - tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1); \ - tcg_gen_movi_tl(cpu_T[0], 0); \ + tcg_gen_brcond_tl(cond, t0, t1, l1); \ + tcg_gen_movi_tl(t0, 0); \ tcg_gen_br(l2); \ gen_set_label(l1); \ - tcg_gen_movi_tl(cpu_T[0], 1); \ + tcg_gen_movi_tl(t0, 1); \ gen_set_label(l2); \ } OP_COND(eq, TCG_COND_EQ); @@ -679,16 +767,16 @@ OP_COND(ltu, TCG_COND_LTU); #undef OP_COND #define OP_CONDI(name, cond) \ -void glue(gen_op_, name) (target_ulong val) \ +void glue(gen_op_, name) (TCGv t, target_ulong val) \ { \ int l1 = gen_new_label(); \ int l2 = gen_new_label(); \ \ - tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1); \ - tcg_gen_movi_tl(cpu_T[0], 0); \ + tcg_gen_brcondi_tl(cond, t, val, l1); \ + tcg_gen_movi_tl(t, 0); \ tcg_gen_br(l2); \ gen_set_label(l1); \ - tcg_gen_movi_tl(cpu_T[0], 1); \ + tcg_gen_movi_tl(t, 1); \ gen_set_label(l2); \ } OP_CONDI(lti, TCG_COND_LT); @@ -696,16 +784,16 @@ OP_CONDI(ltiu, TCG_COND_LTU); #undef OP_CONDI #define OP_CONDZ(name, cond) \ -void glue(gen_op_, name) (void) \ +void glue(gen_op_, name) (TCGv t) \ { \ int l1 = gen_new_label(); \ int l2 = gen_new_label(); \ \ - tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1); \ - tcg_gen_movi_tl(cpu_T[0], 0); \ + tcg_gen_brcondi_tl(cond, t, 0, l1); \ + tcg_gen_movi_tl(t, 0); \ tcg_gen_br(l2); \ gen_set_label(l1); \ - tcg_gen_movi_tl(cpu_T[0], 1); \ + tcg_gen_movi_tl(t, 1); \ gen_set_label(l2); \ } OP_CONDZ(gez, TCG_COND_GE); @@ -783,7 +871,11 @@ static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc) ctx->saved_pc = ctx->pc; } if (ctx->hflags != ctx->saved_hflags) { - gen_op_save_state(ctx->hflags); + TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); + + tcg_gen_movi_i32(r_tmp, ctx->hflags); + tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags)); + tcg_temp_free(r_tmp); ctx->saved_hflags = ctx->hflags; switch (ctx->hflags & MIPS_HFLAG_BMASK) { case MIPS_HFLAG_BR: @@ -815,7 +907,7 @@ static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err) { save_cpu_state(ctx, 1); - tcg_gen_helper_0_2ii(do_raise_exception_err, excp, err); + tcg_gen_helper_0_ii(do_raise_exception_err, excp, err); tcg_gen_helper_0_0(do_interrupt_restart); tcg_gen_exit_tb(0); } @@ -824,15 +916,15 @@ static always_inline void generate_exception (DisasContext *ctx, int excp) { save_cpu_state(ctx, 1); - tcg_gen_helper_0_1i(do_raise_exception, excp); + tcg_gen_helper_0_i(do_raise_exception, excp); tcg_gen_helper_0_0(do_interrupt_restart); tcg_gen_exit_tb(0); } /* Addresses computation */ -static inline void gen_op_addr_add (void) +static inline void gen_op_addr_add (TCGv t0, TCGv t1) { - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_add_tl(t0, t0, t1); #if defined(TARGET_MIPS64) /* For compatibility with 32-bit code, data reference in user mode @@ -840,22 +932,16 @@ static inline void gen_op_addr_add (void) See the MIPS64 PRA manual, section 4.10. */ { int l1 = gen_new_label(); - - { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); - - tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags)); - tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU); - tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1); - } - { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); - - tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status)); - tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX)); - tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1); - } - tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]); + TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32); + + tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags)); + tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU); + tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1); + tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status)); + tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX)); + tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1); + tcg_temp_free(r_tmp); + tcg_gen_ext32s_i64(t0, t0); gen_set_label(l1); } #endif @@ -926,47 +1012,10 @@ static always_inline void check_mips_64(DisasContext *ctx) } /* load/store instructions. */ -#if defined(CONFIG_USER_ONLY) -#define op_ldst(name) gen_op_##name##_raw() -#define OP_LD_TABLE(width) -#define OP_ST_TABLE(width) -#else -#define op_ldst(name) (*gen_op_##name[ctx->mem_idx])() -#define OP_LD_TABLE(width) \ -static GenOpFunc *gen_op_l##width[] = { \ - &gen_op_l##width##_kernel, \ - &gen_op_l##width##_super, \ - &gen_op_l##width##_user, \ -} -#define OP_ST_TABLE(width) \ -static GenOpFunc *gen_op_s##width[] = { \ - &gen_op_s##width##_kernel, \ - &gen_op_s##width##_super, \ - &gen_op_s##width##_user, \ -} -#endif - -#if defined(TARGET_MIPS64) -OP_LD_TABLE(dl); -OP_LD_TABLE(dr); -OP_ST_TABLE(dl); -OP_ST_TABLE(dr); -#endif -OP_LD_TABLE(wl); -OP_LD_TABLE(wr); -OP_ST_TABLE(wl); -OP_ST_TABLE(wr); -OP_LD_TABLE(wc1); -OP_ST_TABLE(wc1); -OP_LD_TABLE(dc1); -OP_ST_TABLE(dc1); -OP_LD_TABLE(uxc1); -OP_ST_TABLE(uxc1); - #define OP_LD(insn,fname) \ -void inline op_ldst_##insn(DisasContext *ctx) \ +void inline op_ldst_##insn(TCGv t0, DisasContext *ctx) \ { \ - tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx); \ + tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx); \ } OP_LD(lb,ld8s); OP_LD(lbu,ld8u); @@ -980,9 +1029,9 @@ OP_LD(ld,ld64); #undef OP_LD #define OP_ST(insn,fname) \ -void inline op_ldst_##insn(DisasContext *ctx) \ +void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ { \ - tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx); \ + tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx); \ } OP_ST(sb,st8); OP_ST(sh,st16); @@ -993,11 +1042,11 @@ OP_ST(sd,st64); #undef OP_ST #define OP_LD_ATOMIC(insn,fname) \ -void inline op_ldst_##insn(DisasContext *ctx) \ +void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ { \ - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); \ - tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx); \ - tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr)); \ + tcg_gen_mov_tl(t1, t0); \ + tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx); \ + tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr)); \ } OP_LD_ATOMIC(ll,ld32s); #if defined(TARGET_MIPS64) @@ -1006,26 +1055,26 @@ OP_LD_ATOMIC(lld,ld64); #undef OP_LD_ATOMIC #define OP_ST_ATOMIC(insn,fname,almask) \ -void inline op_ldst_##insn(DisasContext *ctx) \ +void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ { \ TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL); \ int l1 = gen_new_label(); \ int l2 = gen_new_label(); \ int l3 = gen_new_label(); \ \ - tcg_gen_andi_tl(r_tmp, cpu_T[0], almask); \ + tcg_gen_andi_tl(r_tmp, t0, almask); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1); \ - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \ + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr)); \ generate_exception(ctx, EXCP_AdES); \ gen_set_label(l1); \ tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \ - tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2); \ + tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2); \ tcg_temp_free(r_tmp); \ - tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx); \ - tcg_gen_movi_tl(cpu_T[0], 1); \ + tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx); \ + tcg_gen_movi_tl(t0, 1); \ tcg_gen_br(l3); \ gen_set_label(l2); \ - tcg_gen_movi_tl(cpu_T[0], 0); \ + tcg_gen_movi_tl(t0, 0); \ gen_set_label(l3); \ } OP_ST_ATOMIC(sc,st32,0x3); @@ -1034,175 +1083,168 @@ OP_ST_ATOMIC(scd,st64,0x7); #endif #undef OP_ST_ATOMIC -void inline op_ldst_lwc1(DisasContext *ctx) -{ - op_ldst(lwc1); -} - -void inline op_ldst_ldc1(DisasContext *ctx) -{ - op_ldst(ldc1); -} - -void inline op_ldst_swc1(DisasContext *ctx) -{ - op_ldst(swc1); -} - -void inline op_ldst_sdc1(DisasContext *ctx) -{ - op_ldst(sdc1); -} - /* Load and store */ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, int base, int16_t offset) { const char *opn = "ldst"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (base == 0) { - tcg_gen_movi_tl(cpu_T[0], offset); + tcg_gen_movi_tl(t0, offset); } else if (offset == 0) { - gen_load_gpr(cpu_T[0], base); + gen_load_gpr(t0, base); } else { - gen_load_gpr(cpu_T[0], base); - tcg_gen_movi_tl(cpu_T[1], offset); - gen_op_addr_add(); + gen_load_gpr(t0, base); + tcg_gen_movi_tl(t1, offset); + gen_op_addr_add(t0, t1); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { #if defined(TARGET_MIPS64) case OPC_LWU: - op_ldst_lwu(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lwu(t0, ctx); + gen_store_gpr(t0, rt); opn = "lwu"; break; case OPC_LD: - op_ldst_ld(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_ld(t0, ctx); + gen_store_gpr(t0, rt); opn = "ld"; break; case OPC_LLD: - op_ldst_lld(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lld(t0, t1, ctx); + gen_store_gpr(t0, rt); opn = "lld"; break; case OPC_SD: - gen_load_gpr(cpu_T[1], rt); - op_ldst_sd(ctx); + gen_load_gpr(t1, rt); + op_ldst_sd(t0, t1, ctx); opn = "sd"; break; case OPC_SCD: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - op_ldst_scd(ctx); - gen_store_gpr(cpu_T[0], rt); + gen_load_gpr(t1, rt); + op_ldst_scd(t0, t1, ctx); + gen_store_gpr(t0, rt); opn = "scd"; break; case OPC_LDL: - gen_load_gpr(cpu_T[1], rt); - op_ldst(ldl); - gen_store_gpr(cpu_T[1], rt); + save_cpu_state(ctx, 1); + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2i(do_ldl, t1, t0, t1, ctx->mem_idx); + gen_store_gpr(t1, rt); opn = "ldl"; break; case OPC_SDL: - gen_load_gpr(cpu_T[1], rt); - op_ldst(sdl); + save_cpu_state(ctx, 1); + gen_load_gpr(t1, rt); + tcg_gen_helper_0_2i(do_sdl, t0, t1, ctx->mem_idx); opn = "sdl"; break; case OPC_LDR: - gen_load_gpr(cpu_T[1], rt); - op_ldst(ldr); - gen_store_gpr(cpu_T[1], rt); + save_cpu_state(ctx, 1); + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2i(do_ldr, t1, t0, t1, ctx->mem_idx); + gen_store_gpr(t1, rt); opn = "ldr"; break; case OPC_SDR: - gen_load_gpr(cpu_T[1], rt); - op_ldst(sdr); + save_cpu_state(ctx, 1); + gen_load_gpr(t1, rt); + tcg_gen_helper_0_2i(do_sdr, t0, t1, ctx->mem_idx); opn = "sdr"; break; #endif case OPC_LW: - op_ldst_lw(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lw(t0, ctx); + gen_store_gpr(t0, rt); opn = "lw"; break; case OPC_SW: - gen_load_gpr(cpu_T[1], rt); - op_ldst_sw(ctx); + gen_load_gpr(t1, rt); + op_ldst_sw(t0, t1, ctx); opn = "sw"; break; case OPC_LH: - op_ldst_lh(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lh(t0, ctx); + gen_store_gpr(t0, rt); opn = "lh"; break; case OPC_SH: - gen_load_gpr(cpu_T[1], rt); - op_ldst_sh(ctx); + gen_load_gpr(t1, rt); + op_ldst_sh(t0, t1, ctx); opn = "sh"; break; case OPC_LHU: - op_ldst_lhu(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lhu(t0, ctx); + gen_store_gpr(t0, rt); opn = "lhu"; break; case OPC_LB: - op_ldst_lb(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lb(t0, ctx); + gen_store_gpr(t0, rt); opn = "lb"; break; case OPC_SB: - gen_load_gpr(cpu_T[1], rt); - op_ldst_sb(ctx); + gen_load_gpr(t1, rt); + op_ldst_sb(t0, t1, ctx); opn = "sb"; break; case OPC_LBU: - op_ldst_lbu(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lbu(t0, ctx); + gen_store_gpr(t0, rt); opn = "lbu"; break; case OPC_LWL: - gen_load_gpr(cpu_T[1], rt); - op_ldst(lwl); - gen_store_gpr(cpu_T[1], rt); + save_cpu_state(ctx, 1); + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2i(do_lwl, t1, t0, t1, ctx->mem_idx); + gen_store_gpr(t1, rt); opn = "lwl"; break; case OPC_SWL: - gen_load_gpr(cpu_T[1], rt); - op_ldst(swl); + save_cpu_state(ctx, 1); + gen_load_gpr(t1, rt); + tcg_gen_helper_0_2i(do_swl, t0, t1, ctx->mem_idx); opn = "swr"; break; case OPC_LWR: - gen_load_gpr(cpu_T[1], rt); - op_ldst(lwr); - gen_store_gpr(cpu_T[1], rt); + save_cpu_state(ctx, 1); + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2i(do_lwr, t1, t0, t1, ctx->mem_idx); + gen_store_gpr(t1, rt); opn = "lwr"; break; case OPC_SWR: - gen_load_gpr(cpu_T[1], rt); - op_ldst(swr); + save_cpu_state(ctx, 1); + gen_load_gpr(t1, rt); + tcg_gen_helper_0_2i(do_swr, t0, t1, ctx->mem_idx); opn = "swr"; break; case OPC_LL: - op_ldst_ll(ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_ll(t0, t1, ctx); + gen_store_gpr(t0, rt); opn = "ll"; break; case OPC_SC: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - op_ldst_sc(ctx); - gen_store_gpr(cpu_T[0], rt); + gen_load_gpr(t1, rt); + op_ldst_sc(t0, t1, ctx); + gen_store_gpr(t0, rt); opn = "sc"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } /* Load and store */ @@ -1210,45 +1252,51 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, int base, int16_t offset) { const char *opn = "flt_ldst"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); if (base == 0) { - tcg_gen_movi_tl(cpu_T[0], offset); + tcg_gen_movi_tl(t0, offset); } else if (offset == 0) { - gen_load_gpr(cpu_T[0], base); + gen_load_gpr(t0, base); } else { - gen_load_gpr(cpu_T[0], base); - tcg_gen_movi_tl(cpu_T[1], offset); - gen_op_addr_add(); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, base); + tcg_gen_movi_tl(t1, offset); + gen_op_addr_add(t0, t1); + tcg_temp_free(t1); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { case OPC_LWC1: - op_ldst_lwc1(ctx); - GEN_STORE_FTN_FREG(ft, WT0); + tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx); + gen_store_fpr32(fpu32_T[0], ft); opn = "lwc1"; break; case OPC_SWC1: - GEN_LOAD_FREG_FTN(WT0, ft); - op_ldst_swc1(ctx); + gen_load_fpr32(fpu32_T[0], ft); + tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx); opn = "swc1"; break; case OPC_LDC1: - op_ldst_ldc1(ctx); - GEN_STORE_FTN_FREG(ft, DT0); + tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx); + gen_store_fpr64(ctx, fpu64_T[0], ft); opn = "ldc1"; break; case OPC_SDC1: - GEN_LOAD_FREG_FTN(DT0, ft); - op_ldst_sdc1(ctx); + gen_load_fpr64(ctx, fpu64_T[0], ft); + tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx); opn = "sdc1"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); + out: + tcg_temp_free(t0); } /* Arithmetic with immediate operand */ @@ -1257,12 +1305,13 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, { target_ulong uimm; const char *opn = "imm arith"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { /* If no destination, treat it as a NOP. For addi, we must generate the overflow exception when needed. */ MIPS_DEBUG("NOP"); - return; + goto out; } uimm = (uint16_t)imm; switch (opc) { @@ -1275,15 +1324,14 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, case OPC_SLTI: case OPC_SLTIU: uimm = (target_long)imm; /* Sign extend to 32/64 bits */ - tcg_gen_movi_tl(cpu_T[1], uimm); /* Fall through. */ case OPC_ANDI: case OPC_ORI: case OPC_XORI: - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); break; case OPC_LUI: - tcg_gen_movi_tl(cpu_T[0], imm << 16); + tcg_gen_movi_tl(t0, imm << 16); break; case OPC_SLL: case OPC_SRA: @@ -1297,7 +1345,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, case OPC_DSRL32: #endif uimm &= 0x1f; - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); break; } switch (opc) { @@ -1308,12 +1356,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]); - tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm); + tcg_gen_ext32s_tl(r_tmp1, t0); + tcg_gen_addi_tl(t0, r_tmp1, uimm); tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm); tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); - tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm); + tcg_gen_xori_tl(r_tmp2, t0, uimm); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); @@ -1323,14 +1371,14 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, generate_exception(ctx, EXCP_OVERFLOW); gen_set_label(l1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); } opn = "addi"; break; case OPC_ADDIU: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_addi_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "addiu"; break; #if defined(TARGET_MIPS64) @@ -1341,12 +1389,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_mov_tl(r_tmp1, cpu_T[0]); - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_mov_tl(r_tmp1, t0); + tcg_gen_addi_tl(t0, t0, uimm); tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm); tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); - tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm); + tcg_gen_xori_tl(r_tmp2, t0, uimm); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); @@ -1359,51 +1407,51 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, opn = "daddi"; break; case OPC_DADDIU: - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_addi_tl(t0, t0, uimm); opn = "daddiu"; break; #endif case OPC_SLTI: - gen_op_lti(uimm); + gen_op_lti(t0, uimm); opn = "slti"; break; case OPC_SLTIU: - gen_op_ltiu(uimm); + gen_op_ltiu(t0, uimm); opn = "sltiu"; break; case OPC_ANDI: - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_andi_tl(t0, t0, uimm); opn = "andi"; break; case OPC_ORI: - tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_ori_tl(t0, t0, uimm); opn = "ori"; break; case OPC_XORI: - tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_xori_tl(t0, t0, uimm); opn = "xori"; break; case OPC_LUI: opn = "lui"; break; case OPC_SLL: - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_shli_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "sll"; break; case OPC_SRA: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_sari_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "sra"; break; case OPC_SRL: switch ((ctx->opcode >> 21) & 0x1f) { case 0: - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_shri_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "srl"; break; case 1: @@ -1413,21 +1461,21 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]); + tcg_gen_trunc_tl_i32(r_tmp1, t0); tcg_gen_movi_i32(r_tmp2, 0x20); tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm); tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2); tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm); tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); } opn = "rotr"; } else { - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_shri_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "srl"; } break; @@ -1439,17 +1487,17 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, break; #if defined(TARGET_MIPS64) case OPC_DSLL: - tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_shli_tl(t0, t0, uimm); opn = "dsll"; break; case OPC_DSRA: - tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_sari_tl(t0, t0, uimm); opn = "dsra"; break; case OPC_DSRL: switch ((ctx->opcode >> 21) & 0x1f) { case 0: - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_shri_tl(t0, t0, uimm); opn = "dsrl"; break; case 1: @@ -1460,14 +1508,14 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, tcg_gen_movi_tl(r_tmp1, 0x40); tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm); - tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1); - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1); + tcg_gen_shl_tl(r_tmp1, t0, r_tmp1); + tcg_gen_shri_tl(t0, t0, uimm); + tcg_gen_or_tl(t0, t0, r_tmp1); tcg_temp_free(r_tmp1); } opn = "drotr"; } else { - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_shri_tl(t0, t0, uimm); opn = "dsrl"; } break; @@ -1478,17 +1526,17 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, } break; case OPC_DSLL32: - tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32); + tcg_gen_shli_tl(t0, t0, uimm + 32); opn = "dsll32"; break; case OPC_DSRA32: - tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32); + tcg_gen_sari_tl(t0, t0, uimm + 32); opn = "dsra32"; break; case OPC_DSRL32: switch ((ctx->opcode >> 21) & 0x1f) { case 0: - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32); + tcg_gen_shri_tl(t0, t0, uimm + 32); opn = "dsrl32"; break; case 1: @@ -1501,14 +1549,14 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, tcg_gen_movi_tl(r_tmp2, 32); tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm); tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2); - tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1); - tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2); - tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1); + tcg_gen_shl_tl(r_tmp1, t0, r_tmp1); + tcg_gen_shr_tl(t0, t0, r_tmp2); + tcg_gen_or_tl(t0, t0, r_tmp1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); opn = "drotr32"; } else { - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32); + tcg_gen_shri_tl(t0, t0, uimm + 32); opn = "dsrl32"; } break; @@ -1522,10 +1570,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } - gen_store_gpr(cpu_T[0], rt); + gen_store_gpr(t0, rt); MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); + out: + tcg_temp_free(t0); } /* Arithmetic */ @@ -1533,22 +1583,24 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { const char *opn = "arith"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB && opc != OPC_DADD && opc != OPC_DSUB) { /* If no destination, treat it as a NOP. For add & sub, we must generate the overflow exception when needed. */ MIPS_DEBUG("NOP"); - return; + goto out; } - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); /* Specialcase the conventional move operation. */ if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU || opc == OPC_SUBU || opc == OPC_DSUBU)) { - gen_store_gpr(cpu_T[0], rd); - return; + gen_store_gpr(t0, rd); + goto out; } - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t1, rt); switch (opc) { case OPC_ADD: { @@ -1557,13 +1609,13 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]); - tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]); - tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2); + tcg_gen_ext32s_tl(r_tmp1, t0); + tcg_gen_ext32s_tl(r_tmp2, t1); + tcg_gen_add_tl(t0, r_tmp1, r_tmp2); - tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]); + tcg_gen_xor_tl(r_tmp1, r_tmp1, t1); tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); - tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]); + tcg_gen_xor_tl(r_tmp2, t0, t1); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); @@ -1573,15 +1625,15 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, generate_exception(ctx, EXCP_OVERFLOW); gen_set_label(l1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); } opn = "add"; break; case OPC_ADDU: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_add_tl(t0, t0, t1); + tcg_gen_ext32s_tl(t0, t0); opn = "addu"; break; case OPC_SUB: @@ -1591,12 +1643,12 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]); - tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]); - tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2); + tcg_gen_ext32s_tl(r_tmp1, t0); + tcg_gen_ext32s_tl(r_tmp2, t1); + tcg_gen_sub_tl(t0, r_tmp1, r_tmp2); - tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]); - tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]); + tcg_gen_xor_tl(r_tmp2, r_tmp1, t1); + tcg_gen_xor_tl(r_tmp1, r_tmp1, t0); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); @@ -1606,15 +1658,15 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, generate_exception(ctx, EXCP_OVERFLOW); gen_set_label(l1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); } opn = "sub"; break; case OPC_SUBU: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_sub_tl(t0, t0, t1); + tcg_gen_ext32s_tl(t0, t0); opn = "subu"; break; #if defined(TARGET_MIPS64) @@ -1625,12 +1677,12 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_mov_tl(r_tmp1, cpu_T[0]); - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(r_tmp1, t0); + tcg_gen_add_tl(t0, t0, t1); - tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]); + tcg_gen_xor_tl(r_tmp1, r_tmp1, t1); tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); - tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]); + tcg_gen_xor_tl(r_tmp2, t0, t1); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); @@ -1643,7 +1695,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, opn = "dadd"; break; case OPC_DADDU: - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_add_tl(t0, t0, t1); opn = "daddu"; break; case OPC_DSUB: @@ -1653,11 +1705,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_mov_tl(r_tmp1, cpu_T[0]); - tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(r_tmp1, t0); + tcg_gen_sub_tl(t0, t0, t1); - tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]); - tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]); + tcg_gen_xor_tl(r_tmp2, r_tmp1, t1); + tcg_gen_xor_tl(r_tmp1, r_tmp1, t0); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); @@ -1670,48 +1722,48 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, opn = "dsub"; break; case OPC_DSUBU: - tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_sub_tl(t0, t0, t1); opn = "dsubu"; break; #endif case OPC_SLT: - gen_op_lt(); + gen_op_lt(t0, t1); opn = "slt"; break; case OPC_SLTU: - gen_op_ltu(); + gen_op_ltu(t0, t1); opn = "sltu"; break; case OPC_AND: - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_and_tl(t0, t0, t1); opn = "and"; break; case OPC_NOR: - tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_not_tl(cpu_T[0], cpu_T[0]); + tcg_gen_or_tl(t0, t0, t1); + tcg_gen_not_tl(t0, t0); opn = "nor"; break; case OPC_OR: - tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_or_tl(t0, t0, t1); opn = "or"; break; case OPC_XOR: - tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_xor_tl(t0, t0, t1); opn = "xor"; break; case OPC_MUL: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_mul_tl(t0, t0, t1); + tcg_gen_ext32s_tl(t0, t0); opn = "mul"; break; case OPC_MOVN: { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); - gen_store_gpr(cpu_T[0], rd); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); + gen_store_gpr(t0, rd); gen_set_label(l1); } opn = "movn"; @@ -1720,34 +1772,34 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1); - gen_store_gpr(cpu_T[0], rd); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + gen_store_gpr(t0, rd); gen_set_label(l1); } opn = "movz"; goto print; case OPC_SLLV: - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_shl_tl(t0, t1, t0); + tcg_gen_ext32s_tl(t0, t0); opn = "sllv"; break; case OPC_SRAV: - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_sar_tl(t0, t1, t0); + tcg_gen_ext32s_tl(t0, t0); opn = "srav"; break; case OPC_SRLV: switch ((ctx->opcode >> 6) & 0x1f) { case 0: - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_shr_tl(t0, t1, t0); + tcg_gen_ext32s_tl(t0, t0); opn = "srlv"; break; case 1: @@ -1756,35 +1808,35 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); int l2 = gen_new_label(); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]); - tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]); + tcg_gen_trunc_tl_i32(r_tmp1, t0); + tcg_gen_trunc_tl_i32(r_tmp2, t1); tcg_gen_movi_i32(r_tmp3, 0x20); tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1); tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3); tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1); tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); tcg_temp_free(r_tmp3); tcg_gen_br(l2); } gen_set_label(l1); - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, t1); gen_set_label(l2); opn = "rotrv"; } else { - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_shr_tl(t0, t1, t0); + tcg_gen_ext32s_tl(t0, t0); opn = "srlv"; } break; @@ -1796,20 +1848,20 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, break; #if defined(TARGET_MIPS64) case OPC_DSLLV: - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_shl_tl(t0, t1, t0); opn = "dsllv"; break; case OPC_DSRAV: - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_sar_tl(t0, t1, t0); opn = "dsrav"; break; case OPC_DSRLV: switch ((ctx->opcode >> 6) & 0x1f) { case 0: - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_shr_tl(t0, t1, t0); opn = "dsrlv"; break; case 1: @@ -1818,26 +1870,26 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); int l2 = gen_new_label(); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); tcg_gen_movi_tl(r_tmp1, 0x40); - tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]); - tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1); + tcg_gen_sub_tl(r_tmp1, r_tmp1, t0); + tcg_gen_shl_tl(r_tmp1, t1, r_tmp1); + tcg_gen_shr_tl(t0, t1, t0); + tcg_gen_or_tl(t0, t0, r_tmp1); tcg_temp_free(r_tmp1); tcg_gen_br(l2); } gen_set_label(l1); - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, t1); gen_set_label(l2); opn = "drotrv"; } else { - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_shr_tl(t0, t1, t0); opn = "dsrlv"; } break; @@ -1851,85 +1903,93 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } - gen_store_gpr(cpu_T[0], rd); + gen_store_gpr(t0, rd); print: MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } /* Arithmetic on HI/LO registers */ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) { const char *opn = "hilo"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as NOP. */ MIPS_DEBUG("NOP"); - return; + goto out; } switch (opc) { case OPC_MFHI: - gen_load_HI(cpu_T[0], 0); - gen_store_gpr(cpu_T[0], reg); + gen_load_HI(t0, 0); + gen_store_gpr(t0, reg); opn = "mfhi"; break; case OPC_MFLO: - gen_load_LO(cpu_T[0], 0); - gen_store_gpr(cpu_T[0], reg); + gen_load_LO(t0, 0); + gen_store_gpr(t0, reg); opn = "mflo"; break; case OPC_MTHI: - gen_load_gpr(cpu_T[0], reg); - gen_store_HI(cpu_T[0], 0); + gen_load_gpr(t0, reg); + gen_store_HI(t0, 0); opn = "mthi"; break; case OPC_MTLO: - gen_load_gpr(cpu_T[0], reg); - gen_store_LO(cpu_T[0], 0); + gen_load_gpr(t0, reg); + gen_store_LO(t0, 0); opn = "mtlo"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s", opn, regnames[reg]); + out: + tcg_temp_free(t0); } static void gen_muldiv (DisasContext *ctx, uint32_t opc, int rs, int rt) { const char *opn = "mul/div"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); - gen_load_gpr(cpu_T[0], rs); - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); switch (opc) { case OPC_DIV: { int l1 = gen_new_label(); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); - tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_ext_tl_i64(r_tmp1, t0); + tcg_gen_ext_tl_i64(r_tmp2, t1); tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2); tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2); - tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3); - tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2); + tcg_gen_trunc_i64_tl(t0, r_tmp3); + tcg_gen_trunc_i64_tl(t1, r_tmp2); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); tcg_temp_free(r_tmp3); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } gen_set_label(l1); } @@ -1939,35 +1999,71 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]); - tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]); + tcg_gen_trunc_tl_i32(r_tmp1, t0); + tcg_gen_trunc_tl_i32(r_tmp2, t1); tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2); tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3); - tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp3); + tcg_gen_ext_i32_tl(t1, r_tmp1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); tcg_temp_free(r_tmp3); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } gen_set_label(l1); } opn = "divu"; break; case OPC_MULT: - gen_op_mult(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_ext_tl_i64(r_tmp1, t0); + tcg_gen_ext_tl_i64(r_tmp2, t1); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(t0, r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(t1, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); + } opn = "mult"; break; case OPC_MULTU: - gen_op_multu(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(r_tmp1, t0); + tcg_gen_extu_tl_i64(r_tmp2, t1); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(t0, r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(t1, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); + } opn = "multu"; break; #if defined(TARGET_MIPS64) @@ -1975,16 +2071,16 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); { int l2 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], -1LL << 63, l2); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1LL, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); { - tcg_gen_movi_tl(cpu_T[1], 0); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_movi_tl(t1, 0); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); tcg_gen_br(l1); } gen_set_label(l2); @@ -1992,8 +2088,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]); - tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]); + tcg_gen_div_i64(r_tmp1, t0, t1); + tcg_gen_rem_i64(r_tmp2, t0, t1); gen_store_LO(r_tmp1, 0); gen_store_HI(r_tmp2, 0); tcg_temp_free(r_tmp1); @@ -2008,13 +2104,13 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]); - tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]); + tcg_gen_divu_i64(r_tmp1, t0, t1); + tcg_gen_remu_i64(r_tmp2, t0, t1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); gen_store_LO(r_tmp1, 0); @@ -2025,148 +2121,270 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, opn = "ddivu"; break; case OPC_DMULT: - gen_op_dmult(); + tcg_gen_helper_0_2(do_dmult, t0, t1); opn = "dmult"; break; case OPC_DMULTU: - gen_op_dmultu(); + tcg_gen_helper_0_2(do_dmultu, t0, t1); opn = "dmultu"; break; #endif case OPC_MADD: - gen_op_madd(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_ext_tl_i64(r_tmp1, t0); + tcg_gen_ext_tl_i64(r_tmp2, t1); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + gen_load_LO(t0, 0); + gen_load_HI(t1, 0); + tcg_gen_extu_tl_i64(r_tmp2, t0); + tcg_gen_extu_tl_i64(r_tmp3, t1); + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); + tcg_temp_free(r_tmp3); + tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(t0, r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(t1, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); + } opn = "madd"; break; case OPC_MADDU: - gen_op_maddu(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(r_tmp1, t0); + tcg_gen_extu_tl_i64(r_tmp2, t1); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + gen_load_LO(t0, 0); + gen_load_HI(t1, 0); + tcg_gen_extu_tl_i64(r_tmp2, t0); + tcg_gen_extu_tl_i64(r_tmp3, t1); + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); + tcg_temp_free(r_tmp3); + tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(t0, r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(t1, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); + } opn = "maddu"; break; case OPC_MSUB: - gen_op_msub(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_ext_tl_i64(r_tmp1, t0); + tcg_gen_ext_tl_i64(r_tmp2, t1); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + gen_load_LO(t0, 0); + gen_load_HI(t1, 0); + tcg_gen_extu_tl_i64(r_tmp2, t0); + tcg_gen_extu_tl_i64(r_tmp3, t1); + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); + tcg_temp_free(r_tmp3); + tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(t0, r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(t1, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); + } opn = "msub"; break; case OPC_MSUBU: - gen_op_msubu(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(r_tmp1, t0); + tcg_gen_extu_tl_i64(r_tmp2, t1); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + gen_load_LO(t0, 0); + gen_load_HI(t1, 0); + tcg_gen_extu_tl_i64(r_tmp2, t0); + tcg_gen_extu_tl_i64(r_tmp3, t1); + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); + tcg_temp_free(r_tmp3); + tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(t0, r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(t1, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); + } opn = "msubu"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]); + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { const char *opn = "mul vr54xx"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); - gen_load_gpr(cpu_T[0], rs); - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); switch (opc) { case OPC_VR54XX_MULS: - gen_op_muls(); + tcg_gen_helper_1_2(do_muls, t0, t0, t1); opn = "muls"; break; case OPC_VR54XX_MULSU: - gen_op_mulsu(); + tcg_gen_helper_1_2(do_mulsu, t0, t0, t1); opn = "mulsu"; break; case OPC_VR54XX_MACC: - gen_op_macc(); + tcg_gen_helper_1_2(do_macc, t0, t0, t1); opn = "macc"; break; case OPC_VR54XX_MACCU: - gen_op_maccu(); + tcg_gen_helper_1_2(do_maccu, t0, t0, t1); opn = "maccu"; break; case OPC_VR54XX_MSAC: - gen_op_msac(); + tcg_gen_helper_1_2(do_msac, t0, t0, t1); opn = "msac"; break; case OPC_VR54XX_MSACU: - gen_op_msacu(); + tcg_gen_helper_1_2(do_msacu, t0, t0, t1); opn = "msacu"; break; case OPC_VR54XX_MULHI: - gen_op_mulhi(); + tcg_gen_helper_1_2(do_mulhi, t0, t0, t1); opn = "mulhi"; break; case OPC_VR54XX_MULHIU: - gen_op_mulhiu(); + tcg_gen_helper_1_2(do_mulhiu, t0, t0, t1); opn = "mulhiu"; break; case OPC_VR54XX_MULSHI: - gen_op_mulshi(); + tcg_gen_helper_1_2(do_mulshi, t0, t0, t1); opn = "mulshi"; break; case OPC_VR54XX_MULSHIU: - gen_op_mulshiu(); + tcg_gen_helper_1_2(do_mulshiu, t0, t0, t1); opn = "mulshiu"; break; case OPC_VR54XX_MACCHI: - gen_op_macchi(); + tcg_gen_helper_1_2(do_macchi, t0, t0, t1); opn = "macchi"; break; case OPC_VR54XX_MACCHIU: - gen_op_macchiu(); + tcg_gen_helper_1_2(do_macchiu, t0, t0, t1); opn = "macchiu"; break; case OPC_VR54XX_MSACHI: - gen_op_msachi(); + tcg_gen_helper_1_2(do_msachi, t0, t0, t1); opn = "msachi"; break; case OPC_VR54XX_MSACHIU: - gen_op_msachiu(); + tcg_gen_helper_1_2(do_msachiu, t0, t0, t1); opn = "msachiu"; break; default: MIPS_INVAL("mul vr54xx"); generate_exception(ctx, EXCP_RI); - return; + goto out; } - gen_store_gpr(cpu_T[0], rd); + gen_store_gpr(t0, rd); MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); + + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } static void gen_cl (DisasContext *ctx, uint32_t opc, int rd, int rs) { const char *opn = "CLx"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + if (rd == 0) { /* Treat as NOP. */ MIPS_DEBUG("NOP"); - return; + goto out; } - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); switch (opc) { case OPC_CLO: - tcg_gen_helper_0_0(do_clo); + tcg_gen_helper_1_1(do_clo, t0, t0); opn = "clo"; break; case OPC_CLZ: - tcg_gen_helper_0_0(do_clz); + tcg_gen_helper_1_1(do_clz, t0, t0); opn = "clz"; break; #if defined(TARGET_MIPS64) case OPC_DCLO: - tcg_gen_helper_0_0(do_dclo); + tcg_gen_helper_1_1(do_dclo, t0, t0); opn = "dclo"; break; case OPC_DCLZ: - tcg_gen_helper_0_0(do_dclz); + tcg_gen_helper_1_1(do_dclz, t0, t0); opn = "dclz"; break; #endif default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } - gen_store_gpr(cpu_T[0], rd); + gen_store_gpr(t0, rd); MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]); + + out: + tcg_temp_free(t0); } /* Traps */ @@ -2174,6 +2392,8 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, int rs, int rt, int16_t imm) { int cond; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); cond = 0; /* Load needed operands */ @@ -2186,8 +2406,8 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, case OPC_TNE: /* Compare two registers */ if (rs != rt) { - gen_load_gpr(cpu_T[0], rs); - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); cond = 1; } break; @@ -2199,8 +2419,8 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, case OPC_TNEI: /* Compare register to immediate */ if (rs != 0 || imm != 0) { - gen_load_gpr(cpu_T[0], rs); - tcg_gen_movi_tl(cpu_T[1], (int32_t)imm); + gen_load_gpr(t0, rs); + tcg_gen_movi_tl(t1, (int32_t)imm); cond = 1; } break; @@ -2214,7 +2434,7 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, case OPC_TGEU: /* rs >= rs unsigned */ case OPC_TGEIU: /* r0 >= 0 unsigned */ /* Always trap */ - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); break; case OPC_TLT: /* rs < rs */ case OPC_TLTI: /* r0 < 0 */ @@ -2223,47 +2443,56 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, case OPC_TNE: /* rs != rs */ case OPC_TNEI: /* r0 != 0 */ /* Never trap: treat as NOP. */ - return; + goto out; default: MIPS_INVAL("trap"); generate_exception(ctx, EXCP_RI); - return; + goto out; } } else { switch (opc) { case OPC_TEQ: case OPC_TEQI: - gen_op_eq(); + gen_op_eq(t0, t1); break; case OPC_TGE: case OPC_TGEI: - gen_op_ge(); + gen_op_ge(t0, t1); break; case OPC_TGEU: case OPC_TGEIU: - gen_op_geu(); + gen_op_geu(t0, t1); break; case OPC_TLT: case OPC_TLTI: - gen_op_lt(); + gen_op_lt(t0, t1); break; case OPC_TLTU: case OPC_TLTIU: - gen_op_ltu(); + gen_op_ltu(t0, t1); break; case OPC_TNE: case OPC_TNEI: - gen_op_ne(); + gen_op_ne(t0, t1); break; default: MIPS_INVAL("trap"); generate_exception(ctx, EXCP_RI); - return; + goto out; } } save_cpu_state(ctx, 1); - gen_op_trap(); + { + int l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); + tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP); + gen_set_label(l1); + } ctx->bstate = BS_STOP; + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) @@ -2287,6 +2516,8 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, target_ulong btarget = -1; int blink = 0; int bcond = 0; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (ctx->hflags & MIPS_HFLAG_BMASK) { #ifdef MIPS_DEBUG_DISAS @@ -2297,7 +2528,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, } #endif generate_exception(ctx, EXCP_RI); - return; + goto out; } /* Load needed operands */ @@ -2308,8 +2539,8 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, case OPC_BNEL: /* Compare two registers */ if (rs != rt) { - gen_load_gpr(cpu_T[0], rs); - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); bcond = 1; } btarget = ctx->pc + 4 + offset; @@ -2328,7 +2559,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, case OPC_BLTZL: /* Compare to zero */ if (rs != 0) { - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); bcond = 1; } btarget = ctx->pc + 4 + offset; @@ -2346,14 +2577,14 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, others are reserved. */ MIPS_INVAL("jump hint"); generate_exception(ctx, EXCP_RI); - return; + goto out; } gen_save_breg_target(rs); break; default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); - return; + goto out; } if (bcond == 0) { /* No condition to be computed */ @@ -2380,26 +2611,26 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, case OPC_BLTZ: /* 0 < 0 */ /* Treat as NOP. */ MIPS_DEBUG("bnever (NOP)"); - return; + goto out; case OPC_BLTZAL: /* 0 < 0 */ - tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8); - gen_store_gpr(cpu_T[0], 31); + tcg_gen_movi_tl(t0, ctx->pc + 8); + gen_store_gpr(t0, 31); MIPS_DEBUG("bnever and link"); - return; + goto out; case OPC_BLTZALL: /* 0 < 0 likely */ - tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8); - gen_store_gpr(cpu_T[0], 31); + tcg_gen_movi_tl(t0, ctx->pc + 8); + gen_store_gpr(t0, 31); /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever, link and skip"); ctx->pc += 4; - return; + goto out; case OPC_BNEL: /* rx != rx likely */ case OPC_BGTZL: /* 0 > 0 likely */ case OPC_BLTZL: /* 0 < 0 likely */ /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever and skip"); ctx->pc += 4; - return; + goto out; case OPC_J: ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("j " TARGET_FMT_lx, btarget); @@ -2421,92 +2652,92 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); - return; + goto out; } } else { switch (opc) { case OPC_BEQ: - gen_op_eq(); + gen_op_eq(t0, t1); MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BEQL: - gen_op_eq(); + gen_op_eq(t0, t1); MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BNE: - gen_op_ne(); + gen_op_ne(t0, t1); MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BNEL: - gen_op_ne(); + gen_op_ne(t0, t1); MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BGEZ: - gen_op_gez(); + gen_op_gez(t0); MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGEZL: - gen_op_gez(); + gen_op_gez(t0); MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGEZAL: - gen_op_gez(); + gen_op_gez(t0); MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget); blink = 31; goto not_likely; case OPC_BGEZALL: - gen_op_gez(); + gen_op_gez(t0); blink = 31; MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGTZ: - gen_op_gtz(); + gen_op_gtz(t0); MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGTZL: - gen_op_gtz(); + gen_op_gtz(t0); MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLEZ: - gen_op_lez(); + gen_op_lez(t0); MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLEZL: - gen_op_lez(); + gen_op_lez(t0); MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZ: - gen_op_ltz(); + gen_op_ltz(t0); MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLTZL: - gen_op_ltz(); + gen_op_ltz(t0); MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZAL: - gen_op_ltz(); + gen_op_ltz(t0); blink = 31; MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget); not_likely: ctx->hflags |= MIPS_HFLAG_BC; - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond)); break; case OPC_BLTZALL: - gen_op_ltz(); + gen_op_ltz(t0); blink = 31; MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget); likely: ctx->hflags |= MIPS_HFLAG_BL; - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond)); break; default: MIPS_INVAL("conditional branch/jump"); generate_exception(ctx, EXCP_RI); - return; + goto out; } } MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, @@ -2514,75 +2745,87 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, ctx->btarget = btarget; if (blink > 0) { - tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8); - gen_store_gpr(cpu_T[0], blink); + tcg_gen_movi_tl(t0, ctx->pc + 8); + gen_store_gpr(t0, blink); } + + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } /* special3 bitfield operations */ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, int rs, int lsb, int msb) { - gen_load_gpr(cpu_T[1], rs); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t1, rs); switch (opc) { case OPC_EXT: if (lsb + msb > 31) goto fail; - gen_op_ext(lsb, msb + 1); + tcg_gen_helper_1_2ii(do_ext, t0, t0, t1, lsb, msb + 1); break; #if defined(TARGET_MIPS64) case OPC_DEXTM: if (lsb + msb > 63) goto fail; - gen_op_dext(lsb, msb + 1 + 32); + tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb, msb + 1 + 32); break; case OPC_DEXTU: if (lsb + msb > 63) goto fail; - gen_op_dext(lsb + 32, msb + 1); + tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb + 32, msb + 1); break; case OPC_DEXT: if (lsb + msb > 63) goto fail; - gen_op_dext(lsb, msb + 1); + tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb, msb + 1); break; #endif case OPC_INS: if (lsb > msb) goto fail; - gen_load_gpr(cpu_T[0], rt); - gen_op_ins(lsb, msb - lsb + 1); + gen_load_gpr(t0, rt); + tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1); break; #if defined(TARGET_MIPS64) case OPC_DINSM: if (lsb > msb) goto fail; - gen_load_gpr(cpu_T[0], rt); - gen_op_dins(lsb, msb - lsb + 1 + 32); + gen_load_gpr(t0, rt); + tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32); break; case OPC_DINSU: if (lsb > msb) goto fail; - gen_load_gpr(cpu_T[0], rt); - gen_op_dins(lsb + 32, msb - lsb + 1); + gen_load_gpr(t0, rt); + tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1); break; case OPC_DINS: if (lsb > msb) goto fail; - gen_load_gpr(cpu_T[0], rt); - gen_op_dins(lsb, msb - lsb + 1); + gen_load_gpr(t0, rt); + tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1); break; #endif default: fail: MIPS_INVAL("bitops"); generate_exception(ctx, EXCP_RI); + tcg_temp_free(t0); + tcg_temp_free(t1); return; } - gen_store_gpr(cpu_T[0], rt); + gen_store_gpr(t0, rt); + tcg_temp_free(t0); + tcg_temp_free(t1); } /* CP0 (MMU and control) */ +#ifndef CONFIG_USER_ONLY static inline void gen_mfc0_load32 (TCGv t, target_ulong off) { TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); @@ -2594,14 +2837,26 @@ static inline void gen_mfc0_load32 (TCGv t, target_ulong off) static inline void gen_mfc0_load64 (TCGv t, target_ulong off) { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I64); + tcg_gen_ld_tl(t, cpu_env, off); + tcg_gen_ext32s_tl(t, t); +} + +static inline void gen_mtc0_store32 (TCGv t, target_ulong off) +{ + TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_ld_i64(r_tmp, cpu_env, off); - tcg_gen_trunc_i64_tl(t, r_tmp); + tcg_gen_trunc_tl_i32(r_tmp, t); + tcg_gen_st_i32(r_tmp, cpu_env, off); tcg_temp_free(r_tmp); } -static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) +static inline void gen_mtc0_store64 (TCGv t, target_ulong off) +{ + tcg_gen_ext32s_tl(t, t); + tcg_gen_st_tl(t, cpu_env, off); +} + +static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel) { const char *rn = "invalid"; @@ -2612,22 +2867,22 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index)); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpcontrol(); + tcg_gen_helper_1_0(do_mfc0_mvpcontrol, t0); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpconf0(); + tcg_gen_helper_1_0(do_mfc0_mvpconf0, t0); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpconf1(); + tcg_gen_helper_1_0(do_mfc0_mvpconf1, t0); rn = "MVPConf1"; break; default: @@ -2637,42 +2892,42 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 1: switch (sel) { case 0: - gen_op_mfc0_random(); + tcg_gen_helper_1_0(do_mfc0_random, t0); rn = "Random"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl)); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0)); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1)); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_YQMask)); + gen_mfc0_load64(t0, offsetof(CPUState, CP0_YQMask)); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule)); + gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack)); + gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt)); rn = "VPEOpt"; break; default: @@ -2682,43 +2937,43 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0)); + tcg_gen_ext32s_tl(t0, t0); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcstatus(); + tcg_gen_helper_1_0(do_mfc0_tcstatus, t0); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcbind(); + tcg_gen_helper_1_0(do_mfc0_tcbind, t0); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcrestart(); + tcg_gen_helper_1_0(do_mfc0_tcrestart, t0); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tchalt(); + tcg_gen_helper_1_0(do_mfc0_tchalt, t0); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tccontext(); + tcg_gen_helper_1_0(do_mfc0_tccontext, t0); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcschedule(); + tcg_gen_helper_1_0(do_mfc0_tcschedule, t0); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcschefback(); + tcg_gen_helper_1_0(do_mfc0_tcschefback, t0); rn = "TCScheFBack"; break; default: @@ -2728,8 +2983,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1)); + tcg_gen_ext32s_tl(t0, t0); rn = "EntryLo1"; break; default: @@ -2739,12 +2994,12 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context)); + tcg_gen_ext32s_tl(t0, t0); rn = "Context"; break; case 1: -// gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */ +// tcg_gen_helper_1_0(do_mfc0_contextconfig, t0); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -2754,12 +3009,12 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask)); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain)); rn = "PageGrain"; break; default: @@ -2769,32 +3024,32 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired)); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0)); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1)); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2)); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3)); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4)); rn = "SRSConf4"; break; default: @@ -2805,7 +3060,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna)); rn = "HWREna"; break; default: @@ -2815,8 +3070,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 8: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr)); + tcg_gen_ext32s_tl(t0, t0); rn = "BadVAddr"; break; default: @@ -2826,7 +3081,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - gen_op_mfc0_count(); + tcg_gen_helper_1_0(do_mfc0_count, t0); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -2837,8 +3092,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi)); + tcg_gen_ext32s_tl(t0, t0); rn = "EntryHi"; break; default: @@ -2848,7 +3103,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare)); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -2859,22 +3114,22 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status)); rn = "Status"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl)); rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl)); rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap)); rn = "SRSMap"; break; default: @@ -2884,7 +3139,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause)); rn = "Cause"; break; default: @@ -2894,8 +3149,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC)); + tcg_gen_ext32s_tl(t0, t0); rn = "EPC"; break; default: @@ -2905,12 +3160,12 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 15: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid)); rn = "PRid"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase)); rn = "EBase"; break; default: @@ -2920,29 +3175,29 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0)); rn = "Config"; break; case 1: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1)); rn = "Config1"; break; case 2: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2)); rn = "Config2"; break; case 3: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3)); rn = "Config3"; break; /* 4,5 are reserved */ /* 6,7 are implementation dependent */ case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6)); rn = "Config6"; break; case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7)); rn = "Config7"; break; default: @@ -2952,7 +3207,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 17: switch (sel) { case 0: - gen_op_mfc0_lladdr(); + tcg_gen_helper_1_0(do_mfc0_lladdr, t0); rn = "LLAddr"; break; default: @@ -2962,7 +3217,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - gen_op_mfc0_watchlo(sel); + tcg_gen_helper_1_i(do_mfc0_watchlo, t0, sel); rn = "WatchLo"; break; default: @@ -2972,7 +3227,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ...7: - gen_op_mfc0_watchhi(sel); + tcg_gen_helper_1_i(do_mfc0_watchhi, t0, sel); rn = "WatchHi"; break; default: @@ -2984,8 +3239,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: #if defined(TARGET_MIPS64) check_insn(env, ctx, ISA_MIPS3); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext)); + tcg_gen_ext32s_tl(t0, t0); rn = "XContext"; break; #endif @@ -2997,7 +3252,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask)); rn = "Framemask"; break; default: @@ -3011,23 +3266,23 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - gen_op_mfc0_debug(); /* EJTAG support */ + tcg_gen_helper_1_0(do_mfc0_debug, t0); /* EJTAG support */ rn = "Debug"; break; case 1: -// gen_op_mfc0_tracecontrol(); /* PDtrace support */ +// tcg_gen_helper_1_0(do_mfc0_tracecontrol, t0); /* PDtrace support */ rn = "TraceControl"; // break; case 2: -// gen_op_mfc0_tracecontrol2(); /* PDtrace support */ +// tcg_gen_helper_1_0(do_mfc0_tracecontrol2, t0); /* PDtrace support */ rn = "TraceControl2"; // break; case 3: -// gen_op_mfc0_usertracedata(); /* PDtrace support */ +// tcg_gen_helper_1_0(do_mfc0_usertracedata, t0); /* PDtrace support */ rn = "UserTraceData"; // break; case 4: -// gen_op_mfc0_debug(); /* PDtrace support */ +// tcg_gen_helper_1_0(do_mfc0_tracebpc, t0); /* PDtrace support */ rn = "TraceBPC"; // break; default: @@ -3038,8 +3293,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC)); + tcg_gen_ext32s_tl(t0, t0); rn = "DEPC"; break; default: @@ -3049,35 +3304,35 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0)); rn = "Performance0"; break; case 1: -// gen_op_mfc0_performance1(); +// tcg_gen_helper_1_0(do_mfc0_performance1, t0); rn = "Performance1"; // break; case 2: -// gen_op_mfc0_performance2(); +// tcg_gen_helper_1_0(do_mfc0_performance2, t0); rn = "Performance2"; // break; case 3: -// gen_op_mfc0_performance3(); +// tcg_gen_helper_1_0(do_mfc0_performance3, t0); rn = "Performance3"; // break; case 4: -// gen_op_mfc0_performance4(); +// tcg_gen_helper_1_0(do_mfc0_performance4, t0); rn = "Performance4"; // break; case 5: -// gen_op_mfc0_performance5(); +// tcg_gen_helper_1_0(do_mfc0_performance5, t0); rn = "Performance5"; // break; case 6: -// gen_op_mfc0_performance6(); +// tcg_gen_helper_1_0(do_mfc0_performance6, t0); rn = "Performance6"; // break; case 7: -// gen_op_mfc0_performance7(); +// tcg_gen_helper_1_0(do_mfc0_performance7, t0); rn = "Performance7"; // break; default: @@ -3103,14 +3358,14 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo)); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo)); rn = "DataLo"; break; default: @@ -3123,14 +3378,14 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi)); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi)); rn = "DataHi"; break; default: @@ -3140,8 +3395,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC)); + tcg_gen_ext32s_tl(t0, t0); rn = "ErrorEPC"; break; default: @@ -3152,7 +3407,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -3180,7 +3435,7 @@ die: generate_exception(ctx, EXCP_RI); } -static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) +static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel) { const char *rn = "invalid"; @@ -3191,12 +3446,12 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - gen_op_mtc0_index(); + tcg_gen_helper_0_1(do_mtc0_index, t0); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_mvpcontrol(); + tcg_gen_helper_0_1(do_mtc0_mvpcontrol, t0); rn = "MVPControl"; break; case 2: @@ -3221,37 +3476,37 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpecontrol(); + tcg_gen_helper_0_1(do_mtc0_vpecontrol, t0); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeconf0(); + tcg_gen_helper_0_1(do_mtc0_vpeconf0, t0); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeconf1(); + tcg_gen_helper_0_1(do_mtc0_vpeconf1, t0); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_yqmask(); + tcg_gen_helper_0_1(do_mtc0_yqmask, t0); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeschedule(); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeschefback(); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeopt(); + tcg_gen_helper_0_1(do_mtc0_vpeopt, t0); rn = "VPEOpt"; break; default: @@ -3261,42 +3516,42 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - gen_op_mtc0_entrylo0(); + tcg_gen_helper_0_1(do_mtc0_entrylo0, t0); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcstatus(); + tcg_gen_helper_0_1(do_mtc0_tcstatus, t0); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcbind(); + tcg_gen_helper_0_1(do_mtc0_tcbind, t0); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcrestart(); + tcg_gen_helper_0_1(do_mtc0_tcrestart, t0); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tchalt(); + tcg_gen_helper_0_1(do_mtc0_tchalt, t0); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tccontext(); + tcg_gen_helper_0_1(do_mtc0_tccontext, t0); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcschedule(); + tcg_gen_helper_0_1(do_mtc0_tcschedule, t0); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcschefback(); + tcg_gen_helper_0_1(do_mtc0_tcschefback, t0); rn = "TCScheFBack"; break; default: @@ -3306,7 +3561,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - gen_op_mtc0_entrylo1(); + tcg_gen_helper_0_1(do_mtc0_entrylo1, t0); rn = "EntryLo1"; break; default: @@ -3316,11 +3571,11 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - gen_op_mtc0_context(); + tcg_gen_helper_0_1(do_mtc0_context, t0); rn = "Context"; break; case 1: -// gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */ +// tcg_gen_helper_0_1(do_mtc0_contextconfig, t0); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -3330,12 +3585,12 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - gen_op_mtc0_pagemask(); + tcg_gen_helper_0_1(do_mtc0_pagemask, t0); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_pagegrain(); + tcg_gen_helper_0_1(do_mtc0_pagegrain, t0); rn = "PageGrain"; break; default: @@ -3345,32 +3600,32 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - gen_op_mtc0_wired(); + tcg_gen_helper_0_1(do_mtc0_wired, t0); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf0(); + tcg_gen_helper_0_1(do_mtc0_srsconf0, t0); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf1(); + tcg_gen_helper_0_1(do_mtc0_srsconf1, t0); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf2(); + tcg_gen_helper_0_1(do_mtc0_srsconf2, t0); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf3(); + tcg_gen_helper_0_1(do_mtc0_srsconf3, t0); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf4(); + tcg_gen_helper_0_1(do_mtc0_srsconf4, t0); rn = "SRSConf4"; break; default: @@ -3381,7 +3636,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_hwrena(); + tcg_gen_helper_0_1(do_mtc0_hwrena, t0); rn = "HWREna"; break; default: @@ -3395,7 +3650,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - gen_op_mtc0_count(); + tcg_gen_helper_0_1(do_mtc0_count, t0); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -3408,7 +3663,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - gen_op_mtc0_entryhi(); + tcg_gen_helper_0_1(do_mtc0_entryhi, t0); rn = "EntryHi"; break; default: @@ -3418,7 +3673,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - gen_op_mtc0_compare(); + tcg_gen_helper_0_1(do_mtc0_compare, t0); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -3431,7 +3686,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - gen_op_mtc0_status(); + tcg_gen_helper_0_1(do_mtc0_status, t0); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; @@ -3439,21 +3694,21 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_intctl(); + tcg_gen_helper_0_1(do_mtc0_intctl, t0); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsctl(); + tcg_gen_helper_0_1(do_mtc0_srsctl, t0); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsmap(); + gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSMap"; @@ -3465,7 +3720,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - gen_op_mtc0_cause(); + tcg_gen_helper_0_1(do_mtc0_cause, t0); rn = "Cause"; break; default: @@ -3477,7 +3732,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - gen_op_mtc0_epc(); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC)); rn = "EPC"; break; default: @@ -3492,7 +3747,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_ebase(); + tcg_gen_helper_0_1(do_mtc0_ebase, t0); rn = "EBase"; break; default: @@ -3502,7 +3757,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_op_mtc0_config0(); + tcg_gen_helper_0_1(do_mtc0_config0, t0); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3512,7 +3767,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Config1"; break; case 2: - gen_op_mtc0_config2(); + tcg_gen_helper_0_1(do_mtc0_config2, t0); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3549,7 +3804,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - gen_op_mtc0_watchlo(sel); + tcg_gen_helper_0_1i(do_mtc0_watchlo, t0, sel); rn = "WatchLo"; break; default: @@ -3559,7 +3814,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - gen_op_mtc0_watchhi(sel); + tcg_gen_helper_0_1i(do_mtc0_watchhi, t0, sel); rn = "WatchHi"; break; default: @@ -3571,7 +3826,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: #if defined(TARGET_MIPS64) check_insn(env, ctx, ISA_MIPS3); - gen_op_mtc0_xcontext(); + tcg_gen_helper_0_1(do_mtc0_xcontext, t0); rn = "XContext"; break; #endif @@ -3583,7 +3838,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - gen_op_mtc0_framemask(); + tcg_gen_helper_0_1(do_mtc0_framemask, t0); rn = "Framemask"; break; default: @@ -3597,20 +3852,20 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - gen_op_mtc0_debug(); /* EJTAG support */ + tcg_gen_helper_0_1(do_mtc0_debug, t0); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: -// gen_op_mtc0_tracecontrol(); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol, t0); /* PDtrace support */ rn = "TraceControl"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 2: -// gen_op_mtc0_tracecontrol2(); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol2, t0); /* PDtrace support */ rn = "TraceControl2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3618,13 +3873,13 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; -// gen_op_mtc0_usertracedata(); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_usertracedata, t0); /* PDtrace support */ rn = "UserTraceData"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 4: -// gen_op_mtc0_debug(); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracebpc, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; @@ -3636,7 +3891,8 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 24: switch (sel) { case 0: - gen_op_mtc0_depc(); /* EJTAG support */ + /* EJTAG support */ + gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC)); rn = "DEPC"; break; default: @@ -3646,35 +3902,35 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - gen_op_mtc0_performance0(); + tcg_gen_helper_0_1(do_mtc0_performance0, t0); rn = "Performance0"; break; case 1: -// gen_op_mtc0_performance1(); +// tcg_gen_helper_0_1(do_mtc0_performance1, t0); rn = "Performance1"; // break; case 2: -// gen_op_mtc0_performance2(); +// tcg_gen_helper_0_1(do_mtc0_performance2, t0); rn = "Performance2"; // break; case 3: -// gen_op_mtc0_performance3(); +// tcg_gen_helper_0_1(do_mtc0_performance3, t0); rn = "Performance3"; // break; case 4: -// gen_op_mtc0_performance4(); +// tcg_gen_helper_0_1(do_mtc0_performance4, t0); rn = "Performance4"; // break; case 5: -// gen_op_mtc0_performance5(); +// tcg_gen_helper_0_1(do_mtc0_performance5, t0); rn = "Performance5"; // break; case 6: -// gen_op_mtc0_performance6(); +// tcg_gen_helper_0_1(do_mtc0_performance6, t0); rn = "Performance6"; // break; case 7: -// gen_op_mtc0_performance7(); +// tcg_gen_helper_0_1(do_mtc0_performance7, t0); rn = "Performance7"; // break; default: @@ -3701,14 +3957,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_op_mtc0_taglo(); + tcg_gen_helper_0_1(do_mtc0_taglo, t0); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - gen_op_mtc0_datalo(); + tcg_gen_helper_0_1(do_mtc0_datalo, t0); rn = "DataLo"; break; default: @@ -3721,14 +3977,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_op_mtc0_taghi(); + tcg_gen_helper_0_1(do_mtc0_taghi, t0); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - gen_op_mtc0_datahi(); + tcg_gen_helper_0_1(do_mtc0_datahi, t0); rn = "DataHi"; break; default: @@ -3739,7 +3995,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - gen_op_mtc0_errorepc(); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC)); rn = "ErrorEPC"; break; default: @@ -3749,7 +4005,8 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 31: switch (sel) { case 0: - gen_op_mtc0_desave(); /* EJTAG support */ + /* EJTAG support */ + gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -3780,7 +4037,7 @@ die: } #if defined(TARGET_MIPS64) -static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) +static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel) { const char *rn = "invalid"; @@ -3791,22 +4048,22 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index)); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpcontrol(); + tcg_gen_helper_1_0(do_mfc0_mvpcontrol, t0); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpconf0(); + tcg_gen_helper_1_0(do_mfc0_mvpconf0, t0); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpconf1(); + tcg_gen_helper_1_0(do_mfc0_mvpconf1, t0); rn = "MVPConf1"; break; default: @@ -3816,42 +4073,42 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 1: switch (sel) { case 0: - gen_op_mfc0_random(); + tcg_gen_helper_1_0(do_mfc0_random, t0); rn = "Random"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl)); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0)); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1)); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_YQMask)); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt)); rn = "VPEOpt"; break; default: @@ -3861,42 +4118,42 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0)); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcstatus(); + tcg_gen_helper_1_0(do_mfc0_tcstatus, t0); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcbind(); + tcg_gen_helper_1_0(do_mfc0_tcbind, t0); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tcrestart(); + tcg_gen_helper_1_0(do_dmfc0_tcrestart, t0); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tchalt(); + tcg_gen_helper_1_0(do_dmfc0_tchalt, t0); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tccontext(); + tcg_gen_helper_1_0(do_dmfc0_tccontext, t0); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tcschedule(); + tcg_gen_helper_1_0(do_dmfc0_tcschedule, t0); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tcschefback(); + tcg_gen_helper_1_0(do_dmfc0_tcschefback, t0); rn = "TCScheFBack"; break; default: @@ -3906,7 +4163,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1)); rn = "EntryLo1"; break; default: @@ -3916,11 +4173,11 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context)); rn = "Context"; break; case 1: -// gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */ +// tcg_gen_helper_1_0(do_dmfc0_contextconfig, t0); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -3930,12 +4187,12 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask)); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain)); rn = "PageGrain"; break; default: @@ -3945,32 +4202,32 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired)); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0)); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1)); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2)); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3)); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4)); rn = "SRSConf4"; break; default: @@ -3981,7 +4238,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna)); rn = "HWREna"; break; default: @@ -3991,7 +4248,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 8: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr)); rn = "BadVAddr"; break; default: @@ -4001,7 +4258,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - gen_op_mfc0_count(); + tcg_gen_helper_1_0(do_mfc0_count, t0); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -4012,7 +4269,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi)); rn = "EntryHi"; break; default: @@ -4022,7 +4279,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare)); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -4033,22 +4290,22 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status)); rn = "Status"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl)); rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl)); rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap)); rn = "SRSMap"; break; default: @@ -4058,7 +4315,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause)); rn = "Cause"; break; default: @@ -4068,7 +4325,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC)); rn = "EPC"; break; default: @@ -4078,12 +4335,12 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 15: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid)); rn = "PRid"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase)); rn = "EBase"; break; default: @@ -4093,28 +4350,28 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0)); rn = "Config"; break; case 1: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1)); rn = "Config1"; break; case 2: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2)); rn = "Config2"; break; case 3: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3)); rn = "Config3"; break; /* 6,7 are implementation dependent */ case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6)); rn = "Config6"; break; case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7)); rn = "Config7"; break; default: @@ -4124,7 +4381,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 17: switch (sel) { case 0: - gen_op_dmfc0_lladdr(); + tcg_gen_helper_1_0(do_dmfc0_lladdr, t0); rn = "LLAddr"; break; default: @@ -4134,7 +4391,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - gen_op_dmfc0_watchlo(sel); + tcg_gen_helper_1_i(do_dmfc0_watchlo, t0, sel); rn = "WatchLo"; break; default: @@ -4144,7 +4401,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - gen_op_mfc0_watchhi(sel); + tcg_gen_helper_1_i(do_mfc0_watchhi, t0, sel); rn = "WatchHi"; break; default: @@ -4155,7 +4412,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS3); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext)); rn = "XContext"; break; default: @@ -4166,7 +4423,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask)); rn = "Framemask"; break; default: @@ -4180,23 +4437,23 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - gen_op_mfc0_debug(); /* EJTAG support */ + tcg_gen_helper_1_0(do_mfc0_debug, t0); /* EJTAG support */ rn = "Debug"; break; case 1: -// gen_op_dmfc0_tracecontrol(); /* PDtrace support */ +// tcg_gen_helper_1_0(do_dmfc0_tracecontrol, t0); /* PDtrace support */ rn = "TraceControl"; // break; case 2: -// gen_op_dmfc0_tracecontrol2(); /* PDtrace support */ +// tcg_gen_helper_1_0(do_dmfc0_tracecontrol2, t0); /* PDtrace support */ rn = "TraceControl2"; // break; case 3: -// gen_op_dmfc0_usertracedata(); /* PDtrace support */ +// tcg_gen_helper_1_0(do_dmfc0_usertracedata, t0); /* PDtrace support */ rn = "UserTraceData"; // break; case 4: -// gen_op_dmfc0_debug(); /* PDtrace support */ +// tcg_gen_helper_1_0(do_dmfc0_tracebpc, t0); /* PDtrace support */ rn = "TraceBPC"; // break; default: @@ -4207,7 +4464,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC)); rn = "DEPC"; break; default: @@ -4217,35 +4474,35 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0)); rn = "Performance0"; break; case 1: -// gen_op_dmfc0_performance1(); +// tcg_gen_helper_1_0(do_dmfc0_performance1, t0); rn = "Performance1"; // break; case 2: -// gen_op_dmfc0_performance2(); +// tcg_gen_helper_1_0(do_dmfc0_performance2, t0); rn = "Performance2"; // break; case 3: -// gen_op_dmfc0_performance3(); +// tcg_gen_helper_1_0(do_dmfc0_performance3, t0); rn = "Performance3"; // break; case 4: -// gen_op_dmfc0_performance4(); +// tcg_gen_helper_1_0(do_dmfc0_performance4, t0); rn = "Performance4"; // break; case 5: -// gen_op_dmfc0_performance5(); +// tcg_gen_helper_1_0(do_dmfc0_performance5, t0); rn = "Performance5"; // break; case 6: -// gen_op_dmfc0_performance6(); +// tcg_gen_helper_1_0(do_dmfc0_performance6, t0); rn = "Performance6"; // break; case 7: -// gen_op_dmfc0_performance7(); +// tcg_gen_helper_1_0(do_dmfc0_performance7, t0); rn = "Performance7"; // break; default: @@ -4271,14 +4528,14 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo)); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo)); rn = "DataLo"; break; default: @@ -4291,14 +4548,14 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi)); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi)); rn = "DataHi"; break; default: @@ -4308,7 +4565,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC)); rn = "ErrorEPC"; break; default: @@ -4319,7 +4576,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -4347,7 +4604,7 @@ die: generate_exception(ctx, EXCP_RI); } -static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) +static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel) { const char *rn = "invalid"; @@ -4358,12 +4615,12 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - gen_op_mtc0_index(); + tcg_gen_helper_0_1(do_mtc0_index, t0); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_mvpcontrol(); + tcg_gen_helper_0_1(do_mtc0_mvpcontrol, t0); rn = "MVPControl"; break; case 2: @@ -4388,37 +4645,37 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpecontrol(); + tcg_gen_helper_0_1(do_mtc0_vpecontrol, t0); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeconf0(); + tcg_gen_helper_0_1(do_mtc0_vpeconf0, t0); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeconf1(); + tcg_gen_helper_0_1(do_mtc0_vpeconf1, t0); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_yqmask(); + tcg_gen_helper_0_1(do_mtc0_yqmask, t0); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeschedule(); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeschefback(); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeopt(); + tcg_gen_helper_0_1(do_mtc0_vpeopt, t0); rn = "VPEOpt"; break; default: @@ -4428,42 +4685,42 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - gen_op_mtc0_entrylo0(); + tcg_gen_helper_0_1(do_mtc0_entrylo0, t0); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcstatus(); + tcg_gen_helper_0_1(do_mtc0_tcstatus, t0); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcbind(); + tcg_gen_helper_0_1(do_mtc0_tcbind, t0); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcrestart(); + tcg_gen_helper_0_1(do_mtc0_tcrestart, t0); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tchalt(); + tcg_gen_helper_0_1(do_mtc0_tchalt, t0); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tccontext(); + tcg_gen_helper_0_1(do_mtc0_tccontext, t0); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcschedule(); + tcg_gen_helper_0_1(do_mtc0_tcschedule, t0); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcschefback(); + tcg_gen_helper_0_1(do_mtc0_tcschefback, t0); rn = "TCScheFBack"; break; default: @@ -4473,7 +4730,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - gen_op_mtc0_entrylo1(); + tcg_gen_helper_0_1(do_mtc0_entrylo1, t0); rn = "EntryLo1"; break; default: @@ -4483,11 +4740,11 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - gen_op_mtc0_context(); + tcg_gen_helper_0_1(do_mtc0_context, t0); rn = "Context"; break; case 1: -// gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */ +// tcg_gen_helper_0_1(do_mtc0_contextconfig, t0); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -4497,12 +4754,12 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - gen_op_mtc0_pagemask(); + tcg_gen_helper_0_1(do_mtc0_pagemask, t0); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_pagegrain(); + tcg_gen_helper_0_1(do_mtc0_pagegrain, t0); rn = "PageGrain"; break; default: @@ -4512,32 +4769,32 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - gen_op_mtc0_wired(); + tcg_gen_helper_0_1(do_mtc0_wired, t0); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf0(); + tcg_gen_helper_0_1(do_mtc0_srsconf0, t0); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf1(); + tcg_gen_helper_0_1(do_mtc0_srsconf1, t0); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf2(); + tcg_gen_helper_0_1(do_mtc0_srsconf2, t0); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf3(); + tcg_gen_helper_0_1(do_mtc0_srsconf3, t0); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf4(); + tcg_gen_helper_0_1(do_mtc0_srsconf4, t0); rn = "SRSConf4"; break; default: @@ -4548,7 +4805,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_hwrena(); + tcg_gen_helper_0_1(do_mtc0_hwrena, t0); rn = "HWREna"; break; default: @@ -4562,7 +4819,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - gen_op_mtc0_count(); + tcg_gen_helper_0_1(do_mtc0_count, t0); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -4575,7 +4832,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - gen_op_mtc0_entryhi(); + tcg_gen_helper_0_1(do_mtc0_entryhi, t0); rn = "EntryHi"; break; default: @@ -4585,7 +4842,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - gen_op_mtc0_compare(); + tcg_gen_helper_0_1(do_mtc0_compare, t0); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -4598,7 +4855,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - gen_op_mtc0_status(); + tcg_gen_helper_0_1(do_mtc0_status, t0); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; @@ -4606,21 +4863,21 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_intctl(); + tcg_gen_helper_0_1(do_mtc0_intctl, t0); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsctl(); + tcg_gen_helper_0_1(do_mtc0_srsctl, t0); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsmap(); + gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSMap"; @@ -4632,7 +4889,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - gen_op_mtc0_cause(); + tcg_gen_helper_0_1(do_mtc0_cause, t0); rn = "Cause"; break; default: @@ -4644,7 +4901,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - gen_op_mtc0_epc(); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC)); rn = "EPC"; break; default: @@ -4659,7 +4916,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_ebase(); + tcg_gen_helper_0_1(do_mtc0_ebase, t0); rn = "EBase"; break; default: @@ -4669,7 +4926,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_op_mtc0_config0(); + tcg_gen_helper_0_1(do_mtc0_config0, t0); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -4679,7 +4936,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Config1"; break; case 2: - gen_op_mtc0_config2(); + tcg_gen_helper_0_1(do_mtc0_config2, t0); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -4707,7 +4964,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - gen_op_mtc0_watchlo(sel); + tcg_gen_helper_0_1i(do_mtc0_watchlo, t0, sel); rn = "WatchLo"; break; default: @@ -4717,7 +4974,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - gen_op_mtc0_watchhi(sel); + tcg_gen_helper_0_1i(do_mtc0_watchhi, t0, sel); rn = "WatchHi"; break; default: @@ -4728,7 +4985,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS3); - gen_op_mtc0_xcontext(); + tcg_gen_helper_0_1(do_mtc0_xcontext, t0); rn = "XContext"; break; default: @@ -4739,7 +4996,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - gen_op_mtc0_framemask(); + tcg_gen_helper_0_1(do_mtc0_framemask, t0); rn = "Framemask"; break; default: @@ -4753,32 +5010,32 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - gen_op_mtc0_debug(); /* EJTAG support */ + tcg_gen_helper_0_1(do_mtc0_debug, t0); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: -// gen_op_mtc0_tracecontrol(); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceControl"; // break; case 2: -// gen_op_mtc0_tracecontrol2(); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol2, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceControl2"; // break; case 3: -// gen_op_mtc0_usertracedata(); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_usertracedata, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "UserTraceData"; // break; case 4: -// gen_op_mtc0_debug(); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracebpc, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; @@ -4790,7 +5047,8 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 24: switch (sel) { case 0: - gen_op_mtc0_depc(); /* EJTAG support */ + /* EJTAG support */ + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC)); rn = "DEPC"; break; default: @@ -4800,35 +5058,35 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - gen_op_mtc0_performance0(); + tcg_gen_helper_0_1(do_mtc0_performance0, t0); rn = "Performance0"; break; case 1: -// gen_op_mtc0_performance1(); +// tcg_gen_helper_0_1(do_mtc0_performance1, t0); rn = "Performance1"; // break; case 2: -// gen_op_mtc0_performance2(); +// tcg_gen_helper_0_1(do_mtc0_performance2, t0); rn = "Performance2"; // break; case 3: -// gen_op_mtc0_performance3(); +// tcg_gen_helper_0_1(do_mtc0_performance3, t0); rn = "Performance3"; // break; case 4: -// gen_op_mtc0_performance4(); +// tcg_gen_helper_0_1(do_mtc0_performance4, t0); rn = "Performance4"; // break; case 5: -// gen_op_mtc0_performance5(); +// tcg_gen_helper_0_1(do_mtc0_performance5, t0); rn = "Performance5"; // break; case 6: -// gen_op_mtc0_performance6(); +// tcg_gen_helper_0_1(do_mtc0_performance6, t0); rn = "Performance6"; // break; case 7: -// gen_op_mtc0_performance7(); +// tcg_gen_helper_0_1(do_mtc0_performance7, t0); rn = "Performance7"; // break; default: @@ -4855,14 +5113,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_op_mtc0_taglo(); + tcg_gen_helper_0_1(do_mtc0_taglo, t0); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - gen_op_mtc0_datalo(); + tcg_gen_helper_0_1(do_mtc0_datalo, t0); rn = "DataLo"; break; default: @@ -4875,14 +5133,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_op_mtc0_taghi(); + tcg_gen_helper_0_1(do_mtc0_taghi, t0); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - gen_op_mtc0_datahi(); + tcg_gen_helper_0_1(do_mtc0_datahi, t0); rn = "DataHi"; break; default: @@ -4893,7 +5151,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - gen_op_mtc0_errorepc(); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC)); rn = "ErrorEPC"; break; default: @@ -4903,7 +5161,8 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 31: switch (sel) { case 0: - gen_op_mtc0_desave(); /* EJTAG support */ + /* EJTAG support */ + gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -4921,9 +5180,11 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn, reg, sel); } #endif + tcg_temp_free(t0); return; die: + tcg_temp_free(t0); #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n", @@ -4934,125 +5195,126 @@ die: } #endif /* TARGET_MIPS64 */ -static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, +static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd, int u, int sel, int h) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) != (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE)))) - tcg_gen_movi_tl(cpu_T[0], -1); + tcg_gen_movi_tl(t0, -1); else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) - tcg_gen_movi_tl(cpu_T[0], -1); + tcg_gen_movi_tl(t0, -1); else if (u == 0) { switch (rt) { case 2: switch (sel) { case 1: - gen_op_mftc0_tcstatus(); + tcg_gen_helper_1_1(do_mftc0_tcstatus, t0, t0); break; case 2: - gen_op_mftc0_tcbind(); + tcg_gen_helper_1_1(do_mftc0_tcbind, t0, t0); break; case 3: - gen_op_mftc0_tcrestart(); + tcg_gen_helper_1_1(do_mftc0_tcrestart, t0, t0); break; case 4: - gen_op_mftc0_tchalt(); + tcg_gen_helper_1_1(do_mftc0_tchalt, t0, t0); break; case 5: - gen_op_mftc0_tccontext(); + tcg_gen_helper_1_1(do_mftc0_tccontext, t0, t0); break; case 6: - gen_op_mftc0_tcschedule(); + tcg_gen_helper_1_1(do_mftc0_tcschedule, t0, t0); break; case 7: - gen_op_mftc0_tcschefback(); + tcg_gen_helper_1_1(do_mftc0_tcschefback, t0, t0); break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); break; } break; case 10: switch (sel) { case 0: - gen_op_mftc0_entryhi(); + tcg_gen_helper_1_1(do_mftc0_entryhi, t0, t0); break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); break; } case 12: switch (sel) { case 0: - gen_op_mftc0_status(); + tcg_gen_helper_1_1(do_mftc0_status, t0, t0); break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); break; } case 23: switch (sel) { case 0: - gen_op_mftc0_debug(); + tcg_gen_helper_1_1(do_mftc0_debug, t0, t0); break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); break; } break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); } } else switch (sel) { /* GPR registers. */ case 0: - gen_op_mftgpr(rt); + tcg_gen_helper_1_1i(do_mftgpr, t0, t0, rt); break; /* Auxiliary CPU registers */ case 1: switch (rt) { case 0: - gen_op_mftlo(0); + tcg_gen_helper_1_1i(do_mftlo, t0, t0, 0); break; case 1: - gen_op_mfthi(0); + tcg_gen_helper_1_1i(do_mfthi, t0, t0, 0); break; case 2: - gen_op_mftacx(0); + tcg_gen_helper_1_1i(do_mftacx, t0, t0, 0); break; case 4: - gen_op_mftlo(1); + tcg_gen_helper_1_1i(do_mftlo, t0, t0, 1); break; case 5: - gen_op_mfthi(1); + tcg_gen_helper_1_1i(do_mfthi, t0, t0, 1); break; case 6: - gen_op_mftacx(1); + tcg_gen_helper_1_1i(do_mftacx, t0, t0, 1); break; case 8: - gen_op_mftlo(2); + tcg_gen_helper_1_1i(do_mftlo, t0, t0, 2); break; case 9: - gen_op_mfthi(2); + tcg_gen_helper_1_1i(do_mfthi, t0, t0, 2); break; case 10: - gen_op_mftacx(2); + tcg_gen_helper_1_1i(do_mftacx, t0, t0, 2); break; case 12: - gen_op_mftlo(3); + tcg_gen_helper_1_1i(do_mftlo, t0, t0, 3); break; case 13: - gen_op_mfthi(3); + tcg_gen_helper_1_1i(do_mfthi, t0, t0, 3); break; case 14: - gen_op_mftacx(3); + tcg_gen_helper_1_1i(do_mftacx, t0, t0, 3); break; case 16: - gen_op_mftdsp(); + tcg_gen_helper_1_1(do_mftdsp, t0, t0); break; default: goto die; @@ -5062,16 +5324,16 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 2: /* XXX: For now we support only a single FPU context. */ if (h == 0) { - GEN_LOAD_FREG_FTN(WT0, rt); - gen_op_mfc1(); + gen_load_fpr32(fpu32_T[0], rt); + tcg_gen_ext_i32_tl(t0, fpu32_T[0]); } else { - GEN_LOAD_FREG_FTN(WTH0, rt); - gen_op_mfhc1(); + gen_load_fpr32h(fpu32h_T[0], rt); + tcg_gen_ext_i32_tl(t0, fpu32h_T[0]); } break; case 3: /* XXX: For now we support only a single FPU context. */ - gen_op_cfc1(rt); + tcg_gen_helper_1_1i(do_cfc1, t0, t0, rt); break; /* COP2: Not implemented. */ case 4: @@ -5086,9 +5348,12 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, rt, u, sel, h); } #endif + gen_store_gpr(t0, rd); + tcg_temp_free(t0); return; die: + tcg_temp_free(t0); #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n", @@ -5098,11 +5363,13 @@ die: generate_exception(ctx, EXCP_RI); } -static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, +static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, int u, int sel, int h) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + gen_load_gpr(t0, rt); if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) != (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE)))) @@ -5115,108 +5382,108 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 2: switch (sel) { case 1: - gen_op_mttc0_tcstatus(); + tcg_gen_helper_0_1(do_mttc0_tcstatus, t0); break; case 2: - gen_op_mttc0_tcbind(); + tcg_gen_helper_0_1(do_mttc0_tcbind, t0); break; case 3: - gen_op_mttc0_tcrestart(); + tcg_gen_helper_0_1(do_mttc0_tcrestart, t0); break; case 4: - gen_op_mttc0_tchalt(); + tcg_gen_helper_0_1(do_mttc0_tchalt, t0); break; case 5: - gen_op_mttc0_tccontext(); + tcg_gen_helper_0_1(do_mttc0_tccontext, t0); break; case 6: - gen_op_mttc0_tcschedule(); + tcg_gen_helper_0_1(do_mttc0_tcschedule, t0); break; case 7: - gen_op_mttc0_tcschefback(); + tcg_gen_helper_0_1(do_mttc0_tcschefback, t0); break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); break; } break; case 10: switch (sel) { case 0: - gen_op_mttc0_entryhi(); + tcg_gen_helper_0_1(do_mttc0_entryhi, t0); break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); break; } case 12: switch (sel) { case 0: - gen_op_mttc0_status(); + tcg_gen_helper_0_1(do_mttc0_status, t0); break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); break; } case 23: switch (sel) { case 0: - gen_op_mttc0_debug(); + tcg_gen_helper_0_1(do_mttc0_debug, t0); break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); break; } break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); } } else switch (sel) { /* GPR registers. */ case 0: - gen_op_mttgpr(rd); + tcg_gen_helper_0_1i(do_mttgpr, t0, rd); break; /* Auxiliary CPU registers */ case 1: switch (rd) { case 0: - gen_op_mttlo(0); + tcg_gen_helper_0_1i(do_mttlo, t0, 0); break; case 1: - gen_op_mtthi(0); + tcg_gen_helper_0_1i(do_mtthi, t0, 0); break; case 2: - gen_op_mttacx(0); + tcg_gen_helper_0_1i(do_mttacx, t0, 0); break; case 4: - gen_op_mttlo(1); + tcg_gen_helper_0_1i(do_mttlo, t0, 1); break; case 5: - gen_op_mtthi(1); + tcg_gen_helper_0_1i(do_mtthi, t0, 1); break; case 6: - gen_op_mttacx(1); + tcg_gen_helper_0_1i(do_mttacx, t0, 1); break; case 8: - gen_op_mttlo(2); + tcg_gen_helper_0_1i(do_mttlo, t0, 2); break; case 9: - gen_op_mtthi(2); + tcg_gen_helper_0_1i(do_mtthi, t0, 2); break; case 10: - gen_op_mttacx(2); + tcg_gen_helper_0_1i(do_mttacx, t0, 2); break; case 12: - gen_op_mttlo(3); + tcg_gen_helper_0_1i(do_mttlo, t0, 3); break; case 13: - gen_op_mtthi(3); + tcg_gen_helper_0_1i(do_mtthi, t0, 3); break; case 14: - gen_op_mttacx(3); + tcg_gen_helper_0_1i(do_mttacx, t0, 3); break; case 16: - gen_op_mttdsp(); + tcg_gen_helper_0_1(do_mttdsp, t0); break; default: goto die; @@ -5226,16 +5493,16 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 2: /* XXX: For now we support only a single FPU context. */ if (h == 0) { - gen_op_mtc1(); - GEN_STORE_FTN_FREG(rd, WT0); + tcg_gen_trunc_tl_i32(fpu32_T[0], t0); + gen_store_fpr32(fpu32_T[0], rd); } else { - gen_op_mthc1(); - GEN_STORE_FTN_FREG(rd, WTH0); + tcg_gen_trunc_tl_i32(fpu32h_T[0], t0); + gen_store_fpr32h(fpu32h_T[0], rd); } break; case 3: /* XXX: For now we support only a single FPU context. */ - gen_op_ctc1(rd); + tcg_gen_helper_0_1i(do_ctc1, t0, rd); break; /* COP2: Not implemented. */ case 4: @@ -5250,9 +5517,11 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, rd, u, sel, h); } #endif + tcg_temp_free(t0); return; die: + tcg_temp_free(t0); #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n", @@ -5272,14 +5541,24 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int /* Treat as NOP. */ return; } - gen_mfc0(env, ctx, rd, ctx->opcode & 0x7); - gen_store_gpr(cpu_T[0], rt); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7); + gen_store_gpr(t0, rt); + tcg_temp_free(t0); + } opn = "mfc0"; break; case OPC_MTC0: - gen_load_gpr(cpu_T[0], rt); - save_cpu_state(ctx, 1); - gen_mtc0(env, ctx, rd, ctx->opcode & 0x7); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, rt); + save_cpu_state(ctx, 1); + gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7); + tcg_temp_free(t0); + } opn = "mtc0"; break; #if defined(TARGET_MIPS64) @@ -5289,15 +5568,25 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int /* Treat as NOP. */ return; } - gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7); - gen_store_gpr(cpu_T[0], rt); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7); + gen_store_gpr(t0, rt); + tcg_temp_free(t0); + } opn = "dmfc0"; break; case OPC_DMTC0: check_insn(env, ctx, ISA_MIPS3); - gen_load_gpr(cpu_T[0], rt); - save_cpu_state(ctx, 1); - gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, rt); + save_cpu_state(ctx, 1); + gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7); + tcg_temp_free(t0); + } opn = "dmtc0"; break; #endif @@ -5307,15 +5596,13 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int /* Treat as NOP. */ return; } - gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1, + gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); - gen_store_gpr(cpu_T[0], rd); opn = "mftr"; break; case OPC_MTTR: check_insn(env, ctx, ASE_MT); - gen_load_gpr(cpu_T[0], rt); - gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1, + gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); opn = "mttr"; break; @@ -5323,31 +5610,31 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int opn = "tlbwi"; if (!env->tlb->do_tlbwi) goto die; - gen_op_tlbwi(); + tcg_gen_helper_0_0(env->tlb->do_tlbwi); break; case OPC_TLBWR: opn = "tlbwr"; if (!env->tlb->do_tlbwr) goto die; - gen_op_tlbwr(); + tcg_gen_helper_0_0(env->tlb->do_tlbwr); break; case OPC_TLBP: opn = "tlbp"; if (!env->tlb->do_tlbp) goto die; - gen_op_tlbp(); + tcg_gen_helper_0_0(env->tlb->do_tlbp); break; case OPC_TLBR: opn = "tlbr"; if (!env->tlb->do_tlbr) goto die; - gen_op_tlbr(); + tcg_gen_helper_0_0(env->tlb->do_tlbr); break; case OPC_ERET: opn = "eret"; check_insn(env, ctx, ISA_MIPS2); save_cpu_state(ctx, 1); - gen_op_eret(); + tcg_gen_helper_0_0(do_eret); ctx->bstate = BS_EXCP; break; case OPC_DERET: @@ -5358,7 +5645,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int generate_exception(ctx, EXCP_RI); } else { save_cpu_state(ctx, 1); - gen_op_deret(); + tcg_gen_helper_0_0(do_deret); ctx->bstate = BS_EXCP; } break; @@ -5369,7 +5656,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int ctx->pc += 4; save_cpu_state(ctx, 1); ctx->pc -= 4; - gen_op_wait(); + tcg_gen_helper_0_0(do_wait); ctx->bstate = BS_EXCP; break; default: @@ -5380,6 +5667,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int } MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); } +#endif /* !CONFIG_USER_ONLY */ /* CP1 Branches (before delay slot) */ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, @@ -5387,6 +5675,8 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, { target_ulong btarget; const char *opn = "cp1 cond branch"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (cc != 0) check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); @@ -5395,51 +5685,187 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, switch (op) { case OPC_BC1F: - gen_op_bc1f(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_not_tl(t0, t0); + tcg_gen_movi_tl(t1, 0x1 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(t0, 1); + gen_set_label(l2); + } opn = "bc1f"; goto not_likely; case OPC_BC1FL: - gen_op_bc1f(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_not_tl(t0, t0); + tcg_gen_movi_tl(t1, 0x1 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(t0, 1); + gen_set_label(l2); + } opn = "bc1fl"; goto likely; case OPC_BC1T: - gen_op_bc1t(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_movi_tl(t1, 0x1 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(t0, 1); + gen_set_label(l2); + } opn = "bc1t"; goto not_likely; case OPC_BC1TL: - gen_op_bc1t(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_movi_tl(t1, 0x1 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(t0, 1); + gen_set_label(l2); + } opn = "bc1tl"; likely: ctx->hflags |= MIPS_HFLAG_BL; - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond)); break; case OPC_BC1FANY2: - gen_op_bc1any2f(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_not_tl(t0, t0); + tcg_gen_movi_tl(t1, 0x3 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(t0, 1); + gen_set_label(l2); + } opn = "bc1any2f"; goto not_likely; case OPC_BC1TANY2: - gen_op_bc1any2t(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_movi_tl(t1, 0x3 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(t0, 1); + gen_set_label(l2); + } opn = "bc1any2t"; goto not_likely; case OPC_BC1FANY4: - gen_op_bc1any4f(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_not_tl(t0, t0); + tcg_gen_movi_tl(t1, 0xf << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(t0, 1); + gen_set_label(l2); + } opn = "bc1any4f"; goto not_likely; case OPC_BC1TANY4: - gen_op_bc1any4t(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_movi_tl(t1, 0xf << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(t0, 1); + gen_set_label(l2); + } opn = "bc1any4t"; not_likely: ctx->hflags |= MIPS_HFLAG_BC; - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond)); break; default: MIPS_INVAL(opn); generate_exception (ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn, ctx->hflags, btarget); ctx->btarget = btarget; + + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } /* Coprocessor 1 (FPU) */ @@ -5449,60 +5875,64 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) { const char *opn = "cp1 move"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); switch (opc) { case OPC_MFC1: - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_mfc1(); - gen_store_gpr(cpu_T[0], rt); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_ext_i32_tl(t0, fpu32_T[0]); + gen_store_gpr(t0, rt); opn = "mfc1"; break; case OPC_MTC1: - gen_load_gpr(cpu_T[0], rt); - gen_op_mtc1(); - GEN_STORE_FTN_FREG(fs, WT0); + gen_load_gpr(t0, rt); + tcg_gen_trunc_tl_i32(fpu32_T[0], t0); + gen_store_fpr32(fpu32_T[0], fs); opn = "mtc1"; break; case OPC_CFC1: - gen_op_cfc1(fs); - gen_store_gpr(cpu_T[0], rt); + tcg_gen_helper_1_i(do_cfc1, t0, fs); + gen_store_gpr(t0, rt); opn = "cfc1"; break; case OPC_CTC1: - gen_load_gpr(cpu_T[0], rt); - gen_op_ctc1(fs); + gen_load_gpr(t0, rt); + tcg_gen_helper_0_1i(do_ctc1, t0, fs); opn = "ctc1"; break; case OPC_DMFC1: - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_dmfc1(); - gen_store_gpr(cpu_T[0], rt); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_mov_tl(t0, fpu64_T[0]); + gen_store_gpr(t0, rt); opn = "dmfc1"; break; case OPC_DMTC1: - gen_load_gpr(cpu_T[0], rt); - gen_op_dmtc1(); - GEN_STORE_FTN_FREG(fs, DT0); + gen_load_gpr(t0, rt); + tcg_gen_mov_tl(fpu64_T[0], t0); + gen_store_fpr64(ctx, fpu64_T[0], fs); opn = "dmtc1"; break; case OPC_MFHC1: - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_mfhc1(); - gen_store_gpr(cpu_T[0], rt); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_ext_i32_tl(t0, fpu32h_T[0]); + gen_store_gpr(t0, rt); opn = "mfhc1"; break; case OPC_MTHC1: - gen_load_gpr(cpu_T[0], rt); - gen_op_mthc1(); - GEN_STORE_FTN_FREG(fs, WTH0); + gen_load_gpr(t0, rt); + tcg_gen_trunc_tl_i32(fpu32h_T[0], t0); + gen_store_fpr32h(fpu32h_T[0], fs); opn = "mthc1"; break; default: MIPS_INVAL(opn); generate_exception (ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]); + + out: + tcg_temp_free(t0); } static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) @@ -5510,6 +5940,8 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) int l1 = gen_new_label(); uint32_t ccbit; TCGCond cond; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (cc) ccbit = 1 << (24 + cc); @@ -5520,41 +5952,104 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) else cond = TCG_COND_NE; - gen_load_gpr(cpu_T[0], rd); - gen_load_gpr(cpu_T[1], rs); + gen_load_gpr(t0, rd); + gen_load_gpr(t1, rs); { TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); + TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32); tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu)); tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31)); tcg_temp_free(r_ptr); tcg_gen_andi_i32(r_tmp, r_tmp, ccbit); tcg_gen_brcondi_i32(cond, r_tmp, 0, l1); + tcg_temp_free(r_tmp); } - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, t1); + tcg_temp_free(t1); + + gen_set_label(l1); + gen_store_gpr(t0, rd); + tcg_temp_free(t0); +} + +static inline void gen_movcf_s (int cc, int tf) +{ + uint32_t ccbit; + int cond; + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + int l1 = gen_new_label(); + + if (cc) + ccbit = 1 << (24 + cc); + else + ccbit = 1 << 23; + + if (tf) + cond = TCG_COND_EQ; + else + cond = TCG_COND_NE; + + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); + tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit); + tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); + tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]); + gen_set_label(l1); + tcg_temp_free(r_tmp1); +} +static inline void gen_movcf_d (int cc, int tf) +{ + uint32_t ccbit; + int cond; + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + int l1 = gen_new_label(); + + if (cc) + ccbit = 1 << (24 + cc); + else + ccbit = 1 << 23; + + if (tf) + cond = TCG_COND_EQ; + else + cond = TCG_COND_NE; + + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); + tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit); + tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); + tcg_gen_movi_i64(fpu64_T[2], fpu64_T[0]); gen_set_label(l1); - gen_store_gpr(cpu_T[0], rd); + tcg_temp_free(r_tmp1); } -#define GEN_MOVCF(fmt) \ -static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \ -{ \ - uint32_t ccbit; \ - \ - if (cc) { \ - ccbit = 1 << (24 + cc); \ - } else \ - ccbit = 1 << 23; \ - if (!tf) \ - glue(gen_op_float_movf_, fmt)(ccbit); \ - else \ - glue(gen_op_float_movt_, fmt)(ccbit); \ +static inline void gen_movcf_ps (int cc, int tf) +{ + int cond; + TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32); + TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32); + int l1 = gen_new_label(); + int l2 = gen_new_label(); + + if (tf) + cond = TCG_COND_EQ; + else + cond = TCG_COND_NE; + + get_fp_cond(r_tmp1); + tcg_gen_shri_i32(r_tmp1, r_tmp1, cc); + tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1); + tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1); + tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]); + gen_set_label(l1); + tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2); + tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2); + tcg_gen_movi_i32(fpu32h_T[2], fpu32h_T[0]); + gen_set_label(l2); + tcg_temp_free(r_tmp1); + tcg_temp_free(r_tmp2); } -GEN_MOVCF(d); -GEN_MOVCF(s); -#undef GEN_MOVCF + static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd, int cc) @@ -5601,207 +6096,224 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, switch (ctx->opcode & FOP(0x3f, 0x1f)) { case FOP(0, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - gen_op_float_add_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + tcg_gen_helper_0_0(do_float_add_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "add.s"; optype = BINOP; break; case FOP(1, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - gen_op_float_sub_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + tcg_gen_helper_0_0(do_float_sub_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "sub.s"; optype = BINOP; break; case FOP(2, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - gen_op_float_mul_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + tcg_gen_helper_0_0(do_float_mul_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "mul.s"; optype = BINOP; break; case FOP(3, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - gen_op_float_div_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + tcg_gen_helper_0_0(do_float_div_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "div.s"; optype = BINOP; break; case FOP(4, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_sqrt_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_sqrt_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "sqrt.s"; break; case FOP(5, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_abs_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_abs_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "abs.s"; break; case FOP(6, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_mov_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_store_fpr32(fpu32_T[0], fd); opn = "mov.s"; break; case FOP(7, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_chs_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_chs_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "neg.s"; break; case FOP(8, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_roundl_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_roundl_s); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "round.l.s"; break; case FOP(9, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_truncl_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_truncl_s); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "trunc.l.s"; break; case FOP(10, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_ceill_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_ceill_s); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "ceil.l.s"; break; case FOP(11, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_floorl_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_floorl_s); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "floor.l.s"; break; case FOP(12, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_roundw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_roundw_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "round.w.s"; break; case FOP(13, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_truncw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_truncw_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "trunc.w.s"; break; case FOP(14, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_ceilw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_ceilw_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "ceil.w.s"; break; case FOP(15, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_floorw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_floorw_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "floor.w.s"; break; case FOP(17, 16): - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_movcf_s((ft >> 2) & 0x7, ft & 0x1); + gen_store_fpr32(fpu32_T[2], fd); opn = "movcf.s"; break; case FOP(18, 16): - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - gen_op_float_movz_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + { + int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_temp_free(t0); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + gen_set_label(l1); + } + gen_store_fpr32(fpu32_T[2], fd); opn = "movz.s"; break; case FOP(19, 16): - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - gen_op_float_movn_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + { + int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); + tcg_temp_free(t0); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + gen_set_label(l1); + } + gen_store_fpr32(fpu32_T[2], fd); opn = "movn.s"; break; case FOP(21, 16): check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_recip_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_recip_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "recip.s"; break; case FOP(22, 16): check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_rsqrt_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_rsqrt_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt.s"; break; case FOP(28, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - gen_op_float_recip2_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + tcg_gen_helper_0_0(do_float_recip2_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "recip2.s"; break; case FOP(29, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_recip1_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_recip1_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "recip1.s"; break; case FOP(30, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_rsqrt1_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_rsqrt1_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt1.s"; break; case FOP(31, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, ft); - gen_op_float_rsqrt2_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], ft); + tcg_gen_helper_0_0(do_float_rsqrt2_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt2.s"; break; case FOP(33, 16): check_cp1_registers(ctx, fd); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_cvtd_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtd_s); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.s"; break; case FOP(36, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_cvtw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtw_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.w.s"; break; case FOP(37, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_cvtl_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtl_s); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.l.s"; break; case FOP(38, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT1, fs); - GEN_LOAD_FREG_FTN(WT0, ft); - gen_op_float_cvtps_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + tcg_gen_extu_i32_i64(fpu64_T[0], fpu32_T[0]); + tcg_gen_extu_i32_i64(fpu64_T[1], fpu32_T[1]); + tcg_gen_shli_i64(fpu64_T[1], fpu64_T[1], 32); + tcg_gen_or_i64(fpu64_T[2], fpu64_T[0], fpu64_T[1]); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.ps.s"; break; case FOP(48, 16): @@ -5820,8 +6332,8 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(61, 16): case FOP(62, 16): case FOP(63, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); if (ctx->opcode & (1 << 6)) { check_cop1x(ctx); gen_cmpabs_s(func-48, cc); @@ -5833,190 +6345,204 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(0, 17): check_cp1_registers(ctx, fs | ft | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - gen_op_float_add_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + tcg_gen_helper_0_0(do_float_add_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "add.d"; optype = BINOP; break; case FOP(1, 17): check_cp1_registers(ctx, fs | ft | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - gen_op_float_sub_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + tcg_gen_helper_0_0(do_float_sub_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "sub.d"; optype = BINOP; break; case FOP(2, 17): check_cp1_registers(ctx, fs | ft | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - gen_op_float_mul_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + tcg_gen_helper_0_0(do_float_mul_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "mul.d"; optype = BINOP; break; case FOP(3, 17): check_cp1_registers(ctx, fs | ft | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - gen_op_float_div_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + tcg_gen_helper_0_0(do_float_div_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "div.d"; optype = BINOP; break; case FOP(4, 17): check_cp1_registers(ctx, fs | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_sqrt_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_sqrt_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "sqrt.d"; break; case FOP(5, 17): check_cp1_registers(ctx, fs | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_abs_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_abs_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "abs.d"; break; case FOP(6, 17): check_cp1_registers(ctx, fs | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_mov_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "mov.d"; break; case FOP(7, 17): check_cp1_registers(ctx, fs | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_chs_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_chs_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "neg.d"; break; case FOP(8, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_roundl_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_roundl_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "round.l.d"; break; case FOP(9, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_truncl_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_truncl_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "trunc.l.d"; break; case FOP(10, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_ceill_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_ceill_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "ceil.l.d"; break; case FOP(11, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_floorl_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_floorl_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "floor.l.d"; break; case FOP(12, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_roundw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_roundw_d); + gen_store_fpr32(fpu32_T[2], fd); opn = "round.w.d"; break; case FOP(13, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_truncw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_truncw_d); + gen_store_fpr32(fpu32_T[2], fd); opn = "trunc.w.d"; break; case FOP(14, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_ceilw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_ceilw_d); + gen_store_fpr32(fpu32_T[2], fd); opn = "ceil.w.d"; break; case FOP(15, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_floorw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_floorw_d); + gen_store_fpr32(fpu32_T[2], fd); opn = "floor.w.d"; break; case FOP(17, 17): - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, fd); - gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], fd); + gen_movcf_d((ft >> 2) & 0x7, ft & 0x1); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movcf.d"; break; case FOP(18, 17): - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, fd); - gen_op_float_movz_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], fd); + { + int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_temp_free(t0); + tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]); + gen_set_label(l1); + } + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movz.d"; break; case FOP(19, 17): - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, fd); - gen_op_float_movn_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], fd); + { + int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); + tcg_temp_free(t0); + tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]); + gen_set_label(l1); + } + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movn.d"; break; case FOP(21, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_recip_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_recip_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip.d"; break; case FOP(22, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_rsqrt_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_rsqrt_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt.d"; break; case FOP(28, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, ft); - gen_op_float_recip2_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], ft); + tcg_gen_helper_0_0(do_float_recip2_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip2.d"; break; case FOP(29, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_recip1_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_recip1_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip1.d"; break; case FOP(30, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_rsqrt1_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_rsqrt1_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt1.d"; break; case FOP(31, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, ft); - gen_op_float_rsqrt2_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], ft); + tcg_gen_helper_0_0(do_float_rsqrt2_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt2.d"; break; case FOP(48, 17): @@ -6035,8 +6561,8 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(61, 17): case FOP(62, 17): case FOP(63, 17): - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); if (ctx->opcode & (1 << 6)) { check_cop1x(ctx); check_cp1_registers(ctx, fs | ft); @@ -6050,275 +6576,288 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(32, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_cvts_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_cvts_d); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.d"; break; case FOP(36, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_cvtw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtw_d); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.w.d"; break; case FOP(37, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_cvtl_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtl_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.l.d"; break; case FOP(32, 20): - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_cvts_w(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_cvts_w); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.w"; break; case FOP(33, 20): check_cp1_registers(ctx, fd); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_cvtd_w(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtd_w); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.w"; break; case FOP(32, 21): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_cvts_l(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_cvts_l); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.l"; break; case FOP(33, 21): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_float_cvtd_l(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtd_l); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.l"; break; case FOP(38, 20): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_float_cvtps_pw(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtps_pw); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "cvt.ps.pw"; break; case FOP(0, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - gen_op_float_add_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + tcg_gen_helper_0_0(do_float_add_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "add.ps"; break; case FOP(1, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - gen_op_float_sub_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + tcg_gen_helper_0_0(do_float_sub_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "sub.ps"; break; case FOP(2, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - gen_op_float_mul_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + tcg_gen_helper_0_0(do_float_mul_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "mul.ps"; break; case FOP(5, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_float_abs_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_helper_0_0(do_float_abs_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "abs.ps"; break; case FOP(6, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_float_mov_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_store_fpr32(fpu32_T[0], fd); + gen_store_fpr32h(fpu32h_T[0], fd); opn = "mov.ps"; break; case FOP(7, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_float_chs_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_helper_0_0(do_float_chs_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "neg.ps"; break; case FOP(17, 22): check_cp1_64bitmode(ctx); - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - GEN_LOAD_FREG_FTN(WTH2, fd); - if (ft & 0x1) - gen_op_float_movt_ps ((ft >> 2) & 0x7); - else - gen_op_float_movf_ps ((ft >> 2) & 0x7); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_load_fpr32h(fpu32h_T[2], fd); + gen_movcf_ps((ft >> 2) & 0x7, ft & 0x1); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "movcf.ps"; break; case FOP(18, 22): check_cp1_64bitmode(ctx); - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - GEN_LOAD_FREG_FTN(WTH2, fd); - gen_op_float_movz_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_load_fpr32h(fpu32h_T[2], fd); + { + int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_temp_free(t0); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); + gen_set_label(l1); + } + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "movz.ps"; break; case FOP(19, 22): check_cp1_64bitmode(ctx); - gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - GEN_LOAD_FREG_FTN(WTH2, fd); - gen_op_float_movn_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_load_fpr32h(fpu32h_T[2], fd); + { + int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); + tcg_temp_free(t0); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); + gen_set_label(l1); + } + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "movn.ps"; break; case FOP(24, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, ft); - GEN_LOAD_FREG_FTN(WTH0, ft); - GEN_LOAD_FREG_FTN(WT1, fs); - GEN_LOAD_FREG_FTN(WTH1, fs); - gen_op_float_addr_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], ft); + gen_load_fpr32h(fpu32h_T[0], ft); + gen_load_fpr32(fpu32_T[1], fs); + gen_load_fpr32h(fpu32h_T[1], fs); + tcg_gen_helper_0_0(do_float_addr_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "addr.ps"; break; case FOP(26, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, ft); - GEN_LOAD_FREG_FTN(WTH0, ft); - GEN_LOAD_FREG_FTN(WT1, fs); - GEN_LOAD_FREG_FTN(WTH1, fs); - gen_op_float_mulr_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], ft); + gen_load_fpr32h(fpu32h_T[0], ft); + gen_load_fpr32(fpu32_T[1], fs); + gen_load_fpr32h(fpu32h_T[1], fs); + tcg_gen_helper_0_0(do_float_mulr_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "mulr.ps"; break; case FOP(28, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - GEN_LOAD_FREG_FTN(WTH2, fd); - gen_op_float_recip2_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_load_fpr32h(fpu32h_T[2], fd); + tcg_gen_helper_0_0(do_float_recip2_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "recip2.ps"; break; case FOP(29, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_float_recip1_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_helper_0_0(do_float_recip1_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "recip1.ps"; break; case FOP(30, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_float_rsqrt1_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_helper_0_0(do_float_rsqrt1_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "rsqrt1.ps"; break; case FOP(31, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, ft); - GEN_LOAD_FREG_FTN(WTH2, ft); - gen_op_float_rsqrt2_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], ft); + gen_load_fpr32h(fpu32h_T[2], ft); + tcg_gen_helper_0_0(do_float_rsqrt2_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "rsqrt2.ps"; break; case FOP(32, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_float_cvts_pu(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_helper_0_0(do_float_cvts_pu); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.pu"; break; case FOP(36, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_float_cvtpw_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_helper_0_0(do_float_cvtpw_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "cvt.pw.ps"; break; case FOP(40, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_float_cvts_pl(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_helper_0_0(do_float_cvts_pl); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.pl"; break; case FOP(44, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - gen_op_float_pll_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_store_fpr32h(fpu32_T[0], fd); + gen_store_fpr32(fpu32_T[1], fd); opn = "pll.ps"; break; case FOP(45, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH1, ft); - gen_op_float_plu_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_store_fpr32(fpu32h_T[1], fd); + gen_store_fpr32h(fpu32_T[0], fd); opn = "plu.ps"; break; case FOP(46, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - gen_op_float_pul_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_store_fpr32(fpu32_T[1], fd); + gen_store_fpr32h(fpu32h_T[0], fd); opn = "pul.ps"; break; case FOP(47, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WTH1, ft); - gen_op_float_puu_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_store_fpr32(fpu32h_T[1], fd); + gen_store_fpr32h(fpu32h_T[0], fd); opn = "puu.ps"; break; case FOP(48, 22): @@ -6338,10 +6877,10 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(62, 22): case FOP(63, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); if (ctx->opcode & (1 << 6)) { gen_cmpabs_ps(func-48, cc); opn = condnames_abs[func-48]; @@ -6374,65 +6913,73 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, { const char *opn = "extended float load/store"; int store = 0; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (base == 0) { - gen_load_gpr(cpu_T[0], index); + gen_load_gpr(t0, index); } else if (index == 0) { - gen_load_gpr(cpu_T[0], base); + gen_load_gpr(t0, base); } else { - gen_load_gpr(cpu_T[0], base); - gen_load_gpr(cpu_T[1], index); - gen_op_addr_add(); + gen_load_gpr(t0, base); + gen_load_gpr(t1, index); + gen_op_addr_add(t0, t1); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { case OPC_LWXC1: check_cop1x(ctx); - op_ldst_lwc1(ctx); - GEN_STORE_FTN_FREG(fd, WT0); + tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx); + gen_store_fpr32(fpu32_T[0], fd); opn = "lwxc1"; break; case OPC_LDXC1: check_cop1x(ctx); check_cp1_registers(ctx, fd); - op_ldst_ldc1(ctx); - GEN_STORE_FTN_FREG(fd, DT0); + tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx); + gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "ldxc1"; break; case OPC_LUXC1: check_cp1_64bitmode(ctx); - op_ldst(luxc1); - GEN_STORE_FTN_FREG(fd, DT0); + tcg_gen_andi_tl(t0, t0, ~0x7); + tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx); + gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "luxc1"; break; case OPC_SWXC1: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - op_ldst_swc1(ctx); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx); opn = "swxc1"; store = 1; break; case OPC_SDXC1: check_cop1x(ctx); check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); - op_ldst_sdc1(ctx); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx); opn = "sdxc1"; store = 1; break; case OPC_SUXC1: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - op_ldst(suxc1); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_andi_tl(t0, t0, ~0x7); + tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx); opn = "suxc1"; store = 1; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); + tcg_temp_free(t0); + tcg_temp_free(t1); return; } + tcg_temp_free(t0); + tcg_temp_free(t1); MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd], regnames[index], regnames[base]); } @@ -6445,139 +6992,164 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, switch (opc) { case OPC_ALNV_PS: check_cp1_64bitmode(ctx); - gen_load_gpr(cpu_T[0], fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - gen_op_float_alnv_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + int l1 = gen_new_label(); + int l2 = gen_new_label(); + + gen_load_gpr(t0, fr); + tcg_gen_andi_tl(t0, t0, 0x7); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); + tcg_temp_free(t0); +#ifdef TARGET_WORDS_BIGENDIAN + tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[0]); + tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[1]); +#else + tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[1]); + tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[0]); +#endif + gen_set_label(l2); + } + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "alnv.ps"; break; case OPC_MADD_S: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - gen_op_float_muladd_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + tcg_gen_helper_0_0(do_float_muladd_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "madd.s"; break; case OPC_MADD_D: check_cop1x(ctx); check_cp1_registers(ctx, fd | fs | ft | fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - GEN_LOAD_FREG_FTN(DT2, fr); - gen_op_float_muladd_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + gen_load_fpr64(ctx, fpu64_T[2], fr); + tcg_gen_helper_0_0(do_float_muladd_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "madd.d"; break; case OPC_MADD_PS: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - GEN_LOAD_FREG_FTN(WTH2, fr); - gen_op_float_muladd_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + gen_load_fpr32h(fpu32h_T[2], fr); + tcg_gen_helper_0_0(do_float_muladd_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "madd.ps"; break; case OPC_MSUB_S: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - gen_op_float_mulsub_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + tcg_gen_helper_0_0(do_float_mulsub_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "msub.s"; break; case OPC_MSUB_D: check_cop1x(ctx); check_cp1_registers(ctx, fd | fs | ft | fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - GEN_LOAD_FREG_FTN(DT2, fr); - gen_op_float_mulsub_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + gen_load_fpr64(ctx, fpu64_T[2], fr); + tcg_gen_helper_0_0(do_float_mulsub_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "msub.d"; break; case OPC_MSUB_PS: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - GEN_LOAD_FREG_FTN(WTH2, fr); - gen_op_float_mulsub_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + gen_load_fpr32h(fpu32h_T[2], fr); + tcg_gen_helper_0_0(do_float_mulsub_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "msub.ps"; break; case OPC_NMADD_S: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - gen_op_float_nmuladd_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + tcg_gen_helper_0_0(do_float_nmuladd_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "nmadd.s"; break; case OPC_NMADD_D: check_cop1x(ctx); check_cp1_registers(ctx, fd | fs | ft | fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - GEN_LOAD_FREG_FTN(DT2, fr); - gen_op_float_nmuladd_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + gen_load_fpr64(ctx, fpu64_T[2], fr); + tcg_gen_helper_0_0(do_float_nmuladd_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "nmadd.d"; break; case OPC_NMADD_PS: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - GEN_LOAD_FREG_FTN(WTH2, fr); - gen_op_float_nmuladd_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + gen_load_fpr32h(fpu32h_T[2], fr); + tcg_gen_helper_0_0(do_float_nmuladd_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "nmadd.ps"; break; case OPC_NMSUB_S: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - gen_op_float_nmulsub_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + tcg_gen_helper_0_0(do_float_nmulsub_s); + gen_store_fpr32(fpu32_T[2], fd); opn = "nmsub.s"; break; case OPC_NMSUB_D: check_cop1x(ctx); check_cp1_registers(ctx, fd | fs | ft | fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - GEN_LOAD_FREG_FTN(DT2, fr); - gen_op_float_nmulsub_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + gen_load_fpr64(ctx, fpu64_T[2], fr); + tcg_gen_helper_0_0(do_float_nmulsub_d); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "nmsub.d"; break; case OPC_NMSUB_PS: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - GEN_LOAD_FREG_FTN(WTH2, fr); - gen_op_float_nmulsub_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + gen_load_fpr32h(fpu32h_T[2], fr); + tcg_gen_helper_0_0(do_float_nmulsub_ps); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "nmsub.ps"; break; default: @@ -6622,7 +7194,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx) tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond)); tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1); tcg_temp_free(r_tmp); - gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK); + { + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); + + tcg_gen_movi_i32(r_tmp2, ctx->hflags & ~MIPS_HFLAG_BMASK); + tcg_gen_st_i32(r_tmp2, cpu_env, offsetof(CPUState, hflags)); + tcg_temp_free(r_tmp2); + } gen_goto_tb(ctx, 1, ctx->pc + 4); gen_set_label(l1); } @@ -6676,7 +7254,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) MIPS_INVAL("PMON / selsl"); generate_exception(ctx, EXCP_RI); #else - gen_op_pmon(sa); + tcg_gen_helper_0_i(do_pmon, sa); #endif break; case OPC_SYSCALL: @@ -6781,78 +7359,106 @@ static void decode_opc (CPUState *env, DisasContext *ctx) } break; case OPC_SPECIAL3: - op1 = MASK_SPECIAL3(ctx->opcode); - switch (op1) { - case OPC_EXT: - case OPC_INS: - check_insn(env, ctx, ISA_MIPS32R2); - gen_bitops(ctx, op1, rt, rs, sa, rd); - break; - case OPC_BSHFL: - check_insn(env, ctx, ISA_MIPS32R2); - op2 = MASK_BSHFL(ctx->opcode); - switch (op2) { - case OPC_WSBH: - gen_load_gpr(cpu_T[1], rt); - gen_op_wsbh(); - break; - case OPC_SEB: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]); - break; - case OPC_SEH: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]); - break; - default: /* Invalid */ - MIPS_INVAL("bshfl"); - generate_exception(ctx, EXCP_RI); - break; + op1 = MASK_SPECIAL3(ctx->opcode); + switch (op1) { + case OPC_EXT: + case OPC_INS: + check_insn(env, ctx, ISA_MIPS32R2); + gen_bitops(ctx, op1, rt, rs, sa, rd); + break; + case OPC_BSHFL: + check_insn(env, ctx, ISA_MIPS32R2); + op2 = MASK_BSHFL(ctx->opcode); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + switch (op2) { + case OPC_WSBH: + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2(do_wsbh, t0, t0, t1); + gen_store_gpr(t0, rd); + break; + case OPC_SEB: + gen_load_gpr(t1, rt); + tcg_gen_ext8s_tl(t0, t1); + gen_store_gpr(t0, rd); + break; + case OPC_SEH: + gen_load_gpr(t1, rt); + tcg_gen_ext16s_tl(t0, t1); + gen_store_gpr(t0, rd); + break; + default: /* Invalid */ + MIPS_INVAL("bshfl"); + generate_exception(ctx, EXCP_RI); + break; + } + tcg_temp_free(t0); + tcg_temp_free(t1); } - gen_store_gpr(cpu_T[0], rd); break; case OPC_RDHWR: check_insn(env, ctx, ISA_MIPS32R2); - switch (rd) { - case 0: - save_cpu_state(ctx, 1); - gen_op_rdhwr_cpunum(); - break; - case 1: - save_cpu_state(ctx, 1); - gen_op_rdhwr_synci_step(); - break; - case 2: - save_cpu_state(ctx, 1); - gen_op_rdhwr_cc(); - break; - case 3: - save_cpu_state(ctx, 1); - gen_op_rdhwr_ccres(); - break; - case 29: + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + switch (rd) { + case 0: + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_rdhwr_cpunum, t0, t0); + break; + case 1: + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_rdhwr_synci_step, t0, t0); + break; + case 2: + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_rdhwr_cc, t0, t0); + break; + case 3: + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_rdhwr_ccres, t0, t0); + break; + case 29: #if defined (CONFIG_USER_ONLY) - gen_op_tls_value(); - break; + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); + break; +#else + /* XXX: Some CPUs implement this in hardware. Not supported yet. */ #endif - default: /* Invalid */ - MIPS_INVAL("rdhwr"); - generate_exception(ctx, EXCP_RI); - break; + default: /* Invalid */ + MIPS_INVAL("rdhwr"); + generate_exception(ctx, EXCP_RI); + break; + } + gen_store_gpr(t0, rt); + tcg_temp_free(t0); } - gen_store_gpr(cpu_T[0], rt); break; case OPC_FORK: check_insn(env, ctx, ASE_MT); - gen_load_gpr(cpu_T[0], rt); - gen_load_gpr(cpu_T[1], rs); - gen_op_fork(); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, rt); + gen_load_gpr(t1, rs); + tcg_gen_helper_0_2(do_fork, t0, t1); + tcg_temp_free(t0); + tcg_temp_free(t1); + } break; case OPC_YIELD: check_insn(env, ctx, ASE_MT); - gen_load_gpr(cpu_T[0], rs); - gen_op_yield(); - gen_store_gpr(cpu_T[0], rd); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, rs); + tcg_gen_helper_1_1(do_yield, t0, t0); + gen_store_gpr(t0, rd); + tcg_temp_free(t0); + } break; #if defined(TARGET_MIPS64) case OPC_DEXTM ... OPC_DEXT: @@ -6865,21 +7471,28 @@ static void decode_opc (CPUState *env, DisasContext *ctx) check_insn(env, ctx, ISA_MIPS64R2); check_mips_64(ctx); op2 = MASK_DBSHFL(ctx->opcode); - switch (op2) { - case OPC_DSBH: - gen_load_gpr(cpu_T[1], rt); - gen_op_dsbh(); - break; - case OPC_DSHD: - gen_load_gpr(cpu_T[1], rt); - gen_op_dshd(); - break; - default: /* Invalid */ - MIPS_INVAL("dbshfl"); - generate_exception(ctx, EXCP_RI); - break; + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + switch (op2) { + case OPC_DSBH: + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2(do_dsbh, t0, t0, t1); + break; + case OPC_DSHD: + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2(do_dshd, t0, t0, t1); + break; + default: /* Invalid */ + MIPS_INVAL("dbshfl"); + generate_exception(ctx, EXCP_RI); + break; + } + gen_store_gpr(t0, rd); + tcg_temp_free(t0); + tcg_temp_free(t1); } - gen_store_gpr(cpu_T[0], rd); break; #endif default: /* Invalid */ @@ -6921,60 +7534,67 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_DMFC0: case OPC_DMTC0: #endif +#ifndef CONFIG_USER_ONLY gen_cp0(env, ctx, op1, rt, rd); +#endif break; case OPC_C0_FIRST ... OPC_C0_LAST: +#ifndef CONFIG_USER_ONLY gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); +#endif break; case OPC_MFMC0: op2 = MASK_MFMC0(ctx->opcode); - switch (op2) { - case OPC_DMT: - check_insn(env, ctx, ASE_MT); - gen_op_dmt(); - break; - case OPC_EMT: - check_insn(env, ctx, ASE_MT); - gen_op_emt(); - break; - case OPC_DVPE: - check_insn(env, ctx, ASE_MT); - gen_op_dvpe(); - break; - case OPC_EVPE: - check_insn(env, ctx, ASE_MT); - gen_op_evpe(); - break; - case OPC_DI: - check_insn(env, ctx, ISA_MIPS32R2); - save_cpu_state(ctx, 1); - gen_op_di(); - /* Stop translation as we may have switched the execution mode */ - ctx->bstate = BS_STOP; - break; - case OPC_EI: - check_insn(env, ctx, ISA_MIPS32R2); - save_cpu_state(ctx, 1); - gen_op_ei(); - /* Stop translation as we may have switched the execution mode */ - ctx->bstate = BS_STOP; - break; - default: /* Invalid */ - MIPS_INVAL("mfmc0"); - generate_exception(ctx, EXCP_RI); - break; + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + switch (op2) { + case OPC_DMT: + check_insn(env, ctx, ASE_MT); + tcg_gen_helper_1_1(do_dmt, t0, t0); + break; + case OPC_EMT: + check_insn(env, ctx, ASE_MT); + tcg_gen_helper_1_1(do_emt, t0, t0); + break; + case OPC_DVPE: + check_insn(env, ctx, ASE_MT); + tcg_gen_helper_1_1(do_dvpe, t0, t0); + break; + case OPC_EVPE: + check_insn(env, ctx, ASE_MT); + tcg_gen_helper_1_1(do_evpe, t0, t0); + break; + case OPC_DI: + check_insn(env, ctx, ISA_MIPS32R2); + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_di, t0, t0); + /* Stop translation as we may have switched the execution mode */ + ctx->bstate = BS_STOP; + break; + case OPC_EI: + check_insn(env, ctx, ISA_MIPS32R2); + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_ei, t0, t0); + /* Stop translation as we may have switched the execution mode */ + ctx->bstate = BS_STOP; + break; + default: /* Invalid */ + MIPS_INVAL("mfmc0"); + generate_exception(ctx, EXCP_RI); + break; + } + gen_store_gpr(t0, rt); + tcg_temp_free(t0); } - gen_store_gpr(cpu_T[0], rt); break; case OPC_RDPGPR: check_insn(env, ctx, ISA_MIPS32R2); - gen_load_srsgpr(cpu_T[0], rt); - gen_store_gpr(cpu_T[0], rd); + gen_load_srsgpr(rt, rd); break; case OPC_WRPGPR: check_insn(env, ctx, ISA_MIPS32R2); - gen_load_gpr(cpu_T[0], rt); - gen_store_srsgpr(cpu_T[0], rd); + gen_store_srsgpr(rt, rd); break; default: MIPS_INVAL("cp0"); @@ -7212,7 +7832,8 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, fprintf (logfile, "search pc %d\n", search_pc); pc_start = tb->pc; - gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; + /* Leave some spare opc slots for branch handling. */ + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16; ctx.pc = pc_start; ctx.saved_pc = -1; ctx.tb = tb; @@ -7237,13 +7858,13 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, fprintf(logfile, "\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags); #endif - while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) { + while (ctx.bstate == BS_NONE) { if (env->nb_breakpoints > 0) { for(j = 0; j < env->nb_breakpoints; j++) { if (env->breakpoints[j] == ctx.pc) { save_cpu_state(&ctx, 1); ctx.bstate = BS_BRANCH; - gen_op_debug(); + tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG); /* Include the breakpoint location or the tb won't * be flushed when it must be. */ ctx.pc += 4; @@ -7273,13 +7894,19 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) break; + if (gen_opc_ptr >= gen_opc_end) + break; + + if (gen_opc_ptr >= gen_opc_end) + break; + #if defined (MIPS_SINGLE_STEP) break; #endif } if (env->singlestep_enabled) { save_cpu_state(&ctx, ctx.bstate == BS_NONE); - gen_op_debug(); + tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG); } else { switch (ctx.bstate) { case BS_STOP: @@ -7364,9 +7991,9 @@ void fpu_dump_state(CPUState *env, FILE *f, fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n", env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status, get_float_exception_flags(&env->fpu->fp_status)); - fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0); - fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1); - fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2); + fpu_fprintf(f, "FT0: "); printfpr(&env->ft0); + fpu_fprintf(f, "FT1: "); printfpr(&env->ft1); + fpu_fprintf(f, "FT2: "); printfpr(&env->ft2); for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { fpu_fprintf(f, "%3s: ", fregnames[i]); printfpr(&env->fpu->fpr[i]); @@ -7466,15 +8093,25 @@ static void mips_tcg_init(void) TCG_AREG0, offsetof(CPUState, current_tc_hi), "current_tc_hi"); -#if TARGET_LONG_BITS > HOST_LONG_BITS - cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, - TCG_AREG0, offsetof(CPUState, t0), "T0"); - cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL, - TCG_AREG0, offsetof(CPUState, t1), "T1"); -#else - cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0"); - cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); -#endif + current_fpu = tcg_global_mem_new(TCG_TYPE_PTR, + TCG_AREG0, + offsetof(CPUState, fpu), + "current_fpu"); + + /* register helpers */ +#undef DEF_HELPER +#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name); +#include "helper.h" + + fpu32_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[FP_ENDIAN_IDX]), "WT0"); + fpu32_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[FP_ENDIAN_IDX]), "WT1"); + fpu32_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[FP_ENDIAN_IDX]), "WT2"); + fpu64_T[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft0.d), "DT0"); + fpu64_T[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft1.d), "DT1"); + fpu64_T[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft2.d), "DT2"); + fpu32h_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[!FP_ENDIAN_IDX]), "WTH0"); + fpu32h_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[!FP_ENDIAN_IDX]), "WTH1"); + fpu32h_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[!FP_ENDIAN_IDX]), "WTH2"); inited = 1; } |