Skip to content

Commit

Permalink
target-mips: use the softfloat floatXX_muladd functions
Browse files Browse the repository at this point in the history
Use the new softfloat floatXX_muladd() functions to implement the madd,
msub, nmadd and nmsub instructions. At the same time replace the name of
the helpers by the name of the instruction, as the only reason for the
previous names was to keep the macros simple.

Reviewed-by: Richard Henderson <[email protected]>
Signed-off-by: Aurelien Jarno <[email protected]>
  • Loading branch information
aurel32 committed Oct 31, 2012
1 parent bbc1ded commit b3d6cd4
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 105 deletions.
8 changes: 4 additions & 4 deletions target-mips/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
137 changes: 48 additions & 89 deletions target-mips/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
24 changes: 12 additions & 12 deletions target-mips/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit b3d6cd4

Please sign in to comment.