From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Tom Musta" <tommusta@gmail.com>,
"Peter Crosthwaite" <peter.crosthwaite@xilinx.com>,
patches@linaro.org, "Michael Matz" <matz@suse.de>,
"Alexander Graf" <agraf@suse.de>,
"Claudio Fontana" <claudio.fontana@linaro.org>,
"Dirk Mueller" <dmueller@suse.de>,
"Will Newton" <will.newton@linaro.org>,
"Laurent Desnogues" <laurent.desnogues@gmail.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
kvmarm@lists.cs.columbia.edu,
"Christoffer Dall" <christoffer.dall@linaro.org>,
"Richard Henderson" <rth@twiddle.net>
Subject: [Qemu-devel] [PATCH v2 16/24] softfloat: Add support for ties-away rounding
Date: Mon, 6 Jan 2014 13:11:13 +0000 [thread overview]
Message-ID: <1389013881-15726-17-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1389013881-15726-1-git-send-email-peter.maydell@linaro.org>
IEEE754-2008 specifies a new rounding mode:
"roundTiesToAway: the floating-point number nearest to the infinitely
precise result shall be delivered; if the two nearest floating-point
numbers bracketing an unrepresentable infinitely precise result are
equally near, the one with larger magnitude shall be delivered."
Implement this new mode (it is needed for ARM). The general principle
is that the required code is exactly like the ties-to-even code,
except that we do not need to do the "in case of exact tie clear LSB
to round-to-even", because the rounding operation naturally causes
the exact tie to round up in magnitude.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
include/fpu/softfloat.h | 3 ++-
2 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 42cb705..49d90ef 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -111,6 +111,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
roundNearestEven = ( roundingMode == float_round_nearest_even );
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
roundIncrement = 0x40;
break;
case float_round_to_zero:
@@ -161,6 +162,7 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU
roundNearestEven = ( roundingMode == float_round_nearest_even );
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
increment = ((int64_t) absZ1 < 0);
break;
case float_round_to_zero:
@@ -214,6 +216,7 @@ static int64 roundAndPackUint64(flag zSign, uint64_t absZ0,
roundNearestEven = (roundingMode == float_round_nearest_even);
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
increment = ((int64_t)absZ1 < 0);
break;
case float_round_to_zero:
@@ -366,6 +369,7 @@ static float32 roundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig
roundNearestEven = ( roundingMode == float_round_nearest_even );
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
roundIncrement = 0x40;
break;
case float_round_to_zero:
@@ -550,6 +554,7 @@ static float64 roundAndPackFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig
roundNearestEven = ( roundingMode == float_round_nearest_even );
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
roundIncrement = 0x200;
break;
case float_round_to_zero:
@@ -734,6 +739,7 @@ static floatx80
zSig0 |= ( zSig1 != 0 );
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
break;
case float_round_to_zero:
roundIncrement = 0;
@@ -794,6 +800,7 @@ static floatx80
precision80:
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
increment = ((int64_t)zSig1 < 0);
break;
case float_round_to_zero:
@@ -838,6 +845,7 @@ static floatx80
if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
increment = ((int64_t)zSig1 < 0);
break;
case float_round_to_zero:
@@ -1052,6 +1060,7 @@ static float128
roundNearestEven = ( roundingMode == float_round_nearest_even );
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
increment = ((int64_t)zSig2 < 0);
break;
case float_round_to_zero:
@@ -1114,6 +1123,7 @@ static float128
if ( isTiny && zSig2 ) float_raise( float_flag_underflow STATUS_VAR);
switch (roundingMode) {
case float_round_nearest_even:
+ case float_round_ties_away:
increment = ((int64_t)zSig2 < 0);
break;
case float_round_to_zero:
@@ -1785,6 +1795,11 @@ float32 float32_round_to_int( float32 a STATUS_PARAM)
return packFloat32( aSign, 0x7F, 0 );
}
break;
+ case float_round_ties_away:
+ if (aExp == 0x7E) {
+ return packFloat32(aSign, 0x7F, 0);
+ }
+ break;
case float_round_down:
return make_float32(aSign ? 0xBF800000 : 0);
case float_round_up:
@@ -1803,6 +1818,9 @@ float32 float32_round_to_int( float32 a STATUS_PARAM)
z &= ~lastBitMask;
}
break;
+ case float_round_ties_away:
+ z += lastBitMask >> 1;
+ break;
case float_round_to_zero:
break;
case float_round_up:
@@ -3183,6 +3201,9 @@ static float32 roundAndPackFloat16(flag zSign, int_fast16_t zExp,
increment = zSig & (increment << 1);
}
break;
+ case float_round_ties_away:
+ increment = (mask + 1) >> 1;
+ break;
case float_round_up:
increment = zSign ? 0 : mask;
break;
@@ -3487,6 +3508,11 @@ float64 float64_round_to_int( float64 a STATUS_PARAM )
return packFloat64( aSign, 0x3FF, 0 );
}
break;
+ case float_round_ties_away:
+ if (aExp == 0x3FE) {
+ return packFloat64(aSign, 0x3ff, 0);
+ }
+ break;
case float_round_down:
return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0);
case float_round_up:
@@ -3506,6 +3532,9 @@ float64 float64_round_to_int( float64 a STATUS_PARAM )
z &= ~lastBitMask;
}
break;
+ case float_round_ties_away:
+ z += lastBitMask >> 1;
+ break;
case float_round_to_zero:
break;
case float_round_up:
@@ -4771,6 +4800,11 @@ floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
}
break;
+ case float_round_ties_away:
+ if (aExp == 0x3FFE) {
+ return packFloatx80(aSign, 0x3FFF, LIT64(0x8000000000000000));
+ }
+ break;
case float_round_down:
return
aSign ?
@@ -4794,6 +4828,9 @@ floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
z.low &= ~lastBitMask;
}
break;
+ case float_round_ties_away:
+ z.low += lastBitMask >> 1;
+ break;
case float_round_to_zero:
break;
case float_round_up:
@@ -5862,6 +5899,15 @@ float128 float128_round_to_int( float128 a STATUS_PARAM )
}
}
break;
+ case float_round_ties_away:
+ if (lastBitMask) {
+ add128(z.high, z.low, 0, lastBitMask >> 1, &z.high, &z.low);
+ } else {
+ if ((int64_t) z.low < 0) {
+ ++z.high;
+ }
+ }
+ break;
case float_round_to_zero:
break;
case float_round_up:
@@ -5893,6 +5939,11 @@ float128 float128_round_to_int( float128 a STATUS_PARAM )
return packFloat128( aSign, 0x3FFF, 0, 0 );
}
break;
+ case float_round_ties_away:
+ if (aExp == 0x3FFE) {
+ return packFloat128(aSign, 0x3FFF, 0, 0);
+ }
+ break;
case float_round_down:
return
aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
@@ -5916,6 +5967,9 @@ float128 float128_round_to_int( float128 a STATUS_PARAM )
z.high &= ~ lastBitMask;
}
break;
+ case float_round_ties_away:
+ z.high += lastBitMask>>1;
+ break;
case float_round_to_zero:
break;
case float_round_up:
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 83d324a..806ae13 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -152,7 +152,8 @@ enum {
float_round_nearest_even = 0,
float_round_down = 1,
float_round_up = 2,
- float_round_to_zero = 3
+ float_round_to_zero = 3,
+ float_round_ties_away = 4,
};
/*----------------------------------------------------------------------------
--
1.8.5
next prev parent reply other threads:[~2014-01-06 13:26 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-06 13:10 [Qemu-devel] [PATCH v2 00/24] A64 decoder patchset 6: rest of floating point Peter Maydell
2014-01-06 13:10 ` [Qemu-devel] [PATCH v2 01/24] softfloat: Fix exception flag handling for float32_to_float16() Peter Maydell
2014-01-06 18:18 ` Richard Henderson
2014-01-06 13:10 ` [Qemu-devel] [PATCH v2 02/24] softfloat: Add float to 16bit integer conversions Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 03/24] softfloat: Add 16 bit integer to float conversions Peter Maydell
2014-01-06 18:19 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 04/24] softfloat: Make the int-to-float functions take exact-width types Peter Maydell
2014-01-06 18:20 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 05/24] softfloat: Fix float64_to_uint64 Peter Maydell
2014-01-06 18:23 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 06/24] softfloat: Only raise Invalid when conversions to int are out of range Peter Maydell
2014-01-06 18:24 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 07/24] softfloat: Fix factor 2 error for scalbn on denormal inputs Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 08/24] softfloat: Add float32_to_uint64() Peter Maydell
2014-01-06 18:25 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 09/24] softfloat: Fix float64_to_uint64_round_to_zero Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 10/24] softfloat: Fix float64_to_uint32 Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 11/24] softfloat: Fix float64_to_uint32_round_to_zero Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 12/24] softfloat: Provide complete set of accessors for fp state Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 13/24] softfloat: Factor out RoundAndPackFloat16 and NormalizeFloat16Subnormal Peter Maydell
2014-01-06 18:28 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 14/24] softfloat: Add float16 <=> float64 conversion functions Peter Maydell
2014-01-06 18:30 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 15/24] softfloat: Refactor code handling various rounding modes Peter Maydell
2014-01-06 18:34 ` Richard Henderson
2014-01-06 13:11 ` Peter Maydell [this message]
2014-01-06 18:36 ` [Qemu-devel] [PATCH v2 16/24] softfloat: Add support for ties-away rounding Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 17/24] target-arm: Prepare VFP_CONV_FIX helpers for A64 uses Peter Maydell
2014-01-06 18:37 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 18/24] target-arm: Rename A32 VFP conversion helpers Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 19/24] target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 20/24] target-arm: A64: Add extra VFP fixed point conversion helpers Peter Maydell
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 21/24] target-arm: A64: Add "Floating-point<->fixed-point" instructions Peter Maydell
2014-01-06 18:44 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 22/24] target-arm: A64: Add floating-point<->integer conversion instructions Peter Maydell
2014-01-06 18:47 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 23/24] target-arm: A64: Add 1-source 32-to-32 and 64-to-64 FP instructions Peter Maydell
2014-01-06 18:52 ` Richard Henderson
2014-01-06 13:11 ` [Qemu-devel] [PATCH v2 24/24] target-arm: A64: Add support for FCVT between half, single and double Peter Maydell
2014-01-06 18:55 ` Richard Henderson
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=1389013881-15726-17-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=agraf@suse.de \
--cc=alex.bennee@linaro.org \
--cc=christoffer.dall@linaro.org \
--cc=claudio.fontana@linaro.org \
--cc=dmueller@suse.de \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=laurent.desnogues@gmail.com \
--cc=matz@suse.de \
--cc=patches@linaro.org \
--cc=peter.crosthwaite@xilinx.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
--cc=tommusta@gmail.com \
--cc=will.newton@linaro.org \
/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 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).