On 02/07/2017 11:59 AM, Laurent Vivier wrote:
Signed-off-by: Laurent Vivier <laur...@vivier.eu>
---
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);
Failure to raise OPERR for infinities?
+void HELPER(getman_FP0)(CPUM68KState *env)
+{
+ floatx80 res;
+ res = int64_to_floatx80(env->fp0l, &env->fp_status);
+ floatx80_to_FP0(env, res);
+}
This seems completely wrong. (1) NaN gets returned, (2) Inf raises OPERR, (3)
Normal values return something in the range [1.0 ... 2.0). Which means you
should just force the exponent rather than convert the low part.
+
+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;
+}
Missing handling for NaN, Inf, 0, denormal.
r~