Re: [Qemu-devel] [PATCH v3 2/4] target/m68k: add fmod/frem

2018-02-23 Thread Richard Henderson
On 02/23/2018 06:59 AM, Laurent Vivier wrote:
> Using a local m68k floatx80_mod()
> [copied from previous:
> Written by Andreas Grabher for Previous, NeXT Computer Emulator.]
> 
> The quotient byte of the FPSR is updated with
> the result of the operation.
> 
> Signed-off-by: Laurent Vivier 
> ---
>  target/m68k/Makefile.objs |   3 +-
>  target/m68k/cpu.h |   1 +
>  target/m68k/fpu_helper.c  |  35 +++-
>  target/m68k/helper.h  |   2 +
>  target/m68k/softfloat.c   | 105 
> ++
>  target/m68k/softfloat.h   |  26 
>  target/m68k/translate.c   |   6 +++
>  7 files changed, 176 insertions(+), 2 deletions(-)
>  create mode 100644 target/m68k/softfloat.c
>  create mode 100644 target/m68k/softfloat.h

Reviewed-by: Richard Henderson 


r~



[Qemu-devel] [PATCH v3 2/4] target/m68k: add fmod/frem

2018-02-23 Thread Laurent Vivier
Using a local m68k floatx80_mod()
[copied from previous:
Written by Andreas Grabher for Previous, NeXT Computer Emulator.]

The quotient byte of the FPSR is updated with
the result of the operation.

Signed-off-by: Laurent Vivier 
---
 target/m68k/Makefile.objs |   3 +-
 target/m68k/cpu.h |   1 +
 target/m68k/fpu_helper.c  |  35 +++-
 target/m68k/helper.h  |   2 +
 target/m68k/softfloat.c   | 105 ++
 target/m68k/softfloat.h   |  26 
 target/m68k/translate.c   |   6 +++
 7 files changed, 176 insertions(+), 2 deletions(-)
 create mode 100644 target/m68k/softfloat.c
 create mode 100644 target/m68k/softfloat.h

diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs
index d143f20270..ac61948676 100644
--- a/target/m68k/Makefile.objs
+++ b/target/m68k/Makefile.objs
@@ -1,4 +1,5 @@
 obj-y += m68k-semi.o
-obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o
+obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += fpu_helper.o softfloat.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += monitor.o
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index 65f4fb95cb..2259bf22dc 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -427,6 +427,7 @@ typedef enum {
 /* Quotient */
 
 #define FPSR_QT_MASK  0x00ff
+#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 3c5a82aaa0..8286228b81 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -23,7 +23,7 @@
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
-#include "fpu/softfloat.h"
+#include "softfloat.h"
 
 /* Undefined offsets may be different on various FPU.
  * On 68040 they return 0.0 (floatx80_zero)
@@ -509,3 +509,36 @@ uint32_t HELPER(fmovemd_ld_postinc)(CPUM68KState *env, 
uint32_t addr,
 {
 return fmovem_postinc(env, addr, mask, cpu_ld_float64_ra);
 }
+
+static void make_quotient(CPUM68KState *env, floatx80 val)
+{
+int32_t quotient;
+int sign;
+
+if (floatx80_is_any_nan(val)) {
+return;
+}
+
+quotient = floatx80_to_int32(val, &env->fp_status);
+sign = quotient < 0;
+if (sign) {
+quotient = -quotient;
+}
+
+quotient = (sign << 7) | (quotient & 0x7f);
+env->fpsr = (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT);
+}
+
+void HELPER(fmod)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+res->d = floatx80_mod(val1->d, val0->d, &env->fp_status);
+
+make_quotient(env, res->d);
+}
+
+void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+res->d = floatx80_rem(val1->d, val0->d, &env->fp_status);
+
+make_quotient(env, res->d);
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 7f400f0def..76a0590c9c 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -63,6 +63,8 @@ DEF_HELPER_3(fmovemx_ld_postinc, i32, env, i32, i32)
 DEF_HELPER_3(fmovemd_st_predec, i32, env, i32, i32)
 DEF_HELPER_3(fmovemd_st_postinc, i32, env, i32, i32)
 DEF_HELPER_3(fmovemd_ld_postinc, i32, env, i32, i32)
+DEF_HELPER_4(fmod, void, env, fp, fp, fp)
+DEF_HELPER_4(frem, void, env, fp, fp, fp)
 
 DEF_HELPER_3(mac_move, void, env, i32, i32)
 DEF_HELPER_3(macmulf, i64, env, i32, i32)
diff --git a/target/m68k/softfloat.c b/target/m68k/softfloat.c
new file mode 100644
index 00..8c77757b4e
--- /dev/null
+++ b/target/m68k/softfloat.c
@@ -0,0 +1,105 @@
+/*
+ * Ported from a work by Andreas Grabher for Previous, NeXT Computer Emulator,
+ * derived from NetBSD M68040 FPSP functions,
+ * derived from release 2a of the SoftFloat IEC/IEEE Floating-point Arithmetic
+ * Package. Those parts of the code (and some later contributions) are
+ * provided under that license, as detailed below.
+ * It has subsequently been modified by contributors to the QEMU Project,
+ * so some portions are provided under:
+ *  the SoftFloat-2a license
+ *  the BSD license
+ *  GPL-v2-or-later
+ *
+ * Any future contributions to this file will be taken to be licensed under
+ * the Softfloat-2a license unless specifically indicated otherwise.
+ */
+
+/* Portions of this work are licensed under the terms of the GNU GPL,
+ * version 2 or later. See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "softfloat.h"
+#include "fpu/softfloat-macros.h"
+
+/*
+ | Returns the modulo remainder of the extended double-precision floating-point
+ | value `a' with respect to the corresponding value `b'.
+ 
**/
+
+floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
+{
+flag aSign, zSign;
+int32_t aExp, bExp, expDiff;
+uint64_t aSig0, aSig1, bSig;
+uint64_t qTemp, term0, term1;
+
+aSig0 = extractFloatx80Frac(a);
+aExp =