[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 15/31] softfloat: merge floatx80_mod and floatx80_rem
From: |
Paolo Bonzini |
Subject: |
[PULL 15/31] softfloat: merge floatx80_mod and floatx80_rem |
Date: |
Wed, 24 Jun 2020 06:50:32 -0400 |
From: Joseph Myers <joseph@codesourcery.com>
The m68k-specific softfloat code includes a function floatx80_mod that
is extremely similar to floatx80_rem, but computing the remainder
based on truncating the quotient toward zero rather than rounding it
to nearest integer. This is also useful for emulating the x87 fprem
and fprem1 instructions. Change the floatx80_rem implementation into
floatx80_modrem that can perform either operation, with both
floatx80_rem and floatx80_mod as thin wrappers available for all
targets.
There does not appear to be any use for the _mod operation for other
floating-point formats in QEMU (the only other architectures using
_rem at all are linux-user/arm/nwfpe, for FPA emulation, and openrisc,
for instructions that have been removed in the latest version of the
architecture), so no change is made to the code for other formats.
Signed-off-by: Joseph Myers <joseph@codesourcery.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <alpine.DEB.2.21.2006081654280.23637@digraph.polyomino.org.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
fpu/softfloat.c | 49 ++++++++++++++++++------
include/fpu/softfloat.h | 2 +
target/m68k/softfloat.c | 83 -----------------------------------------
target/m68k/softfloat.h | 1 -
4 files changed, 40 insertions(+), 95 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 5e9746c287..b7dcf4d6c3 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5697,10 +5697,13 @@ floatx80 floatx80_div(floatx80 a, floatx80 b,
float_status *status)
/*----------------------------------------------------------------------------
| Returns the remainder of the extended double-precision floating-point value
| `a' with respect to the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic,
+| if 'mod' is false; if 'mod' is true, return the remainder based on truncating
+| the quotient toward zero instead.
*----------------------------------------------------------------------------*/
-floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
+floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
+ float_status *status)
{
bool aSign, zSign;
int32_t aExp, bExp, expDiff;
@@ -5746,7 +5749,7 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b,
float_status *status)
expDiff = aExp - bExp;
aSig1 = 0;
if ( expDiff < 0 ) {
- if ( expDiff < -1 ) return a;
+ if ( mod || expDiff < -1 ) return a;
shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
expDiff = 0;
}
@@ -5778,14 +5781,16 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b,
float_status *status)
term1 = 0;
term0 = bSig;
}
- sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
- if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
- || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
- && ( q & 1 ) )
- ) {
- aSig0 = alternateASig0;
- aSig1 = alternateASig1;
- zSign = ! zSign;
+ if (!mod) {
+ sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
+ if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
+ || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
+ && ( q & 1 ) )
+ ) {
+ aSig0 = alternateASig0;
+ aSig1 = alternateASig1;
+ zSign = ! zSign;
+ }
}
return
normalizeRoundAndPackFloatx80(
@@ -5793,6 +5798,28 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b,
float_status *status)
}
+/*----------------------------------------------------------------------------
+| Returns the remainder of the extended double-precision floating-point value
+| `a' with respect to the corresponding value `b'. The operation is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
+{
+ return floatx80_modrem(a, b, false, status);
+}
+
+/*----------------------------------------------------------------------------
+| Returns the remainder of the extended double-precision floating-point value
+| `a' with respect to the corresponding value `b', with the quotient truncated
+| toward zero.
+*----------------------------------------------------------------------------*/
+
+floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
+{
+ return floatx80_modrem(a, b, true, status);
+}
+
/*----------------------------------------------------------------------------
| Returns the square root of the extended double-precision floating-point
| value `a'. The operation is performed according to the IEC/IEEE Standard
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 16ca697a73..bff6934d09 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -687,6 +687,8 @@ floatx80 floatx80_add(floatx80, floatx80, float_status
*status);
floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
floatx80 floatx80_div(floatx80, floatx80, float_status *status);
+floatx80 floatx80_modrem(floatx80, floatx80, bool, float_status *status);
+floatx80 floatx80_mod(floatx80, floatx80, float_status *status);
floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
floatx80 floatx80_sqrt(floatx80, float_status *status);
FloatRelation floatx80_compare(floatx80, floatx80, float_status *status);
diff --git a/target/m68k/softfloat.c b/target/m68k/softfloat.c
index 9f120cf15e..b6d0ed7acf 100644
--- a/target/m68k/softfloat.c
+++ b/target/m68k/softfloat.c
@@ -42,89 +42,6 @@ static floatx80 propagateFloatx80NaNOneArg(floatx80 a,
float_status *status)
return a;
}
-/*
- * 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)
-{
- bool 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 |= UINT64_C(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 -= 62;
- }
- 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);
-}
-
/*
* Returns the mantissa of the extended double-precision floating-point
* value `a'.
diff --git a/target/m68k/softfloat.h b/target/m68k/softfloat.h
index 365ef6ac7a..4bb9567134 100644
--- a/target/m68k/softfloat.h
+++ b/target/m68k/softfloat.h
@@ -23,7 +23,6 @@
#define TARGET_M68K_SOFTFLOAT_H
#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);
--
2.26.2
- [PULL 02/31] util/getauxval: Porting to FreeBSD getauxval feature, (continued)
- [PULL 02/31] util/getauxval: Porting to FreeBSD getauxval feature, Paolo Bonzini, 2020/06/24
- [PULL 03/31] libqos: usb-hcd-ehci: use 32-bit write for config register, Paolo Bonzini, 2020/06/24
- [PULL 04/31] libqos: pci-pc: use 32-bit write for EJ register, Paolo Bonzini, 2020/06/24
- [PULL 05/31] memory: Revert "memory: accept mismatching sizes in memory_region_access_valid", Paolo Bonzini, 2020/06/24
- [PULL 06/31] replay: notify the main loop when there are no instructions, Paolo Bonzini, 2020/06/24
- [PULL 09/31] exec: fetch the alignment of Linux devdax pmem character device nodes, Paolo Bonzini, 2020/06/24
- [PULL 13/31] xen: Actually fix build without passthrough, Paolo Bonzini, 2020/06/24
- [PULL 08/31] configure: add libdaxctl support, Paolo Bonzini, 2020/06/24
- [PULL 10/31] docs/nvdimm: add description of alignment requirement of device dax, Paolo Bonzini, 2020/06/24
- [PULL 11/31] hw/scsi/megasas: Fix possible out-of-bounds array access in tracepoints, Paolo Bonzini, 2020/06/24
- [PULL 15/31] softfloat: merge floatx80_mod and floatx80_rem,
Paolo Bonzini <=
- [PULL 16/31] softfloat: fix floatx80 remainder pseudo-denormal check for zero, Paolo Bonzini, 2020/06/24
- [PULL 18/31] softfloat: do not set denominator high bit for floatx80 remainder, Paolo Bonzini, 2020/06/24
- [PULL 12/31] Makefile: Install qemu-[qmp/ga]-ref.* into the directory "interop", Paolo Bonzini, 2020/06/24
- [PULL 14/31] target/i386: reimplement f2xm1 using floatx80 operations, Paolo Bonzini, 2020/06/24
- [PULL 20/31] target/i386: reimplement fprem, fprem1 using floatx80 operations, Paolo Bonzini, 2020/06/24
- [PULL 19/31] softfloat: return low bits of quotient from floatx80_modrem, Paolo Bonzini, 2020/06/24
- [PULL 24/31] target/i386: Add notes for versioned CPU models, Paolo Bonzini, 2020/06/24
- [PULL 17/31] softfloat: do not return pseudo-denormal from floatx80 remainder, Paolo Bonzini, 2020/06/24
- [PULL 23/31] target/i386: reimplement fpatan using floatx80 operations, Paolo Bonzini, 2020/06/24
- [PULL 27/31] kvm: i386: allow TSC to differ by NTP correction bounds without TSC scaling, Paolo Bonzini, 2020/06/24