qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/5] M68k for 2.12 patches
@ 2018-03-04 17:32 Laurent Vivier
  2018-03-04 17:32 ` [Qemu-devel] [PULL 1/5] target/m68k: TCGv returned by gen_load() must be freed Laurent Vivier
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Laurent Vivier @ 2018-03-04 17:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Laurent Vivier

The following changes since commit 136c67e07869227b21b3f627316e03679ce7b738:

  Merge remote-tracking branch 'remotes/bkoppelmann/tags/pull-tricore-2018-03-02' into staging (2018-03-02 16:56:20 +0000)

are available in the Git repository at:

  git://github.com/vivier/qemu-m68k.git tags/m68k-for-2.12-pull-request

for you to fetch changes up to 0d379c1709aa6b2d09dd3b493bfdf3a5fe6debcd:

  target/m68k: add fscale, fgetman and fgetexp (2018-03-04 17:27:59 +0100)

----------------------------------------------------------------

----------------------------------------------------------------

Laurent Vivier (5):
  target/m68k: TCGv returned by gen_load() must be freed
  softfloat: export some functions
  target/m68k: add fmod/frem
  softfloat: use floatx80_infinity in softfloat
  target/m68k: add fscale, fgetman and fgetexp

 fpu/softfloat-specialize.h              |  17 ++-
 fpu/softfloat.c                         | 130 +++++------------
 {fpu => include/fpu}/softfloat-macros.h |  10 +-
 include/fpu/softfloat.h                 | 134 ++++++++++++++++-
 target/m68k/Makefile.objs               |   3 +-
 target/m68k/cpu.h                       |   1 +
 target/m68k/fpu_helper.c                |  50 ++++++-
 target/m68k/helper.h                    |   5 +
 target/m68k/softfloat.c                 | 249 ++++++++++++++++++++++++++++++++
 target/m68k/softfloat.h                 |  29 ++++
 target/m68k/translate.c                 |  26 ++++
 11 files changed, 548 insertions(+), 106 deletions(-)
 rename {fpu => include/fpu}/softfloat-macros.h (98%)
 create mode 100644 target/m68k/softfloat.c
 create mode 100644 target/m68k/softfloat.h

-- 
2.14.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 1/5] target/m68k: TCGv returned by gen_load() must be freed
  2018-03-04 17:32 [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Laurent Vivier
@ 2018-03-04 17:32 ` Laurent Vivier
  2018-03-04 17:32 ` [Qemu-devel] [PULL 2/5] softfloat: export some functions Laurent Vivier
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Laurent Vivier @ 2018-03-04 17:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20180217235920.2254-1-laurent@vivier.eu>
---
 target/m68k/translate.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 93cd38950e..a22993c7ce 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -2871,6 +2871,7 @@ DISAS_INSN(unlk)
     tcg_gen_mov_i32(reg, tmp);
     tcg_gen_addi_i32(QREG_SP, src, 4);
     tcg_temp_free(src);
+    tcg_temp_free(tmp);
 }
 
 #if defined(CONFIG_SOFTMMU)
@@ -3148,6 +3149,9 @@ DISAS_INSN(subx_mem)
     gen_subx(s, src, dest, opsize);
 
     gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
+
+    tcg_temp_free(dest);
+    tcg_temp_free(src);
 }
 
 DISAS_INSN(mov3q)
@@ -3354,6 +3358,9 @@ DISAS_INSN(addx_mem)
     gen_addx(s, src, dest, opsize);
 
     gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
+
+    tcg_temp_free(dest);
+    tcg_temp_free(src);
 }
 
 static inline void shift_im(DisasContext *s, uint16_t insn, int opsize)
@@ -4398,6 +4405,8 @@ DISAS_INSN(chk2)
     gen_flush_flags(s);
     gen_helper_chk2(cpu_env, reg, bound1, bound2);
     tcg_temp_free(reg);
+    tcg_temp_free(bound1);
+    tcg_temp_free(bound2);
 }
 
 static void m68k_copy_line(TCGv dst, TCGv src, int index)
@@ -4547,6 +4556,7 @@ DISAS_INSN(moves)
         } else {
             gen_partset_reg(opsize, reg, tmp);
         }
+        tcg_temp_free(tmp);
     }
     switch (extract32(insn, 3, 3)) {
     case 3: /* Indirect postincrement.  */
@@ -5537,6 +5547,7 @@ DISAS_INSN(mac)
         case 4: /* Pre-decrement.  */
             tcg_gen_mov_i32(AREG(insn, 0), addr);
         }
+        tcg_temp_free(loadval);
     }
 }
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 2/5] softfloat: export some functions
  2018-03-04 17:32 [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Laurent Vivier
  2018-03-04 17:32 ` [Qemu-devel] [PULL 1/5] target/m68k: TCGv returned by gen_load() must be freed Laurent Vivier
@ 2018-03-04 17:32 ` Laurent Vivier
  2018-03-04 17:32 ` [Qemu-devel] [PULL 3/5] target/m68k: add fmod/frem Laurent Vivier
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Laurent Vivier @ 2018-03-04 17:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Laurent Vivier

