more fixes for uint conversions based on latest QEMU patches by Tom Musta

This commit is contained in:
Stanislav Shwartsman 2014-01-20 21:22:29 +00:00
parent 649075527e
commit 4705ed6bdd
3 changed files with 29 additions and 31 deletions

View File

@ -158,32 +158,40 @@ Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, float_status_t &
| 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 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(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

View File

@ -73,7 +73,7 @@ Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, float_status_t &
| 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

View File

@ -433,14 +433,10 @@ Bit64u float32_to_uint64(float32 a, float_status_t &status)
if (aExp == 0) aSig = 0;
}
if (aSign) {
if (aExp > 0x7E) {
if ((aSign) && (aExp > 0x7E)) {
float_raise(status, float_flag_invalid);
return uint64_indefinite;
}
if (aExp | aSig) float_raise(status, float_flag_inexact);
return 0;
}
shiftCount = 0xBE - aExp;
if (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,14 +1383,10 @@ Bit64u float64_to_uint64(float64 a, float_status_t &status)
if (aExp == 0) aSig = 0;
}
if (aSign) {
if (aExp > 0x3FE) {
if (aSign && (aExp > 0x3FE)) {
float_raise(status, float_flag_invalid);
return uint64_indefinite;
}
if (aExp | aSig) float_raise(status, float_flag_inexact);
return 0;
}
if (aExp) {
aSig |= BX_CONST64(0x0010000000000000);
@ -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);
}
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);
}
/*----------------------------------------------------------------------------