DAZ support (still under validation)
This commit is contained in:
parent
7e7cbdba6f
commit
338e7b4fe2
@ -178,6 +178,33 @@ BX_CPP_INLINE flag extractFloat32Sign(float32 a)
|
||||
return a>>31;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Determine single-precision floating-point number class
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
BX_CPP_INLINE float_class_t float32_class(float32 a)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
|
||||
if(aExp == 0xFF) {
|
||||
if (aSig == 0) {
|
||||
return (aSign) ? float_negative_inf : float_positive_inf;
|
||||
}
|
||||
return float_NaN;
|
||||
}
|
||||
|
||||
if(aExp == 0) {
|
||||
if (aSig == 0) {
|
||||
return (aSign) ? float_negative_zero : float_positive_zero;
|
||||
}
|
||||
return float_denormal;
|
||||
}
|
||||
|
||||
return float_normalized;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Normalizes the subnormal single-precision floating-point value represented
|
||||
| by the denormalized significand `aSig'. The normalized exponent and
|
||||
@ -331,6 +358,33 @@ BX_CPP_INLINE flag extractFloat64Sign(float64 a)
|
||||
return a>>63;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Determine double-precision floating-point number class
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
BX_CPP_INLINE float_class_t float64_class(float64 a)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
|
||||
if(aExp == 0x7FF) {
|
||||
if (aSig == 0) {
|
||||
return (aSign) ? float_negative_inf : float_positive_inf;
|
||||
}
|
||||
return float_NaN;
|
||||
}
|
||||
|
||||
if(aExp == 0) {
|
||||
if (aSig == 0) {
|
||||
return (aSign) ? float_negative_zero : float_positive_zero;
|
||||
}
|
||||
return float_denormal;
|
||||
}
|
||||
|
||||
return float_normalized;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Normalizes the subnormal double-precision floating-point value represented
|
||||
| by the denormalized significand `aSig'. The normalized exponent and
|
||||
@ -703,19 +757,16 @@ Bit64s float32_to_int64_round_to_zero(float32 a, float_status_t &status)
|
||||
|
||||
float64 float32_to_float64(float32 a, float_status_t &status)
|
||||
{
|
||||
flag aSign;
|
||||
Bit16s aExp;
|
||||
Bit32u aSig;
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
|
||||
aSig = extractFloat32Frac(a);
|
||||
aExp = extractFloat32Exp(a);
|
||||
aSign = extractFloat32Sign(a);
|
||||
if (aExp == 0xFF) {
|
||||
if (aSig) return commonNaNToFloat64(float32ToCommonNaN(a, status));
|
||||
return packFloat64(aSign, 0x7FF, 0);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return packFloat64(aSign, 0, 0);
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(aSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
--aExp;
|
||||
@ -800,9 +851,20 @@ static float32 addFloat32Sigs(float32 a, float32 b, flag zSign, float_status_t &
|
||||
bSig = extractFloat32Frac(b);
|
||||
bExp = extractFloat32Exp(b);
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((aExp == 0) && aSig) {
|
||||
if (get_DAZ(status)) {
|
||||
aExp = 0;
|
||||
aSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((bExp == 0) && bSig) {
|
||||
if (get_DAZ(status)) {
|
||||
bExp = 0;
|
||||
bSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
expDiff = aExp - bExp;
|
||||
aSig <<= 6;
|
||||
@ -876,9 +938,20 @@ static float32 subFloat32Sigs(float32 a, float32 b, flag zSign, float_status_t &
|
||||
bSig = extractFloat32Frac(b);
|
||||
bExp = extractFloat32Exp(b);
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((aExp == 0) && aSig) {
|
||||
if (get_DAZ(status)) {
|
||||
aExp = 0;
|
||||
aSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((bExp == 0) && bSig) {
|
||||
if (get_DAZ(status)) {
|
||||
bExp = 0;
|
||||
bSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
expDiff = aExp - bExp;
|
||||
aSig <<= 7;
|
||||
@ -1016,12 +1089,12 @@ float32 float32_mul(float32 a, float32 b, float_status_t &status)
|
||||
return packFloat32(zSign, 0xFF, 0);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return packFloat32(zSign, 0, 0);
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0) return packFloat32(zSign, 0, 0);
|
||||
if (bSig == 0 || get_DAZ(status)) return packFloat32(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
@ -1070,10 +1143,12 @@ float32 float32_div(float32 a, float32 b, float_status_t &status)
|
||||
return packFloat32(zSign, 0, 0);
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0) {
|
||||
if ((aExp | aSig) == 0) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float32_default_nan;
|
||||
if (bSig == 0 || get_DAZ(status)) {
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float32_default_nan;
|
||||
}
|
||||
}
|
||||
float_raise(status, float_flag_divbyzero);
|
||||
return packFloat32(zSign, 0xFF, 0);
|
||||
@ -1082,7 +1157,7 @@ float32 float32_div(float32 a, float32 b, float_status_t &status)
|
||||
normalizeFloat32Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return packFloat32(zSign, 0, 0);
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -1134,7 +1209,7 @@ float32 float32_rem(float32 a, float32 b, float_status_t &status)
|
||||
return a;
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0) {
|
||||
if (bSig == 0 || get_DAZ(status)) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float32_default_nan;
|
||||
}
|
||||
@ -1142,7 +1217,7 @@ float32 float32_rem(float32 a, float32 b, float_status_t &status)
|
||||
normalizeFloat32Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return a;
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(aSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -1224,12 +1299,14 @@ float32 float32_sqrt(float32 a, float_status_t &status)
|
||||
return float32_default_nan;
|
||||
}
|
||||
if (aSign) {
|
||||
if ((aExp | aSig) == 0) return a;
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(aSign, 0, 0);
|
||||
}
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float32_default_nan;
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return 0;
|
||||
if (aSig == 0 || get_DAZ(status)) return 0;
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -1263,12 +1340,10 @@ float32 float32_sqrt(float32 a, float_status_t &status)
|
||||
|
||||
int float32_eq(float32 a, float32 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit16s bExp = extractFloat32Exp(b);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit32u bSig = extractFloat32Frac(b);
|
||||
float_class_t aClass = float32_class(a);
|
||||
float_class_t bClass = float32_class(b);
|
||||
|
||||
if (((aExp == 0xFF) && aSig) || ((bExp == 0xFF) && bSig))
|
||||
if (aClass == float_NaN || bClass == float_NaN)
|
||||
{
|
||||
if (float32_is_signaling_nan(a) || float32_is_signaling_nan(b))
|
||||
{
|
||||
@ -1277,8 +1352,13 @@ int float32_eq(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return (a == b) || ((Bit32u) ((a | b)<<1) == 0);
|
||||
@ -1293,18 +1373,21 @@ int float32_eq(float32 a, float32 b, float_status_t &status)
|
||||
|
||||
int float32_le(float32 a, float32 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit16s bExp = extractFloat32Exp(b);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit32u bSig = extractFloat32Frac(b);
|
||||
float_class_t aClass = float32_class(a);
|
||||
float_class_t bClass = float32_class(b);
|
||||
|
||||
if (((aExp == 0xFF) && aSig) || ((bExp == 0xFF) && bSig)) {
|
||||
if (aClass == float_NaN || bClass == float_NaN) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
@ -1321,18 +1404,21 @@ int float32_le(float32 a, float32 b, float_status_t &status)
|
||||
|
||||
int float32_lt(float32 a, float32 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit16s bExp = extractFloat32Exp(b);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit32u bSig = extractFloat32Frac(b);
|
||||
float_class_t aClass = float32_class(a);
|
||||
float_class_t bClass = float32_class(b);
|
||||
|
||||
if (((aExp == 0xFF) && aSig) || ((bExp == 0xFF) && bSig)) {
|
||||
if (aClass == float_NaN || bClass == float_NaN) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
@ -1350,18 +1436,21 @@ int float32_lt(float32 a, float32 b, float_status_t &status)
|
||||
|
||||
int float32_eq_signaling(float32 a, float32 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit16s bExp = extractFloat32Exp(b);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit32u bSig = extractFloat32Frac(b);
|
||||
float_class_t aClass = float32_class(a);
|
||||
float_class_t bClass = float32_class(b);
|
||||
|
||||
if (((aExp == 0xFF) && aSig) || ((bExp == 0xFF) && bSig)) {
|
||||
if (aClass == float_NaN || bClass == float_NaN) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return (a == b) || ((Bit32u) ((a | b)<<1) == 0);
|
||||
@ -1376,12 +1465,10 @@ int float32_eq_signaling(float32 a, float32 b, float_status_t &status)
|
||||
|
||||
int float32_le_quiet(float32 a, float32 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit16s bExp = extractFloat32Exp(b);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit32u bSig = extractFloat32Frac(b);
|
||||
float_class_t aClass = float32_class(a);
|
||||
float_class_t bClass = float32_class(b);
|
||||
|
||||
if (((aExp == 0xFF) && aSig) || ((bExp == 0xFF) && bSig))
|
||||
if (aClass == float_NaN || bClass == float_NaN)
|
||||
{
|
||||
if (float32_is_signaling_nan(a) || float32_is_signaling_nan(b))
|
||||
{
|
||||
@ -1390,8 +1477,13 @@ int float32_le_quiet(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
@ -1409,12 +1501,10 @@ int float32_le_quiet(float32 a, float32 b, float_status_t &status)
|
||||
|
||||
int float32_lt_quiet(float32 a, float32 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit16s bExp = extractFloat32Exp(b);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit32u bSig = extractFloat32Frac(b);
|
||||
float_class_t aClass = float32_class(a);
|
||||
float_class_t bClass = float32_class(b);
|
||||
|
||||
if (((aExp == 0xFF) && aSig) || ((bExp == 0xFF) && bSig))
|
||||
if (aClass == float_NaN || bClass == float_NaN)
|
||||
{
|
||||
if (float32_is_signaling_nan(a) || float32_is_signaling_nan(b))
|
||||
{
|
||||
@ -1423,8 +1513,13 @@ int float32_lt_quiet(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
@ -1461,18 +1556,21 @@ int float32_unordered(float32 a, float32 b, float_status_t &status)
|
||||
|
||||
int float32_compare(float32 a, float32 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit16s bExp = extractFloat32Exp(b);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit32u bSig = extractFloat32Frac(b);
|
||||
float_class_t aClass = float32_class(a);
|
||||
float_class_t bClass = float32_class(b);
|
||||
|
||||
if (((aExp == 0xFF) && aSig) || ((bExp == 0xFF) && bSig)) {
|
||||
if (aClass == float_NaN || bClass == float_NaN) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float_relation_unordered;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
if ((a == b) || ((Bit32u) ((a | b)<<1) == 0)) return float_relation_equal;
|
||||
@ -1497,12 +1595,10 @@ int float32_compare(float32 a, float32 b, float_status_t &status)
|
||||
|
||||
int float32_compare_quiet(float32 a, float32 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat32Exp(a);
|
||||
Bit16s bExp = extractFloat32Exp(b);
|
||||
Bit32u aSig = extractFloat32Frac(a);
|
||||
Bit32u bSig = extractFloat32Frac(b);
|
||||
float_class_t aClass = float32_class(a);
|
||||
float_class_t bClass = float32_class(b);
|
||||
|
||||
if (((aExp == 0xFF) && aSig) || ((bExp == 0xFF) && bSig))
|
||||
if (aClass == float_NaN || bClass == float_NaN)
|
||||
{
|
||||
if (float32_is_signaling_nan(a) || float32_is_signaling_nan(b))
|
||||
{
|
||||
@ -1511,8 +1607,13 @@ int float32_compare_quiet(float32 a, float32 b, float_status_t &status)
|
||||
return float_relation_unordered;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
if ((a == b) || ((Bit32u) ((a | b)<<1) == 0)) return float_relation_equal;
|
||||
@ -1709,7 +1810,7 @@ float32 float64_to_float32(float64 a, float_status_t &status)
|
||||
return packFloat32(aSign, 0xFF, 0);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return packFloat32(aSign, 0, 0);
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(aSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
shift64RightJamming(aSig, 22, &aSig);
|
||||
@ -1799,9 +1900,20 @@ static float64 addFloat64Sigs(float64 a, float64 b, flag zSign, float_status_t &
|
||||
bSig = extractFloat64Frac(b);
|
||||
bExp = extractFloat64Exp(b);
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((aExp == 0) && aSig) {
|
||||
if (get_DAZ(status)) {
|
||||
aExp = 0;
|
||||
aSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((bExp == 0) && bSig) {
|
||||
if (get_DAZ(status)) {
|
||||
bExp = 0;
|
||||
bSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
expDiff = aExp - bExp;
|
||||
aSig <<= 9;
|
||||
@ -1874,9 +1986,20 @@ static float64 subFloat64Sigs(float64 a, float64 b, flag zSign, float_status_t &
|
||||
bSig = extractFloat64Frac(b);
|
||||
bExp = extractFloat64Exp(b);
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((aExp == 0) && aSig) {
|
||||
if (get_DAZ(status)) {
|
||||
aExp = 0;
|
||||
aSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((bExp == 0) && bSig) {
|
||||
if (get_DAZ(status)) {
|
||||
bExp = 0;
|
||||
bSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
expDiff = aExp - bExp;
|
||||
aSig <<= 10;
|
||||
@ -2012,12 +2135,12 @@ float64 float64_mul(float64 a, float64 b, float_status_t &status)
|
||||
return packFloat64(zSign, 0x7FF, 0);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return packFloat64(zSign, 0, 0);
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0) return packFloat64(zSign, 0, 0);
|
||||
if (bSig == 0 || get_DAZ(status)) return packFloat64(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
@ -2068,10 +2191,12 @@ float64 float64_div(float64 a, float64 b, float_status_t &status)
|
||||
return packFloat64(zSign, 0, 0);
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0) {
|
||||
if ((aExp | aSig) == 0) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float64_default_nan;
|
||||
if (bSig == 0 || get_DAZ(status)) {
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float64_default_nan;
|
||||
}
|
||||
}
|
||||
float_raise(status, float_flag_divbyzero);
|
||||
return packFloat64(zSign, 0x7FF, 0);
|
||||
@ -2080,7 +2205,7 @@ float64 float64_div(float64 a, float64 b, float_status_t &status)
|
||||
normalizeFloat64Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return packFloat64(zSign, 0, 0);
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -2136,7 +2261,7 @@ float64 float64_rem(float64 a, float64 b, float_status_t &status)
|
||||
return a;
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0) {
|
||||
if (bSig == 0 || get_DAZ(status)) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float64_default_nan;
|
||||
}
|
||||
@ -2144,7 +2269,7 @@ float64 float64_rem(float64 a, float64 b, float_status_t &status)
|
||||
normalizeFloat64Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return a;
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(aSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -2214,12 +2339,14 @@ float64 float64_sqrt(float64 a, float_status_t &status)
|
||||
return float64_default_nan;
|
||||
}
|
||||
if (aSign) {
|
||||
if ((aExp | aSig) == 0) return a;
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(aSign, 0, 0);
|
||||
}
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float64_default_nan;
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0) return 0;
|
||||
if (aSig == 0 || get_DAZ(status)) return 0;
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -2250,12 +2377,10 @@ float64 float64_sqrt(float64 a, float_status_t &status)
|
||||
|
||||
int float64_eq(float64 a, float64 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit16s bExp = extractFloat64Exp(b);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
Bit64u bSig = extractFloat64Frac(b);
|
||||
float_class_t aClass = float64_class(a);
|
||||
float_class_t bClass = float64_class(b);
|
||||
|
||||
if (((aExp == 0x7FF) && aSig) || ((bExp == 0x7FF) && bSig))
|
||||
if (aClass == float_NaN || bClass == float_NaN)
|
||||
{
|
||||
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
|
||||
{
|
||||
@ -2264,8 +2389,13 @@ int float64_eq(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return (a == b) || ((Bit64u) ((a | b)<<1) == 0);
|
||||
@ -2280,18 +2410,21 @@ int float64_eq(float64 a, float64 b, float_status_t &status)
|
||||
|
||||
int float64_le(float64 a, float64 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit16s bExp = extractFloat64Exp(b);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
Bit64u bSig = extractFloat64Frac(b);
|
||||
float_class_t aClass = float64_class(a);
|
||||
float_class_t bClass = float64_class(b);
|
||||
|
||||
if (((aExp == 0x7FF) && aSig) || ((bExp == 0x7FF) && bSig)) {
|
||||
if (aClass == float_NaN || bClass == float_NaN) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
@ -2308,18 +2441,21 @@ int float64_le(float64 a, float64 b, float_status_t &status)
|
||||
|
||||
int float64_lt(float64 a, float64 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit16s bExp = extractFloat64Exp(b);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
Bit64u bSig = extractFloat64Frac(b);
|
||||
float_class_t aClass = float64_class(a);
|
||||
float_class_t bClass = float64_class(b);
|
||||
|
||||
if (((aExp == 0x7FF) && aSig) || ((bExp == 0x7FF) && bSig)) {
|
||||
if (aClass == float_NaN || bClass == float_NaN) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
@ -2337,18 +2473,21 @@ int float64_lt(float64 a, float64 b, float_status_t &status)
|
||||
|
||||
int float64_eq_signaling(float64 a, float64 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit16s bExp = extractFloat64Exp(b);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
Bit64u bSig = extractFloat64Frac(b);
|
||||
float_class_t aClass = float64_class(a);
|
||||
float_class_t bClass = float64_class(b);
|
||||
|
||||
if (((aExp == 0x7FF) && aSig) || ((bExp == 0x7FF) && bSig)) {
|
||||
if (aClass == float_NaN || bClass == float_NaN) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return (a == b) || ((Bit64u) ((a | b)<<1) == 0);
|
||||
@ -2363,12 +2502,10 @@ int float64_eq_signaling(float64 a, float64 b, float_status_t &status)
|
||||
|
||||
int float64_le_quiet(float64 a, float64 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit16s bExp = extractFloat64Exp(b);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
Bit64u bSig = extractFloat64Frac(b);
|
||||
float_class_t aClass = float64_class(a);
|
||||
float_class_t bClass = float64_class(b);
|
||||
|
||||
if (((aExp == 0x7FF) && aSig) || ((bExp == 0x7FF) && bSig))
|
||||
if (aClass == float_NaN || bClass == float_NaN)
|
||||
{
|
||||
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
|
||||
{
|
||||
@ -2377,8 +2514,13 @@ int float64_le_quiet(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
@ -2396,12 +2538,10 @@ int float64_le_quiet(float64 a, float64 b, float_status_t &status)
|
||||
|
||||
int float64_lt_quiet(float64 a, float64 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit16s bExp = extractFloat64Exp(b);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
Bit64u bSig = extractFloat64Frac(b);
|
||||
float_class_t aClass = float64_class(a);
|
||||
float_class_t bClass = float64_class(b);
|
||||
|
||||
if (((aExp == 0x7FF) && aSig) || ((bExp == 0x7FF) && bSig))
|
||||
if (aClass == float_NaN || bClass == float_NaN)
|
||||
{
|
||||
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
|
||||
{
|
||||
@ -2410,8 +2550,13 @@ int float64_lt_quiet(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
@ -2449,18 +2594,21 @@ int float64_unordered(float64 a, float64 b, float_status_t &status)
|
||||
|
||||
int float64_compare(float64 a, float64 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit16s bExp = extractFloat64Exp(b);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
Bit64u bSig = extractFloat64Frac(b);
|
||||
float_class_t aClass = float64_class(a);
|
||||
float_class_t bClass = float64_class(b);
|
||||
|
||||
if (((aExp == 0x7FF) && aSig) || ((bExp == 0x7FF) && bSig)) {
|
||||
if (aClass == float_NaN || bClass == float_NaN) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float_relation_unordered;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
if ((a == b) || ((Bit64u) ((a | b)<<1) == 0)) return float_relation_equal;
|
||||
@ -2485,22 +2633,25 @@ int float64_compare(float64 a, float64 b, float_status_t &status)
|
||||
|
||||
int float64_compare_quiet(float64 a, float64 b, float_status_t &status)
|
||||
{
|
||||
Bit16s aExp = extractFloat64Exp(a);
|
||||
Bit16s bExp = extractFloat64Exp(b);
|
||||
Bit64u aSig = extractFloat64Frac(a);
|
||||
Bit64u bSig = extractFloat64Frac(b);
|
||||
float_class_t aClass = float64_class(a);
|
||||
float_class_t bClass = float64_class(b);
|
||||
|
||||
if (((aExp == 0x7FF) && aSig) || ((bExp == 0x7FF) && bSig))
|
||||
if (aClass == float_NaN || bClass == float_NaN)
|
||||
{
|
||||
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
|
||||
if (float64_is_signaling_nan(a) || float64_is_signaling_nan(b))
|
||||
{
|
||||
float_raise(status, float_flag_invalid);
|
||||
}
|
||||
return float_relation_unordered;
|
||||
}
|
||||
|
||||
if (((aExp == 0) && aSig) || ((bExp == 0) && bSig)) {
|
||||
float_raise(status, float_flag_denormal);
|
||||
if (aClass == float_denormal) {
|
||||
if (get_DAZ(status)) a = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if (bClass == float_denormal) {
|
||||
if (get_DAZ(status)) b = 0;
|
||||
else float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
if ((a == b) || ((Bit64u) ((a | b)<<1) == 0)) return float_relation_equal;
|
||||
|
@ -49,6 +49,19 @@ these four paragraphs for those parts of this code that are retained.
|
||||
typedef Bit32u float32, Float32;
|
||||
typedef Bit64u float64, Float64;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE floating-point class.
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
float_negative_zero,
|
||||
float_positive_zero,
|
||||
float_NaN,
|
||||
float_negative_inf,
|
||||
float_positive_inf,
|
||||
float_denormal,
|
||||
float_normalized,
|
||||
} float_class_t;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE floating-point underflow tininess-detection mode.
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -90,7 +103,6 @@ enum float_exception_flag_t {
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE floating-point ordering relations
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
enum {
|
||||
float_relation_less = -1,
|
||||
float_relation_equal = 0,
|
||||
@ -162,6 +174,7 @@ int float32_unordered(float32, float32, float_status_t &status);
|
||||
int float32_compare(float32, float32, float_status_t &status);
|
||||
int float32_compare_quiet(float32, float32, float_status_t &status);
|
||||
|
||||
float_class_t float32_class(float32);
|
||||
int float32_is_signaling_nan(float32);
|
||||
int float32_is_zero(float32);
|
||||
|
||||
@ -196,5 +209,6 @@ int float64_unordered(float64, float64, float_status_t &status);
|
||||
int float64_compare(float64, float64, float_status_t &status);
|
||||
int float64_compare_quiet(float64, float64, float_status_t &status);
|
||||
|
||||
float_class_t float64_class(float64);
|
||||
int float64_is_signaling_nan(float64);
|
||||
int float64_is_zero(float64);
|
||||
|
Loading…
Reference in New Issue
Block a user