All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Vivier <laurent@vivier.eu>
To: qemu-devel@nongnu.org
Cc: Thomas Huth <huth@tuxfamily.org>,
	Aurelien Jarno <aurelien@aurel32.net>,
	Richard Henderson <rth@twiddle.net>,
	Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PATCH v2 4/5] softfloat: add floatx80_getman(), floatx80_getexp(), floatx80_scale()
Date: Thu, 23 Nov 2017 17:35:37 +0100	[thread overview]
Message-ID: <20171123163538.31411-5-laurent@vivier.eu> (raw)
In-Reply-To: <20171123163538.31411-1-laurent@vivier.eu>

copied from previous:
Written by Andreas Grabher for Previous, NeXT Computer Emulator.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 fpu/softfloat-specialize.h |  15 ++++++
 fpu/softfloat.c            | 132 +++++++++++++++++++++++++++++++++++++++++++++
 include/fpu/softfloat.h    |   3 ++
 3 files changed, 150 insertions(+)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 1cb3502e5a..4706a0ec3a 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -1163,6 +1163,21 @@ static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,
     }
 }
 
+#if defined(TARGET_M68K)
+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);
+}
+#endif
+
 #ifdef NO_SIGNALING_NANS
 int float128_is_quiet_nan(float128 a_, float_status *status)
 {
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index c6289bba75..a17e849fe7 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5800,6 +5800,138 @@ 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);
+
+}
 #endif /* TARGET_M68K */
 
 /*----------------------------------------------------------------------------
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 413cdb20cb..84ddcb12a1 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -630,6 +630,9 @@ floatx80 floatx80_div(floatx80, floatx80, float_status *status);
 floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
 floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status);
 floatx80 floatx80_sqrt(floatx80, 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);
 int floatx80_eq(floatx80, floatx80, float_status *status);
 int floatx80_le(floatx80, floatx80, float_status *status);
 int floatx80_lt(floatx80, floatx80, float_status *status);
-- 
2.13.6

  parent reply	other threads:[~2017-11-23 16:36 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-23 16:35 [Qemu-devel] [PATCH v2 0/5] target/m68k: implement 680x0 FPU (part 3) Laurent Vivier
2017-11-23 16:35 ` [Qemu-devel] [PATCH v2 1/5] softfloat: add floatx80_mod() Laurent Vivier
2017-11-23 16:35 ` [Qemu-devel] [PATCH v2 2/5] target/m68k: add fmod/frem Laurent Vivier
2017-11-23 16:35 ` [Qemu-devel] [PATCH v2 3/5] softfloat: use floatx80_infinity in softfloat Laurent Vivier
2017-11-23 16:35 ` Laurent Vivier [this message]
2017-11-23 16:35 ` [Qemu-devel] [PATCH v2 5/5] target-m68k: add fscale, fgetman and fgetexp Laurent Vivier
2017-11-29 12:49 ` [Qemu-devel] [PATCH v2 0/5] target/m68k: implement 680x0 FPU (part 3) Peter Maydell
2017-11-29 13:42   ` Laurent Vivier
2017-11-29 13:59     ` Peter Maydell
2017-11-29 14:08       ` Thomas Huth
2017-11-29 14:17         ` Laurent Vivier
2017-11-29 15:19           ` Thomas Huth
2017-12-05  8:56             ` william lin
2017-12-05  9:46               ` Laurent Vivier
2017-12-05 17:42                 ` Andreas Grabher
2017-12-05 20:01                   ` Laurent Vivier
2017-12-05 21:24                     ` william lin
2017-12-06  8:20                       ` Laurent Vivier
2017-12-06 10:24 ` Alex Bennée
2017-12-15  8:29   ` william lin
2017-12-20 18:25 ` Laurent Vivier
2017-12-29  8:21   ` Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171123163538.31411-5-laurent@vivier.eu \
    --to=laurent@vivier.eu \
    --cc=aurelien@aurel32.net \
    --cc=huth@tuxfamily.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.