diff options
Diffstat (limited to 'target-mips')
-rw-r--r-- | target-mips/helper.h | 8 | ||||
-rw-r--r-- | target-mips/op_helper.c | 137 | ||||
-rw-r--r-- | target-mips/translate.c | 24 |
3 files changed, 64 insertions, 105 deletions
diff --git a/target-mips/helper.h b/target-mips/helper.h index 36a2e8da07..da8d9a1381 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -254,10 +254,10 @@ FOP_PROTO(rsqrt2) DEF_HELPER_4(float_ ## op ## _s, i32, env, i32, i32, i32) \ DEF_HELPER_4(float_ ## op ## _d, i64, env, i64, i64, i64) \ DEF_HELPER_4(float_ ## op ## _ps, i64, env, i64, i64, i64) -FOP_PROTO(muladd) -FOP_PROTO(mulsub) -FOP_PROTO(nmuladd) -FOP_PROTO(nmulsub) +FOP_PROTO(madd) +FOP_PROTO(msub) +FOP_PROTO(nmadd) +FOP_PROTO(nmsub) #undef FOP_PROTO #define FOP_PROTO(op) \ diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index d50334f45f..1abed8e3da 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -3031,95 +3031,54 @@ FLOAT_BINOP(mul) FLOAT_BINOP(div) #undef FLOAT_BINOP -/* ternary operations */ -#define FLOAT_TERNOP(name1, name2) \ -uint64_t helper_float_ ## name1 ## name2 ## _d(CPUMIPSState *env, \ - uint64_t fdt0, \ - uint64_t fdt1, \ - uint64_t fdt2) \ -{ \ - fdt0 = float64_ ## name1 (fdt0, fdt1, &env->active_fpu.fp_status); \ - return float64_ ## name2 (fdt0, fdt2, &env->active_fpu.fp_status); \ -} \ - \ -uint32_t helper_float_ ## name1 ## name2 ## _s(CPUMIPSState *env, \ - uint32_t fst0, \ - uint32_t fst1, \ - uint32_t fst2) \ -{ \ - fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status); \ - return float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status); \ -} \ - \ -uint64_t helper_float_ ## name1 ## name2 ## _ps(CPUMIPSState *env, \ - uint64_t fdt0, \ - uint64_t fdt1, \ - uint64_t fdt2) \ -{ \ - uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ - uint32_t fsth0 = fdt0 >> 32; \ - uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ - uint32_t fsth1 = fdt1 >> 32; \ - uint32_t fst2 = fdt2 & 0XFFFFFFFF; \ - uint32_t fsth2 = fdt2 >> 32; \ - \ - fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status); \ - fsth0 = float32_ ## name1 (fsth0, fsth1, &env->active_fpu.fp_status); \ - fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status); \ - fsth2 = float32_ ## name2 (fsth0, fsth2, &env->active_fpu.fp_status); \ - return ((uint64_t)fsth2 << 32) | fst2; \ -} - -FLOAT_TERNOP(mul, add) -FLOAT_TERNOP(mul, sub) -#undef FLOAT_TERNOP - -/* negated ternary operations */ -#define FLOAT_NTERNOP(name1, name2) \ -uint64_t helper_float_n ## name1 ## name2 ## _d(CPUMIPSState *env, \ - uint64_t fdt0, \ - uint64_t fdt1, \ - uint64_t fdt2) \ -{ \ - fdt0 = float64_ ## name1 (fdt0, fdt1, &env->active_fpu.fp_status); \ - fdt2 = float64_ ## name2 (fdt0, fdt2, &env->active_fpu.fp_status); \ - return float64_chs(fdt2); \ -} \ - \ -uint32_t helper_float_n ## name1 ## name2 ## _s(CPUMIPSState *env, \ - uint32_t fst0, \ - uint32_t fst1, \ - uint32_t fst2) \ -{ \ - fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status); \ - fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status); \ - return float32_chs(fst2); \ -} \ - \ -uint64_t helper_float_n ## name1 ## name2 ## _ps(CPUMIPSState *env, \ - uint64_t fdt0, \ - uint64_t fdt1, \ - uint64_t fdt2) \ -{ \ - uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ - uint32_t fsth0 = fdt0 >> 32; \ - uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ - uint32_t fsth1 = fdt1 >> 32; \ - uint32_t fst2 = fdt2 & 0XFFFFFFFF; \ - uint32_t fsth2 = fdt2 >> 32; \ - \ - fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status); \ - fsth0 = float32_ ## name1 (fsth0, fsth1, &env->active_fpu.fp_status); \ - fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status); \ - fsth2 = float32_ ## name2 (fsth0, fsth2, &env->active_fpu.fp_status); \ - fst2 = float32_chs(fst2); \ - fsth2 = float32_chs(fsth2); \ - return ((uint64_t)fsth2 << 32) | fst2; \ -} - -FLOAT_NTERNOP(mul, add) -FLOAT_NTERNOP(mul, sub) -#undef FLOAT_NTERNOP +/* FMA based operations */ +#define FLOAT_FMA(name, type) \ +uint64_t helper_float_ ## name ## _d(CPUMIPSState *env, \ + uint64_t fdt0, uint64_t fdt1, \ + uint64_t fdt2) \ +{ \ + set_float_exception_flags(0, &env->active_fpu.fp_status); \ + fdt0 = float64_muladd(fdt0, fdt1, fdt2, type, \ + &env->active_fpu.fp_status); \ + update_fcr31(env); \ + return fdt0; \ +} \ + \ +uint32_t helper_float_ ## name ## _s(CPUMIPSState *env, \ + uint32_t fst0, uint32_t fst1, \ + uint32_t fst2) \ +{ \ + set_float_exception_flags(0, &env->active_fpu.fp_status); \ + fst0 = float32_muladd(fst0, fst1, fst2, type, \ + &env->active_fpu.fp_status); \ + update_fcr31(env); \ + return fst0; \ +} \ + \ +uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env, \ + uint64_t fdt0, uint64_t fdt1, \ + uint64_t fdt2) \ +{ \ + uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ + uint32_t fsth0 = fdt0 >> 32; \ + uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ + uint32_t fsth1 = fdt1 >> 32; \ + uint32_t fst2 = fdt2 & 0XFFFFFFFF; \ + uint32_t fsth2 = fdt2 >> 32; \ + \ + set_float_exception_flags(0, &env->active_fpu.fp_status); \ + fst0 = float32_muladd(fst0, fst1, fst2, type, \ + &env->active_fpu.fp_status); \ + fsth0 = float32_muladd(fsth0, fsth1, fsth2, type, \ + &env->active_fpu.fp_status); \ + update_fcr31(env); \ + return ((uint64_t)fsth0 << 32) | fst0; \ +} +FLOAT_FMA(madd, 0) +FLOAT_FMA(msub, float_muladd_negate_c) +FLOAT_FMA(nmadd, float_muladd_negate_result) +FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c) +#undef FLOAT_FMA /* MIPS specific binary operations */ uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) diff --git a/target-mips/translate.c b/target-mips/translate.c index a84ed6e547..e7184715bf 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -8817,7 +8817,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32(fp0, fs); gen_load_fpr32(fp1, ft); gen_load_fpr32(fp2, fr); - gen_helper_float_muladd_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(fp1); gen_store_fpr32(fp2, fd); @@ -8836,7 +8836,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); gen_load_fpr64(ctx, fp2, fr); - gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2); + gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2); tcg_temp_free_i64(fp0); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp2, fd); @@ -8854,7 +8854,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); gen_load_fpr64(ctx, fp2, fr); - gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2); + gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2); tcg_temp_free_i64(fp0); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp2, fd); @@ -8872,7 +8872,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32(fp0, fs); gen_load_fpr32(fp1, ft); gen_load_fpr32(fp2, fr); - gen_helper_float_mulsub_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(fp1); gen_store_fpr32(fp2, fd); @@ -8891,7 +8891,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); gen_load_fpr64(ctx, fp2, fr); - gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2); + gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2); tcg_temp_free_i64(fp0); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp2, fd); @@ -8909,7 +8909,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); gen_load_fpr64(ctx, fp2, fr); - gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2); + gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2); tcg_temp_free_i64(fp0); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp2, fd); @@ -8927,7 +8927,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32(fp0, fs); gen_load_fpr32(fp1, ft); gen_load_fpr32(fp2, fr); - gen_helper_float_nmuladd_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(fp1); gen_store_fpr32(fp2, fd); @@ -8946,7 +8946,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); gen_load_fpr64(ctx, fp2, fr); - gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2); + gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2); tcg_temp_free_i64(fp0); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp2, fd); @@ -8964,7 +8964,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); gen_load_fpr64(ctx, fp2, fr); - gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2); + gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2); tcg_temp_free_i64(fp0); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp2, fd); @@ -8982,7 +8982,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32(fp0, fs); gen_load_fpr32(fp1, ft); gen_load_fpr32(fp2, fr); - gen_helper_float_nmulsub_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(fp1); gen_store_fpr32(fp2, fd); @@ -9001,7 +9001,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); gen_load_fpr64(ctx, fp2, fr); - gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2); + gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2); tcg_temp_free_i64(fp0); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp2, fd); @@ -9019,7 +9019,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fp0, fs); gen_load_fpr64(ctx, fp1, ft); gen_load_fpr64(ctx, fp2, fr); - gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2); + gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2); tcg_temp_free_i64(fp0); tcg_temp_free_i64(fp1); gen_store_fpr64(ctx, fp2, fd); |