target-mips: add Config5.FRE support allowing Status.FR=0 emulation

This relatively small architectural feature adds the following:

FIR.FREP: Read-only. If FREP=1, then Config5.FRE and Config5.UFE are
          available.

Config5.FRE: When enabled all single-precision FP arithmetic instructions,
             LWC1/LWXC1/MTC1, SWC1/SWXC1/MFC1 cause a Reserved Instructions
             exception.

Config5.UFE: Allows user to write/read Config5.FRE using CTC1/CFC1
             instructions.

Enable the feature in MIPS64R6-generic CPU.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
Leon Alrae 2015-04-21 16:06:28 +01:00
parent eab9944c78
commit 7c979afd11
4 changed files with 208 additions and 156 deletions

View File

@ -100,6 +100,7 @@ struct CPUMIPSFPUContext {
float_status fp_status; float_status fp_status;
/* fpu implementation/revision register (fir) */ /* fpu implementation/revision register (fir) */
uint32_t fcr0; uint32_t fcr0;
#define FCR0_FREP 29
#define FCR0_UFRP 28 #define FCR0_UFRP 28
#define FCR0_F64 22 #define FCR0_F64 22
#define FCR0_L 21 #define FCR0_L 21
@ -462,6 +463,8 @@ struct CPUMIPSState {
#define CP0C5_CV 29 #define CP0C5_CV 29
#define CP0C5_EVA 28 #define CP0C5_EVA 28
#define CP0C5_MSAEn 27 #define CP0C5_MSAEn 27
#define CP0C5_UFE 9
#define CP0C5_FRE 8
#define CP0C5_SBRI 6 #define CP0C5_SBRI 6
#define CP0C5_UFR 2 #define CP0C5_UFR 2
#define CP0C5_NFExists 0 #define CP0C5_NFExists 0
@ -514,7 +517,7 @@ struct CPUMIPSState {
#define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */ #define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */
uint32_t hflags; /* CPU State */ uint32_t hflags; /* CPU State */
/* TMASK defines different execution modes */ /* TMASK defines different execution modes */
#define MIPS_HFLAG_TMASK 0x15807FF #define MIPS_HFLAG_TMASK 0x35807FF
#define MIPS_HFLAG_MODE 0x00007 /* execution modes */ #define MIPS_HFLAG_MODE 0x00007 /* execution modes */
/* The KSU flags must be the lowest bits in hflags. The flag order /* The KSU flags must be the lowest bits in hflags. The flag order
must be the same as defined for CP0 Status. This allows to use must be the same as defined for CP0 Status. This allows to use
@ -561,6 +564,7 @@ struct CPUMIPSState {
#define MIPS_HFLAG_SBRI 0x400000 /* R6 SDBBP causes RI excpt. in user mode */ #define MIPS_HFLAG_SBRI 0x400000 /* R6 SDBBP causes RI excpt. in user mode */
#define MIPS_HFLAG_FBNSLOT 0x800000 /* Forbidden slot */ #define MIPS_HFLAG_FBNSLOT 0x800000 /* Forbidden slot */
#define MIPS_HFLAG_MSA 0x1000000 #define MIPS_HFLAG_MSA 0x1000000
#define MIPS_HFLAG_FRE 0x2000000 /* FRE enabled */
target_ulong btarget; /* Jump / branch target */ target_ulong btarget; /* Jump / branch target */
target_ulong bcond; /* Branch condition (if needed) */ target_ulong bcond; /* Branch condition (if needed) */
@ -843,7 +847,7 @@ static inline void compute_hflags(CPUMIPSState *env)
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 | MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA); MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE);
if (!(env->CP0_Status & (1 << CP0St_EXL)) && if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
!(env->CP0_Status & (1 << CP0St_ERL)) && !(env->CP0_Status & (1 << CP0St_ERL)) &&
!(env->hflags & MIPS_HFLAG_DM)) { !(env->hflags & MIPS_HFLAG_DM)) {
@ -924,6 +928,11 @@ static inline void compute_hflags(CPUMIPSState *env)
env->hflags |= MIPS_HFLAG_MSA; env->hflags |= MIPS_HFLAG_MSA;
} }
} }
if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
if (env->CP0_Config5 & (1 << CP0C5_FRE)) {
env->hflags |= MIPS_HFLAG_FRE;
}
}
} }
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY

