mirror of
https://github.com/Cxbx-Reloaded/unicorn.git
synced 2024-12-02 16:36:39 +00:00
Port patch from upstream to check for invalid long double encodings
This commit is contained in:
parent
236b6e9085
commit
1f5d14df4d
@ -4602,6 +4602,10 @@ int32 floatx80_to_int32( floatx80 a STATUS_PARAM )
|
||||
int32 aExp, shiftCount;
|
||||
uint64_t aSig;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return 1 << 31;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -4630,6 +4634,10 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
|
||||
uint64_t aSig, savedASig;
|
||||
int32_t z;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return 1 << 31;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -4674,6 +4682,10 @@ int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
|
||||
int32 aExp, shiftCount;
|
||||
uint64_t aSig, aSigExtra;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return (uint64_t)1 << 63;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -4715,6 +4727,10 @@ int64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
|
||||
uint64_t aSig;
|
||||
int64 z;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return (uint64_t)1 << 63;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -4755,6 +4771,10 @@ float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
|
||||
int32 aExp;
|
||||
uint64_t aSig;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return float32_default_nan;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -4783,6 +4803,10 @@ float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
|
||||
int32 aExp;
|
||||
uint64_t aSig, zSig;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return float64_default_nan;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -4811,6 +4835,10 @@ float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
|
||||
int_fast16_t aExp;
|
||||
uint64_t aSig, zSig0, zSig1;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return float128_default_nan;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -4836,6 +4864,10 @@ floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
|
||||
uint64_t lastBitMask, roundBitsMask;
|
||||
floatx80 z;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return floatx80_default_nan;
|
||||
}
|
||||
aExp = extractFloatx80Exp( a );
|
||||
if ( 0x403E <= aExp ) {
|
||||
if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) {
|
||||
@ -5058,6 +5090,10 @@ floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
flag aSign, bSign;
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return floatx80_default_nan;
|
||||
}
|
||||
aSign = extractFloatx80Sign( a );
|
||||
bSign = extractFloatx80Sign( b );
|
||||
if ( aSign == bSign ) {
|
||||
@ -5079,6 +5115,10 @@ floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
flag aSign, bSign;
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return floatx80_default_nan;
|
||||
}
|
||||
aSign = extractFloatx80Sign( a );
|
||||
bSign = extractFloatx80Sign( b );
|
||||
if ( aSign == bSign ) {
|
||||
@ -5103,6 +5143,10 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
uint64_t aSig, bSig, zSig0, zSig1;
|
||||
floatx80 z;
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return floatx80_default_nan;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -5163,6 +5207,10 @@ floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
uint64_t rem0, rem1, rem2, term0, term1, term2;
|
||||
floatx80 z;
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return floatx80_default_nan;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -5243,6 +5291,10 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
uint64_t q, term0, term1, alternateASig0, alternateASig1;
|
||||
floatx80 z;
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return floatx80_default_nan;
|
||||
}
|
||||
aSig0 = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -5339,6 +5391,10 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
|
||||
uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
|
||||
floatx80 z;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return floatx80_default_nan;
|
||||
}
|
||||
aSig0 = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
@ -5405,10 +5461,11 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
|
||||
int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
|
||||
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
|
||||
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)
|
||||
|| (extractFloatx80Exp(a) == 0x7FFF
|
||||
&& (uint64_t) (extractFloatx80Frac(a) << 1))
|
||||
|| (extractFloatx80Exp(b) == 0x7FFF
|
||||
&& (uint64_t) (extractFloatx80Frac(b) << 1))
|
||||
) {
|
||||
float_raise( float_flag_invalid STATUS_VAR);
|
||||
return 0;
|
||||
@ -5434,10 +5491,11 @@ int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
flag aSign, bSign;
|
||||
|
||||
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
|
||||
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)
|
||||
|| (extractFloatx80Exp(a) == 0x7FFF
|
||||
&& (uint64_t) (extractFloatx80Frac(a) << 1))
|
||||
|| (extractFloatx80Exp(b) == 0x7FFF
|
||||
&& (uint64_t) (extractFloatx80Frac(b) << 1))
|
||||
) {
|
||||
float_raise( float_flag_invalid STATUS_VAR);
|
||||
return 0;
|
||||
@ -5467,10 +5525,11 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
flag aSign, bSign;
|
||||
|
||||
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
|
||||
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)
|
||||
|| (extractFloatx80Exp(a) == 0x7FFF
|
||||
&& (uint64_t) (extractFloatx80Frac(a) << 1))
|
||||
|| (extractFloatx80Exp(b) == 0x7FFF
|
||||
&& (uint64_t) (extractFloatx80Frac(b) << 1))
|
||||
) {
|
||||
float_raise( float_flag_invalid STATUS_VAR);
|
||||
return 0;
|
||||
@ -5497,10 +5556,11 @@ int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
*----------------------------------------------------------------------------*/
|
||||
int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
|
||||
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)
|
||||
|| (extractFloatx80Exp(a) == 0x7FFF
|
||||
&& (uint64_t) (extractFloatx80Frac(a) << 1))
|
||||
|| (extractFloatx80Exp(b) == 0x7FFF
|
||||
&& (uint64_t) (extractFloatx80Frac(b) << 1))
|
||||
) {
|
||||
float_raise( float_flag_invalid STATUS_VAR);
|
||||
return 1;
|
||||
@ -5518,6 +5578,10 @@ int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return 0;
|
||||
}
|
||||
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
|
||||
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
||||
@ -5549,6 +5613,10 @@ int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
flag aSign, bSign;
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return 0;
|
||||
}
|
||||
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
|
||||
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
||||
@ -5585,6 +5653,10 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
flag aSign, bSign;
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return 0;
|
||||
}
|
||||
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
|
||||
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
||||
@ -5618,6 +5690,10 @@ int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
*----------------------------------------------------------------------------*/
|
||||
int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM )
|
||||
{
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return 1;
|
||||
}
|
||||
if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
|
||||
&& (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
|
||||
|| ( ( extractFloatx80Exp( b ) == 0x7FFF )
|
||||
@ -6855,7 +6931,7 @@ uint32 float32_to_uint32( float32 a STATUS_PARAM )
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
set_float_exception_flags(old_exc_flags, status);
|
||||
set_float_exception_flags(old_exc_flags STATUS_VAR);
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return res;
|
||||
}
|
||||
@ -7145,6 +7221,10 @@ static inline int floatx80_compare_internal( floatx80 a, floatx80 b,
|
||||
{
|
||||
flag aSign, bSign;
|
||||
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return float_relation_unordered;
|
||||
}
|
||||
if (( ( extractFloatx80Exp( a ) == 0x7fff ) &&
|
||||
( extractFloatx80Frac( a )<<1 ) ) ||
|
||||
( ( extractFloatx80Exp( b ) == 0x7fff ) &&
|
||||
@ -7409,6 +7489,10 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
|
||||
int32_t aExp;
|
||||
uint64_t aSig;
|
||||
|
||||
if (floatx80_invalid_encoding(a)) {
|
||||
float_raise(float_flag_invalid STATUS_VAR);
|
||||
return floatx80_default_nan;
|
||||
}
|
||||
aSig = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
|
@ -625,6 +625,21 @@ static inline int floatx80_is_any_nan(floatx80 a)
|
||||
return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Return whether the given value is an invalid floatx80 encoding.
|
||||
| Invalid floatx80 encodings arise when the integer bit is not set, but
|
||||
| the exponent is not zero. The only times the integer bit is permitted to
|
||||
| be zero is in subnormal numbers and the value zero.
|
||||
| This includes what the Intel software developer's manual calls pseudo-NaNs,
|
||||
| pseudo-infinities and un-normal numbers. It does not include
|
||||
| pseudo-denormals, which must still be correctly handled as inputs even
|
||||
| if they are never generated as outputs.
|
||||
*----------------------------------------------------------------------------*/
|
||||
static inline bool floatx80_invalid_encoding(floatx80 a)
|
||||
{
|
||||
return (a.low & ((uint64_t)1 << 63)) == 0 && (a.high & 0x7FFF) != 0;
|
||||
}
|
||||
|
||||
#define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
|
||||
#define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
|
||||
#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
|
||||
|
Loading…
Reference in New Issue
Block a user