Move fpu/softfloat-macros.h to include/fpu/

Export floatx80 functions to be used by target floatx80
specific implementations.

Exports:
  propagateFloatx80NaN(), extractFloatx80Frac(),
  extractFloatx80Exp(), extractFloatx80Sign(),
  normalizeFloatx80Subnormal(), packFloatx80(),
  roundAndPackFloatx80(), normalizeRoundAndPackFloatx80()

Also exports packFloat32() that will be used to implement
m68k fsinh, fcos, fsin, ftan operations.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20180224201802.911-2-laurent@vivier.eu>
---
 fpu/softfloat-specialize.h              |   3 +-
 fpu/softfloat.c                         |  91 +++---------------------
 {fpu => include/fpu}/softfloat-macros.h |  10 +--
 include/fpu/softfloat.h                 | 121 ++++++++++++++++++++++++++++++++
 4 files changed, 137 insertions(+), 88 deletions(-)
 rename {fpu => include/fpu}/softfloat-macros.h (98%)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index e81ca001e1..46126e9e0a 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -1011,8 +1011,7 @@ static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status)
 | `b' is a signaling NaN, the invalid exception is raised.
 *----------------------------------------------------------------------------*/
 
-static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,
-                                     float_status *status)
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
 {
     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
     flag aIsLargerSignificand;
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e7fb0d357a..fb4853682e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -93,7 +93,7 @@ this code that are retained.
 | division and square root approximations.  (Can be specialized to target if
 | desired.)
 *----------------------------------------------------------------------------*/
-#include "softfloat-macros.h"
+#include "fpu/softfloat-macros.h"
 
 /*----------------------------------------------------------------------------
 | Functions and definitions to determine:  (1) whether tininess for underflow
@@ -2192,25 +2192,6 @@ static void
 
 }
 
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| single-precision floating-point value, returning the result.  After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result.  This means that any integer portion of `zSig'
-| will be added into the exponent.  Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-static inline float32 packFloat32(flag zSign, int zExp, uint32_t zSig)
-{
-
-    return make_float32(
-          ( ( (uint32_t) zSign )<<31 ) + ( ( (uint32_t) zExp )<<23 ) + zSig);
-
-}
-
 /*----------------------------------------------------------------------------
 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
 | and significand `zSig', and returns the proper single-precision floating-
@@ -2490,42 +2471,6 @@ static float64
 
 }
 
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-static inline uint64_t extractFloatx80Frac( floatx80 a )
-{
-
-    return a.low;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-static inline int32_t extractFloatx80Exp( floatx80 a )
-{
-
-    return a.high & 0x7FFF;
-
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the extended double-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-static inline flag extractFloatx80Sign( floatx80 a )
-{
-
-    return a.high>>15;
-
-}
-
 /*----------------------------------------------------------------------------
 | Normalizes the subnormal extended double-precision floating-point value
 | represented by the denormalized significand `aSig'.  The normalized exponent
@@ -2533,30 +2478,14 @@ static inline flag extractFloatx80Sign( floatx80 a )
 | `zSigPtr', respectively.
 *----------------------------------------------------------------------------*/
 
-static void
- normalizeFloatx80Subnormal( uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr )
+void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
+                                uint64_t *zSigPtr)
 {
     int8_t shiftCount;
 
     shiftCount = countLeadingZeros64( aSig );
     *zSigPtr = aSig<<shiftCount;
     *zExpPtr = 1 - shiftCount;
-
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
-| extended double-precision floating-point value, returning the result.
-*----------------------------------------------------------------------------*/
-
-static inline floatx80 packFloatx80( flag zSign, int32_t zExp, uint64_t zSig )
-{
-    floatx80 z;
-
-    z.low = zSig;
-    z.high = ( ( (uint16_t) zSign )<<15 ) + zExp;
-    return z;
-
 }
 
 /*----------------------------------------------------------------------------
@@ -2583,9 +2512,9 @@ static inline floatx80 packFloatx80( flag zSign, int32_t zExp, uint64_t zSig )
 | Floating-Point Arithmetic.
 *----------------------------------------------------------------------------*/
 
-static floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
-                                     int32_t zExp, uint64_t zSig0, uint64_t zSig1,
-                                     float_status *status)
+floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
+                              int32_t zExp, uint64_t zSig0, uint64_t zSig1,
+                              float_status *status)
 {
     int8_t roundingMode;
     flag roundNearestEven, increment, isTiny;
@@ -2779,10 +2708,10 @@ static floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
 | normalized.
 *----------------------------------------------------------------------------*/
 
-static floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
-                                              flag zSign, int32_t zExp,
-                                              uint64_t zSig0, uint64_t zSig1,
-                                              float_status *status)
+floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
+                                       flag zSign, int32_t zExp,
+                                       uint64_t zSig0, uint64_t zSig1,
+                                       float_status *status)
 {
     int8_t shiftCount;
 
diff --git a/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h
similarity index 98%
rename from fpu/softfloat-macros.h
rename to include/fpu/softfloat-macros.h
index c45a23193e..35e1603a5e 100644
--- a/fpu/softfloat-macros.h
+++ b/include/fpu/softfloat-macros.h
@@ -603,7 +603,7 @@ static inline void
 | unsigned integer is returned.
 *----------------------------------------------------------------------------*/
 
-static uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b )
+static inline uint64_t estimateDiv128To64(uint64_t a0, uint64_t a1, uint64_t b)
 {
     uint64_t b0, b1;
     uint64_t rem0, rem1, term0, term1;
@@ -630,7 +630,7 @@ static uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b )
  *
  * Licensed under the GPLv2/LGPLv3
  */
