more fixes for uint conversions based on latest QEMU patches by Tom Musta
This commit is contained in:
parent
649075527e
commit
4705ed6bdd
@ -154,21 +154,24 @@ Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, float_status_t &
|
||||
| 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
|
||||
| as an integer. However, if the fixed-point input is too large, the invalid
|
||||
| exception is raised and the largest unsigned integer is returned.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
Bit64u roundAndPackUint64(Bit64u absZ0, Bit64u absZ1, float_status_t &status)
|
||||
Bit64u roundAndPackUint64(int zSign, Bit64u absZ0, Bit64u absZ1, float_status_t &status)
|
||||
{
|
||||
int roundingMode = get_float_rounding_mode(status);
|
||||
int roundNearestEven = (roundingMode == float_round_nearest_even);
|
||||
int increment = ((Bit64s) absZ1 < 0);
|
||||
|
||||
if (!roundNearestEven) {
|
||||
if (roundingMode == float_round_to_zero) {
|
||||
increment = 0;
|
||||
} else {
|
||||
increment = (roundingMode == float_round_up) && absZ1;
|
||||
} else if (absZ1) {
|
||||
if (zSign) {
|
||||
increment = (roundingMode == float_round_down) && absZ1;
|
||||
} else {
|
||||
increment = (roundingMode == float_round_up) && absZ1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (increment) {
|
||||
@ -177,13 +180,18 @@ Bit64u roundAndPackUint64(Bit64u absZ0, Bit64u absZ1, float_status_t &status)
|
||||
float_raise(status, float_flag_invalid);
|
||||
return uint64_indefinite;
|
||||
}
|
||||
absZ0 &= ~(((Bit64u)(absZ1<<1) == 0) & roundNearestEven);
|
||||
absZ0 &= ~(((Bit64u) (absZ1<<1) == 0) & roundNearestEven);
|
||||
}
|
||||
Bit64u z = absZ0;
|
||||
|
||||
if (zSign && absZ0) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return uint64_indefinite;
|
||||
}
|
||||
|
||||
if (absZ1) {
|
||||
float_raise(status, float_flag_inexact);
|
||||
}
|
||||
return z;
|
||||
return absZ0;
|
||||
}
|
||||
|
||||
#ifdef FLOAT16
|
||||
|
@ -69,11 +69,11 @@ Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, float_status_t &
|
||||
| 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
|
||||
| as an integer. However, if the fixed-point input is too large, the invalid
|
||||
| exception is raised and the largest unsigned integer is returned.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
Bit64u roundAndPackUint64(Bit64u absZ0, Bit64u absZ1, float_status_t &status);
|
||||
Bit64u roundAndPackUint64(int zSign, Bit64u absZ0, Bit64u absZ1, float_status_t &status);
|
||||
|
||||
#ifdef FLOAT16
|
||||
|
||||
|
@ -433,13 +433,9 @@ Bit64u float32_to_uint64(float32 a, float_status_t &status)
|
||||
if (aExp == 0) aSig = 0;
|
||||
}
|
||||
|
||||
if (aSign) {
|
||||
if (aExp > 0x7E) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return uint64_indefinite;
|
||||
}
|
||||
if (aExp | aSig) float_raise(status, float_flag_inexact);
|
||||
return 0;
|
||||
if ((aSign) && (aExp > 0x7E)) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return uint64_indefinite;
|
||||
}
|
||||
|
||||
shiftCount = 0xBE - aExp;
|
||||
@ -454,7 +450,7 @@ Bit64u float32_to_uint64(float32 a, float_status_t &status)
|
||||
aSig64 = aSig;
|
||||
aSig64 <<= 40;
|
||||
shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra);
|
||||
return roundAndPackUint64(aSig64, aSigExtra, status);
|
||||
return roundAndPackUint64(aSign, aSig64, aSigExtra, status);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
@ -1387,13 +1383,9 @@ Bit64u float64_to_uint64(float64 a, float_status_t &status)
|
||||
if (aExp == 0) aSig = 0;
|
||||
}
|
||||
|
||||
if (aSign) {
|
||||
if (aExp > 0x3FE) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return uint64_indefinite;
|
||||
}
|
||||
if (aExp | aSig) float_raise(status, float_flag_inexact);
|
||||
return 0;
|
||||
if (aSign && (aExp > 0x3FE)) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return uint64_indefinite;
|
||||
}
|
||||
|
||||
if (aExp) {
|
||||
@ -1402,9 +1394,7 @@ Bit64u float64_to_uint64(float64 a, float_status_t &status)
|
||||
shiftCount = 0x433 - aExp;
|
||||
if (shiftCount <= 0) {
|
||||
if (0x43E < aExp) {
|
||||
if ((aSig != BX_CONST64(0x0010000000000000)) || (aExp == 0x7FF)) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
}
|
||||
float_raise(status, float_flag_invalid);
|
||||
return uint64_indefinite;
|
||||
}
|
||||
aSigExtra = 0;
|
||||
@ -1413,7 +1403,7 @@ Bit64u float64_to_uint64(float64 a, float_status_t &status)
|
||||
shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra);
|
||||
}
|
||||
|
||||
return roundAndPackUint64(aSig, aSigExtra, status);
|
||||
return roundAndPackUint64(aSign, aSig, aSigExtra, status);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user