* [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point
@ 2013-12-31 13:35 Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 01/22] softfloat: Fix exception flag handling for float32_to_float16() Peter Maydell
` (22 more replies)
0 siblings, 23 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
This patchset completes the FP emulation, leaving us with only
Neon (and CRC32) to go to complete the user-mode emulation.
Most of this is fixing issues and adding new features to softfloat.
(As usual, all Linaro authored softfloat patches are licensed under
either softfloat-2a or softfloat-2b, at your option.)
We need Tom Musta's softfloat patches too, so I have included them
here. Note that two of these still have outstanding issues identified
in code review : see the notes in their commit messages (and I haven't
applied my signed-off-by line to them).
This patchset sits on top of the previous ones; you can find a git tree at
git://git.linaro.org/people/peter.maydell/qemu-arm.git a64-sixth-set
web UI:
https://git.linaro.org/people/peter.maydell/qemu-arm.git/shortlog/refs/heads/a64-sixth-set
New Year's Resolution for 2014: avoid using the phrase "yeah,
sure, we can get that done by the end of the year".
thanks
-- PMM
Alexander Graf (1):
target-arm: A64: Add "Floating-point<->fixed-point" instructions
Peter Maydell (11):
softfloat: Fix exception flag handling for float32_to_float16()
softfloat: Add 16 bit integer to float conversions
softfloat: Only raise Invalid when conversions to int are out of range
softfloat: Fix factor 2 error for scalbn on denormal inputs
softfloat: Provide complete set of accessors for fp state
softfloat: Factor out RoundAndPackFloat16 and
NormalizeFloat16Subnormal
softfloat: Add float16 <=> float64 conversion functions
softfloat: Add support for ties-away rounding
target-arm: Ignore most exceptions from scalbn when doing fixpoint
conversion
target-arm: A64: Add 1-source 32-to-32 and 64-to-64 FP instructions
target-arm: A64: Add support for FCVT between half, single and double
Tom Musta (5):
softfloat: Fix float64_to_uint64
softfloat: Add float32_to_uint64()
softfloat: Fix float64_to_uint64_round_to_zero
softfloat: Fix float64_to_uint32
softfloat: Fix float64_to_uint32_round_to_zero
Will Newton (5):
softfloat: Add float to 16bit integer conversions.
target-arm: Prepare VFP_CONV_FIX helpers for A64 uses
target-arm: Rename A32 VFP conversion helpers
target-arm: A64: Add extra VFP fixed point conversion helpers
target-arm: A64: Add floating-point<->integer conversion instructions
fpu/softfloat.c | 660 +++++++++++++++++++++++++++++++++++----------
include/fpu/softfloat.h | 66 ++++-
target-arm/helper.c | 141 ++++++++--
target-arm/helper.h | 25 ++
target-arm/translate-a64.c | 424 ++++++++++++++++++++++++++++-
target-arm/translate.c | 24 +-
6 files changed, 1162 insertions(+), 178 deletions(-)
--
1.8.5
^ permalink raw reply [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 01/22] softfloat: Fix exception flag handling for float32_to_float16()
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 02/22] softfloat: Add float to 16bit integer conversions Peter Maydell
` (21 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
Our float32 to float16 conversion routine was generating the correct
numerical answers, but not always setting the right set of exception
flags. Fix this, mostly by rearranging the code to more closely
resemble RoundAndPackFloat*, and in particular:
* non-IEEE halfprec always raises Invalid for input NaNs
* we need to check for the overflow case before underflow
* we weren't getting the tininess-detected-after-rounding
case correct (somewhat academic since only ARM uses halfprec
and it is always tininess-detected-before-rounding)
* non-IEEE halfprec overflow raises only Invalid, not
Invalid + Inexact
* we weren't setting Inexact when we should
Also add some clarifying comments about what the code is doing.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 105 +++++++++++++++++++++++++++++++++++---------------------
1 file changed, 66 insertions(+), 39 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index dbda61b..6a6b656 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3046,6 +3046,10 @@ float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
uint32_t mask;
uint32_t increment;
int8 roundingMode;
+ int maxexp = ieee ? 15 : 16;
+ bool rounding_bumps_exp;
+ bool is_tiny = false;
+
a = float32_squash_input_denormal(a STATUS_VAR);
aSig = extractFloat32Frac( a );
@@ -3054,11 +3058,12 @@ float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
if ( aExp == 0xFF ) {
if (aSig) {
/* Input is a NaN */
- float16 r = commonNaNToFloat16( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
if (!ieee) {
+ float_raise(float_flag_invalid STATUS_VAR);
return packFloat16(aSign, 0, 0);
}
- return r;
+ return commonNaNToFloat16(
+ float32ToCommonNaN(a STATUS_VAR) STATUS_VAR);
}
/* Infinity */
if (!ieee) {
@@ -3070,58 +3075,80 @@ float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
if (aExp == 0 && aSig == 0) {
return packFloat16(aSign, 0, 0);
}
- /* Decimal point between bits 22 and 23. */
+ /* Decimal point between bits 22 and 23. Note that we add the 1 bit
+ * even if the input is denormal; however this is harmless because
+ * the largest possible single-precision denormal is still smaller
+ * than the smallest representable half-precision denormal, and so we
+ * will end up ignoring aSig and returning via the "always return zero"
+ * codepath.
+ */
aSig |= 0x00800000;
aExp -= 0x7f;
+ /* Calculate the mask of bits of the mantissa which are not
+ * representable in half-precision and will be lost.
+ */
if (aExp < -14) {
+ /* Will be denormal in halfprec */
mask = 0x00ffffff;
if (aExp >= -24) {
mask >>= 25 + aExp;
}
} else {
+ /* Normal number in halfprec */
mask = 0x00001fff;
}
- if (aSig & mask) {
- float_raise( float_flag_underflow STATUS_VAR );
- roundingMode = STATUS(float_rounding_mode);
- switch (roundingMode) {
- case float_round_nearest_even:
- increment = (mask + 1) >> 1;
- if ((aSig & mask) == increment) {
- increment = aSig & (increment << 1);
- }
- break;
- case float_round_up:
- increment = aSign ? 0 : mask;
- break;
- case float_round_down:
- increment = aSign ? mask : 0;
- break;
- default: /* round_to_zero */
- increment = 0;
- break;
- }
- aSig += increment;
- if (aSig >= 0x01000000) {
- aSig >>= 1;
- aExp++;
- }
- } else if (aExp < -14
- && STATUS(float_detect_tininess) == float_tininess_before_rounding) {
- float_raise( float_flag_underflow STATUS_VAR);
- }
- if (ieee) {
- if (aExp > 15) {
- float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
+ roundingMode = STATUS(float_rounding_mode);
+ switch (roundingMode) {
+ case float_round_nearest_even:
+ increment = (mask + 1) >> 1;
+ if ((aSig & mask) == increment) {
+ increment = aSig & (increment << 1);
+ }
+ break;
+ case float_round_up:
+ increment = aSign ? 0 : mask;
+ break;
+ case float_round_down:
+ increment = aSign ? mask : 0;
+ break;
+ default: /* round_to_zero */
+ increment = 0;
+ break;
+ }
+
+ rounding_bumps_exp = (aSig + increment >= 0x01000000);
+
+ if (aExp > maxexp || (aExp == maxexp && rounding_bumps_exp)) {
+ if (ieee) {
+ float_raise(float_flag_overflow | float_flag_inexact STATUS_VAR);
return packFloat16(aSign, 0x1f, 0);
- }
- } else {
- if (aExp > 16) {
- float_raise(float_flag_invalid | float_flag_inexact STATUS_VAR);
+ } else {
+ float_raise(float_flag_invalid STATUS_VAR);
return packFloat16(aSign, 0x1f, 0x3ff);
}
}
+
+ if (aExp < -14) {
+ /* Note that flush-to-zero does not affect half-precision results */
+ is_tiny =
+ (STATUS(float_detect_tininess) == float_tininess_before_rounding)
+ || (aExp < -15)
+ || (!rounding_bumps_exp);
+ }
+ if (aSig & mask) {
+ float_raise(float_flag_inexact STATUS_VAR);
+ if (is_tiny) {
+ float_raise(float_flag_underflow STATUS_VAR);
+ }
+ }
+
+ aSig += increment;
+ if (rounding_bumps_exp) {
+ aSig >>= 1;
+ aExp++;
+ }
+
if (aExp < -24) {
return packFloat16(aSign, 0, 0);
}
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 02/22] softfloat: Add float to 16bit integer conversions.
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 01/22] softfloat: Fix exception flag handling for float32_to_float16() Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 14:18 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions Peter Maydell
` (20 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Will Newton <will.newton@linaro.org>
ARMv8 requires support for converting 32 and 64bit floating point
values to signed and unsigned 16bit integers.
Signed-off-by: Will Newton <will.newton@linaro.org>
[PMM: updated not to incorrectly set Inexact for Invalid inputs]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++
include/fpu/softfloat.h | 4 +++
2 files changed, 84 insertions(+)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6a6b656..e078539 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6491,6 +6491,46 @@ uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
return res;
}
+int_fast16_t float32_to_int16(float32 a STATUS_PARAM)
+{
+ int64_t v;
+ int_fast16_t res;
+ int old_exc_flags = get_float_exception_flags(status);
+
+ v = float32_to_int64(a STATUS_VAR);
+ if (v < -0x8000) {
+ res = -0x8000;
+ } else if (v > 0x7fff) {
+ res = 0x7fff;
+ } else {
+ return v;
+ }
+
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
+ return res;
+}
+
+uint_fast16_t float32_to_uint16(float32 a STATUS_PARAM)
+{
+ int64_t v;
+ uint_fast16_t res;
+ int old_exc_flags = get_float_exception_flags(status);
+
+ v = float32_to_int64(a STATUS_VAR);
+ if (v < 0) {
+ res = 0;
+ } else if (v > 0xffff) {
+ res = 0xffff;
+ } else {
+ return v;
+ }
+
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
+ return res;
+}
+
uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM)
{
int64_t v;
@@ -6545,6 +6585,46 @@ uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
return res;
}
+int_fast16_t float64_to_int16(float64 a STATUS_PARAM)
+{
+ int64_t v;
+ int_fast16_t res;
+ int old_exc_flags = get_float_exception_flags(status);
+
+ v = float64_to_int64(a STATUS_VAR);
+ if (v < -0x8000) {
+ res = -0x8000;
+ } else if (v > 0x7fff) {
+ res = 0x7fff;
+ } else {
+ return v;
+ }
+
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
+ return res;
+}
+
+uint_fast16_t float64_to_uint16(float64 a STATUS_PARAM)
+{
+ int64_t v;
+ uint_fast16_t res;
+ int old_exc_flags = get_float_exception_flags(status);
+
+ v = float64_to_int64(a STATUS_VAR);
+ if (v < 0) {
+ res = 0;
+ } else if (v > 0xffff) {
+ res = 0xffff;
+ } else {
+ return v;
+ }
+
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
+ return res;
+}
+
uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM)
{
int64_t v;
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 2365274..a9b8cd9 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -265,6 +265,8 @@ extern const float16 float16_default_nan;
/*----------------------------------------------------------------------------
| Software IEC/IEEE single-precision conversion routines.
*----------------------------------------------------------------------------*/
+int_fast16_t float32_to_int16(float32 STATUS_PARAM);
+uint_fast16_t float32_to_uint16(float32 STATUS_PARAM);
int_fast16_t float32_to_int16_round_to_zero(float32 STATUS_PARAM);
uint_fast16_t float32_to_uint16_round_to_zero(float32 STATUS_PARAM);
int32 float32_to_int32( float32 STATUS_PARAM );
@@ -371,6 +373,8 @@ extern const float32 float32_default_nan;
/*----------------------------------------------------------------------------
| Software IEC/IEEE double-precision conversion routines.
*----------------------------------------------------------------------------*/
+int_fast16_t float64_to_int16(float64 STATUS_PARAM);
+uint_fast16_t float64_to_uint16(float64 STATUS_PARAM);
int_fast16_t float64_to_int16_round_to_zero(float64 STATUS_PARAM);
uint_fast16_t float64_to_uint16_round_to_zero(float64 STATUS_PARAM);
int32 float64_to_int32( float64 STATUS_PARAM );
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 01/22] softfloat: Fix exception flag handling for float32_to_float16() Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 02/22] softfloat: Add float to 16bit integer conversions Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 14:21 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 04/22] softfloat: Fix float64_to_uint64 Peter Maydell
` (19 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
Add the float to 16 bit integer conversion routines. These can be
trivially implemented in terms of the int32_to_float* routines, but
providing them makes our API more symmetrical and can simplify callers.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/fpu/softfloat.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index a9b8cd9..3790b10 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -238,6 +238,23 @@ float64 uint64_to_float64( uint64 STATUS_PARAM );
floatx80 int64_to_floatx80( int64 STATUS_PARAM );
float128 int64_to_float128( int64 STATUS_PARAM );
float128 uint64_to_float128( uint64 STATUS_PARAM );
+/* We provide the int16 versions for symmetry of API with float-to-int */
+INLINE float32 int16_to_float32(int_fast16_t v STATUS_PARAM)
+{
+ return int32_to_float32(v STATUS_VAR);
+}
+INLINE float32 uint16_to_float32(uint_fast16_t v STATUS_PARAM)
+{
+ return uint32_to_float32(v STATUS_VAR);
+}
+INLINE float64 int16_to_float64(int_fast16_t v STATUS_PARAM)
+{
+ return int32_to_float64(v STATUS_VAR);
+}
+INLINE float64 uint16_to_float64(uint_fast16_t v STATUS_PARAM)
+{
+ return uint32_to_float64(v STATUS_VAR);
+}
/*----------------------------------------------------------------------------
| Software half-precision conversion routines.
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 04/22] softfloat: Fix float64_to_uint64
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (2 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 05/22] softfloat: Only raise Invalid when conversions to int are out of range Peter Maydell
` (18 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Tom Musta <tommusta@gmail.com>
The comment preceding the float64_to_uint64 routine suggests that
the implementation is broken. And this is, indeed, the case.
This patch properly implements the conversion of a 64-bit floating
point number to an unsigned, 64 bit integer.
This contribution can be licensed under either the softfloat-2a or -2b
license.
V2: Added softfloat license statement.
V3: Modified to meet QEMU coding conventions.
V4: Fixed incorrect handling of small negatives, which, if rounded
up to zero should not set the inexact flag.
Signed-off-by: Tom Musta <tommusta@gmail.com>
Message-id: 1387397961-4894-2-git-send-email-tommusta@gmail.com
PMM notes: this looks like it gives the wrong answer for NaNs
with the sign bit set.
---
fpu/softfloat.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 89 insertions(+), 9 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index e078539..afabb04 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -161,7 +161,6 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
| exception is raised and the largest positive or negative integer is
| returned.
*----------------------------------------------------------------------------*/
-
static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATUS_PARAM)
{
int8 roundingMode;
@@ -204,6 +203,56 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU
}
/*----------------------------------------------------------------------------
+| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
+| `absZ1', with binary point between bits 63 and 64 (between the input words),
+| and returns the properly rounded 64-bit unsigned integer corresponding to the
+| input. Ordinarily, the fixed-point input is simply rounded to an integer,
+| with the inexact exception raised if the input cannot be represented exactly
+| as an integer. However, if the fixed-point input is too large, the invalid
+| exception is raised and the largest unsigned integer is returned.
+*----------------------------------------------------------------------------*/
+
+static int64 roundAndPackUint64(flag zSign, uint64_t absZ0,
+ uint64_t absZ1 STATUS_PARAM)
+{
+ int8 roundingMode;
+ flag roundNearestEven, increment;
+
+ roundingMode = STATUS(float_rounding_mode);
+ roundNearestEven = (roundingMode == float_round_nearest_even);
+ increment = ((int64_t)absZ1 < 0);
+ if (!roundNearestEven) {
+ if (roundingMode == float_round_to_zero) {
+ increment = 0;
+ } else if (absZ1) {
+ if (zSign) {
+ increment = (roundingMode == float_round_down) && absZ1;
+ } else {
+ increment = (roundingMode == float_round_up) && absZ1;
+ }
+ }
+ }
+ if (increment) {
+ ++absZ0;
+ if (absZ0 == 0) {
+ float_raise(float_flag_invalid STATUS_VAR);
+ return LIT64(0xFFFFFFFFFFFFFFFF);
+ }
+ absZ0 &= ~(((uint64_t)(absZ1<<1) == 0) & roundNearestEven);
+ }
+
+ if (zSign && absZ0) {
+ float_raise(float_flag_invalid STATUS_VAR);
+ return 0;
+ }
+
+ if (absZ1) {
+ STATUS(float_exception_flags) |= float_flag_inexact;
+ }
+ return absZ0;
+}
+
+/*----------------------------------------------------------------------------
| Returns the fraction bits of the single-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
@@ -6643,18 +6692,49 @@ uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM)
return res;
}
-/* FIXME: This looks broken. */
-uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
-{
- int64_t v;
+/*----------------------------------------------------------------------------
+| Returns the result of converting the double-precision floating-point value
+| `a' to the 64-bit unsigned integer format. The conversion is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic---which means in particular that the conversion is rounded
+| according to the current rounding mode. If `a' is a NaN, the largest
+| positive integer is returned. If the conversion overflows, the
+| largest unsigned integer is returned. If 'a' is negative, zero is
+| returned.
+*----------------------------------------------------------------------------*/
- v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
- v += float64_val(a);
- v = float64_to_int64(make_float64(v) STATUS_VAR);
+uint64_t float64_to_uint64(float64 a STATUS_PARAM)
+{
+ flag aSign;
+ int_fast16_t aExp, shiftCount;
+ uint64_t aSig, aSigExtra;
+ a = float64_squash_input_denormal(a STATUS_VAR);
- return v - INT64_MIN;
+ aSig = extractFloat64Frac(a);
+ aExp = extractFloat64Exp(a);
+ aSign = extractFloat64Sign(a);
+ if (aSign && (aExp > 1022)) {
+ float_raise(float_flag_invalid STATUS_VAR);
+ return 0;
+ }
+ if (aExp) {
+ aSig |= LIT64(0x0010000000000000);
+ }
+ shiftCount = 0x433 - aExp;
+ if (shiftCount <= 0) {
+ if (0x43E < aExp) {
+ float_raise(float_flag_invalid STATUS_VAR);
+ return LIT64(0xFFFFFFFFFFFFFFFF);
+ }
+ aSigExtra = 0;
+ aSig <<= -shiftCount;
+ } else {
+ shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra);
+ }
+ return roundAndPackUint64(aSign, aSig, aSigExtra STATUS_VAR);
}
+
uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
{
int64_t v;
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 05/22] softfloat: Only raise Invalid when conversions to int are out of range
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (3 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 04/22] softfloat: Fix float64_to_uint64 Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 06/22] softfloat: Fix factor 2 error for scalbn on denormal inputs Peter Maydell
` (17 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
We implement a number of float-to-integer conversions using conversion
to an integer type with a wider range and then a check against the
narrower range we are actually converting to. If we find the result to
be out of range we correctly raise the Invalid exception, but we must
also suppress other exceptions which might have been raised by the
conversion function we called.
This won't throw away exceptions we should have preserved, because for
the 'core' exception flags the IEEE spec mandates that the only valid
combinations of exception that can be raised by a single operation are
Inexact + Overflow and Inexact + Underflow. For the non-IEEE softfloat
flag for input denormals, we can guarantee that that flag won't have
been set for out of range float-to-int conversions because a squashed
denormal by definition goes to plus or minus zero, which is always in
range after conversion to integer zero.
This bug has been fixed for some of the float-to-int conversion routines
by previous patches; fix it for the remaining functions as well, so
that they all restore the pre-conversion status flags prior to raising
Invalid.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
---
fpu/softfloat.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index afabb04..41e4432 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6508,17 +6508,18 @@ uint32 float32_to_uint32( float32 a STATUS_PARAM )
{
int64_t v;
uint32 res;
+ int old_exc_flags = get_float_exception_flags(status);
v = float32_to_int64(a STATUS_VAR);
if (v < 0) {
res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
} else if (v > 0xffffffff) {
res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
} else {
- res = v;
+ return v;
}
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
return res;
}
@@ -6526,17 +6527,18 @@ uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
{
int64_t v;
uint32 res;
+ int old_exc_flags = get_float_exception_flags(status);
v = float32_to_int64_round_to_zero(a STATUS_VAR);
if (v < 0) {
res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
} else if (v > 0xffffffff) {
res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
} else {
- res = v;
+ return v;
}
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
return res;
}
@@ -6584,17 +6586,18 @@ uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM)
{
int64_t v;
uint_fast16_t res;
+ int old_exc_flags = get_float_exception_flags(status);
v = float32_to_int64_round_to_zero(a STATUS_VAR);
if (v < 0) {
res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
} else if (v > 0xffff) {
res = 0xffff;
- float_raise( float_flag_invalid STATUS_VAR);
} else {
- res = v;
+ return v;
}
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
return res;
}
@@ -6678,17 +6681,18 @@ uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM)
{
int64_t v;
uint_fast16_t res;
+ int old_exc_flags = get_float_exception_flags(status);
v = float64_to_int64_round_to_zero(a STATUS_VAR);
if (v < 0) {
res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
} else if (v > 0xffff) {
res = 0xffff;
- float_raise( float_flag_invalid STATUS_VAR);
} else {
- res = v;
+ return v;
}
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
return res;
}
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 06/22] softfloat: Fix factor 2 error for scalbn on denormal inputs
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (4 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 05/22] softfloat: Only raise Invalid when conversions to int are out of range Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 07/22] softfloat: Add float32_to_uint64() Peter Maydell
` (16 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
If the input to float*_scalbn() is denormal then it represents
a number 0.[mantissabits] * 2^(1-exponentbias) (and the actual
exponent field is all zeroes). This means that when we convert
it to our unpacked encoding the unpacked exponent must be one
greater than for a normal number, which represents
1.[mantissabits] * 2^(e-exponentbias) for an exponent field e.
This meant we were giving answers too small by a factor of 2 for
all denormal inputs.
Note that the float-to-int routines also have this behaviour
of not adjusting the exponent for denormals; however there it is
harmless because denormals will all convert to integer zero anyway.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
fpu/softfloat.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 41e4432..1af6ca5 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6986,10 +6986,13 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
}
return a;
}
- if ( aExp != 0 )
+ if (aExp != 0) {
aSig |= 0x00800000;
- else if ( aSig == 0 )
+ } else if (aSig == 0) {
return a;
+ } else {
+ aExp++;
+ }
if (n > 0x200) {
n = 0x200;
@@ -7019,10 +7022,13 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
}
return a;
}
- if ( aExp != 0 )
+ if (aExp != 0) {
aSig |= LIT64( 0x0010000000000000 );
- else if ( aSig == 0 )
+ } else if (aSig == 0) {
return a;
+ } else {
+ aExp++;
+ }
if (n > 0x1000) {
n = 0x1000;
@@ -7052,8 +7058,12 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
return a;
}
- if (aExp == 0 && aSig == 0)
- return a;
+ if (aExp == 0) {
+ if (aSig == 0) {
+ return a;
+ }
+ aExp++;
+ }
if (n > 0x10000) {
n = 0x10000;
@@ -7082,10 +7092,13 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
}
return a;
}
- if ( aExp != 0 )
+ if (aExp != 0) {
aSig0 |= LIT64( 0x0001000000000000 );
- else if ( aSig0 == 0 && aSig1 == 0 )
+ } else if (aSig0 == 0 && aSig1 == 0) {
return a;
+ } else {
+ aExp++;
+ }
if (n > 0x10000) {
n = 0x10000;
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 07/22] softfloat: Add float32_to_uint64()
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (5 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 06/22] softfloat: Fix factor 2 error for scalbn on denormal inputs Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 08/22] softfloat: Fix float64_to_uint64_round_to_zero Peter Maydell
` (15 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Tom Musta <tommusta@gmail.com>
This patch adds the float32_to_uint64() routine, which converts a
32-bit floating point number to an unsigned 64 bit number.
This contribution can be licensed under either the softfloat-2a or -2b
license.
V2: Reduced patch to just this single routine per feedback from Peter
Maydell.
V4: Now passing sign to roundAndPackUint64()
Signed-off-by: Tom Musta <tommusta@gmail.com>
Message-id: 1387397961-4894-3-git-send-email-tommusta@gmail.com
PMM notes:
* signed NaNs again
* not convinced about handling of negative-but-round-to-zero inputs
---
fpu/softfloat.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
include/fpu/softfloat.h | 1 +
2 files changed, 46 insertions(+)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 1af6ca5..af37164 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1558,6 +1558,51 @@ int64 float32_to_int64( float32 a STATUS_PARAM )
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
+| `a' to the 64-bit unsigned integer format. The conversion is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic---which means in particular that the conversion is rounded
+| according to the current rounding mode. If `a' is a NaN, the largest
+| unsigned integer is returned. Otherwise, if the conversion overflows, the
+| largest unsigned integer is returned. If the 'a' is negative, zero is
+| returned.
+*----------------------------------------------------------------------------*/
+
+uint64 float32_to_uint64(float32 a STATUS_PARAM)
+{
+ flag aSign;
+ int_fast16_t aExp, shiftCount;
+ uint32_t aSig;
+ uint64_t aSig64, aSigExtra;
+ a = float32_squash_input_denormal(a STATUS_VAR);
+
+ aSig = extractFloat32Frac(a);
+ aExp = extractFloat32Exp(a);
+ aSign = extractFloat32Sign(a);
+ if (aSign) {
+ if (aExp) {
+ float_raise(float_flag_invalid STATUS_VAR);
+ } else if (aSig) { /* negative denormalized */
+ float_raise(float_flag_inexact STATUS_VAR);
+ }
+ return 0;
+ }
+ shiftCount = 0xBE - aExp;
+ if (aExp) {
+ aSig |= 0x00800000;
+ }
+ if (shiftCount < 0) {
+ float_raise(float_flag_invalid STATUS_VAR);
+ return (int64_t)LIT64(0xFFFFFFFFFFFFFFFF);
+ }
+
+ aSig64 = aSig;
+ aSig64 <<= 40;
+ shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra);
+ return roundAndPackUint64(aSign, aSig64, aSigExtra STATUS_VAR);
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the single-precision floating-point value
| `a' to the 64-bit two's complement integer format. The conversion is
| performed according to the IEC/IEEE Standard for Binary Floating-Point
| Arithmetic, except that the conversion is always rounded toward zero. If
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 3790b10..c49e836 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -291,6 +291,7 @@ int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM );
uint32 float32_to_uint32( float32 STATUS_PARAM );
uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
int64 float32_to_int64( float32 STATUS_PARAM );
+uint64 float32_to_uint64(float32 STATUS_PARAM);
int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM );
float64 float32_to_float64( float32 STATUS_PARAM );
floatx80 float32_to_floatx80( float32 STATUS_PARAM );
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 08/22] softfloat: Fix float64_to_uint64_round_to_zero
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (6 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 07/22] softfloat: Add float32_to_uint64() Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 14:23 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 09/22] softfloat: Fix float64_to_uint32 Peter Maydell
` (14 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Tom Musta <tommusta@gmail.com>
The float64_to_uint64_round_to_zero routine is incorrect.
For example, the following test pattern:
46697351FF4AEC29 / 0x1.97351ff4aec29p+103
currently produces 8000000000000000 instead of FFFFFFFFFFFFFFFF.
This patch re-implements the routine to temporarily force the
rounding mode and use the float64_to_uint64 routine.
This contribution can be licensed under either the softfloat-2a or -2b
license.
Signed-off-by: Tom Musta <tommusta@gmail.com>
Message-id: 1387397961-4894-4-git-send-email-tommusta@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index af37164..8e536ad 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6786,13 +6786,11 @@ uint64_t float64_to_uint64(float64 a STATUS_PARAM)
uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
{
- int64_t v;
-
- v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
- v += float64_val(a);
- v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR);
-
- return v - INT64_MIN;
+ signed char current_rounding_mode = STATUS(float_rounding_mode);
+ set_float_rounding_mode(float_round_to_zero STATUS_VAR);
+ int64_t v = float64_to_uint64(a STATUS_VAR);
+ set_float_rounding_mode(current_rounding_mode STATUS_VAR);
+ return v;
}
#define COMPARE(s, nan_exp) \
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 09/22] softfloat: Fix float64_to_uint32
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (7 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 08/22] softfloat: Fix float64_to_uint64_round_to_zero Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 14:24 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 10/22] softfloat: Fix float64_to_uint32_round_to_zero Peter Maydell
` (13 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Tom Musta <tommusta@gmail.com>
The float64_to_uint32 has several flaws:
- for numbers between 2**32 and 2**64, the inexact exception flag
may get incorrectly set. In this case, only the invalid flag
should be set.
test pattern: 425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38
- for numbers between 2**63 and 2**64, incorrect results may
be produced:
test pattern: 43EAAF73F1F0B8BD / 0x1.aaf73f1f0b8bdp+63
This patch re-implements float64_to_uint32 to re-use the
float64_to_uint64 routine (instead of float64_to_int64). For the
saturation case, we ignore any flags which the conversion routine
has set and raise only the invalid flag.
This contribution can be licensed under either the softfloat-2a or -2b
license.
Signed-off-by: Tom Musta <tommusta@gmail.com>
Message-id: 1387397961-4894-5-git-send-email-tommusta@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 8e536ad..6b07ef2 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6648,19 +6648,18 @@ uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM)
uint32 float64_to_uint32( float64 a STATUS_PARAM )
{
- int64_t v;
+ uint64_t v;
uint32 res;
+ int old_exc_flags = get_float_exception_flags(status);
- v = float64_to_int64(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
+ v = float64_to_uint64(a STATUS_VAR);
+ if (v > 0xffffffff) {
res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
} else {
- res = v;
+ return v;
}
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
return res;
}
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 10/22] softfloat: Fix float64_to_uint32_round_to_zero
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (8 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 09/22] softfloat: Fix float64_to_uint32 Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 14:24 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 11/22] softfloat: Provide complete set of accessors for fp state Peter Maydell
` (12 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Tom Musta <tommusta@gmail.com>
The float64_to_uint32_round_to_zero routine is incorrect.
For example, the following test pattern:
425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38
will erroneously set the inexact flag.
This patch re-implements the routine to use the float64_to_uint64_round_to_zero
routine. If saturation occurs we ignore any flags set by the
conversion function and raise only Invalid.
This contribution can be licensed under either the softfloat-2a or -2b
license.
Signed-off-by: Tom Musta <tommusta@gmail.com>
Message-id: 1387397961-4894-6-git-send-email-tommusta@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6b07ef2..0eb4a29 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6665,19 +6665,18 @@ uint32 float64_to_uint32( float64 a STATUS_PARAM )
uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
{
- int64_t v;
+ uint64_t v;
uint32 res;
+ int old_exc_flags = get_float_exception_flags(status);
- v = float64_to_int64_round_to_zero(a STATUS_VAR);
- if (v < 0) {
- res = 0;
- float_raise( float_flag_invalid STATUS_VAR);
- } else if (v > 0xffffffff) {
+ v = float64_to_uint64_round_to_zero(a STATUS_VAR);
+ if (v > 0xffffffff) {
res = 0xffffffff;
- float_raise( float_flag_invalid STATUS_VAR);
} else {
- res = v;
+ return v;
}
+ set_float_exception_flags(old_exc_flags, status);
+ float_raise(float_flag_invalid STATUS_VAR);
return res;
}
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 11/22] softfloat: Provide complete set of accessors for fp state
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (9 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 10/22] softfloat: Fix float64_to_uint32_round_to_zero Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 14:26 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 12/22] softfloat: Factor out RoundAndPackFloat16 and NormalizeFloat16Subnormal Peter Maydell
` (11 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
Tidy up the get/set accessors for the fp state to add missing ones
and make them all inline in softfloat.h rather than some inline and
some not.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
The specific one we want for A64 is to get the rounding mode,
but we might as well fill in the gaps.
---
fpu/softfloat.c | 15 ---------------
include/fpu/softfloat.h | 39 ++++++++++++++++++++++++++++++++++++---
2 files changed, 36 insertions(+), 18 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 0eb4a29..495f46f 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -59,21 +59,6 @@ these four paragraphs for those parts of this code that are retained.
*----------------------------------------------------------------------------*/
#include "softfloat-specialize.h"
-void set_float_rounding_mode(int val STATUS_PARAM)
-{
- STATUS(float_rounding_mode) = val;
-}
-
-void set_float_exception_flags(int val STATUS_PARAM)
-{
- STATUS(float_exception_flags) = val;
-}
-
-void set_floatx80_rounding_precision(int val STATUS_PARAM)
-{
- STATUS(floatx80_rounding_precision) = val;
-}
-
/*----------------------------------------------------------------------------
| Returns the fraction bits of the half-precision floating-point value `a'.
*----------------------------------------------------------------------------*/
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index c49e836..b8d2b30 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -180,12 +180,22 @@ typedef struct float_status {
flag default_nan_mode;
} float_status;
-void set_float_rounding_mode(int val STATUS_PARAM);
-void set_float_exception_flags(int val STATUS_PARAM);
INLINE void set_float_detect_tininess(int val STATUS_PARAM)
{
STATUS(float_detect_tininess) = val;
}
+INLINE void set_float_rounding_mode(int val STATUS_PARAM)
+{
+ STATUS(float_rounding_mode) = val;
+}
+INLINE void set_float_exception_flags(int val STATUS_PARAM)
+{
+ STATUS(float_exception_flags) = val;
+}
+INLINE void set_floatx80_rounding_precision(int val STATUS_PARAM)
+{
+ STATUS(floatx80_rounding_precision) = val;
+}
INLINE void set_flush_to_zero(flag val STATUS_PARAM)
{
STATUS(flush_to_zero) = val;
@@ -198,11 +208,34 @@ INLINE void set_default_nan_mode(flag val STATUS_PARAM)
{
STATUS(default_nan_mode) = val;
}
+INLINE int get_float_detect_tininess(float_status *status)
+{
+ return STATUS(float_detect_tininess);
+}
+INLINE int get_float_rounding_mode(float_status *status)
+{
+ return STATUS(float_rounding_mode);
+}
INLINE int get_float_exception_flags(float_status *status)
{
return STATUS(float_exception_flags);
}
-void set_floatx80_rounding_precision(int val STATUS_PARAM);
+INLINE int get_floatx80_rounding_precision(float_status *status)
+{
+ return STATUS(floatx80_rounding_precision);
+}
+INLINE flag get_flush_to_zero(float_status *status)
+{
+ return STATUS(flush_to_zero);
+}
+INLINE flag get_flush_inputs_to_zero(float_status *status)
+{
+ return STATUS(flush_inputs_to_zero);
+}
+INLINE flag get_default_nan_mode(float_status *status)
+{
+ return STATUS(default_nan_mode);
+}
/*----------------------------------------------------------------------------
| Routine to raise any or all of the software IEC/IEEE floating-point
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 12/22] softfloat: Factor out RoundAndPackFloat16 and NormalizeFloat16Subnormal
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (10 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 11/22] softfloat: Provide complete set of accessors for fp state Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 13/22] softfloat: Add float16 <=> float64 conversion functions Peter Maydell
` (10 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
In preparation for adding conversions between float16 and float64,
factor out code currently done inline in the float16<=>float32
conversion functions into functions RoundAndPackFloat16 and
NormalizeFloat16Subnormal along the lines of the existing versions
for the other float types.
Note that we change the handling of zExp from the inline code
to match the API of the other RoundAndPackFloat functions; however
we leave the positioning of the binary point between bits 22 and 23
rather than shifting it up to the high end of the word.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 209 +++++++++++++++++++++++++++++++++-----------------------
1 file changed, 125 insertions(+), 84 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 495f46f..925db05 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3084,6 +3084,127 @@ static float16 packFloat16(flag zSign, int_fast16_t zExp, uint16_t zSig)
(((uint32_t)zSign) << 15) + (((uint32_t)zExp) << 10) + zSig);
}
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+| and significand `zSig', and returns the proper half-precision floating-
+| point value corresponding to the abstract input. Ordinarily, the abstract
+| value is simply rounded and packed into the half-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 half-
+| precision floating-point number.
+| The `ieee' flag indicates whether to use IEEE standard half precision, or
+| ARM-style "alternative representation", which omits the NaN and Inf
+| encodings in order to raise the maximum representable exponent by one.
+| The input significand `zSig' has its binary point between bits 22
+| and 23, which is 13 bits to the left of the usual location. This shifted
+| significand must be normalized or smaller. If `zSig' is not normalized,
+| `zExp' must be 0; in that case, the result returned is a subnormal number,
+| and it must not require rounding. In the usual case that `zSig' is
+| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
+| Note the slightly odd position of the binary point in zSig compared with the
+| other roundAndPackFloat functions. This should probably be fixed if we
+| need to implement more float16 routines than just conversion.
+| The handling of underflow and overflow follows the IEC/IEEE Standard for
+| Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+static float32 roundAndPackFloat16(flag zSign, int_fast16_t zExp,
+ uint32_t zSig, flag ieee STATUS_PARAM)
+{
+ int maxexp = ieee ? 29 : 30;
+ uint32_t mask;
+ uint32_t increment;
+ int8 roundingMode;
+ bool rounding_bumps_exp;
+ bool is_tiny = false;
+
+ /* Calculate the mask of bits of the mantissa which are not
+ * representable in half-precision and will be lost.
+ */
+ if (zExp < 1) {
+ /* Will be denormal in halfprec */
+ mask = 0x00ffffff;
+ if (zExp >= -11) {
+ mask >>= 11 + zExp;
+ }
+ } else {
+ /* Normal number in halfprec */
+ mask = 0x00001fff;
+ }
+
+ roundingMode = STATUS(float_rounding_mode);
+ switch (roundingMode) {
+ case float_round_nearest_even:
+ increment = (mask + 1) >> 1;
+ if ((zSig & mask) == increment) {
+ increment = zSig & (increment << 1);
+ }
+ break;
+ case float_round_up:
+ increment = zSign ? 0 : mask;
+ break;
+ case float_round_down:
+ increment = zSign ? mask : 0;
+ break;
+ default: /* round_to_zero */
+ increment = 0;
+ break;
+ }
+
+ rounding_bumps_exp = (zSig + increment >= 0x01000000);
+
+ if (zExp > maxexp || (zExp == maxexp && rounding_bumps_exp)) {
+ if (ieee) {
+ float_raise(float_flag_overflow | float_flag_inexact STATUS_VAR);
+ return packFloat16(zSign, 0x1f, 0);
+ } else {
+ float_raise(float_flag_invalid STATUS_VAR);
+ return packFloat16(zSign, 0x1f, 0x3ff);
+ }
+ }
+
+ if (zExp < 0) {
+ /* Note that flush-to-zero does not affect half-precision results */
+ is_tiny =
+ (STATUS(float_detect_tininess) == float_tininess_before_rounding)
+ || (zExp < -1)
+ || (!rounding_bumps_exp);
+ }
+ if (zSig & mask) {
+ float_raise(float_flag_inexact STATUS_VAR);
+ if (is_tiny) {
+ float_raise(float_flag_underflow STATUS_VAR);
+ }
+ }
+
+ zSig += increment;
+ if (rounding_bumps_exp) {
+ zSig >>= 1;
+ zExp++;
+ }
+
+ if (zExp < -10) {
+ return packFloat16(zSign, 0, 0);
+ }
+ if (zExp < 0) {
+ zSig >>= -zExp;
+ zExp = 0;
+ }
+ return packFloat16(zSign, zExp, zSig >> 13);
+}
+
+static void normalizeFloat16Subnormal(uint32_t aSig, int_fast16_t *zExpPtr,
+ uint32_t *zSigPtr)
+{
+ int8_t shiftCount = countLeadingZeros32(aSig) - 21;
+ *zSigPtr = aSig << shiftCount;
+ *zExpPtr = 1 - shiftCount;
+}
+
/* Half precision floats come in two formats: standard IEEE and "ARM" format.
The latter gains extra exponent range by omitting the NaN/Inf encodings. */
@@ -3104,15 +3225,12 @@ float32 float16_to_float32(float16 a, flag ieee STATUS_PARAM)
return packFloat32(aSign, 0xff, 0);
}
if (aExp == 0) {
- int8 shiftCount;
-
if (aSig == 0) {
return packFloat32(aSign, 0, 0);
}
- shiftCount = countLeadingZeros32( aSig ) - 21;
- aSig = aSig << shiftCount;
- aExp = -shiftCount;
+ normalizeFloat16Subnormal(aSig, &aExp, &aSig);
+ aExp--;
}
return packFloat32( aSign, aExp + 0x70, aSig << 13);
}
@@ -3122,12 +3240,6 @@ float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
flag aSign;
int_fast16_t aExp;
uint32_t aSig;
- uint32_t mask;
- uint32_t increment;
- int8 roundingMode;
- int maxexp = ieee ? 15 : 16;
- bool rounding_bumps_exp;
- bool is_tiny = false;
a = float32_squash_input_denormal(a STATUS_VAR);
@@ -3162,80 +3274,9 @@ float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
* codepath.
*/
aSig |= 0x00800000;
- aExp -= 0x7f;
- /* Calculate the mask of bits of the mantissa which are not
- * representable in half-precision and will be lost.
- */
- if (aExp < -14) {
- /* Will be denormal in halfprec */
- mask = 0x00ffffff;
- if (aExp >= -24) {
- mask >>= 25 + aExp;
- }
- } else {
- /* Normal number in halfprec */
- mask = 0x00001fff;
- }
+ aExp -= 0x71;
- roundingMode = STATUS(float_rounding_mode);
- switch (roundingMode) {
- case float_round_nearest_even:
- increment = (mask + 1) >> 1;
- if ((aSig & mask) == increment) {
- increment = aSig & (increment << 1);
- }
- break;
- case float_round_up:
- increment = aSign ? 0 : mask;
- break;
- case float_round_down:
- increment = aSign ? mask : 0;
- break;
- default: /* round_to_zero */
- increment = 0;
- break;
- }
-
- rounding_bumps_exp = (aSig + increment >= 0x01000000);
-
- if (aExp > maxexp || (aExp == maxexp && rounding_bumps_exp)) {
- if (ieee) {
- float_raise(float_flag_overflow | float_flag_inexact STATUS_VAR);
- return packFloat16(aSign, 0x1f, 0);
- } else {
- float_raise(float_flag_invalid STATUS_VAR);
- return packFloat16(aSign, 0x1f, 0x3ff);
- }
- }
-
- if (aExp < -14) {
- /* Note that flush-to-zero does not affect half-precision results */
- is_tiny =
- (STATUS(float_detect_tininess) == float_tininess_before_rounding)
- || (aExp < -15)
- || (!rounding_bumps_exp);
- }
- if (aSig & mask) {
- float_raise(float_flag_inexact STATUS_VAR);
- if (is_tiny) {
- float_raise(float_flag_underflow STATUS_VAR);
- }
- }
-
- aSig += increment;
- if (rounding_bumps_exp) {
- aSig >>= 1;
- aExp++;
- }
-
- if (aExp < -24) {
- return packFloat16(aSign, 0, 0);
- }
- if (aExp < -14) {
- aSig >>= -14 - aExp;
- aExp = -14;
- }
- return packFloat16(aSign, aExp + 14, aSig >> 13);
+ return roundAndPackFloat16(aSign, aExp, aSig, ieee STATUS_VAR);
}
/*----------------------------------------------------------------------------
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 13/22] softfloat: Add float16 <=> float64 conversion functions
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (11 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 12/22] softfloat: Factor out RoundAndPackFloat16 and NormalizeFloat16Subnormal Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 14/22] softfloat: Add support for ties-away rounding Peter Maydell
` (9 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
Add the conversion functions float16_to_float64() and
float64_to_float16(), which will be needed for the ARM
A64 instruction set.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
include/fpu/softfloat.h | 2 ++
2 files changed, 77 insertions(+)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 925db05..623a4b9 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3279,6 +3279,81 @@ float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
return roundAndPackFloat16(aSign, aExp, aSig, ieee STATUS_VAR);
}
+float64 float16_to_float64(float16 a, flag ieee STATUS_PARAM)
+{
+ flag aSign;
+ int_fast16_t aExp;
+ uint32_t aSig;
+
+ aSign = extractFloat16Sign(a);
+ aExp = extractFloat16Exp(a);
+ aSig = extractFloat16Frac(a);
+
+ if (aExp == 0x1f && ieee) {
+ if (aSig) {
+ return commonNaNToFloat64(
+ float16ToCommonNaN(a STATUS_VAR) STATUS_VAR);
+ }
+ return packFloat64(aSign, 0x7ff, 0);
+ }
+ if (aExp == 0) {
+ if (aSig == 0) {
+ return packFloat64(aSign, 0, 0);
+ }
+
+ normalizeFloat16Subnormal(aSig, &aExp, &aSig);
+ aExp--;
+ }
+ return packFloat64(aSign, aExp + 0x3f0, ((uint64_t)aSig) << 42);
+}
+
+float16 float64_to_float16(float64 a, flag ieee STATUS_PARAM)
+{
+ flag aSign;
+ int_fast16_t aExp;
+ uint64_t aSig;
+ uint32_t zSig;
+
+ a = float64_squash_input_denormal(a STATUS_VAR);
+
+ aSig = extractFloat64Frac(a);
+ aExp = extractFloat64Exp(a);
+ aSign = extractFloat64Sign(a);
+ if (aExp == 0x7FF) {
+ if (aSig) {
+ /* Input is a NaN */
+ if (!ieee) {
+ float_raise(float_flag_invalid STATUS_VAR);
+ return packFloat16(aSign, 0, 0);
+ }
+ return commonNaNToFloat16(
+ float64ToCommonNaN(a STATUS_VAR) STATUS_VAR);
+ }
+ /* Infinity */
+ if (!ieee) {
+ float_raise(float_flag_invalid STATUS_VAR);
+ return packFloat16(aSign, 0x1f, 0x3ff);
+ }
+ return packFloat16(aSign, 0x1f, 0);
+ }
+ shift64RightJamming(aSig, 29, &aSig);
+ zSig = aSig;
+ if (aExp == 0 && zSig == 0) {
+ return packFloat16(aSign, 0, 0);
+ }
+ /* Decimal point between bits 22 and 23. Note that we add the 1 bit
+ * even if the input is denormal; however this is harmless because
+ * the largest possible single-precision denormal is still smaller
+ * than the smallest representable half-precision denormal, and so we
+ * will end up ignoring aSig and returning via the "always return zero"
+ * codepath.
+ */
+ zSig |= 0x00800000;
+ aExp -= 0x3F1;
+
+ return roundAndPackFloat16(aSign, aExp, zSig, ieee STATUS_VAR);
+}
+
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the extended double-precision floating-point format. The conversion
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index b8d2b30..08c7559 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -294,6 +294,8 @@ INLINE float64 uint16_to_float64(uint_fast16_t v STATUS_PARAM)
*----------------------------------------------------------------------------*/
float16 float32_to_float16( float32, flag STATUS_PARAM );
float32 float16_to_float32( float16, flag STATUS_PARAM );
+float16 float64_to_float16(float64 a, flag ieee STATUS_PARAM);
+float64 float16_to_float64(float16 a, flag ieee STATUS_PARAM);
/*----------------------------------------------------------------------------
| Software half-precision operations.
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 14/22] softfloat: Add support for ties-away rounding
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (12 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 13/22] softfloat: Add float16 <=> float64 conversion functions Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 14:51 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 15/22] target-arm: Prepare VFP_CONV_FIX helpers for A64 uses Peter Maydell
` (8 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
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 | 68 ++++++++++++++++++++++++++++++++++++-------------
include/fpu/softfloat.h | 3 ++-
2 files changed, 53 insertions(+), 18 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 623a4b9..ce7970f 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -107,7 +107,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
roundingMode = STATUS(float_rounding_mode);
roundNearestEven = ( roundingMode == float_round_nearest_even );
roundIncrement = 0x40;
- if ( ! roundNearestEven ) {
+ if (!roundNearestEven && roundingMode != float_round_ties_away) {
if ( roundingMode == float_round_to_zero ) {
roundIncrement = 0;
}
@@ -155,7 +155,7 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU
roundingMode = STATUS(float_rounding_mode);
roundNearestEven = ( roundingMode == float_round_nearest_even );
increment = ( (int64_t) absZ1 < 0 );
- if ( ! roundNearestEven ) {
+ if (!roundNearestEven && roundingMode != float_round_ties_away) {
if ( roundingMode == float_round_to_zero ) {
increment = 0;
}
@@ -206,7 +206,7 @@ static int64 roundAndPackUint64(flag zSign, uint64_t absZ0,
roundingMode = STATUS(float_rounding_mode);
roundNearestEven = (roundingMode == float_round_nearest_even);
increment = ((int64_t)absZ1 < 0);
- if (!roundNearestEven) {
+ if (!roundNearestEven && roundingMode != float_round_ties_away) {
if (roundingMode == float_round_to_zero) {
increment = 0;
} else if (absZ1) {
@@ -354,7 +354,7 @@ static float32 roundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig
roundingMode = STATUS(float_rounding_mode);
roundNearestEven = ( roundingMode == float_round_nearest_even );
roundIncrement = 0x40;
- if ( ! roundNearestEven ) {
+ if (!roundNearestEven && roundingMode != float_round_ties_away) {
if ( roundingMode == float_round_to_zero ) {
roundIncrement = 0;
}
@@ -536,7 +536,7 @@ static float64 roundAndPackFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig
roundingMode = STATUS(float_rounding_mode);
roundNearestEven = ( roundingMode == float_round_nearest_even );
roundIncrement = 0x200;
- if ( ! roundNearestEven ) {
+ if (!roundNearestEven && roundingMode != float_round_ties_away) {
if ( roundingMode == float_round_to_zero ) {
roundIncrement = 0;
}
@@ -718,7 +718,7 @@ static floatx80
goto precision80;
}
zSig0 |= ( zSig1 != 0 );
- if ( ! roundNearestEven ) {
+ if (!roundNearestEven && roundingMode != float_round_ties_away) {
if ( roundingMode == float_round_to_zero ) {
roundIncrement = 0;
}
@@ -1029,7 +1029,7 @@ static float128
roundingMode = STATUS(float_rounding_mode);
roundNearestEven = ( roundingMode == float_round_nearest_even );
increment = ( (int64_t) zSig2 < 0 );
- if ( ! roundNearestEven ) {
+ if (!roundNearestEven && roundingMode != float_round_ties_away) {
if ( roundingMode == float_round_to_zero ) {
increment = 0;
}
@@ -1756,6 +1756,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:
@@ -1771,8 +1776,9 @@ float32 float32_round_to_int( float32 a STATUS_PARAM)
if ( roundingMode == float_round_nearest_even ) {
z += lastBitMask>>1;
if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
+ } else if (roundingMode == float_round_ties_away) {
+ z += lastBitMask >> 1;
+ } else if (roundingMode != float_round_to_zero) {
if ( extractFloat32Sign( make_float32(z) ) ^ ( roundingMode == float_round_up ) ) {
z += roundBitsMask;
}
@@ -3144,6 +3150,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;
@@ -3449,6 +3458,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:
@@ -3465,8 +3479,9 @@ float64 float64_round_to_int( float64 a STATUS_PARAM )
if ( roundingMode == float_round_nearest_even ) {
z += lastBitMask>>1;
if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
+ } else if (roundingMode == float_round_ties_away) {
+ z += lastBitMask >> 1;
+ } else if (roundingMode != float_round_to_zero) {
if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) {
z += roundBitsMask;
}
@@ -4722,6 +4737,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 ?
@@ -4742,8 +4762,9 @@ floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
if ( roundingMode == float_round_nearest_even ) {
z.low += lastBitMask>>1;
if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
- }
- else if ( roundingMode != float_round_to_zero ) {
+ } else if (roundingMode == float_round_ties_away) {
+ z.low += lastBitMask >> 1;
+ } else if (roundingMode != float_round_to_zero) {
if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
z.low += roundBitsMask;
}
@@ -5801,8 +5822,15 @@ float128 float128_round_to_int( float128 a STATUS_PARAM )
if ( (uint64_t) ( z.low<<1 ) == 0 ) z.high &= ~1;
}
}
- }
- else if ( roundingMode != float_round_to_zero ) {
+ } else if (roundingMode == 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;
+ }
+ }
+ } else if (roundingMode != float_round_to_zero) {
if ( extractFloat128Sign( z )
^ ( roundingMode == float_round_up ) ) {
add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
@@ -5824,6 +5852,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 )
@@ -5846,8 +5879,9 @@ float128 float128_round_to_int( float128 a STATUS_PARAM )
if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
z.high &= ~ lastBitMask;
}
- }
- else if ( roundingMode != float_round_to_zero ) {
+ } else if (roundingMode == float_round_ties_away) {
+ z.high += lastBitMask>>1;
+ } else if (roundingMode != float_round_to_zero) {
if ( extractFloat128Sign( z )
^ ( roundingMode == float_round_up ) ) {
z.high |= ( a.low != 0 );
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 08c7559..7f50d4f 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
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 15/22] target-arm: Prepare VFP_CONV_FIX helpers for A64 uses
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (13 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 14/22] softfloat: Add support for ties-away rounding Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 15:00 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 16/22] target-arm: Rename A32 VFP conversion helpers Peter Maydell
` (7 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Will Newton <will.newton@linaro.org>
Make the VFP_CONV_FIX helpers a little more flexible in
preparation for the A64 uses. This requires two changes:
* use the correct softfloat conversion function based on itype
rather than always the int32 one; this is possible now that
softfloat provides int16 versions and necessary for the
future conversion-to-int64 A64 variants. This also allows
us to drop the awkward 'sign' macro argument.
* split the 'fsz' argument which currently controls both
width of the input float type and width of the output
integer type into two; this will allow us to specify the
A64 64-bit-int-to-single conversion function, where the
two widths are different.
Signed-off-by: Will Newton <will.newton@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index b157c55..ba54f74 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3984,17 +3984,17 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
}
/* VFP3 fixed point conversion. */
-#define VFP_CONV_FIX(name, p, fsz, itype, sign) \
-float##fsz HELPER(vfp_##name##to##p)(uint##fsz##_t x, uint32_t shift, \
- void *fpstp) \
+#define VFP_CONV_FIX(name, p, fsz, isz, itype) \
+float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
+ void *fpstp) \
{ \
float_status *fpst = fpstp; \
float##fsz tmp; \
- tmp = sign##int32_to_##float##fsz((itype##_t)x, fpst); \
+ tmp = itype##_to_##float##fsz((itype##_t)x, fpst); \
return float##fsz##_scalbn(tmp, -(int)shift, fpst); \
} \
-uint##fsz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
- void *fpstp) \
+uint##isz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
+ void *fpstp) \
{ \
float_status *fpst = fpstp; \
float##fsz tmp; \
@@ -4006,14 +4006,14 @@ uint##fsz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \
}
-VFP_CONV_FIX(sh, d, 64, int16, )
-VFP_CONV_FIX(sl, d, 64, int32, )
-VFP_CONV_FIX(uh, d, 64, uint16, u)
-VFP_CONV_FIX(ul, d, 64, uint32, u)
-VFP_CONV_FIX(sh, s, 32, int16, )
-VFP_CONV_FIX(sl, s, 32, int32, )
-VFP_CONV_FIX(uh, s, 32, uint16, u)
-VFP_CONV_FIX(ul, s, 32, uint32, u)
+VFP_CONV_FIX(sh, d, 64, 64, int16)
+VFP_CONV_FIX(sl, d, 64, 64, int32)
+VFP_CONV_FIX(uh, d, 64, 64, uint16)
+VFP_CONV_FIX(ul, d, 64, 64, uint32)
+VFP_CONV_FIX(sh, s, 32, 32, int16)
+VFP_CONV_FIX(sl, s, 32, 32, int32)
+VFP_CONV_FIX(uh, s, 32, 32, uint16)
+VFP_CONV_FIX(ul, s, 32, 32, uint32)
#undef VFP_CONV_FIX
/* Half precision conversions. */
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 16/22] target-arm: Rename A32 VFP conversion helpers
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (14 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 15/22] target-arm: Prepare VFP_CONV_FIX helpers for A64 uses Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 15:04 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 17/22] target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion Peter Maydell
` (6 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Will Newton <will.newton@linaro.org>
The VFP conversion helpers for A32 round to zero as this is the only
rounding mode supported. Rename these helpers to make it clear that
they round to zero and are not suitable for use in the AArch64 code.
Signed-off-by: Will Newton <will.newton@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 19 ++++++++++++++-----
target-arm/helper.h | 16 ++++++++--------
target-arm/translate.c | 24 +++++++++++++-----------
3 files changed, 35 insertions(+), 24 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index ba54f74..a9b0927 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3984,7 +3984,7 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
}
/* VFP3 fixed point conversion. */
-#define VFP_CONV_FIX(name, p, fsz, isz, itype) \
+#define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
void *fpstp) \
{ \
@@ -3992,9 +3992,12 @@ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
float##fsz tmp; \
tmp = itype##_to_##float##fsz((itype##_t)x, fpst); \
return float##fsz##_scalbn(tmp, -(int)shift, fpst); \
-} \
-uint##isz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
- void *fpstp) \
+}
+
+#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \
+uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \
+ uint32_t shift, \
+ void *fpstp) \
{ \
float_status *fpst = fpstp; \
float##fsz tmp; \
@@ -4003,9 +4006,13 @@ uint##isz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
return 0; \
} \
tmp = float##fsz##_scalbn(x, shift, fpst); \
- return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \
+ return float##fsz##_to_##itype##round(tmp, fpst); \
}
+#define VFP_CONV_FIX(name, p, fsz, isz, itype) \
+VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero)
+
VFP_CONV_FIX(sh, d, 64, 64, int16)
VFP_CONV_FIX(sl, d, 64, 64, int32)
VFP_CONV_FIX(uh, d, 64, 64, uint16)
@@ -4015,6 +4022,8 @@ VFP_CONV_FIX(sl, s, 32, 32, int32)
VFP_CONV_FIX(uh, s, 32, 32, uint16)
VFP_CONV_FIX(ul, s, 32, 32, uint32)
#undef VFP_CONV_FIX
+#undef VFP_CONV_FIX_FLOAT
+#undef VFP_CONV_FLOAT_FIX_ROUND
/* Half precision conversions. */
static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s)
diff --git a/target-arm/helper.h b/target-arm/helper.h
index dd1160e..b785623 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -115,14 +115,14 @@ DEF_HELPER_2(vfp_tosid, i32, f64, ptr)
DEF_HELPER_2(vfp_tosizs, i32, f32, ptr)
DEF_HELPER_2(vfp_tosizd, i32, f64, ptr)
-DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
-DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
-DEF_HELPER_3(vfp_touhs, i32, f32, i32, ptr)
-DEF_HELPER_3(vfp_touls, i32, f32, i32, ptr)
-DEF_HELPER_3(vfp_toshd, i64, f64, i32, ptr)
-DEF_HELPER_3(vfp_tosld, i64, f64, i32, ptr)
-DEF_HELPER_3(vfp_touhd, i64, f64, i32, ptr)
-DEF_HELPER_3(vfp_tould, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_toshs_round_to_zero, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_tosls_round_to_zero, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_touhs_round_to_zero, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_touls_round_to_zero, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_toshd_round_to_zero, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_tosld_round_to_zero, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_shtos, f32, i32, i32, ptr)
DEF_HELPER_3(vfp_sltos, f32, i32, i32, ptr)
DEF_HELPER_3(vfp_uhtos, f32, i32, i32, ptr)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index d04fc9f..8d240e1 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -1098,27 +1098,29 @@ VFP_GEN_FTOI(tosi)
VFP_GEN_FTOI(tosiz)
#undef VFP_GEN_FTOI
-#define VFP_GEN_FIX(name) \
+#define VFP_GEN_FIX(name, round) \
static inline void gen_vfp_##name(int dp, int shift, int neon) \
{ \
TCGv_i32 tmp_shift = tcg_const_i32(shift); \
TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
if (dp) { \
- gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
+ gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
+ statusptr); \
} else { \
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
+ gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
+ statusptr); \
} \
tcg_temp_free_i32(tmp_shift); \
tcg_temp_free_ptr(statusptr); \
}
-VFP_GEN_FIX(tosh)
-VFP_GEN_FIX(tosl)
-VFP_GEN_FIX(touh)
-VFP_GEN_FIX(toul)
-VFP_GEN_FIX(shto)
-VFP_GEN_FIX(slto)
-VFP_GEN_FIX(uhto)
-VFP_GEN_FIX(ulto)
+VFP_GEN_FIX(tosh, _round_to_zero)
+VFP_GEN_FIX(tosl, _round_to_zero)
+VFP_GEN_FIX(touh, _round_to_zero)
+VFP_GEN_FIX(toul, _round_to_zero)
+VFP_GEN_FIX(shto, )
+VFP_GEN_FIX(slto, )
+VFP_GEN_FIX(uhto, )
+VFP_GEN_FIX(ulto, )
#undef VFP_GEN_FIX
static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 17/22] target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (15 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 16/22] target-arm: Rename A32 VFP conversion helpers Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 15:17 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 18/22] target-arm: A64: Add extra VFP fixed point conversion helpers Peter Maydell
` (5 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
The VFP fixed point conversion helpers first call float_scalbn and
then convert the result to an integer. This scalbn operation may
set floating point exception flags for:
* overflow & inexact (if it overflows to infinity)
* input denormal squashed to zero
* output denormal squashed to zero
Of these, we only care about the input-denormal flag, since
the output of the whole scale-and-convert operation will be
an integer (so squashed-output-denormal and overflow don't
apply). Suppress the others by saving the pre-scalb exception
flags and only copying across a potential input-denormal flag.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index a9b0927..67dc212 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3994,18 +3994,27 @@ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
return float##fsz##_scalbn(tmp, -(int)shift, fpst); \
}
+/* Notice that we want only input-denormal exception flags from the
+ * scalbn operation: the other possible flags (overflow+inexact if
+ * we overflow to infinity, output-denormal) aren't correct for the
+ * complete scale-and-convert operation.
+ */
#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \
uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \
uint32_t shift, \
void *fpstp) \
{ \
float_status *fpst = fpstp; \
+ int old_exc_flags = get_float_exception_flags(fpst); \
float##fsz tmp; \
if (float##fsz##_is_any_nan(x)) { \
float_raise(float_flag_invalid, fpst); \
return 0; \
} \
tmp = float##fsz##_scalbn(x, shift, fpst); \
+ old_exc_flags |= get_float_exception_flags(fpst) \
+ & float_flag_input_denormal; \
+ set_float_exception_flags(old_exc_flags, fpst); \
return float##fsz##_to_##itype##round(tmp, fpst); \
}
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 18/22] target-arm: A64: Add extra VFP fixed point conversion helpers
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (16 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 17/22] target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 15:18 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 19/22] target-arm: A64: Add "Floating-point<->fixed-point" instructions Peter Maydell
` (4 subsequent siblings)
22 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Will Newton <will.newton@linaro.org>
Define the full set of floating point to fixed point conversion
helpers required to support AArch64.
Signed-off-by: Will Newton <will.newton@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 11 ++++++++++-
target-arm/helper.h | 16 ++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 67dc212..7736d4b 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4020,16 +4020,25 @@ uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \
#define VFP_CONV_FIX(name, p, fsz, isz, itype) \
VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
-VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero)
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, _round_to_zero) \
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, )
+
+#define VFP_CONV_FIX_A64(name, p, fsz, isz, itype) \
+VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, )
VFP_CONV_FIX(sh, d, 64, 64, int16)
VFP_CONV_FIX(sl, d, 64, 64, int32)
+VFP_CONV_FIX_A64(sq, d, 64, 64, int64)
VFP_CONV_FIX(uh, d, 64, 64, uint16)
VFP_CONV_FIX(ul, d, 64, 64, uint32)
+VFP_CONV_FIX_A64(uq, d, 64, 64, uint64)
VFP_CONV_FIX(sh, s, 32, 32, int16)
VFP_CONV_FIX(sl, s, 32, 32, int32)
+VFP_CONV_FIX_A64(sq, s, 32, 64, int64)
VFP_CONV_FIX(uh, s, 32, 32, uint16)
VFP_CONV_FIX(ul, s, 32, 32, uint32)
+VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
#undef VFP_CONV_FIX
#undef VFP_CONV_FIX_FLOAT
#undef VFP_CONV_FLOAT_FIX_ROUND
diff --git a/target-arm/helper.h b/target-arm/helper.h
index b785623..2e1af46 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -123,14 +123,30 @@ DEF_HELPER_3(vfp_toshd_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_tosld_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
+DEF_HELPER_3(vfp_touhs, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_touls, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_touqs, i64, f32, i32, ptr)
+DEF_HELPER_3(vfp_toshd, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_tosld, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_tosqd, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_touhd, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_tould, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_touqd, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_shtos, f32, i32, i32, ptr)
DEF_HELPER_3(vfp_sltos, f32, i32, i32, ptr)
+DEF_HELPER_3(vfp_sqtos, f32, i64, i32, ptr)
DEF_HELPER_3(vfp_uhtos, f32, i32, i32, ptr)
DEF_HELPER_3(vfp_ultos, f32, i32, i32, ptr)
+DEF_HELPER_3(vfp_uqtos, f32, i64, i32, ptr)
DEF_HELPER_3(vfp_shtod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_sltod, f64, i64, i32, ptr)
+DEF_HELPER_3(vfp_sqtod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
+DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env)
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 19/22] target-arm: A64: Add "Floating-point<->fixed-point" instructions
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (17 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 18/22] target-arm: A64: Add extra VFP fixed point conversion helpers Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 20/22] target-arm: A64: Add floating-point<->integer conversion instructions Peter Maydell
` (3 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Alexander Graf <agraf@suse.de>
This patch adds emulation for the instruction group labeled
"Floating-point <-> fixed-point conversions" in the ARM ARM.
Namely this includes the instructions SCVTF, UCVTF, FCVTZS, FCVTZU
(scalar, fixed-point).
Signed-off-by: Alexander Graf <agraf@suse.de>
[WN: Commit message tweak, rebased, updated to new infrastructure.
Applied bug fixes from Michael Matz and Janne Grunau.]
Signed-off-by: Will Newton <will.newton@linaro.org>
[PMM: significant cleanup]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 13 ++++
target-arm/helper.h | 2 +
target-arm/translate-a64.c | 186 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 200 insertions(+), 1 deletion(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7736d4b..5b5f24e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4043,6 +4043,19 @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
#undef VFP_CONV_FIX_FLOAT
#undef VFP_CONV_FLOAT_FIX_ROUND
+/* Set the current fp rounding mode and return the old one.
+ * The argument is a softfloat float_round_ value.
+ */
+uint32_t HELPER(set_rmode)(uint32_t rmode, CPUARMState *env)
+{
+ float_status *fp_status = &env->vfp.fp_status;
+
+ uint32_t prev_rmode = get_float_rounding_mode(fp_status);
+ set_float_rounding_mode(rmode, fp_status);
+
+ return prev_rmode;
+}
+
/* Half precision conversions. */
static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s)
{
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 2e1af46..25b6b4f 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -148,6 +148,8 @@ DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
+DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, env)
+
DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env)
DEF_HELPER_2(neon_fcvt_f16_to_f32, f32, i32, env)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index c9fbf0f..ec8abc7 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -3186,6 +3186,34 @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
}
}
+/* Convert ARM rounding mode to softfloat */
+static inline int arm_rmode_to_sf(int rmode)
+{
+ switch (rmode) {
+ case FPROUNDING_TIEAWAY:
+ rmode = float_round_ties_away;
+ break;
+ case FPROUNDING_ODD:
+ /* FIXME: add support for TIEAWAY and ODD */
+ qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
+ rmode);
+ case FPROUNDING_TIEEVEN:
+ default:
+ rmode = float_round_nearest_even;
+ break;
+ case FPROUNDING_POSINF:
+ rmode = float_round_up;
+ break;
+ case FPROUNDING_NEGINF:
+ rmode = float_round_down;
+ break;
+ case FPROUNDING_ZERO:
+ rmode = float_round_to_zero;
+ break;
+ }
+ return rmode;
+}
+
static void handle_fp_compare(DisasContext *s, bool is_double,
unsigned int rn, unsigned int rm,
bool cmp_with_zero, bool signal_all_nans)
@@ -3651,6 +3679,132 @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_res);
}
+/* Handle floating point <=> fixed point conversions. Note that we can
+ * also deal with fp <=> integer conversions as a special case (scale == 64)
+ * OPTME: consider handling that special case specially or at least skipping
+ * the call to scalbn in the helpers for zero shifts.
+ */
+static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
+ bool itof, int rmode, int scale, int sf, int type)
+{
+ bool is_signed = !(opcode & 1);
+ bool is_double = type;
+ TCGv_ptr tcg_fpstatus;
+ TCGv_i32 tcg_shift;
+
+ tcg_fpstatus = get_fpstatus_ptr();
+
+ tcg_shift = tcg_const_i32(64 - scale);
+
+ if (itof) {
+ TCGv_i64 tcg_int = cpu_reg(s, rn);
+ if (!sf) {
+ TCGv_i64 tcg_extend = new_tmp_a64(s);
+
+ if (is_signed) {
+ tcg_gen_ext32s_i64(tcg_extend, tcg_int);
+ } else {
+ tcg_gen_ext32u_i64(tcg_extend, tcg_int);
+ }
+
+ tcg_int = tcg_extend;
+ }
+
+ if (is_double) {
+ TCGv_i64 tcg_double = tcg_temp_new_i64();
+ if (is_signed) {
+ gen_helper_vfp_sqtod(tcg_double, tcg_int,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_uqtod(tcg_double, tcg_int,
+ tcg_shift, tcg_fpstatus);
+ }
+ write_fp_dreg(s, rd, tcg_double);
+ tcg_temp_free_i64(tcg_double);
+ } else {
+ TCGv_i32 tcg_single = tcg_temp_new_i32();
+ if (is_signed) {
+ gen_helper_vfp_sqtos(tcg_single, tcg_int,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_uqtos(tcg_single, tcg_int,
+ tcg_shift, tcg_fpstatus);
+ }
+ write_fp_sreg(s, rd, tcg_single);
+ tcg_temp_free_i32(tcg_single);
+ }
+ } else {
+ TCGv_i64 tcg_int = cpu_reg(s, rd);
+ TCGv_i32 tcg_rmode;
+
+ if (extract32(opcode, 2, 1)) {
+ /* There are too many rounding modes to all fit into rmode,
+ * so FCVTA[US] is a special case.
+ */
+ rmode = FPROUNDING_TIEAWAY;
+ }
+
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
+
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+
+ if (is_double) {
+ TCGv_i64 tcg_double = read_fp_dreg(s, rn);
+ if (is_signed) {
+ if (!sf) {
+ gen_helper_vfp_tosld(tcg_int, tcg_double,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_tosqd(tcg_int, tcg_double,
+ tcg_shift, tcg_fpstatus);
+ }
+ } else {
+ if (!sf) {
+ gen_helper_vfp_tould(tcg_int, tcg_double,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_touqd(tcg_int, tcg_double,
+ tcg_shift, tcg_fpstatus);
+ }
+ }
+ tcg_temp_free_i64(tcg_double);
+ } else {
+ TCGv_i32 tcg_single = read_fp_sreg(s, rn);
+ if (sf) {
+ if (is_signed) {
+ gen_helper_vfp_tosqs(tcg_int, tcg_single,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_touqs(tcg_int, tcg_single,
+ tcg_shift, tcg_fpstatus);
+ }
+ } else {
+ TCGv_i32 tcg_dest = tcg_temp_new_i32();
+ if (is_signed) {
+ gen_helper_vfp_tosls(tcg_dest, tcg_single,
+ tcg_shift, tcg_fpstatus);
+ } else {
+ gen_helper_vfp_touls(tcg_dest, tcg_single,
+ tcg_shift, tcg_fpstatus);
+ }
+ tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
+ tcg_temp_free_i32(tcg_dest);
+ }
+ tcg_temp_free_i32(tcg_single);
+ }
+
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ tcg_temp_free_i32(tcg_rmode);
+
+ if (!sf) {
+ tcg_gen_ext32u_i64(tcg_int, tcg_int);
+ }
+ }
+
+ tcg_temp_free_ptr(tcg_fpstatus);
+ tcg_temp_free_i32(tcg_shift);
+}
+
/* C3.6.29 Floating point <-> fixed point conversions
* 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0
* +----+---+---+-----------+------+---+-------+--------+-------+------+------+
@@ -3659,7 +3813,37 @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
*/
static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
{
- unsupported_encoding(s, insn);
+ int rd = extract32(insn, 0, 5);
+ int rn = extract32(insn, 5, 5);
+ int scale = extract32(insn, 10, 6);
+ int opcode = extract32(insn, 16, 3);
+ int rmode = extract32(insn, 19, 2);
+ int type = extract32(insn, 22, 2);
+ bool sbit = extract32(insn, 29, 1);
+ bool sf = extract32(insn, 31, 1);
+ bool itof;
+
+ if (sbit || (type > 1)
+ || (!sf && scale < 32)) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ switch ((rmode << 3) | opcode) {
+ case 0x2: /* SCVTF */
+ case 0x3: /* UCVTF */
+ itof = true;
+ break;
+ case 0x18: /* FCVTZS */
+ case 0x19: /* FCVTZU */
+ itof = false;
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ handle_fpfpcvt(s, rd, rn, opcode, itof, FPROUNDING_ZERO, scale, sf, type);
}
static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 20/22] target-arm: A64: Add floating-point<->integer conversion instructions
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (18 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 19/22] target-arm: A64: Add "Floating-point<->fixed-point" instructions Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 21/22] target-arm: A64: Add 1-source 32-to-32 and 64-to-64 FP instructions Peter Maydell
` (2 subsequent siblings)
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
From: Will Newton <will.newton@linaro.org>
Add support for the AArch64 floating-point <-> integer conversion
instructions to disas_fpintconv. In the process we can rearrange
and simplify the detection of unallocated encodings a little.
We also correct a typo in the instruction encoding diagram for this
instruction group: bit 21 is 1, not 0.
Signed-off-by: Will Newton <will.newton@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/translate-a64.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index ec8abc7..9b23d37 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -3904,7 +3904,7 @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
/* C3.6.30 Floating point <-> integer conversions
* 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0
* +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
- * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
+ * | sf | 0 | S | 1 1 1 1 0 | type | 1 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
* +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
*/
static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
@@ -3917,10 +3917,20 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
bool sbit = extract32(insn, 29, 1);
bool sf = extract32(insn, 31, 1);
- if (!sbit && (rmode < 2) && (opcode > 5)) {
+ if (sbit) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (opcode > 5) {
/* FMOV */
bool itof = opcode & 1;
+ if (rmode >= 2) {
+ unallocated_encoding(s);
+ return;
+ }
+
switch (sf << 3 | type << 1 | rmode) {
case 0x0: /* 32 bit */
case 0xa: /* 64 bit */
@@ -3935,7 +3945,14 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
handle_fmov(s, rd, rn, type, itof);
} else {
/* actual FP conversions */
- unsupported_encoding(s, insn);
+ bool itof = extract32(opcode, 1, 1);
+
+ if (type > 1 || (rmode != 0 && opcode > 1)) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
}
}
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 21/22] target-arm: A64: Add 1-source 32-to-32 and 64-to-64 FP instructions
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (19 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 20/22] target-arm: A64: Add floating-point<->integer conversion instructions Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 22/22] target-arm: A64: Add support for FCVT between half, single and double Peter Maydell
2014-01-02 19:12 ` [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Tom Musta
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
This patch adds support for those instructions in the "Floating-point
data-processing (1 source)" group which are simple 32-bit-to-32-bit
or 64-bit-to-64-bit operations (ie everything except FCVT between
single/double/half precision).
We put the new round-to-int helpers in helper.c because they will
also be used by the new ARMv8 A32/T32 rounding instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
[WN: Commit message tweak, merged single and double precision patches,
updated to new infrastructure.]
Signed-off-by: Will Newton <will.newton@linaro.org>
[PMM: reworked decode, split FCVT out into their own patch]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 45 ++++++++++++++
target-arm/helper.h | 5 ++
target-arm/translate-a64.c | 142 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 191 insertions(+), 1 deletion(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5b5f24e..154ee4a 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4361,3 +4361,48 @@ float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp)
float_status *fpst = fpstp;
return float64_muladd(a, b, c, 0, fpst);
}
+
+/* ARMv8 round to integral */
+float32 HELPER(rints_exact)(float32 x, void *fp_status)
+{
+ return float32_round_to_int(x, fp_status);
+}
+
+float64 HELPER(rintd_exact)(float64 x, void *fp_status)
+{
+ return float64_round_to_int(x, fp_status);
+}
+
+float32 HELPER(rints)(float32 x, void *fp_status)
+{
+ int old_flags = get_float_exception_flags(fp_status), new_flags;
+ float32 ret;
+
+ ret = float32_round_to_int(x, fp_status);
+
+ /* Suppress any inexact exceptions the conversion produced */
+ if (!(old_flags & float_flag_inexact)) {
+ new_flags = get_float_exception_flags(fp_status);
+ set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
+ }
+
+ return ret;
+}
+
+float64 HELPER(rintd)(float64 x, void *fp_status)
+{
+ int old_flags = get_float_exception_flags(fp_status), new_flags;
+ float64 ret;
+
+ ret = float64_round_to_int(x, fp_status);
+
+ new_flags = get_float_exception_flags(fp_status);
+
+ /* Suppress any inexact exceptions the conversion produced */
+ if (!(old_flags & float_flag_inexact)) {
+ new_flags = get_float_exception_flags(fp_status);
+ set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
+ }
+
+ return ret;
+}
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 25b6b4f..832ec12 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -171,6 +171,11 @@ DEF_HELPER_3(shr_cc, i32, env, i32, i32)
DEF_HELPER_3(sar_cc, i32, env, i32, i32)
DEF_HELPER_3(ror_cc, i32, env, i32, i32)
+DEF_HELPER_FLAGS_2(rints_exact, TCG_CALL_NO_RWG_SE, f32, f32, ptr)
+DEF_HELPER_FLAGS_2(rintd_exact, TCG_CALL_NO_RWG_SE, f64, f64, ptr)
+DEF_HELPER_FLAGS_2(rints, TCG_CALL_NO_RWG_SE, f32, f32, ptr)
+DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG_SE, f64, f64, ptr)
+
/* neon_helper.c */
DEF_HELPER_3(neon_qadd_u8, i32, env, i32, i32)
DEF_HELPER_3(neon_qadd_s8, i32, env, i32, i32)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 9b23d37..345a47b 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -3386,6 +3386,118 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
}
}
+/* C3.6.25 Floating-point data-processing (1 source) - single precision */
+static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
+{
+ TCGv_ptr fpst;
+ TCGv_i32 tcg_op;
+ TCGv_i32 tcg_res;
+
+ fpst = get_fpstatus_ptr();
+ tcg_op = read_fp_sreg(s, rn);
+ tcg_res = tcg_temp_new_i32();
+
+ switch (opcode) {
+ case 0x0: /* FMOV */
+ tcg_gen_mov_i32(tcg_res, tcg_op);
+ break;
+ case 0x1: /* FABS */
+ gen_helper_vfp_abss(tcg_res, tcg_op);
+ break;
+ case 0x2: /* FNEG */
+ gen_helper_vfp_negs(tcg_res, tcg_op);
+ break;
+ case 0x3: /* FSQRT */
+ gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
+ break;
+ case 0x8: /* FRINTN */
+ case 0x9: /* FRINTP */
+ case 0xa: /* FRINTM */
+ case 0xb: /* FRINTZ */
+ case 0xc: /* FRINTA */
+ {
+ TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
+
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ gen_helper_rints(tcg_res, tcg_op, fpst);
+
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ tcg_temp_free_i32(tcg_rmode);
+ break;
+ }
+ case 0xe: /* FRINTX */
+ gen_helper_rints_exact(tcg_res, tcg_op, fpst);
+ break;
+ case 0xf: /* FRINTI */
+ gen_helper_rints(tcg_res, tcg_op, fpst);
+ break;
+ default:
+ abort();
+ }
+
+ write_fp_sreg(s, rd, tcg_res);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(tcg_op);
+ tcg_temp_free_i32(tcg_res);
+}
+
+/* C3.6.25 Floating-point data-processing (1 source) - double precision */
+static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
+{
+ TCGv_ptr fpst;
+ TCGv_i64 tcg_op;
+ TCGv_i64 tcg_res;
+
+ fpst = get_fpstatus_ptr();
+ tcg_op = read_fp_dreg(s, rn);
+ tcg_res = tcg_temp_new_i64();
+
+ switch (opcode) {
+ case 0x0: /* FMOV */
+ tcg_gen_mov_i64(tcg_res, tcg_op);
+ break;
+ case 0x1: /* FABS */
+ gen_helper_vfp_absd(tcg_res, tcg_op);
+ break;
+ case 0x2: /* FNEG */
+ gen_helper_vfp_negd(tcg_res, tcg_op);
+ break;
+ case 0x3: /* FSQRT */
+ gen_helper_vfp_sqrtd(tcg_res, tcg_op, cpu_env);
+ break;
+ case 0x8: /* FRINTN */
+ case 0x9: /* FRINTP */
+ case 0xa: /* FRINTM */
+ case 0xb: /* FRINTZ */
+ case 0xc: /* FRINTA */
+ {
+ TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
+
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ gen_helper_rintd(tcg_res, tcg_op, fpst);
+
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
+ tcg_temp_free_i32(tcg_rmode);
+ break;
+ }
+ case 0xe: /* FRINTX */
+ gen_helper_rintd_exact(tcg_res, tcg_op, fpst);
+ break;
+ case 0xf: /* FRINTI */
+ gen_helper_rintd(tcg_res, tcg_op, fpst);
+ break;
+ default:
+ abort();
+ }
+
+ write_fp_dreg(s, rd, tcg_res);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i64(tcg_op);
+ tcg_temp_free_i64(tcg_res);
+}
+
/* C3.6.25 Floating point data-processing (1 source)
* 31 30 29 28 24 23 22 21 20 15 14 10 9 5 4 0
* +---+---+---+-----------+------+---+--------+-----------+------+------+
@@ -3394,7 +3506,35 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
*/
static void disas_fp_1src(DisasContext *s, uint32_t insn)
{
- unsupported_encoding(s, insn);
+ int type = extract32(insn, 22, 2);
+ int opcode = extract32(insn, 15, 6);
+ int rn = extract32(insn, 5, 5);
+ int rd = extract32(insn, 0, 5);
+
+ switch (opcode) {
+ case 0x4: case 0x5: case 0x7:
+ /* FCVT between half, single and double precision */
+ unsupported_encoding(s, insn);
+ break;
+ case 0x0 ... 0x3:
+ case 0x8 ... 0xc:
+ case 0xe ... 0xf:
+ /* 32-to-32 and 64-to-64 ops */
+ switch (type) {
+ case 0:
+ handle_fp_1src_single(s, opcode, rd, rn);
+ break;
+ case 1:
+ handle_fp_1src_double(s, opcode, rd, rn);
+ break;
+ default:
+ unallocated_encoding(s);
+ }
+ break;
+ default:
+ unallocated_encoding(s);
+ break;
+ }
}
/* C3.6.26 Floating-point data-processing (2 source) - single precision */
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 22/22] target-arm: A64: Add support for FCVT between half, single and double
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (20 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 21/22] target-arm: A64: Add 1-source 32-to-32 and 64-to-64 FP instructions Peter Maydell
@ 2013-12-31 13:35 ` Peter Maydell
2014-01-02 19:12 ` [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Tom Musta
22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 13:35 UTC (permalink / raw)
To: qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall, Richard Henderson
Add support for FCVT between half, single and double precision.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 20 +++++++++++++
target-arm/helper.h | 2 ++
target-arm/translate-a64.c | 75 +++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 96 insertions(+), 1 deletion(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 154ee4a..4b91e1d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -4097,6 +4097,26 @@ uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUARMState *env)
return do_fcvt_f32_to_f16(a, env, &env->vfp.fp_status);
}
+float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, CPUARMState *env)
+{
+ int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
+ float64 r = float16_to_float64(make_float16(a), ieee, &env->vfp.fp_status);
+ if (ieee) {
+ return float64_maybe_silence_nan(r);
+ }
+ return r;
+}
+
+uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, CPUARMState *env)
+{
+ int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
+ float16 r = float64_to_float16(a, ieee, &env->vfp.fp_status);
+ if (ieee) {
+ r = float16_maybe_silence_nan(r);
+ }
+ return float16_val(r);
+}
+
#define float32_two make_float32(0x40000000)
#define float32_three make_float32(0x40400000)
#define float32_one_point_five make_float32(0x3fc00000)
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 832ec12..213ccc6 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -154,6 +154,8 @@ DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env)
DEF_HELPER_2(neon_fcvt_f16_to_f32, f32, i32, env)
DEF_HELPER_2(neon_fcvt_f32_to_f16, i32, f32, env)
+DEF_HELPER_FLAGS_2(vfp_fcvt_f16_to_f64, TCG_CALL_NO_RWG, f64, i32, env)
+DEF_HELPER_FLAGS_2(vfp_fcvt_f64_to_f16, TCG_CALL_NO_RWG, i32, f64, env)
DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 345a47b..cf80c46 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -3498,6 +3498,72 @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
tcg_temp_free_i64(tcg_res);
}
+static void handle_fp_fcvt(DisasContext *s, int opcode,
+ int rd, int rn, int dtype, int ntype)
+{
+ switch (ntype) {
+ case 0x0:
+ {
+ TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
+ if (dtype == 1) {
+ /* Single to double */
+ TCGv_i64 tcg_rd = tcg_temp_new_i64();
+ gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, cpu_env);
+ write_fp_dreg(s, rd, tcg_rd);
+ tcg_temp_free_i64(tcg_rd);
+ } else {
+ /* Single to half */
+ TCGv_i32 tcg_rd = tcg_temp_new_i32();
+ gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, cpu_env);
+ /* write_fp_sreg is OK here because top half of tcg_rd is zero */
+ write_fp_sreg(s, rd, tcg_rd);
+ tcg_temp_free_i32(tcg_rd);
+ }
+ tcg_temp_free_i32(tcg_rn);
+ break;
+ }
+ case 0x1:
+ {
+ TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
+ TCGv_i32 tcg_rd = tcg_temp_new_i32();
+ if (dtype == 0) {
+ /* Double to single */
+ gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, cpu_env);
+ } else {
+ /* Double to half */
+ gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, cpu_env);
+ /* write_fp_sreg is OK here because top half of tcg_rd is zero */
+ }
+ write_fp_sreg(s, rd, tcg_rd);
+ tcg_temp_free_i32(tcg_rd);
+ tcg_temp_free_i64(tcg_rn);
+ break;
+ }
+ case 0x3:
+ {
+ TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
+ tcg_gen_ext16u_i32(tcg_rn, tcg_rn);
+ if (dtype == 0) {
+ /* Half to single */
+ TCGv_i32 tcg_rd = tcg_temp_new_i32();
+ gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, cpu_env);
+ write_fp_sreg(s, rd, tcg_rd);
+ tcg_temp_free_i32(tcg_rd);
+ } else {
+ /* Half to double */
+ TCGv_i64 tcg_rd = tcg_temp_new_i64();
+ gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, cpu_env);
+ write_fp_dreg(s, rd, tcg_rd);
+ tcg_temp_free_i64(tcg_rd);
+ }
+ tcg_temp_free_i32(tcg_rn);
+ break;
+ }
+ default:
+ abort();
+ }
+}
+
/* C3.6.25 Floating point data-processing (1 source)
* 31 30 29 28 24 23 22 21 20 15 14 10 9 5 4 0
* +---+---+---+-----------+------+---+--------+-----------+------+------+
@@ -3513,9 +3579,16 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
switch (opcode) {
case 0x4: case 0x5: case 0x7:
+ {
/* FCVT between half, single and double precision */
- unsupported_encoding(s, insn);
+ int dtype = extract32(opcode, 0, 2);
+ if (type == 2 || dtype == type) {
+ unallocated_encoding(s);
+ return;
+ }
+ handle_fp_fcvt(s, opcode, rd, rn, dtype, type);
break;
+ }
case 0x0 ... 0x3:
case 0x8 ... 0xc:
case 0xe ... 0xf:
--
1.8.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 02/22] softfloat: Add float to 16bit integer conversions.
2013-12-31 13:35 ` [Qemu-devel] [PATCH 02/22] softfloat: Add float to 16bit integer conversions Peter Maydell
@ 2013-12-31 14:18 ` Richard Henderson
2013-12-31 14:22 ` Peter Maydell
0 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:18 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> + int64_t v;
> + int_fast16_t res;
> + int old_exc_flags = get_float_exception_flags(status);
> +
> + v = float32_to_int64(a STATUS_VAR);
Any good reason not to use int32 as the intermediate, for the benefit of 32-bit
hosts?
Otherwise,
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions
2013-12-31 13:35 ` [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions Peter Maydell
@ 2013-12-31 14:21 ` Richard Henderson
2013-12-31 14:27 ` Peter Maydell
0 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:21 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> +/* We provide the int16 versions for symmetry of API with float-to-int */
> +INLINE float32 int16_to_float32(int_fast16_t v STATUS_PARAM)
> +{
> + return int32_to_float32(v STATUS_VAR);
> +}
If you're going to have int16 versions, I don't think you should use
int_fast16_t, but rather int16_t so that we will properly truncate the incoming
value. Otherwise there's not much point in having these, IMO.
And please add blank lines between the functions.
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 02/22] softfloat: Add float to 16bit integer conversions.
2013-12-31 14:18 ` Richard Henderson
@ 2013-12-31 14:22 ` Peter Maydell
2013-12-31 14:29 ` Richard Henderson
0 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 14:22 UTC (permalink / raw)
To: Richard Henderson
Cc: Tom Musta, Peter Crosthwaite, Patch Tracking, Aurelien Jarno,
Michael Matz, Alexander Graf, QEMU Developers, Claudio Fontana,
Dirk Mueller, Will Newton, Laurent Desnogues, Alex Bennée,
kvmarm@lists.cs.columbia.edu, Christoffer Dall
On 31 December 2013 14:18, Richard Henderson <rth@twiddle.net> wrote:
> On 12/31/2013 05:35 AM, Peter Maydell wrote:
>> + int64_t v;
>> + int_fast16_t res;
>> + int old_exc_flags = get_float_exception_flags(status);
>> +
>> + v = float32_to_int64(a STATUS_VAR);
>
> Any good reason not to use int32 as the intermediate, for the benefit of 32-bit
> hosts?
You mean 'v'? Making v less than 64 bits will give wrong results
for input values which fit in a 64 bit int but not a 32 bit int, won't it?
Or do you mean we should call float32_to_int32() instead?
I think that ought to work...
thanks
-- PMM
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 08/22] softfloat: Fix float64_to_uint64_round_to_zero
2013-12-31 13:35 ` [Qemu-devel] [PATCH 08/22] softfloat: Fix float64_to_uint64_round_to_zero Peter Maydell
@ 2013-12-31 14:23 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:23 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> From: Tom Musta <tommusta@gmail.com>
>
> The float64_to_uint64_round_to_zero routine is incorrect.
>
> For example, the following test pattern:
>
> 46697351FF4AEC29 / 0x1.97351ff4aec29p+103
>
> currently produces 8000000000000000 instead of FFFFFFFFFFFFFFFF.
>
> This patch re-implements the routine to temporarily force the
> rounding mode and use the float64_to_uint64 routine.
>
> This contribution can be licensed under either the softfloat-2a or -2b
> license.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
> Message-id: 1387397961-4894-4-git-send-email-tommusta@gmail.com
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> fpu/softfloat.c | 12 +++++-------
> 1 file changed, 5 insertions(+), 7 deletions(-)
Perhaps a duplicate with Tom's thread, but:
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 09/22] softfloat: Fix float64_to_uint32
2013-12-31 13:35 ` [Qemu-devel] [PATCH 09/22] softfloat: Fix float64_to_uint32 Peter Maydell
@ 2013-12-31 14:24 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:24 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> From: Tom Musta <tommusta@gmail.com>
>
> The float64_to_uint32 has several flaws:
>
> - for numbers between 2**32 and 2**64, the inexact exception flag
> may get incorrectly set. In this case, only the invalid flag
> should be set.
>
> test pattern: 425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38
>
> - for numbers between 2**63 and 2**64, incorrect results may
> be produced:
>
> test pattern: 43EAAF73F1F0B8BD / 0x1.aaf73f1f0b8bdp+63
>
> This patch re-implements float64_to_uint32 to re-use the
> float64_to_uint64 routine (instead of float64_to_int64). For the
> saturation case, we ignore any flags which the conversion routine
> has set and raise only the invalid flag.
>
> This contribution can be licensed under either the softfloat-2a or -2b
> license.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
> Message-id: 1387397961-4894-5-git-send-email-tommusta@gmail.com
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> fpu/softfloat.c | 15 +++++++--------
> 1 file changed, 7 insertions(+), 8 deletions(-)
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 10/22] softfloat: Fix float64_to_uint32_round_to_zero
2013-12-31 13:35 ` [Qemu-devel] [PATCH 10/22] softfloat: Fix float64_to_uint32_round_to_zero Peter Maydell
@ 2013-12-31 14:24 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:24 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> From: Tom Musta <tommusta@gmail.com>
>
> The float64_to_uint32_round_to_zero routine is incorrect.
>
> For example, the following test pattern:
>
> 425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38
>
> will erroneously set the inexact flag.
>
> This patch re-implements the routine to use the float64_to_uint64_round_to_zero
> routine. If saturation occurs we ignore any flags set by the
> conversion function and raise only Invalid.
>
> This contribution can be licensed under either the softfloat-2a or -2b
> license.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
> Message-id: 1387397961-4894-6-git-send-email-tommusta@gmail.com
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> fpu/softfloat.c | 15 +++++++--------
> 1 file changed, 7 insertions(+), 8 deletions(-)
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 11/22] softfloat: Provide complete set of accessors for fp state
2013-12-31 13:35 ` [Qemu-devel] [PATCH 11/22] softfloat: Provide complete set of accessors for fp state Peter Maydell
@ 2013-12-31 14:26 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:26 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> Tidy up the get/set accessors for the fp state to add missing ones
> and make them all inline in softfloat.h rather than some inline and
> some not.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> The specific one we want for A64 is to get the rounding mode,
> but we might as well fill in the gaps.
> ---
> fpu/softfloat.c | 15 ---------------
> include/fpu/softfloat.h | 39 ++++++++++++++++++++++++++++++++++++---
> 2 files changed, 36 insertions(+), 18 deletions(-)
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions
2013-12-31 14:21 ` Richard Henderson
@ 2013-12-31 14:27 ` Peter Maydell
2013-12-31 14:35 ` Richard Henderson
0 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 14:27 UTC (permalink / raw)
To: Richard Henderson
Cc: Tom Musta, Peter Crosthwaite, Patch Tracking, Aurelien Jarno,
Michael Matz, Alexander Graf, QEMU Developers, Claudio Fontana,
Dirk Mueller, Will Newton, Laurent Desnogues, Alex Bennée,
kvmarm@lists.cs.columbia.edu, Christoffer Dall
On 31 December 2013 14:21, Richard Henderson <rth@twiddle.net> wrote:
> On 12/31/2013 05:35 AM, Peter Maydell wrote:
>> +/* We provide the int16 versions for symmetry of API with float-to-int */
>> +INLINE float32 int16_to_float32(int_fast16_t v STATUS_PARAM)
>> +{
>> + return int32_to_float32(v STATUS_VAR);
>> +}
>
> If you're going to have int16 versions, I don't think you should use
> int_fast16_t, but rather int16_t so that we will properly truncate the incoming
> value. Otherwise there's not much point in having these, IMO.
I was going for consistency with the convert-to-int16, which return
int_fast16_t. The benefit of having these functions is that the
caller doesn't have to effectively have an extra bit of logic in
its macros to say "conversion from 32 bit int is int32_to_float32,
conversion from 64 bit int is int64_to_float32, but conversion
from 16 bit int is not int16_to_float32".
The existing int32_to_float* functions take int32, not int32_t,
so this is the same semantics. You could argue that it would
be better for all of them to take the exact type rather than
the at-least-this-big type (it would let me drop a cast in the
ARM code that calls these), I suppose.
> And please add blank lines between the functions.
Sure.
thanks
-- PMM
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 02/22] softfloat: Add float to 16bit integer conversions.
2013-12-31 14:22 ` Peter Maydell
@ 2013-12-31 14:29 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:29 UTC (permalink / raw)
To: Peter Maydell
Cc: Tom Musta, Peter Crosthwaite, Patch Tracking, Aurelien Jarno,
Michael Matz, Alexander Graf, QEMU Developers, Claudio Fontana,
Dirk Mueller, Will Newton, Laurent Desnogues, Alex Bennée,
kvmarm@lists.cs.columbia.edu, Christoffer Dall
On 12/31/2013 06:22 AM, Peter Maydell wrote:
> Or do you mean we should call float32_to_int32() instead?
> I think that ought to work...
Yes, that's what I meant.
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions
2013-12-31 14:27 ` Peter Maydell
@ 2013-12-31 14:35 ` Richard Henderson
2013-12-31 14:45 ` Peter Maydell
0 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:35 UTC (permalink / raw)
To: Peter Maydell
Cc: Tom Musta, Peter Crosthwaite, Patch Tracking, Aurelien Jarno,
Michael Matz, Alexander Graf, QEMU Developers, Claudio Fontana,
Dirk Mueller, Will Newton, Laurent Desnogues, Alex Bennée,
kvmarm@lists.cs.columbia.edu, Christoffer Dall
On 12/31/2013 06:27 AM, Peter Maydell wrote:
> I was going for consistency with the convert-to-int16, which return
> int_fast16_t.
Perhaps, but in that case we've properly bounded the result; it's guaranteed to
be in range of int16_t.
> The existing int32_to_float* functions take int32, not int32_t,
> so this is the same semantics. You could argue that it would
> be better for all of them to take the exact type rather than
> the at-least-this-big type (it would let me drop a cast in the
> ARM code that calls these), I suppose.
Yes, that's what I'm arguing. Of course, I'd forgotten that we already have
that problem, since my eyes refuse to see the lack of "_t" there. But is that
existing bug any reason to extend the problem?
One of these days we should just clean up all the crap formatting, bogus types,
and stupid STATUS_* macros...
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions
2013-12-31 14:35 ` Richard Henderson
@ 2013-12-31 14:45 ` Peter Maydell
0 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 14:45 UTC (permalink / raw)
To: Richard Henderson
Cc: Tom Musta, Peter Crosthwaite, Patch Tracking, Aurelien Jarno,
Michael Matz, Alexander Graf, QEMU Developers, Claudio Fontana,
Dirk Mueller, Will Newton, Laurent Desnogues, Alex Bennée,
kvmarm@lists.cs.columbia.edu, Christoffer Dall
On 31 December 2013 14:35, Richard Henderson <rth@twiddle.net> wrote:
> On 12/31/2013 06:27 AM, Peter Maydell wrote:
>> The existing int32_to_float* functions take int32, not int32_t,
>> so this is the same semantics. You could argue that it would
>> be better for all of them to take the exact type rather than
>> the at-least-this-big type (it would let me drop a cast in the
>> ARM code that calls these), I suppose.
>
> Yes, that's what I'm arguing. Of course, I'd forgotten that we already have
> that problem, since my eyes refuse to see the lack of "_t" there. But is that
> existing bug any reason to extend the problem?
OK, let's make this one return int16_t. I may throw in an extra patch
making the other int-to-float routines take the precise types too.
> One of these days we should just clean up all the crap formatting, bogus types,
> and stupid STATUS_* macros...
Yes, the STATUS_ stuff is definitely on my list to zap, once we get
all this stuff reviewed and committed (since it would otherwise
cause conflicts all over the place).
I think the standing question about the types is whether we should be
converting int32 to int32_t or int_fast32_t (and indeed whether it
makes much performance difference). That's why we have the current
setup where some of the intfoo got changed to int_fastfoo_t and
some didn't.
My other hope for this year is that we can clear up the relicensing
stuff so I don't have to keep prodding people about specifying the
2a-or-2b stuff on new patches...
thanks
-- PMM
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 14/22] softfloat: Add support for ties-away rounding
2013-12-31 13:35 ` [Qemu-devel] [PATCH 14/22] softfloat: Add support for ties-away rounding Peter Maydell
@ 2013-12-31 14:51 ` Richard Henderson
2013-12-31 14:56 ` Peter Maydell
0 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:51 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
[Tom, this is exactly what you need to fix FRIN rounding.]
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> - float_round_to_zero = 3
> + float_round_to_zero = 3,
> + float_round_ties_away = 4,
I'm not keen on the name. Does anyone else think float_round_nearest_inf is a
better name?
> +++ b/fpu/softfloat.c
> @@ -107,7 +107,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
> roundingMode = STATUS(float_rounding_mode);
> roundNearestEven = ( roundingMode == float_round_nearest_even );
> roundIncrement = 0x40;
> - if ( ! roundNearestEven ) {
> + if (!roundNearestEven && roundingMode != float_round_ties_away) {
> if ( roundingMode == float_round_to_zero ) {
> roundIncrement = 0;
> }
This whole section of code is now a mess. I know you're looking for minimal
changes here, but perhaps I can convince you that
switch (roundingMode) {
case float_round_nearest_even:
case float_round_ties_away:
roundIncrement = 0x40;
break;
case float_round_to_zero:
roundIncrement = 0;
break;
case float_round_up:
roundIncrement = zSign ? 0 : 0x7f;
break;
case float_round_down:
roundIncrement = zSign ? 0x7f : 0;
break;
default:
abort();
}
is easier to follow?
Otherwise, I don't see anything actually wrong in the patch.
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 14/22] softfloat: Add support for ties-away rounding
2013-12-31 14:51 ` Richard Henderson
@ 2013-12-31 14:56 ` Peter Maydell
2013-12-31 14:59 ` Richard Henderson
0 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2013-12-31 14:56 UTC (permalink / raw)
To: Richard Henderson
Cc: Tom Musta, Peter Crosthwaite, Patch Tracking, Aurelien Jarno,
Michael Matz, Alexander Graf, QEMU Developers, Claudio Fontana,
Dirk Mueller, Will Newton, Laurent Desnogues, Alex Bennée,
kvmarm@lists.cs.columbia.edu, Christoffer Dall
On 31 December 2013 14:51, Richard Henderson <rth@twiddle.net> wrote:
> [Tom, this is exactly what you need to fix FRIN rounding.]
>
> On 12/31/2013 05:35 AM, Peter Maydell wrote:
>> - float_round_to_zero = 3
>> + float_round_to_zero = 3,
>> + float_round_ties_away = 4,
>
> I'm not keen on the name. Does anyone else think float_round_nearest_inf is a
> better name?
The IEEE spec specifically calls this roundTiesToAway. I'd rather
not deviate from the official name unless there's a good reason.
(Though admittedly we don't really match up on the other rounding
mode names.)
>
>> +++ b/fpu/softfloat.c
>> @@ -107,7 +107,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
>> roundingMode = STATUS(float_rounding_mode);
>> roundNearestEven = ( roundingMode == float_round_nearest_even );
>> roundIncrement = 0x40;
>> - if ( ! roundNearestEven ) {
>> + if (!roundNearestEven && roundingMode != float_round_ties_away) {
>> if ( roundingMode == float_round_to_zero ) {
>> roundIncrement = 0;
>> }
>
> This whole section of code is now a mess. I know you're looking for minimal
> changes here, but perhaps I can convince you that
>
> switch (roundingMode) {
> case float_round_nearest_even:
> case float_round_ties_away:
> roundIncrement = 0x40;
> break;
> case float_round_to_zero:
> roundIncrement = 0;
> break;
> case float_round_up:
> roundIncrement = zSign ? 0 : 0x7f;
> break;
> case float_round_down:
> roundIncrement = zSign ? 0x7f : 0;
> break;
> default:
> abort();
> }
>
> is easier to follow?
I agree it looks much better. I'd prefer to keep adding features
and refactoring code in separate patches, though.
thanks
-- PMM
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 14/22] softfloat: Add support for ties-away rounding
2013-12-31 14:56 ` Peter Maydell
@ 2013-12-31 14:59 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 14:59 UTC (permalink / raw)
To: Peter Maydell
Cc: Tom Musta, Peter Crosthwaite, Patch Tracking, Aurelien Jarno,
Michael Matz, Alexander Graf, QEMU Developers, Claudio Fontana,
Dirk Mueller, Will Newton, Laurent Desnogues, Alex Bennée,
kvmarm@lists.cs.columbia.edu, Christoffer Dall
On 12/31/2013 06:56 AM, Peter Maydell wrote:
> The IEEE spec specifically calls this roundTiesToAway. I'd rather
> not deviate from the official name unless there's a good reason.
Fair enough.
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 15/22] target-arm: Prepare VFP_CONV_FIX helpers for A64 uses
2013-12-31 13:35 ` [Qemu-devel] [PATCH 15/22] target-arm: Prepare VFP_CONV_FIX helpers for A64 uses Peter Maydell
@ 2013-12-31 15:00 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 15:00 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> From: Will Newton <will.newton@linaro.org>
>
> Make the VFP_CONV_FIX helpers a little more flexible in
> preparation for the A64 uses. This requires two changes:
> * use the correct softfloat conversion function based on itype
> rather than always the int32 one; this is possible now that
> softfloat provides int16 versions and necessary for the
> future conversion-to-int64 A64 variants. This also allows
> us to drop the awkward 'sign' macro argument.
> * split the 'fsz' argument which currently controls both
> width of the input float type and width of the output
> integer type into two; this will allow us to specify the
> A64 64-bit-int-to-single conversion function, where the
> two widths are different.
>
> Signed-off-by: Will Newton <will.newton@linaro.org>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target-arm/helper.c | 28 ++++++++++++++--------------
> 1 file changed, 14 insertions(+), 14 deletions(-)
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 16/22] target-arm: Rename A32 VFP conversion helpers
2013-12-31 13:35 ` [Qemu-devel] [PATCH 16/22] target-arm: Rename A32 VFP conversion helpers Peter Maydell
@ 2013-12-31 15:04 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 15:04 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> From: Will Newton <will.newton@linaro.org>
>
> The VFP conversion helpers for A32 round to zero as this is the only
> rounding mode supported. Rename these helpers to make it clear that
> they round to zero and are not suitable for use in the AArch64 code.
>
> Signed-off-by: Will Newton <will.newton@linaro.org>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target-arm/helper.c | 19 ++++++++++++++-----
> target-arm/helper.h | 16 ++++++++--------
> target-arm/translate.c | 24 +++++++++++++-----------
> 3 files changed, 35 insertions(+), 24 deletions(-)
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 17/22] target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion
2013-12-31 13:35 ` [Qemu-devel] [PATCH 17/22] target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion Peter Maydell
@ 2013-12-31 15:17 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 15:17 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> The VFP fixed point conversion helpers first call float_scalbn and
> then convert the result to an integer. This scalbn operation may
> set floating point exception flags for:
> * overflow & inexact (if it overflows to infinity)
> * input denormal squashed to zero
> * output denormal squashed to zero
> Of these, we only care about the input-denormal flag, since
> the output of the whole scale-and-convert operation will be
> an integer (so squashed-output-denormal and overflow don't
> apply). Suppress the others by saving the pre-scalb exception
> flags and only copying across a potential input-denormal flag.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target-arm/helper.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 18/22] target-arm: A64: Add extra VFP fixed point conversion helpers
2013-12-31 13:35 ` [Qemu-devel] [PATCH 18/22] target-arm: A64: Add extra VFP fixed point conversion helpers Peter Maydell
@ 2013-12-31 15:18 ` Richard Henderson
0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2013-12-31 15:18 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Tom Musta, Peter Crosthwaite, patches, Aurelien Jarno,
Michael Matz, Alexander Graf, Claudio Fontana, Dirk Mueller,
Will Newton, Laurent Desnogues, Alex Bennée, kvmarm,
Christoffer Dall
On 12/31/2013 05:35 AM, Peter Maydell wrote:
> From: Will Newton <will.newton@linaro.org>
>
> Define the full set of floating point to fixed point conversion
> helpers required to support AArch64.
>
> Signed-off-by: Will Newton <will.newton@linaro.org>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target-arm/helper.c | 11 ++++++++++-
> target-arm/helper.h | 16 ++++++++++++++++
> 2 files changed, 26 insertions(+), 1 deletion(-)
Reviewed-by: Richard Henderson <rth@twiddle.net>
r~
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
` (21 preceding siblings ...)
2013-12-31 13:35 ` [Qemu-devel] [PATCH 22/22] target-arm: A64: Add support for FCVT between half, single and double Peter Maydell
@ 2014-01-02 19:12 ` Tom Musta
22 siblings, 0 replies; 42+ messages in thread
From: Tom Musta @ 2014-01-02 19:12 UTC (permalink / raw)
To: Peter Maydell, qemu-devel
Cc: Peter Crosthwaite, patches, Aurelien Jarno, Michael Matz,
Alexander Graf, Claudio Fontana, Dirk Mueller, Will Newton,
Laurent Desnogues, Alex Bennée, kvmarm, Christoffer Dall,
Richard Henderson
On 12/31/2013 7:35 AM, Peter Maydell wrote:
> We need Tom Musta's softfloat patches too, so I have included them
> here. Note that two of these still have outstanding issues identified
> in code review : see the notes in their commit messages (and I haven't
> applied my signed-off-by line to them).
Peter: I have been out but am back. I hope to publish revisions to
my patches yet today.
^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2014-01-02 19:13 UTC | newest]
Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-31 13:35 [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 01/22] softfloat: Fix exception flag handling for float32_to_float16() Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 02/22] softfloat: Add float to 16bit integer conversions Peter Maydell
2013-12-31 14:18 ` Richard Henderson
2013-12-31 14:22 ` Peter Maydell
2013-12-31 14:29 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 03/22] softfloat: Add 16 bit integer to float conversions Peter Maydell
2013-12-31 14:21 ` Richard Henderson
2013-12-31 14:27 ` Peter Maydell
2013-12-31 14:35 ` Richard Henderson
2013-12-31 14:45 ` Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 04/22] softfloat: Fix float64_to_uint64 Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 05/22] softfloat: Only raise Invalid when conversions to int are out of range Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 06/22] softfloat: Fix factor 2 error for scalbn on denormal inputs Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 07/22] softfloat: Add float32_to_uint64() Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 08/22] softfloat: Fix float64_to_uint64_round_to_zero Peter Maydell
2013-12-31 14:23 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 09/22] softfloat: Fix float64_to_uint32 Peter Maydell
2013-12-31 14:24 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 10/22] softfloat: Fix float64_to_uint32_round_to_zero Peter Maydell
2013-12-31 14:24 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 11/22] softfloat: Provide complete set of accessors for fp state Peter Maydell
2013-12-31 14:26 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 12/22] softfloat: Factor out RoundAndPackFloat16 and NormalizeFloat16Subnormal Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 13/22] softfloat: Add float16 <=> float64 conversion functions Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 14/22] softfloat: Add support for ties-away rounding Peter Maydell
2013-12-31 14:51 ` Richard Henderson
2013-12-31 14:56 ` Peter Maydell
2013-12-31 14:59 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 15/22] target-arm: Prepare VFP_CONV_FIX helpers for A64 uses Peter Maydell
2013-12-31 15:00 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 16/22] target-arm: Rename A32 VFP conversion helpers Peter Maydell
2013-12-31 15:04 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 17/22] target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion Peter Maydell
2013-12-31 15:17 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 18/22] target-arm: A64: Add extra VFP fixed point conversion helpers Peter Maydell
2013-12-31 15:18 ` Richard Henderson
2013-12-31 13:35 ` [Qemu-devel] [PATCH 19/22] target-arm: A64: Add "Floating-point<->fixed-point" instructions Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 20/22] target-arm: A64: Add floating-point<->integer conversion instructions Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 21/22] target-arm: A64: Add 1-source 32-to-32 and 64-to-64 FP instructions Peter Maydell
2013-12-31 13:35 ` [Qemu-devel] [PATCH 22/22] target-arm: A64: Add support for FCVT between half, single and double Peter Maydell
2014-01-02 19:12 ` [Qemu-devel] [PATCH 00/22] A64 decoder patchset 6: rest of floating point Tom Musta
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).