-static uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d)
+static inline uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d)
 {
     uint64_t d0, d1, q0, q1, r1, r0, m;
 
@@ -683,7 +683,7 @@ static uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d)
 | value.
 *----------------------------------------------------------------------------*/
 
-static uint32_t estimateSqrt32(int aExp, uint32_t a)
+static inline uint32_t estimateSqrt32(int aExp, uint32_t a)
 {
     static const uint16_t sqrtOddAdjustments[] = {
         0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
@@ -717,7 +717,7 @@ static uint32_t estimateSqrt32(int aExp, uint32_t a)
 | `a'.  If `a' is zero, 32 is returned.
 *----------------------------------------------------------------------------*/
 
-static int8_t countLeadingZeros32( uint32_t a )
+static inline int8_t countLeadingZeros32(uint32_t a)
 {
 #if SOFTFLOAT_GNUC_PREREQ(3, 4)
     if (a) {
@@ -765,7 +765,7 @@ static int8_t countLeadingZeros32( uint32_t a )
 | `a'.  If `a' is zero, 64 is returned.
 *----------------------------------------------------------------------------*/
 
-static int8_t countLeadingZeros64( uint64_t a )
+static inline int8_t countLeadingZeros64(uint64_t a)
 {
 #if SOFTFLOAT_GNUC_PREREQ(3, 4)
     if (a) {
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 27876e711c..fa4fae224f 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -425,6 +425,23 @@ static inline float32 float32_set_sign(float32 a, int sign)
 #define float32_three make_float32(0x40400000)
 #define float32_infinity make_float32(0x7f800000)
 
+/*----------------------------------------------------------------------------
+| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+| single-precision floating-point value, returning the result.  After being
+| shifted into the proper positions, the three fields are simply added
+| together to form the result.  This means that any integer portion of `zSig'
+| will be added into the exponent.  Since a properly normalized significand
+| will have an integer portion equal to 1, the `zExp' input should be 1 less
+| than the desired result exponent whenever `zSig' is a complete, normalized
+| significand.
+*----------------------------------------------------------------------------*/
+
+static inline float32 packFloat32(flag zSign, int zExp, uint32_t zSig)
+{
+    return make_float32(
+          (((uint32_t)zSign) << 31) + (((uint32_t)zExp) << 23) + zSig);
+}
+
 /*----------------------------------------------------------------------------
 | The pattern for a default generated single-precision NaN.
 *----------------------------------------------------------------------------*/
@@ -640,6 +657,110 @@ static inline bool floatx80_invalid_encoding(floatx80 a)
 #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
 #define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
 
+/*----------------------------------------------------------------------------
+| Returns the fraction bits of the extended double-precision floating-point
+| value `a'.
+*----------------------------------------------------------------------------*/
+
+static inline uint64_t extractFloatx80Frac(floatx80 a)
+{
+    return a.low;
+}
+
+/*----------------------------------------------------------------------------
+| Returns the exponent bits of the extended double-precision floating-point
+| value `a'.
+*----------------------------------------------------------------------------*/
+
+static inline int32_t extractFloatx80Exp(floatx80 a)
+{
+    return a.high & 0x7FFF;
+}
+
+/*----------------------------------------------------------------------------
+| Returns the sign bit of the extended double-precision floating-point value
+| `a'.
+*----------------------------------------------------------------------------*/
+
+static inline flag extractFloatx80Sign(floatx80 a)
+{
+    return a.high >> 15;
+}
+
+/*----------------------------------------------------------------------------
+| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
+| extended double-precision floating-point value, returning the result.
+*----------------------------------------------------------------------------*/
+
+static inline floatx80 packFloatx80(flag zSign, int32_t zExp, uint64_t zSig)
+{
+    floatx80 z;
+
+    z.low = zSig;
+    z.high = (((uint16_t)zSign) << 15) + zExp;
+    return z;
+}
+
+/*----------------------------------------------------------------------------
+| Normalizes the subnormal extended double-precision floating-point value
+| represented by the denormalized significand `aSig'.  The normalized exponent
+| and significand are stored at the locations pointed to by `zExpPtr' and
+| `zSigPtr', respectively.
+*----------------------------------------------------------------------------*/
+
+void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
+                                uint64_t *zSigPtr);
+
+/*----------------------------------------------------------------------------
+| Takes two extended double-precision floating-point values `a' and `b', one
+| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
+| `b' is a signaling NaN, the invalid exception is raised.
+*----------------------------------------------------------------------------*/
+
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status);
+
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+| and extended significand formed by the concatenation of `zSig0' and `zSig1',
+| and returns the proper extended double-precision floating-point value
+| corresponding to the abstract input.  Ordinarily, the abstract value is
+| rounded and packed into the extended double-precision format, with the
+| inexact exception raised if the abstract input cannot be represented
+| exactly.  However, if the abstract value is too large, the overflow and
+| inexact exceptions are raised and an infinity or maximal finite value is
+| returned.  If the abstract value is too small, the input value is rounded to
+| a subnormal number, and the underflow and inexact exceptions are raised if
+| the abstract input cannot be represented exactly as a subnormal extended
+| double-precision floating-point number.
+|     If `roundingPrecision' is 32 or 64, the result is rounded to the same
+| number of bits as single or double precision, respectively.  Otherwise, the
+| result is rounded to the full precision of the extended double-precision
+| format.
+|     The input significand must be normalized or smaller.  If the input
+| significand is not normalized, `zExp' must be 0; in that case, the result
+| returned is a subnormal number, and it must not require rounding.  The
+| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
+                              int32_t zExp, uint64_t zSig0, uint64_t zSig1,
+                              float_status *status);
+
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent
+| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
+| and returns the proper extended double-precision floating-point value
+| corresponding to the abstract input.  This routine is just like
+| `roundAndPackFloatx80' except that the input significand does not have to be
+| normalized.
+*----------------------------------------------------------------------------*/
+
+floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
+                                       flag zSign, int32_t zExp,
+                                       uint64_t zSig0, uint64_t zSig1,
+                                       float_status *status);
+
 /*----------------------------------------------------------------------------
 | The pattern for a default generated extended double-precision NaN.
 *----------------------------------------------------------------------------*/
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 3/5] target/m68k: add fmod/frem
  2018-03-04 17:32 [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Laurent Vivier
  2018-03-04 17:32 ` [Qemu-devel] [PULL 1/5] target/m68k: TCGv returned by gen_load() must be freed Laurent Vivier
  2018-03-04 17:32 ` [Qemu-devel] [PULL 2/5] softfloat: export some functions Laurent Vivier
@ 2018-03-04 17:32 ` Laurent Vivier
  2018-05-08 10:27   ` Peter Maydell
  2018-03-04 17:32 ` [Qemu-devel] [PULL 4/5] softfloat: use floatx80_infinity in softfloat Laurent Vivier
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Laurent Vivier @ 2018-03-04 17:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, 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 <laurent@vivier.eu>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20180224201802.911-3-laurent@vivier.eu>
---
 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  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 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 0000000000..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 = extractFloatx80Exp(a);
+    aSign = extractFloatx80Sign(a);
+    bSig = extractFloatx80Frac(b);
+    bExp = extractFloatx80Exp(b);
+
+    if (aExp == 0x7FFF) {
+        if ((uint64_t) (aSig0 << 1)
+            || ((bExp == 0x7FFF) && (uint64_t) (bSig << 1))) {
+            return propagateFloatx80NaN(a, b, status);
+        }
+        goto invalid;
+    }
+    if (bExp == 0x7FFF) {
+        if ((uint64_t) (bSig << 1)) {
+            return propagateFloatx80NaN(a, b, status);
+        }
+        return a;
+    }
+    if (bExp == 0) {
+        if (bSig == 0) {
+        invalid:
+            float_raise(float_flag_invalid, status);
+            return floatx80_default_nan(status);
+        }
+        normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+    }
+    if (aExp == 0) {
+        if ((uint64_t) (aSig0 << 1) == 0) {
+            return a;
+        }
+        normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+    }
+    bSig |= LIT64(0x8000000000000000);
+    zSign = aSign;
+    expDiff = aExp - bExp;
+    aSig1 = 0;
+    if (expDiff < 0) {
+        return a;
+    }
+    qTemp = (bSig <= aSig0);
+    if (qTemp) {
+        aSig0 -= bSig;
+    }
+    expDiff -= 64;
+    while (0 < expDiff) {
+        qTemp = estimateDiv128To64(aSig0, aSig1, bSig);
+        qTemp = (2 < qTemp) ? qTemp - 2 : 0;
+        mul64To128(bSig, qTemp, &term0, &term1);
+        sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
+        shortShift128Left(aSig0, aSig1, 62, &aSig0, &aSig1);
+    }
+    expDiff += 64;
+    if (0 < expDiff) {
+        qTemp = estimateDiv128To64(aSig0, aSig1, bSig);
+        qTemp = (2 < qTemp) ? qTemp - 2 : 0;
+        qTemp >>= 64 - expDiff;
+        mul64To128(bSig, qTemp << (64 - expDiff), &term0, &term1);
+        sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
+        shortShift128Left(0, bSig, 64 - expDiff, &term0, &term1);
+        while (le128(term0, term1, aSig0, aSig1)) {
+            ++qTemp;
+            sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
+        }
+    }
+    return
+        normalizeRoundAndPackFloatx80(
+            80, zSign, bExp + expDiff, aSig0, aSig1, status);
+}
diff --git a/target/m68k/softfloat.h b/target/m68k/softfloat.h
new file mode 100644
index 0000000000..8d8ca0fc45
--- /dev/null
+++ b/target/m68k/softfloat.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef TARGET_M68K_SOFTFLOAT_H
+#define TARGET_M68K_SOFTFLOAT_H
+#include "fpu/softfloat.h"
+
+floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status);
+#endif
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index a22993c7ce..f8db26fa8e 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -5081,6 +5081,9 @@ DISAS_INSN(fpu)
     case 0x64: /* fddiv */
         gen_helper_fddiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
+    case 0x21: /* fmod */
+        gen_helper_fmod(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
     case 0x22: /* fadd */
         gen_helper_fadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
@@ -5102,6 +5105,9 @@ DISAS_INSN(fpu)
     case 0x24: /* fsgldiv */
         gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
+    case 0x25: /* frem */
+        gen_helper_frem(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
     case 0x27: /* fsglmul */
         gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 4/5] softfloat: use floatx80_infinity in softfloat
  2018-03-04 17:32 [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Laurent Vivier
                   ` (2 preceding siblings ...)
  2018-03-04 17:32 ` [Qemu-devel] [PULL 3/5] target/m68k: add fmod/frem Laurent Vivier
@ 2018-03-04 17:32 ` Laurent Vivier
  2018-03-04 17:32 ` [Qemu-devel] [PULL 5/5] target/m68k: add fscale, fgetman and fgetexp Laurent Vivier
  2018-03-05 14:27 ` [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Peter Maydell
  5 siblings, 0 replies; 8+ messages in thread
From: Laurent Vivier @ 2018-03-04 17:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Laurent Vivier

Since f3218a8 ("softfloat: add floatx80 constants")
floatx80_infinity is defined but never used.

This patch updates floatx80 functions to use
this definition.

This allows to define a different default Infinity
value on m68k: the m68k FPU defines infinity with
all bits set to zero in the mantissa.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20180224201802.911-4-laurent@vivier.eu>
---
 fpu/softfloat-specialize.h | 14 ++++++++++++++
 fpu/softfloat.c            | 39 +++++++++++++++++++++++++--------------
 include/fpu/softfloat.h    | 13 +++++++++++--
 3 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 46126e9e0a..9ccb59422c 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -177,6 +177,20 @@ floatx80 floatx80_default_nan(float_status *status)
     return r;
 }
 
+/*----------------------------------------------------------------------------
+| The pattern for a default generated extended double-precision inf.
+*----------------------------------------------------------------------------*/
+
+#define floatx80_infinity_high 0x7FFF
+#if defined(TARGET_M68K)
+#define floatx80_infinity_low  LIT64(0x0000000000000000)
+#else
+#define floatx80_infinity_low  LIT64(0x8000000000000000)
+#endif
+
+const floatx80 floatx80_infinity
+    = make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low);
+
 /*----------------------------------------------------------------------------
 | The pattern for a default generated quadruple-precision NaN.
 *----------------------------------------------------------------------------*/
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index fb4853682e..e124df9f7e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2636,7 +2636,9 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
                ) {
                 return packFloatx80( zSign, 0x7FFE, ~ roundMask );
             }
-            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+            return packFloatx80(zSign,
+                                floatx80_infinity_high,
+                                floatx80_infinity_low);
         }
         if ( zExp <= 0 ) {
             isTiny =
@@ -3182,7 +3184,9 @@ floatx80 float32_to_floatx80(float32 a, float_status *status)
         if (aSig) {
             return commonNaNToFloatx80(float32ToCommonNaN(a, status), status);
         }
-        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        return packFloatx80(aSign,
+                            floatx80_infinity_high,
+                            floatx80_infinity_low);
     }
     if ( aExp == 0 ) {
         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
@@ -4037,7 +4041,9 @@ floatx80 float64_to_floatx80(float64 a, float_status *status)
         if (aSig) {
             return commonNaNToFloatx80(float64ToCommonNaN(a, status), status);
         }
-        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        return packFloatx80(aSign,
+                            floatx80_infinity_high,
+                            floatx80_infinity_low);
     }
     if ( aExp == 0 ) {
         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
@@ -4549,10 +4555,7 @@ int64_t floatx80_to_int64(floatx80 a, float_status *status)
     if ( shiftCount <= 0 ) {
         if ( shiftCount ) {
             float_raise(float_flag_invalid, status);
-            if (    ! aSign
-                 || (    ( aExp == 0x7FFF )
-                      && ( aSig != LIT64( 0x8000000000000000 ) ) )
-               ) {
+            if (!aSign || floatx80_is_any_nan(a)) {
                 return LIT64( 0x7FFFFFFFFFFFFFFF );
             }
             return (int64_t) LIT64( 0x8000000000000000 );
@@ -4858,7 +4861,9 @@ static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
             if ((uint64_t)(bSig << 1)) {
                 return propagateFloatx80NaN(a, b, status);
             }
-            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+            return packFloatx80(zSign,
+                                floatx80_infinity_high,
+                                floatx80_infinity_low);
         }
         if ( aExp == 0 ) ++expDiff;
         shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
@@ -4933,7 +4938,8 @@ static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, flag zSign,
         if ((uint64_t)(bSig << 1)) {
             return propagateFloatx80NaN(a, b, status);
         }
-        return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        return packFloatx80(zSign ^ 1, floatx80_infinity_high,
+                            floatx80_infinity_low);
     }
     if ( aExp == 0 ) ++expDiff;
     shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
@@ -5038,7 +5044,8 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
             return propagateFloatx80NaN(a, b, status);
         }
         if ( ( bExp | bSig ) == 0 ) goto invalid;
-        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        return packFloatx80(zSign, floatx80_infinity_high,
+                                   floatx80_infinity_low);
     }
     if ( bExp == 0x7FFF ) {
         if ((uint64_t)(bSig << 1)) {
@@ -5049,7 +5056,8 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
             float_raise(float_flag_invalid, status);
             return floatx80_default_nan(status);
         }
-        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        return packFloatx80(zSign, floatx80_infinity_high,
+                                   floatx80_infinity_low);
     }
     if ( aExp == 0 ) {
         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
@@ -5103,7 +5111,8 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
             }
             goto invalid;
         }
-        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        return packFloatx80(zSign, floatx80_infinity_high,
+                                   floatx80_infinity_low);
     }
     if ( bExp == 0x7FFF ) {
         if ((uint64_t)(bSig << 1)) {
@@ -5119,7 +5128,8 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
                 return floatx80_default_nan(status);
             }
             float_raise(float_flag_divbyzero, status);
-            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+            return packFloatx80(zSign, floatx80_infinity_high,
+                                       floatx80_infinity_low);
         }
         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
     }
@@ -5942,7 +5952,8 @@ floatx80 float128_to_floatx80(float128 a, float_status *status)
         if ( aSig0 | aSig1 ) {
             return commonNaNToFloatx80(float128ToCommonNaN(a, status), status);
         }
-        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        return packFloatx80(aSign, floatx80_infinity_high,
+                                   floatx80_infinity_low);
     }
     if ( aExp == 0 ) {
         if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index fa4fae224f..36626a501b 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -572,6 +572,11 @@ float32 floatx80_to_float32(floatx80, float_status *status);
 float64 floatx80_to_float64(floatx80, float_status *status);
 float128 floatx80_to_float128(floatx80, float_status *status);
 
+/*----------------------------------------------------------------------------
+| The pattern for an extended double-precision inf.
+*----------------------------------------------------------------------------*/
+extern const floatx80 floatx80_infinity;
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision operations.
 *----------------------------------------------------------------------------*/
@@ -612,7 +617,12 @@ static inline floatx80 floatx80_chs(floatx80 a)
 
 static inline int floatx80_is_infinity(floatx80 a)
 {
-    return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL;
+#if defined(TARGET_M68K)
+    return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1);
+#else
+    return (a.high & 0x7fff) == floatx80_infinity.high &&
+                       a.low == floatx80_infinity.low;
+#endif
 }
 
 static inline int floatx80_is_neg(floatx80 a)
@@ -655,7 +665,6 @@ static inline bool floatx80_invalid_encoding(floatx80 a)
 #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
 #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
 #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
-#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
 
 /*----------------------------------------------------------------------------
 | Returns the fraction bits of the extended double-precision floating-point
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PULL 5/5] target/m68k: add fscale, fgetman and fgetexp
  2018-03-04 17:32 [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Laurent Vivier
                   ` (3 preceding siblings ...)
  2018-03-04 17:32 ` [Qemu-devel] [PULL 4/5] softfloat: use floatx80_infinity in softfloat Laurent Vivier
@ 2018-03-04 17:32 ` Laurent Vivier
  2018-03-05 14:27 ` [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Peter Maydell
  5 siblings, 0 replies; 8+ messages in thread
From: Laurent Vivier @ 2018-03-04 17:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Laurent Vivier

Using local m68k floatx80_getman(), floatx80_getexp(), floatx80_scale()
[copied from previous:
Written by Andreas Grabher for Previous, NeXT Computer Emulator.]

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20180224201802.911-5-laurent@vivier.eu>
---
 target/m68k/fpu_helper.c |  15 +++++
 target/m68k/helper.h     |   3 +
 target/m68k/softfloat.c  | 144 +++++++++++++++++++++++++++++++++++++++++++++++
 target/m68k/softfloat.h  |   3 +
 target/m68k/translate.c  |   9 +++
 5 files changed, 174 insertions(+)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 8286228b81..cdb9b50462 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -542,3 +542,18 @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 
     make_quotient(env, res->d);
 }
+
+void HELPER(fgetexp)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    res->d = floatx80_getexp(val->d, &env->fp_status);
+}
+
+void HELPER(fgetman)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    res->d = floatx80_getman(val->d, &env->fp_status);
+}
+
+void HELPER(fscale)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    res->d = floatx80_scale(val1->d, val0->d, &env->fp_status);
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 76a0590c9c..c348dced3a 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -65,6 +65,9 @@ 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(fgetexp, void, env, fp, fp)
+DEF_HELPER_3(fgetman, void, env, fp, fp)
+DEF_HELPER_4(fscale, 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
index 8c77757b4e..9cb141900c 100644
--- a/target/m68k/softfloat.c
+++ b/target/m68k/softfloat.c
@@ -22,6 +22,19 @@
 #include "softfloat.h"
 #include "fpu/softfloat-macros.h"
 
+static floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *status)
+{
+    if (floatx80_is_signaling_nan(a, status)) {
+        float_raise(float_flag_invalid, status);
+    }
+
+    if (status->default_nan_mode) {
+        return floatx80_default_nan(status);
+    }
+
+    return floatx80_maybe_silence_nan(a, status);
+}
+
 /*----------------------------------------------------------------------------
  | Returns the modulo remainder of the extended double-precision floating-point
  | value `a' with respect to the corresponding value `b'.
@@ -103,3 +116,134 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
         normalizeRoundAndPackFloatx80(
             80, zSign, bExp + expDiff, aSig0, aSig1, status);
 }
+
+/*----------------------------------------------------------------------------
+ | Returns the mantissa of the extended double-precision floating-point
+ | value `a'.
+ *----------------------------------------------------------------------------*/
+
+floatx80 floatx80_getman(floatx80 a, float_status *status)
+{
+    flag aSign;
+    int32_t aExp;
+    uint64_t aSig;
+
+    aSig = extractFloatx80Frac(a);
+    aExp = extractFloatx80Exp(a);
+    aSign = extractFloatx80Sign(a);
+
+    if (aExp == 0x7FFF) {
+        if ((uint64_t) (aSig << 1)) {
+            return propagateFloatx80NaNOneArg(a , status);
+        }
+        float_raise(float_flag_invalid , status);
+        return floatx80_default_nan(status);
+    }
+
+    if (aExp == 0) {
+        if (aSig == 0) {
+            return packFloatx80(aSign, 0, 0);
+        }
+        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+    }
+
+    return roundAndPackFloatx80(status->floatx80_rounding_precision, aSign,
+                                0x3FFF, aSig, 0, status);
+}
+
+/*----------------------------------------------------------------------------
+ | Returns the exponent of the extended double-precision floating-point
+ | value `a' as an extended double-precision value.
+ *----------------------------------------------------------------------------*/
+
+floatx80 floatx80_getexp(floatx80 a, float_status *status)
+{
+    flag aSign;
+    int32_t aExp;
+    uint64_t aSig;
+
+    aSig = extractFloatx80Frac(a);
+    aExp = extractFloatx80Exp(a);
+    aSign = extractFloatx80Sign(a);
+
+    if (aExp == 0x7FFF) {
+        if ((uint64_t) (aSig << 1)) {
+            return propagateFloatx80NaNOneArg(a , status);
+        }
+        float_raise(float_flag_invalid , status);
+        return floatx80_default_nan(status);
+    }
+
+    if (aExp == 0) {
+        if (aSig == 0) {
+            return packFloatx80(aSign, 0, 0);
+        }
+        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+    }
+
+    return int32_to_floatx80(aExp - 0x3FFF, status);
+}
+
+/*----------------------------------------------------------------------------
+ | Scales extended double-precision floating-point value in operand `a' by
+ | value `b'. The function truncates the value in the second operand 'b' to
+ | an integral value and adds that value to the exponent of the operand 'a'.
+ | The operation performed according to the IEC/IEEE Standard for Binary
+ | Floating-Point Arithmetic.
+ *----------------------------------------------------------------------------*/
+
+floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status)
+{
+    flag aSign, bSign;
+    int32_t aExp, bExp, shiftCount;
+    uint64_t aSig, bSig;
+
+    aSig = extractFloatx80Frac(a);
+    aExp = extractFloatx80Exp(a);
+    aSign = extractFloatx80Sign(a);
+    bSig = extractFloatx80Frac(b);
+    bExp = extractFloatx80Exp(b);
+    bSign = extractFloatx80Sign(b);
+
+    if (bExp == 0x7FFF) {
+        if ((uint64_t) (bSig << 1) ||
+            ((aExp == 0x7FFF) && (uint64_t) (aSig << 1))) {
+            return propagateFloatx80NaN(a, b, status);
+        }
+        float_raise(float_flag_invalid , status);
+        return floatx80_default_nan(status);
+    }
+    if (aExp == 0x7FFF) {
+        if ((uint64_t) (aSig << 1)) {
+            return propagateFloatx80NaN(a, b, status);
+        }
+        return packFloatx80(aSign, floatx80_infinity.high,
+                            floatx80_infinity.low);
+    }
+    if (aExp == 0) {
+        if (aSig == 0) {
+            return packFloatx80(aSign, 0, 0);
+        }
+        if (bExp < 0x3FFF) {
+            return a;
+        }
+        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+    }
+
+    if (bExp < 0x3FFF) {
+        return a;
+    }
+
+    if (0x400F < bExp) {
+        aExp = bSign ? -0x6001 : 0xE000;
+        return roundAndPackFloatx80(status->floatx80_rounding_precision,
+                                    aSign, aExp, aSig, 0, status);
+    }
+
+    shiftCount = 0x403E - bExp;
+    bSig >>= shiftCount;
+    aExp = bSign ? (aExp - bSig) : (aExp + bSig);
+
+    return roundAndPackFloatx80(status->floatx80_rounding_precision,
+                                aSign, aExp, aSig, 0, status);
+}
diff --git a/target/m68k/softfloat.h b/target/m68k/softfloat.h
index 8d8ca0fc45..78fbc0cd0c 100644
--- a/target/m68k/softfloat.h
+++ b/target/m68k/softfloat.h
@@ -23,4 +23,7 @@
 #include "fpu/softfloat.h"
 
 floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status);
