[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 12/16] target-m68k: add fscale, fgetman, fgetexp
From: |
Laurent Vivier |
Subject: |
[Qemu-devel] [PATCH v3 12/16] target-m68k: add fscale, fgetman, fgetexp and fmod |
Date: |
Tue, 7 Feb 2017 01:59:26 +0100 |
Signed-off-by: Laurent Vivier <address@hidden>
---
target/m68k/cpu.h | 1 +
target/m68k/fpu_helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
target/m68k/helper.h | 4 ++++
target/m68k/translate.c | 14 ++++++++++++
4 files changed, 75 insertions(+)
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 7985dc3..3042ab7 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -253,6 +253,7 @@ typedef enum {
/* Quotient */
#define FPSR_QT_MASK 0x00ff0000
+#define FPSR_QT_SHIFT 16
/* Floating-Point Control Register */
/* Rounding mode */
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index d8145e0..42f5b5c 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -458,3 +458,59 @@ void HELPER(const_FP0)(CPUM68KState *env, uint32_t offset)
env->fp0l = fpu_rom[offset].low;
env->fp0h = fpu_rom[offset].high;
}
+
+void HELPER(getexp_FP0)(CPUM68KState *env)
+{
+ int32_t exp;
+ floatx80 res;
+
+ res = FP0_to_floatx80(env);
+ if (floatx80_is_zero_or_denormal(res) || floatx80_is_any_nan(res) ||
+ floatx80_is_infinity(res)) {
+ return;
+ }
+ exp = (env->fp0h & 0x7fff) - 0x3fff;
+
+ res = int32_to_floatx80(exp, &env->fp_status);
+
+ floatx80_to_FP0(env, res);
+}
+
+void HELPER(getman_FP0)(CPUM68KState *env)
+{
+ floatx80 res;
+ res = int64_to_floatx80(env->fp0l, &env->fp_status);
+ floatx80_to_FP0(env, res);
+}
+
+void HELPER(scale_FP0_FP1)(CPUM68KState *env)
+{
+ int32_t scale;
+ int32_t exp;
+
+ scale = floatx80_to_int32(FP0_to_floatx80(env), &env->fp_status);
+
+ exp = (env->fp1h & 0x7fff) + scale;
+
+ env->fp0h = (env->fp1h & 0x8000) | (exp & 0x7fff);
+ env->fp0l = env->fp1l;
+}
+
+static void make_quotient(CPUM68KState *env, floatx80 val)
+{
+ uint32_t quotient = floatx80_to_int32(val, &env->fp_status);
+ uint32_t sign = (quotient >> 24) & 0x80;
+ quotient = sign | (quotient & 0x7f);
+ env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
+}
+
+void HELPER(mod_FP0_FP1)(CPUM68KState *env)
+{
+ floatx80 res;
+
+ res = floatx80_rem(FP1_to_floatx80(env), FP0_to_floatx80(env),
+ &env->fp_status);
+ make_quotient(env, res);
+
+ floatx80_to_FP0(env, res);
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 4927324..620e707 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -33,6 +33,10 @@ DEF_HELPER_1(tst_FP0, void, env)
DEF_HELPER_1(update_fpstatus, void, env)
DEF_HELPER_4(fmovem, void, env, i32, i32, i32)
DEF_HELPER_2(const_FP0, void, env, i32)
+DEF_HELPER_1(getexp_FP0, void, env)
+DEF_HELPER_1(getman_FP0, void, env)
+DEF_HELPER_1(scale_FP0_FP1, void, env)
+DEF_HELPER_1(mod_FP0_FP1, void, env)
DEF_HELPER_3(mac_move, void, env, i32, i32)
DEF_HELPER_3(macmulf, i64, env, i32, i32)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 23eac63..be18083 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4629,10 +4629,20 @@ DISAS_INSN(fpu)
case 0x1a: case 0x5a: case 0x5e: /* fneg */
gen_helper_chs_FP0(cpu_env);
break;
+ case 0x1e: /* fgetexp */
+ gen_helper_getexp_FP0(cpu_env);
+ break;
+ case 0x1f: /* fgetman */
+ gen_helper_getman_FP0(cpu_env);
+ break;
case 0x20: case 0x60: case 0x64: /* fdiv */
gen_op_load_fpr_FP1(REG(ext, 7));
gen_helper_div_FP0_FP1(cpu_env);
break;
+ case 0x21: /* fmod */
+ gen_op_load_fpr_FP1(REG(ext, 7));
+ gen_helper_mod_FP0_FP1(cpu_env);
+ break;
case 0x22: case 0x62: case 0x66: /* fadd */
gen_op_load_fpr_FP1(REG(ext, 7));
gen_helper_add_FP0_FP1(cpu_env);
@@ -4641,6 +4651,10 @@ DISAS_INSN(fpu)
gen_op_load_fpr_FP1(REG(ext, 7));
gen_helper_mul_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 0x28: case 0x68: case 0x6c: /* fsub */
gen_op_load_fpr_FP1(REG(ext, 7));
gen_helper_sub_FP0_FP1(cpu_env);
--
2.9.3
- [Qemu-devel] [PATCH v3 08/16] target-m68k: define 96bit FP registers for gdb on 680x0, (continued)
- [Qemu-devel] [PATCH v3 08/16] target-m68k: define 96bit FP registers for gdb on 680x0, Laurent Vivier, 2017/02/06
- [Qemu-devel] [PATCH v3 04/16] target-m68k: define ext_opsize, Laurent Vivier, 2017/02/06
- [Qemu-devel] [PATCH v3 06/16] target-m68k: add FPCR and FPSR, Laurent Vivier, 2017/02/06
- [Qemu-devel] [PATCH v3 09/16] target-m68k: add fmovem, Laurent Vivier, 2017/02/06
- [Qemu-devel] [PATCH v3 11/16] target-m68k: add fmovecr, Laurent Vivier, 2017/02/06
- [Qemu-devel] [PATCH v3 12/16] target-m68k: add fscale, fgetman, fgetexp and fmod,
Laurent Vivier <=
- [Qemu-devel] [PATCH v3 05/16] target-m68k: use floatx80 internally, Laurent Vivier, 2017/02/06
- [Qemu-devel] [PATCH v3 16/16] target-m68k: add fsincos, Laurent Vivier, 2017/02/06
- [Qemu-devel] [PATCH v3 15/16] target-m68k: add more FPU instructions, Laurent Vivier, 2017/02/06
[Qemu-devel] [PATCH v3 13/16] target-m68k: add fsglmul and fsgldiv, Laurent Vivier, 2017/02/06