diff mbox

[v3,13/16] target-m68k: add fsglmul and fsgldiv

Message ID 20170207005930.28327-14-laurent@vivier.eu (mailing list archive)
State New, archived
Headers show

Commit Message

Laurent Vivier Feb. 7, 2017, 12:59 a.m. UTC
fsglmul and fsgldiv truncate data to single precision before computing
results.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/fpu_helper.c | 22 ++++++++++++++++++++++
 target/m68k/helper.h     |  2 ++
 target/m68k/translate.c  |  8 ++++++++
 3 files changed, 32 insertions(+)

Comments

Richard Henderson Feb. 16, 2017, 1:36 a.m. UTC | #1
On 02/07/2017 11:59 AM, Laurent Vivier wrote:
> fsglmul and fsgldiv truncate data to single precision before computing
> results.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>  target/m68k/fpu_helper.c | 22 ++++++++++++++++++++++
>  target/m68k/helper.h     |  2 ++
>  target/m68k/translate.c  |  8 ++++++++
>  3 files changed, 32 insertions(+)
>
> diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
> index 42f5b5c..8a3eed3 100644
> --- a/target/m68k/fpu_helper.c
> +++ b/target/m68k/fpu_helper.c
> @@ -351,6 +351,17 @@ void HELPER(mul_FP0_FP1)(CPUM68KState *env)
>      floatx80_to_FP0(env, res);
>  }
>
> +void HELPER(sglmul_FP0_FP1)(CPUM68KState *env)
> +{
> +    float64 a, b, res;
> +
> +    a = floatx80_to_float64(FP0_to_floatx80(env), &env->fp_status);
> +    b = floatx80_to_float64(FP1_to_floatx80(env), &env->fp_status);

s/float64/float32/g

Kinda sorta, probably close enough.  The manual says the resulting exponent may 
be out of range.  Which means this will produce +Inf in cases HW won't.


r~
diff mbox

Patch

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 42f5b5c..8a3eed3 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -351,6 +351,17 @@  void HELPER(mul_FP0_FP1)(CPUM68KState *env)
     floatx80_to_FP0(env, res);
 }
 
+void HELPER(sglmul_FP0_FP1)(CPUM68KState *env)
+{
+    float64 a, b, res;
+
+    a = floatx80_to_float64(FP0_to_floatx80(env), &env->fp_status);
+    b = floatx80_to_float64(FP1_to_floatx80(env), &env->fp_status);
+    res = float64_mul(a, b, &env->fp_status);
+
+    floatx80_to_FP0(env, float64_to_floatx80(res, &env->fp_status));
+}
+
 void HELPER(div_FP0_FP1)(CPUM68KState *env)
 {
     floatx80 res;
@@ -361,6 +372,17 @@  void HELPER(div_FP0_FP1)(CPUM68KState *env)
     floatx80_to_FP0(env, res);
 }
 
+void HELPER(sgldiv_FP0_FP1)(CPUM68KState *env)
+{
+    float64 a, b, res;
+
+    a = floatx80_to_float64(FP1_to_floatx80(env), &env->fp_status);
+    b = floatx80_to_float64(FP0_to_floatx80(env), &env->fp_status);
+    res = float64_div(a, b, &env->fp_status);
+
+    floatx80_to_FP0(env, float64_to_floatx80(res, &env->fp_status));
+}
+
 static int float_comp_to_cc(int float_compare)
 {
     switch (float_compare) {
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 620e707..c30e5f7 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -26,7 +26,9 @@  DEF_HELPER_1(chs_FP0, void, env)
 DEF_HELPER_1(add_FP0_FP1, void, env)
 DEF_HELPER_1(sub_FP0_FP1, void, env)
 DEF_HELPER_1(mul_FP0_FP1, void, env)
+DEF_HELPER_1(sglmul_FP0_FP1, void, env)
 DEF_HELPER_1(div_FP0_FP1, void, env)
+DEF_HELPER_1(sgldiv_FP0_FP1, void, env)
 DEF_HELPER_1(cmp_FP0_FP1, void, env)
 DEF_HELPER_2(set_fpcr, void, env, i32)
 DEF_HELPER_1(tst_FP0, void, env)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index be18083..99f41d3 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4651,10 +4651,18 @@  DISAS_INSN(fpu)
         gen_op_load_fpr_FP1(REG(ext, 7));
         gen_helper_mul_FP0_FP1(cpu_env);
         break;
+    case 0x24: /* fsgldiv */
+        gen_op_load_fpr_FP1(REG(ext, 7));
+        gen_helper_sgldiv_FP0_FP1(cpu_env);
+        break;
     case 0x26: /* fscale */
         gen_op_load_fpr_FP1(REG(ext, 7));
         gen_helper_scale_FP0_FP1(cpu_env);
         break;
+    case 0x27: /* fsglmul */
+        gen_op_load_fpr_FP1(REG(ext, 7));
+        gen_helper_sglmul_FP0_FP1(cpu_env);
+        break;
     case 0x28: case 0x68: case 0x6c: /* fsub */
         gen_op_load_fpr_FP1(REG(ext, 7));
         gen_helper_sub_FP0_FP1(cpu_env);