+floatx80 floatx80_getman(floatx80 a, float_status *status);
+floatx80 floatx80_getexp(floatx80 a, float_status *status);
+floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status);
 #endif
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index f8db26fa8e..dbb24f8d84 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -5072,6 +5072,12 @@ DISAS_INSN(fpu)
     case 0x5e: /* fdneg */
         gen_helper_fdneg(cpu_env, cpu_dest, cpu_src);
         break;
+    case 0x1e: /* fgetexp */
+        gen_helper_fgetexp(cpu_env, cpu_dest, cpu_src);
+        break;
+    case 0x1f: /* fgetman */
+        gen_helper_fgetman(cpu_env, cpu_dest, cpu_src);
+        break;
     case 0x20: /* fdiv */
         gen_helper_fdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
@@ -5108,6 +5114,9 @@ DISAS_INSN(fpu)
     case 0x25: /* frem */
         gen_helper_frem(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
+    case 0x26: /* fscale */
+        gen_helper_fscale(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
     case 0x27: /* fsglmul */
         gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PULL 0/5] M68k for 2.12 patches
  2018-03-04 17:32 [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Laurent Vivier
                   ` (4 preceding siblings ...)
  2018-03-04 17:32 ` [Qemu-devel] [PULL 5/5] target/m68k: add fscale, fgetman and fgetexp Laurent Vivier
@ 2018-03-05 14:27 ` Peter Maydell
  5 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2018-03-05 14:27 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: QEMU Developers, Aurelien Jarno

On 4 March 2018 at 17:32, Laurent Vivier <laurent@vivier.eu> wrote:
> The following changes since commit 136c67e07869227b21b3f627316e03679ce7b738:
>
>   Merge remote-tracking branch 'remotes/bkoppelmann/tags/pull-tricore-2018-03-02' into staging (2018-03-02 16:56:20 +0000)
>
> are available in the Git repository at:
>
>   git://github.com/vivier/qemu-m68k.git tags/m68k-for-2.12-pull-request
>
> for you to fetch changes up to 0d379c1709aa6b2d09dd3b493bfdf3a5fe6debcd:
>
>   target/m68k: add fscale, fgetman and fgetexp (2018-03-04 17:27:59 +0100)
>
> ----------------------------------------------------------------
>
> ----------------------------------------------------------------
>
> Laurent Vivier (5):
>   target/m68k: TCGv returned by gen_load() must be freed
>   softfloat: export some functions
>   target/m68k: add fmod/frem
>   softfloat: use floatx80_infinity in softfloat
>   target/m68k: add fscale, fgetman and fgetexp
>

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PULL 3/5] target/m68k: add fmod/frem
  2018-03-04 17:32 ` [Qemu-devel] [PULL 3/5] target/m68k: add fmod/frem Laurent Vivier
@ 2018-05-08 10:27   ` Peter Maydell
  0 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2018-05-08 10:27 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: QEMU Developers, Aurelien Jarno

On 4 March 2018 at 17:32, Laurent Vivier <laurent@vivier.eu> 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 <laurent@vivier.eu>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Message-Id: <20180224201802.911-3-laurent@vivier.eu>

Hi; Coverity points out that there's a bug in the
floatx80_mod() function this patch introduces (CID 1390568):

> +    expDiff -= 64;
> +    while (0 < expDiff) {
> +        qTemp = estimateDiv128To64(aSig0, aSig1, bSig);
> +        qTemp = (2 < qTemp) ? qTemp - 2 : 0;
> +        mul64To128(bSig, qTemp, &term0, &term1);
> +        sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
> +        shortShift128Left(aSig0, aSig1, 62, &aSig0, &aSig1);
> +    }

This loop condition checks expDiff, but the loop body
never changes that variable, so if we go round the loop
at all then we'll do so forever.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-05-08 10:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-04 17:32 [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Laurent Vivier
2018-03-04 17:32 ` [Qemu-devel] [PULL 1/5] target/m68k: TCGv returned by gen_load() must be freed Laurent Vivier
2018-03-04 17:32 ` [Qemu-devel] [PULL 2/5] softfloat: export some functions Laurent Vivier
2018-03-04 17:32 ` [Qemu-devel] [PULL 3/5] target/m68k: add fmod/frem Laurent Vivier
2018-05-08 10:27   ` Peter Maydell
2018-03-04 17:32 ` [Qemu-devel] [PULL 4/5] softfloat: use floatx80_infinity in softfloat Laurent Vivier
2018-03-04 17:32 ` [Qemu-devel] [PULL 5/5] target/m68k: add fscale, fgetman and fgetexp Laurent Vivier
2018-03-05 14:27 ` [Qemu-devel] [PULL 0/5] M68k for 2.12 patches Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).