View File

@ -2303,6 +2303,16 @@ target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
} }
} }
break; break;
case 5:
/* FRE Support - read Config5.FRE bit */
if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
} else {
helper_raise_exception(env, EXCP_RI);
}
}
break;
case 25: case 25:
arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | ((env->active_fpu.fcr31 >> 23) & 0x1); arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | ((env->active_fpu.fcr31 >> 23) & 0x1);
break; break;
@ -2347,6 +2357,30 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
helper_raise_exception(env, EXCP_RI); helper_raise_exception(env, EXCP_RI);
} }
break; break;
case 5:
/* FRE Support - clear Config5.FRE bit */
if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
return;
}
if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
env->CP0_Config5 &= ~(1 << CP0C5_FRE);
compute_hflags(env);
} else {
helper_raise_exception(env, EXCP_RI);
}
break;
case 6:
/* FRE Support - set Config5.FRE bit */
if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
return;
}
if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
env->CP0_Config5 |= (1 << CP0C5_FRE);
compute_hflags(env);
} else {
helper_raise_exception(env, EXCP_RI);
}
break;
case 25: case 25:
if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) { if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) {
return; return;

View File

@ -1616,14 +1616,21 @@ static inline void generate_exception(DisasContext *ctx, int excp)
} }
/* Floating point register moves. */ /* Floating point register moves. */
static void gen_load_fpr32(TCGv_i32 t, int reg) static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
{ {
if (ctx->hflags & MIPS_HFLAG_FRE) {
generate_exception(ctx, EXCP_RI);
}
tcg_gen_trunc_i64_i32(t, fpu_f64[reg]); tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
} }
static void gen_store_fpr32(TCGv_i32 t, int reg) static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
{ {
TCGv_i64 t64 = tcg_temp_new_i64(); TCGv_i64 t64;
if (ctx->hflags & MIPS_HFLAG_FRE) {
generate_exception(ctx, EXCP_RI);
}
t64 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(t64, t); tcg_gen_extu_i32_i64(t64, t);
tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
tcg_temp_free_i64(t64); tcg_temp_free_i64(t64);
@ -1637,7 +1644,7 @@ static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
tcg_gen_trunc_i64_i32(t, t64); tcg_gen_trunc_i64_i32(t, t64);
tcg_temp_free_i64(t64); tcg_temp_free_i64(t64);
} else { } else {
gen_load_fpr32(t, reg | 1); gen_load_fpr32(ctx, t, reg | 1);
} }
} }
@ -1649,7 +1656,7 @@ static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
tcg_temp_free_i64(t64); tcg_temp_free_i64(t64);
} else { } else {
gen_store_fpr32(t, reg | 1); gen_store_fpr32(ctx, t, reg | 1);
} }
} }
@ -1817,7 +1824,7 @@ static inline void check_mips_64(DisasContext *ctx)
calling interface for 32 and 64-bit FPRs. No sense in changing calling interface for 32 and 64-bit FPRs. No sense in changing
all callers for gen_load_fpr32 when we need the CTX parameter for all callers for gen_load_fpr32 when we need the CTX parameter for
this one use. */ this one use. */
#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y) #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
#define FOP_CONDS(type, abs, fmt, ifmt, bits) \ #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \ static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
@ -1961,7 +1968,7 @@ static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
} }
FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd)) FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd)) FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
#undef FOP_CONDNS #undef FOP_CONDNS
#undef gen_ldcmp_fpr32 #undef gen_ldcmp_fpr32
#undef gen_ldcmp_fpr64 #undef gen_ldcmp_fpr64
@ -2346,7 +2353,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL); tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
gen_store_fpr32(fp0, ft); gen_store_fpr32(ctx, fp0, ft);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "lwc1"; opn = "lwc1";
@ -2354,7 +2361,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
case OPC_SWC1: case OPC_SWC1:
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, ft); gen_load_fpr32(ctx, fp0, ft);
tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
@ -7555,7 +7562,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
if (h == 0) { if (h == 0) {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, rt); gen_load_fpr32(ctx, fp0, rt);
tcg_gen_ext_i32_tl(t0, fp0); tcg_gen_ext_i32_tl(t0, fp0);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} else { } else {
@ -7754,7 +7761,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(fp0, t0); tcg_gen_trunc_tl_i32(fp0, t0);
gen_store_fpr32(fp0, rd); gen_store_fpr32(ctx, fp0, rd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} else { } else {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
@ -8344,7 +8351,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
tcg_gen_ext_i32_tl(t0, fp0); tcg_gen_ext_i32_tl(t0, fp0);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
@ -8357,7 +8364,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
tcg_gen_trunc_tl_i32(fp0, t0); tcg_gen_trunc_tl_i32(fp0, t0);
gen_store_fpr32(fp0, fs); gen_store_fpr32(ctx, fp0, fs);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "mtc1"; opn = "mtc1";
@ -8455,7 +8462,8 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
gen_set_label(l1); gen_set_label(l1);
} }
static inline void gen_movcf_s (int fs, int fd, int cc, int tf) static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
int tf)
{ {
int cond; int cond;
TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i32 t0 = tcg_temp_new_i32();
@ -8468,8 +8476,8 @@ static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
tcg_gen_brcondi_i32(cond, t0, 0, l1); tcg_gen_brcondi_i32(cond, t0, 0, l1);
gen_load_fpr32(t0, fs); gen_load_fpr32(ctx, t0, fs);
gen_store_fpr32(t0, fd); gen_store_fpr32(ctx, t0, fd);
gen_set_label(l1); gen_set_label(l1);
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
} }
@ -8511,8 +8519,8 @@ static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
tcg_gen_brcondi_i32(cond, t0, 0, l1); tcg_gen_brcondi_i32(cond, t0, 0, l1);
gen_load_fpr32(t0, fs); gen_load_fpr32(ctx, t0, fs);
gen_store_fpr32(t0, fd); gen_store_fpr32(ctx, t0, fd);
gen_set_label(l1); gen_set_label(l1);
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1)); tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
@ -8530,9 +8538,9 @@ static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fd); gen_load_fpr32(ctx, fp0, fd);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_load_fpr32(fp2, fs); gen_load_fpr32(ctx, fp2, fs);
switch (op1) { switch (op1) {
case OPC_SEL_S: case OPC_SEL_S:
@ -8553,7 +8561,7 @@ static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
break; break;
} }
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
@ -8646,11 +8654,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "add.s"; opn = "add.s";
@ -8661,11 +8669,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "sub.s"; opn = "sub.s";
@ -8676,11 +8684,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "mul.s"; opn = "mul.s";
@ -8691,11 +8699,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "div.s"; opn = "div.s";
@ -8705,9 +8713,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_sqrt_s(fp0, cpu_env, fp0); gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "sqrt.s"; opn = "sqrt.s";
@ -8716,9 +8724,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_abs_s(fp0, fp0); gen_helper_float_abs_s(fp0, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "abs.s"; opn = "abs.s";
@ -8727,8 +8735,8 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "mov.s"; opn = "mov.s";
@ -8737,9 +8745,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_chs_s(fp0, fp0); gen_helper_float_chs_s(fp0, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "neg.s"; opn = "neg.s";
@ -8750,7 +8758,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp32 = tcg_temp_new_i32(); TCGv_i32 fp32 = tcg_temp_new_i32();
TCGv_i64 fp64 = tcg_temp_new_i64(); TCGv_i64 fp64 = tcg_temp_new_i64();
gen_load_fpr32(fp32, fs); gen_load_fpr32(ctx, fp32, fs);
gen_helper_float_roundl_s(fp64, cpu_env, fp32); gen_helper_float_roundl_s(fp64, cpu_env, fp32);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
gen_store_fpr64(ctx, fp64, fd); gen_store_fpr64(ctx, fp64, fd);
@ -8764,7 +8772,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp32 = tcg_temp_new_i32(); TCGv_i32 fp32 = tcg_temp_new_i32();
TCGv_i64 fp64 = tcg_temp_new_i64(); TCGv_i64 fp64 = tcg_temp_new_i64();
gen_load_fpr32(fp32, fs); gen_load_fpr32(ctx, fp32, fs);
gen_helper_float_truncl_s(fp64, cpu_env, fp32); gen_helper_float_truncl_s(fp64, cpu_env, fp32);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
gen_store_fpr64(ctx, fp64, fd); gen_store_fpr64(ctx, fp64, fd);
@ -8778,7 +8786,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp32 = tcg_temp_new_i32(); TCGv_i32 fp32 = tcg_temp_new_i32();
TCGv_i64 fp64 = tcg_temp_new_i64(); TCGv_i64 fp64 = tcg_temp_new_i64();
gen_load_fpr32(fp32, fs); gen_load_fpr32(ctx, fp32, fs);
gen_helper_float_ceill_s(fp64, cpu_env, fp32); gen_helper_float_ceill_s(fp64, cpu_env, fp32);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
gen_store_fpr64(ctx, fp64, fd); gen_store_fpr64(ctx, fp64, fd);
@ -8792,7 +8800,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp32 = tcg_temp_new_i32(); TCGv_i32 fp32 = tcg_temp_new_i32();
TCGv_i64 fp64 = tcg_temp_new_i64(); TCGv_i64 fp64 = tcg_temp_new_i64();
gen_load_fpr32(fp32, fs); gen_load_fpr32(ctx, fp32, fs);
gen_helper_float_floorl_s(fp64, cpu_env, fp32); gen_helper_float_floorl_s(fp64, cpu_env, fp32);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
gen_store_fpr64(ctx, fp64, fd); gen_store_fpr64(ctx, fp64, fd);
@ -8804,9 +8812,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_roundw_s(fp0, cpu_env, fp0); gen_helper_float_roundw_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "round.w.s"; opn = "round.w.s";
@ -8815,9 +8823,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_truncw_s(fp0, cpu_env, fp0); gen_helper_float_truncw_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "trunc.w.s"; opn = "trunc.w.s";
@ -8826,9 +8834,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_ceilw_s(fp0, cpu_env, fp0); gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "ceil.w.s"; opn = "ceil.w.s";
@ -8837,9 +8845,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_floorw_s(fp0, cpu_env, fp0); gen_helper_float_floorw_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "floor.w.s"; opn = "floor.w.s";
@ -8861,7 +8869,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
break; break;
case OPC_MOVCF_S: case OPC_MOVCF_S:
check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1); gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
opn = "movcf.s"; opn = "movcf.s";
break; break;
case OPC_MOVZ_S: case OPC_MOVZ_S:
@ -8874,8 +8882,8 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1); tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
} }
fp0 = tcg_temp_new_i32(); fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
gen_set_label(l1); gen_set_label(l1);
} }
@ -8890,8 +8898,8 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
if (ft != 0) { if (ft != 0) {
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1); tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
fp0 = tcg_temp_new_i32(); fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
gen_set_label(l1); gen_set_label(l1);
} }
@ -8903,9 +8911,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_recip_s(fp0, cpu_env, fp0); gen_helper_float_recip_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "recip.s"; opn = "recip.s";
@ -8915,9 +8923,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "rsqrt.s"; opn = "rsqrt.s";
@ -8928,11 +8936,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_load_fpr32(fp2, fd); gen_load_fpr32(ctx, fp2, fd);
gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2); gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
gen_store_fpr32(fp2, fd); gen_store_fpr32(ctx, fp2, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
@ -8945,11 +8953,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_load_fpr32(fp2, fd); gen_load_fpr32(ctx, fp2, fd);
gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2); gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
gen_store_fpr32(fp2, fd); gen_store_fpr32(ctx, fp2, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
@ -8960,9 +8968,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
check_insn(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS32R6);
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_rint_s(fp0, cpu_env, fp0); gen_helper_float_rint_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
opn = "rint.s"; opn = "rint.s";
} }
@ -8971,9 +8979,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
check_insn(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS32R6);
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_class_s(fp0, fp0); gen_helper_float_class_s(fp0, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
opn = "class.s"; opn = "class.s";
} }
@ -8984,10 +8992,10 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
gen_store_fpr32(fp2, fd); gen_store_fpr32(ctx, fp2, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
@ -8999,11 +9007,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1); gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "recip2.s"; opn = "recip2.s";
@ -9015,10 +9023,10 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
gen_store_fpr32(fp2, fd); gen_store_fpr32(ctx, fp2, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
@ -9029,9 +9037,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_recip1_s(fp0, cpu_env, fp0); gen_helper_float_recip1_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "recip1.s"; opn = "recip1.s";
@ -9042,10 +9050,10 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
/* OPC_MAX_S */ /* OPC_MAX_S */
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
gen_store_fpr32(fp1, fd); gen_store_fpr32(ctx, fp1, fd);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
opn = "max.s"; opn = "max.s";
@ -9055,9 +9063,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0); gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "rsqrt1.s"; opn = "rsqrt1.s";
@ -9068,10 +9076,10 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
/* OPC_MAXA_S */ /* OPC_MAXA_S */
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
gen_store_fpr32(fp1, fd); gen_store_fpr32(ctx, fp1, fd);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
opn = "maxa.s"; opn = "maxa.s";
@ -9082,11 +9090,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1); gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "rsqrt2.s"; opn = "rsqrt2.s";
@ -9098,7 +9106,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp32 = tcg_temp_new_i32(); TCGv_i32 fp32 = tcg_temp_new_i32();
TCGv_i64 fp64 = tcg_temp_new_i64(); TCGv_i64 fp64 = tcg_temp_new_i64();
gen_load_fpr32(fp32, fs); gen_load_fpr32(ctx, fp32, fs);
gen_helper_float_cvtd_s(fp64, cpu_env, fp32); gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
gen_store_fpr64(ctx, fp64, fd); gen_store_fpr64(ctx, fp64, fd);
@ -9110,9 +9118,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_cvtw_s(fp0, cpu_env, fp0); gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "cvt.w.s"; opn = "cvt.w.s";
@ -9123,7 +9131,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp32 = tcg_temp_new_i32(); TCGv_i32 fp32 = tcg_temp_new_i32();
TCGv_i64 fp64 = tcg_temp_new_i64(); TCGv_i64 fp64 = tcg_temp_new_i64();
gen_load_fpr32(fp32, fs); gen_load_fpr32(ctx, fp32, fs);
gen_helper_float_cvtl_s(fp64, cpu_env, fp32); gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
gen_store_fpr64(ctx, fp64, fd); gen_store_fpr64(ctx, fp64, fd);
@ -9139,8 +9147,8 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp32_0 = tcg_temp_new_i32(); TCGv_i32 fp32_0 = tcg_temp_new_i32();
TCGv_i32 fp32_1 = tcg_temp_new_i32(); TCGv_i32 fp32_1 = tcg_temp_new_i32();
gen_load_fpr32(fp32_0, fs); gen_load_fpr32(ctx, fp32_0, fs);
gen_load_fpr32(fp32_1, ft); gen_load_fpr32(ctx, fp32_1, ft);
tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0); tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
tcg_temp_free_i32(fp32_1); tcg_temp_free_i32(fp32_1);
tcg_temp_free_i32(fp32_0); tcg_temp_free_i32(fp32_0);
@ -9342,7 +9350,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr64(ctx, fp64, fs); gen_load_fpr64(ctx, fp64, fs);
gen_helper_float_roundw_d(fp32, cpu_env, fp64); gen_helper_float_roundw_d(fp32, cpu_env, fp64);
tcg_temp_free_i64(fp64); tcg_temp_free_i64(fp64);
gen_store_fpr32(fp32, fd); gen_store_fpr32(ctx, fp32, fd);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
} }
opn = "round.w.d"; opn = "round.w.d";
@ -9356,7 +9364,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr64(ctx, fp64, fs); gen_load_fpr64(ctx, fp64, fs);
gen_helper_float_truncw_d(fp32, cpu_env, fp64); gen_helper_float_truncw_d(fp32, cpu_env, fp64);
tcg_temp_free_i64(fp64); tcg_temp_free_i64(fp64);
gen_store_fpr32(fp32, fd); gen_store_fpr32(ctx, fp32, fd);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
} }
opn = "trunc.w.d"; opn = "trunc.w.d";
@ -9370,7 +9378,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr64(ctx, fp64, fs); gen_load_fpr64(ctx, fp64, fs);
gen_helper_float_ceilw_d(fp32, cpu_env, fp64); gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
tcg_temp_free_i64(fp64); tcg_temp_free_i64(fp64);
gen_store_fpr32(fp32, fd); gen_store_fpr32(ctx, fp32, fd);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
} }
opn = "ceil.w.d"; opn = "ceil.w.d";
@ -9384,7 +9392,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr64(ctx, fp64, fs); gen_load_fpr64(ctx, fp64, fs);
gen_helper_float_floorw_d(fp32, cpu_env, fp64); gen_helper_float_floorw_d(fp32, cpu_env, fp64);
tcg_temp_free_i64(fp64); tcg_temp_free_i64(fp64);
gen_store_fpr32(fp32, fd); gen_store_fpr32(ctx, fp32, fd);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
} }
opn = "floor.w.d"; opn = "floor.w.d";
@ -9667,7 +9675,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr64(ctx, fp64, fs); gen_load_fpr64(ctx, fp64, fs);
gen_helper_float_cvts_d(fp32, cpu_env, fp64); gen_helper_float_cvts_d(fp32, cpu_env, fp64);
tcg_temp_free_i64(fp64); tcg_temp_free_i64(fp64);
gen_store_fpr32(fp32, fd); gen_store_fpr32(ctx, fp32, fd);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
} }
opn = "cvt.s.d"; opn = "cvt.s.d";
@ -9681,7 +9689,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr64(ctx, fp64, fs); gen_load_fpr64(ctx, fp64, fs);
gen_helper_float_cvtw_d(fp32, cpu_env, fp64); gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
tcg_temp_free_i64(fp64); tcg_temp_free_i64(fp64);
gen_store_fpr32(fp32, fd); gen_store_fpr32(ctx, fp32, fd);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
} }
opn = "cvt.w.d"; opn = "cvt.w.d";
@ -9702,9 +9710,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_cvts_w(fp0, cpu_env, fp0); gen_helper_float_cvts_w(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "cvt.s.w"; opn = "cvt.s.w";
@ -9715,7 +9723,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp32 = tcg_temp_new_i32(); TCGv_i32 fp32 = tcg_temp_new_i32();
TCGv_i64 fp64 = tcg_temp_new_i64(); TCGv_i64 fp64 = tcg_temp_new_i64();
gen_load_fpr32(fp32, fs); gen_load_fpr32(ctx, fp32, fs);
gen_helper_float_cvtd_w(fp64, cpu_env, fp32); gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
gen_store_fpr64(ctx, fp64, fd); gen_store_fpr64(ctx, fp64, fd);
@ -9732,7 +9740,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr64(ctx, fp64, fs); gen_load_fpr64(ctx, fp64, fs);
gen_helper_float_cvts_l(fp32, cpu_env, fp64); gen_helper_float_cvts_l(fp32, cpu_env, fp64);
tcg_temp_free_i64(fp64); tcg_temp_free_i64(fp64);
gen_store_fpr32(fp32, fd); gen_store_fpr32(ctx, fp32, fd);
tcg_temp_free_i32(fp32); tcg_temp_free_i32(fp32);
} }
opn = "cvt.s.l"; opn = "cvt.s.l";
@ -9971,7 +9979,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr32h(ctx, fp0, fs); gen_load_fpr32h(ctx, fp0, fs);
gen_helper_float_cvts_pu(fp0, cpu_env, fp0); gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "cvt.s.pu"; opn = "cvt.s.pu";
@ -9993,9 +10001,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_helper_float_cvts_pl(fp0, cpu_env, fp0); gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "cvt.s.pl"; opn = "cvt.s.pl";
@ -10006,10 +10014,10 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_store_fpr32h(ctx, fp0, fd); gen_store_fpr32h(ctx, fp0, fd);
gen_store_fpr32(fp1, fd); gen_store_fpr32(ctx, fp1, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
} }
@ -10021,9 +10029,9 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32h(ctx, fp1, ft); gen_load_fpr32h(ctx, fp1, ft);
gen_store_fpr32(fp1, fd); gen_store_fpr32(ctx, fp1, fd);
gen_store_fpr32h(ctx, fp0, fd); gen_store_fpr32h(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
@ -10037,8 +10045,8 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32h(ctx, fp0, fs); gen_load_fpr32h(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_store_fpr32(fp1, fd); gen_store_fpr32(ctx, fp1, fd);
gen_store_fpr32h(ctx, fp0, fd); gen_store_fpr32h(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
@ -10053,7 +10061,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr32h(ctx, fp0, fs); gen_load_fpr32h(ctx, fp0, fs);
gen_load_fpr32h(ctx, fp1, ft); gen_load_fpr32h(ctx, fp1, ft);
gen_store_fpr32(fp1, fd); gen_store_fpr32(ctx, fp1, fd);
gen_store_fpr32h(ctx, fp0, fd); gen_store_fpr32h(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
@ -10128,7 +10136,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
tcg_gen_trunc_tl_i32(fp0, t0); tcg_gen_trunc_tl_i32(fp0, t0);
gen_store_fpr32(fp0, fd); gen_store_fpr32(ctx, fp0, fd);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
opn = "lwxc1"; opn = "lwxc1";
@ -10160,7 +10168,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
check_cop1x(ctx); check_cop1x(ctx);
{ {
TCGv_i32 fp0 = tcg_temp_new_i32(); TCGv_i32 fp0 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
} }
@ -10217,23 +10225,23 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
tcg_gen_andi_tl(t0, t0, 0x7); tcg_gen_andi_tl(t0, t0, 0x7);
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
gen_load_fpr32(fp, fs); gen_load_fpr32(ctx, fp, fs);
gen_load_fpr32h(ctx, fph, fs); gen_load_fpr32h(ctx, fph, fs);
gen_store_fpr32(fp, fd); gen_store_fpr32(ctx, fp, fd);
gen_store_fpr32h(ctx, fph, fd); gen_store_fpr32h(ctx, fph, fd);
tcg_gen_br(l2); tcg_gen_br(l2);
gen_set_label(l1); gen_set_label(l1);
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
tcg_temp_free(t0); tcg_temp_free(t0);
#ifdef TARGET_WORDS_BIGENDIAN #ifdef TARGET_WORDS_BIGENDIAN
gen_load_fpr32(fp, fs); gen_load_fpr32(ctx, fp, fs);
gen_load_fpr32h(ctx, fph, ft); gen_load_fpr32h(ctx, fph, ft);
gen_store_fpr32h(ctx, fp, fd); gen_store_fpr32h(ctx, fp, fd);
gen_store_fpr32(fph, fd); gen_store_fpr32(ctx, fph, fd);
#else #else
gen_load_fpr32h(ctx, fph, fs); gen_load_fpr32h(ctx, fph, fs);
gen_load_fpr32(fp, ft); gen_load_fpr32(ctx, fp, ft);
gen_store_fpr32(fph, fd); gen_store_fpr32(ctx, fph, fd);
gen_store_fpr32h(ctx, fp, fd); gen_store_fpr32h(ctx, fp, fd);
#endif #endif
gen_set_label(l2); gen_set_label(l2);
@ -10249,13 +10257,13 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_load_fpr32(fp2, fr); gen_load_fpr32(ctx, fp2, fr);
gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2); gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp2, fd); gen_store_fpr32(ctx, fp2, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
} }
opn = "madd.s"; opn = "madd.s";
@ -10304,13 +10312,13 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_load_fpr32(fp2, fr); gen_load_fpr32(ctx, fp2, fr);
gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2); gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp2, fd); gen_store_fpr32(ctx, fp2, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
} }
opn = "msub.s"; opn = "msub.s";
@ -10359,13 +10367,13 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_load_fpr32(fp2, fr); gen_load_fpr32(ctx, fp2, fr);
gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2); gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp2, fd); gen_store_fpr32(ctx, fp2, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
} }
opn = "nmadd.s"; opn = "nmadd.s";
@ -10414,13 +10422,13 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
TCGv_i32 fp1 = tcg_temp_new_i32(); TCGv_i32 fp1 = tcg_temp_new_i32();
TCGv_i32 fp2 = tcg_temp_new_i32(); TCGv_i32 fp2 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs); gen_load_fpr32(ctx, fp0, fs);
gen_load_fpr32(fp1, ft); gen_load_fpr32(ctx, fp1, ft);
gen_load_fpr32(fp2, fr); gen_load_fpr32(ctx, fp2, fr);
gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2); gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
tcg_temp_free_i32(fp0); tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1); tcg_temp_free_i32(fp1);
gen_store_fpr32(fp2, fd); gen_store_fpr32(ctx, fp2, fd);
tcg_temp_free_i32(fp2); tcg_temp_free_i32(fp2);
} }
opn = "nmsub.s"; opn = "nmsub.s";
@ -13500,7 +13508,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
case MOVF_FMT: case MOVF_FMT:
switch (fmt) { switch (fmt) {
case FMT_SDPS_S: case FMT_SDPS_S:
gen_movcf_s(rs, rt, cc, 0); gen_movcf_s(ctx, rs, rt, cc, 0);
break; break;
case FMT_SDPS_D: case FMT_SDPS_D:
gen_movcf_d(ctx, rs, rt, cc, 0); gen_movcf_d(ctx, rs, rt, cc, 0);
@ -13515,7 +13523,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
case MOVT_FMT: case MOVT_FMT:
switch (fmt) { switch (fmt) {
case FMT_SDPS_S: case FMT_SDPS_S:
gen_movcf_s(rs, rt, cc, 1); gen_movcf_s(ctx, rs, rt, cc, 1);
break; break;
case FMT_SDPS_D: case FMT_SDPS_D:
gen_movcf_d(ctx, rs, rt, cc, 1); gen_movcf_d(ctx, rs, rt, cc, 1);

View File

@ -622,7 +622,8 @@ static const mips_def_t mips_defs[] =
(1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1U << CP0C3_M), (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1U << CP0C3_M),
.CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
(3 << CP0C4_IE) | (1 << CP0C4_M), (3 << CP0C4_IE) | (1 << CP0C4_M),
.CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI), .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
(1 << CP0C5_UFE),
.CP0_LLAddr_rw_bitmask = 0, .CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 0, .CP0_LLAddr_shift = 0,
.SYNCI_Step = 32, .SYNCI_Step = 32,
@ -631,9 +632,9 @@ static const mips_def_t mips_defs[] =
.CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) | .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
(1U << CP0PG_RIE), (1U << CP0PG_RIE),
.CP0_PageGrain_rw_bitmask = 0, .CP0_PageGrain_rw_bitmask = 0,
.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) |
(1 << FCR0_D) | (1 << FCR0_S) | (0x00 << FCR0_PRID) | (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
(0x0 << FCR0_REV), (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 42, .SEGBITS = 42,
/* The architectural limit is 59, but we have hardcoded 36 bit /* The architectural limit is 59, but we have hardcoded 36 bit
in some places... in some places...