Quite different implementation of DAZ feature
Fixed bugs in execution of float64 packed instructions (almost all instructions affected)
This commit is contained in:
parent
c82060a215
commit
0cb847f6d3
@ -65,16 +65,6 @@ BX_CPP_INLINE int get_float_nan_handling_mode(float_status_t &status)
|
||||
return status.float_nan_handling_mode;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the <denormals-are-zeroes> feature is supported;
|
||||
| otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
BX_CPP_INLINE int get_DAZ(float_status_t &status)
|
||||
{
|
||||
return status.denormals_are_zeroes;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the <flush-underflow-to-zero> feature is supported;
|
||||
| otherwise returns 0.
|
||||
@ -107,7 +97,7 @@ typedef struct {
|
||||
| otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float32_is_nan(float32 a)
|
||||
int float32_is_nan(float32 a)
|
||||
{
|
||||
return (0xFF000000 < (Bit32u) (a<<1));
|
||||
}
|
||||
@ -117,7 +107,7 @@ flag float32_is_nan(float32 a)
|
||||
| NaN; otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float32_is_signaling_nan(float32 a)
|
||||
int float32_is_signaling_nan(float32 a)
|
||||
{
|
||||
return (((a>>22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
|
||||
}
|
||||
@ -199,7 +189,7 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status_t &status)
|
||||
| otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float64_is_nan(float64 a)
|
||||
int float64_is_nan(float64 a)
|
||||
{
|
||||
return (BX_CONST64(0xFFE0000000000000) < (Bit64u) (a<<1));
|
||||
}
|
||||
@ -209,7 +199,7 @@ flag float64_is_nan(float64 a)
|
||||
| NaN; otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float64_is_signaling_nan(float64 a)
|
||||
int float64_is_signaling_nan(float64 a)
|
||||
{
|
||||
return (((a>>51) & 0xFFF) == 0xFFE) && (a & BX_CONST64(0x0007FFFFFFFFFFFF));
|
||||
}
|
||||
|
@ -766,7 +766,7 @@ float64 float32_to_float64(float32 a, float_status_t &status)
|
||||
return packFloat64(aSign, 0x7FF, 0);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(aSign, 0, 0);
|
||||
if (aSig == 0) return packFloat64(aSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
--aExp;
|
||||
@ -852,16 +852,10 @@ static float32 addFloat32Sigs(float32 a, float32 b, flag zSign, float_status_t &
|
||||
bExp = extractFloat32Exp(b);
|
||||
|
||||
if ((aExp == 0) && aSig) {
|
||||
if (get_DAZ(status)) {
|
||||
aSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((bExp == 0) && bSig) {
|
||||
if (get_DAZ(status)) {
|
||||
bSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
expDiff = aExp - bExp;
|
||||
@ -937,16 +931,10 @@ static float32 subFloat32Sigs(float32 a, float32 b, flag zSign, float_status_t &
|
||||
bExp = extractFloat32Exp(b);
|
||||
|
||||
if ((aExp == 0) && aSig) {
|
||||
if (get_DAZ(status)) {
|
||||
aSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((bExp == 0) && bSig) {
|
||||
if (get_DAZ(status)) {
|
||||
bSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
expDiff = aExp - bExp;
|
||||
@ -1085,12 +1073,12 @@ float32 float32_mul(float32 a, float32 b, float_status_t &status)
|
||||
return packFloat32(zSign, 0xFF, 0);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(zSign, 0, 0);
|
||||
if (aSig == 0) return packFloat32(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0 || get_DAZ(status)) return packFloat32(zSign, 0, 0);
|
||||
if (bSig == 0) return packFloat32(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
@ -1139,12 +1127,10 @@ float32 float32_div(float32 a, float32 b, float_status_t &status)
|
||||
return packFloat32(zSign, 0, 0);
|
||||
}
|
||||
if (bExp == 0) {
|
||||
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;
|
||||
}
|
||||
if (bSig == 0) {
|
||||
if ((aExp | aSig) == 0) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float32_default_nan;
|
||||
}
|
||||
float_raise(status, float_flag_divbyzero);
|
||||
return packFloat32(zSign, 0xFF, 0);
|
||||
@ -1153,7 +1139,7 @@ float32 float32_div(float32 a, float32 b, float_status_t &status)
|
||||
normalizeFloat32Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(zSign, 0, 0);
|
||||
if (aSig == 0) return packFloat32(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -1205,7 +1191,7 @@ float32 float32_rem(float32 a, float32 b, float_status_t &status)
|
||||
return a;
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0 || get_DAZ(status)) {
|
||||
if (bSig == 0) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float32_default_nan;
|
||||
}
|
||||
@ -1213,7 +1199,7 @@ float32 float32_rem(float32 a, float32 b, float_status_t &status)
|
||||
normalizeFloat32Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(aSign, 0, 0);
|
||||
if (aSig == 0) return packFloat32(aSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -1295,14 +1281,12 @@ float32 float32_sqrt(float32 a, float_status_t &status)
|
||||
return float32_default_nan;
|
||||
}
|
||||
if (aSign) {
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(aSign, 0, 0);
|
||||
}
|
||||
if ((aExp | aSig) == 0) return a;
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float32_default_nan;
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return 0;
|
||||
if (aSig == 0) return 0;
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -1348,13 +1332,9 @@ int float32_eq(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return (a == b) || ((Bit32u) ((a | b)<<1) == 0);
|
||||
@ -1377,13 +1357,9 @@ int float32_le(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
@ -1408,13 +1384,9 @@ int float32_lt(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
@ -1440,13 +1412,9 @@ int float32_eq_signaling(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return (a == b) || ((Bit32u) ((a | b)<<1) == 0);
|
||||
@ -1473,13 +1441,9 @@ int float32_le_quiet(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
@ -1509,13 +1473,9 @@ int float32_lt_quiet(float32 a, float32 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat32Sign(a);
|
||||
@ -1545,8 +1505,7 @@ int float32_unordered(float32 a, float32 b, float_status_t &status)
|
||||
|
||||
if (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
if (! get_DAZ(status))
|
||||
float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1570,13 +1529,9 @@ int float32_compare(float32 a, float32 b, float_status_t &status)
|
||||
return float_relation_unordered;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
if ((a == b) || ((Bit32u) ((a | b)<<1) == 0)) return float_relation_equal;
|
||||
@ -1613,13 +1568,9 @@ int float32_compare_quiet(float32 a, float32 b, float_status_t &status)
|
||||
return float_relation_unordered;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
if ((a == b) || ((Bit32u) ((a | b)<<1) == 0)) return float_relation_equal;
|
||||
@ -1816,7 +1767,7 @@ float32 float64_to_float32(float64 a, float_status_t &status)
|
||||
return packFloat32(aSign, 0xFF, 0);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat32(aSign, 0, 0);
|
||||
if (aSig == 0) return packFloat32(aSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
shift64RightJamming(aSig, 22, &aSig);
|
||||
@ -1907,16 +1858,10 @@ static float64 addFloat64Sigs(float64 a, float64 b, flag zSign, float_status_t &
|
||||
bExp = extractFloat64Exp(b);
|
||||
|
||||
if ((aExp == 0) && aSig) {
|
||||
if (get_DAZ(status)) {
|
||||
aSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((bExp == 0) && bSig) {
|
||||
if (get_DAZ(status)) {
|
||||
bSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
expDiff = aExp - bExp;
|
||||
@ -1991,16 +1936,10 @@ static float64 subFloat64Sigs(float64 a, float64 b, flag zSign, float_status_t &
|
||||
bExp = extractFloat64Exp(b);
|
||||
|
||||
if ((aExp == 0) && aSig) {
|
||||
if (get_DAZ(status)) {
|
||||
aSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
if ((bExp == 0) && bSig) {
|
||||
if (get_DAZ(status)) {
|
||||
bSig = 0;
|
||||
}
|
||||
else float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
expDiff = aExp - bExp;
|
||||
@ -2137,12 +2076,12 @@ float64 float64_mul(float64 a, float64 b, float_status_t &status)
|
||||
return packFloat64(zSign, 0x7FF, 0);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(zSign, 0, 0);
|
||||
if (aSig == 0) return packFloat64(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0 || get_DAZ(status)) return packFloat64(zSign, 0, 0);
|
||||
if (bSig == 0) return packFloat64(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
@ -2193,12 +2132,10 @@ float64 float64_div(float64 a, float64 b, float_status_t &status)
|
||||
return packFloat64(zSign, 0, 0);
|
||||
}
|
||||
if (bExp == 0) {
|
||||
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;
|
||||
}
|
||||
if (bSig == 0) {
|
||||
if ((aExp | aSig) == 0) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float64_default_nan;
|
||||
}
|
||||
float_raise(status, float_flag_divbyzero);
|
||||
return packFloat64(zSign, 0x7FF, 0);
|
||||
@ -2207,7 +2144,7 @@ float64 float64_div(float64 a, float64 b, float_status_t &status)
|
||||
normalizeFloat64Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(zSign, 0, 0);
|
||||
if (aSig == 0) return packFloat64(zSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -2263,7 +2200,7 @@ float64 float64_rem(float64 a, float64 b, float_status_t &status)
|
||||
return a;
|
||||
}
|
||||
if (bExp == 0) {
|
||||
if (bSig == 0 || get_DAZ(status)) {
|
||||
if (bSig == 0) {
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float64_default_nan;
|
||||
}
|
||||
@ -2271,7 +2208,7 @@ float64 float64_rem(float64 a, float64 b, float_status_t &status)
|
||||
normalizeFloat64Subnormal(bSig, &bExp, &bSig);
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(aSign, 0, 0);
|
||||
if (aSig == 0) return packFloat64(aSign, 0, 0);
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -2341,14 +2278,12 @@ float64 float64_sqrt(float64 a, float_status_t &status)
|
||||
return float64_default_nan;
|
||||
}
|
||||
if (aSign) {
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return packFloat64(aSign, 0, 0);
|
||||
}
|
||||
if ((aExp | aSig) == 0) return a;
|
||||
float_raise(status, float_flag_invalid);
|
||||
return float64_default_nan;
|
||||
}
|
||||
if (aExp == 0) {
|
||||
if (aSig == 0 || get_DAZ(status)) return 0;
|
||||
if (aSig == 0) return 0;
|
||||
float_raise(status, float_flag_denormal);
|
||||
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
|
||||
}
|
||||
@ -2391,13 +2326,9 @@ int float64_eq(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return (a == b) || ((Bit64u) ((a | b)<<1) == 0);
|
||||
@ -2420,13 +2351,9 @@ int float64_le(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
@ -2451,13 +2378,9 @@ int float64_lt(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
@ -2483,13 +2406,9 @@ int float64_eq_signaling(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return (a == b) || ((Bit64u) ((a | b)<<1) == 0);
|
||||
@ -2516,13 +2435,9 @@ int float64_le_quiet(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
@ -2552,13 +2467,9 @@ int float64_lt_quiet(float64 a, float64 b, float_status_t &status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
flag aSign = extractFloat64Sign(a);
|
||||
@ -2588,8 +2499,7 @@ int float64_unordered(float64 a, float64 b, float_status_t &status)
|
||||
|
||||
if (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
if (! get_DAZ(status))
|
||||
float_raise(status, float_flag_denormal);
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2613,13 +2523,9 @@ int float64_compare(float64 a, float64 b, float_status_t &status)
|
||||
return float_relation_unordered;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
if ((a == b) || ((Bit64u) ((a | b)<<1) == 0)) return float_relation_equal;
|
||||
@ -2656,13 +2562,9 @@ int float64_compare_quiet(float64 a, float64 b, float_status_t &status)
|
||||
return float_relation_unordered;
|
||||
}
|
||||
|
||||
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 (aClass == float_denormal || bClass == float_denormal)
|
||||
{
|
||||
float_raise(status, float_flag_denormal);
|
||||
}
|
||||
|
||||
if ((a == b) || ((Bit64u) ((a | b)<<1) == 0)) return float_relation_equal;
|
||||
|
@ -36,7 +36,6 @@ these four paragraphs for those parts of this code that are retained.
|
||||
* Still to be fixed:
|
||||
* -----------------
|
||||
* * Denormals support for add/sub/compare/convert operations (implemented)
|
||||
* * DAZ (denormals-are-zeroes) feature support
|
||||
* * Flush underflow to zero feature support (implemented)
|
||||
* * Floating point reciprocal and sqrt reciprocal operations
|
||||
*/
|
||||
@ -119,7 +118,6 @@ struct float_status_t
|
||||
int float_rounding_mode;
|
||||
int float_exception_flags;
|
||||
int float_nan_handling_mode;
|
||||
int denormals_are_zeroes; /* flag register */
|
||||
int flush_underflow_to_zero; /* flag register */
|
||||
};
|
||||
typedef struct float_status_t softfloat_status_word_t;
|
||||
|
@ -47,12 +47,23 @@ static void MXCSR_to_softfloat_status_word(softfloat_status_word_t &status, bx_m
|
||||
status.float_exception_flags = 0; // clear exceptions before execution
|
||||
status.float_nan_handling_mode = float_first_operand_nan;
|
||||
status.float_rounding_mode = mxcsr.get_rounding_mode();
|
||||
status.denormals_are_zeroes = mxcsr.get_DAZ();
|
||||
// if underflow is masked and FUZ is 1, set it to 1, else to 0
|
||||
status.flush_underflow_to_zero =
|
||||
(mxcsr.get_flush_masked_underflow() && mxcsr.get_UM()) ? 1 : 0;
|
||||
}
|
||||
|
||||
float32 handleDAZ(float32 op)
|
||||
{
|
||||
if (float32_class(op) == float_denormal) op &= ((Bit32u)(1) << 31);
|
||||
return op;
|
||||
}
|
||||
|
||||
float64 handleDAZ(float64 op)
|
||||
{
|
||||
if (float64_class(op) == float_denormal) op &= ((Bit64u)(1) << 63);
|
||||
return op;
|
||||
}
|
||||
|
||||
/* Comparison predicate for CMPSS/CMPPS instructions */
|
||||
static float32_compare_method compare32[4] = {
|
||||
float32_eq,
|
||||
@ -629,6 +640,11 @@ void BX_CPU_C::CVTPS2PD_VpsWps(bxInstruction_c *i)
|
||||
Float32 r0 = (Float32)(op & 0xFFFFFFFF);
|
||||
Float32 r1 = (Float32)(op >> 32);
|
||||
|
||||
if (MXCSR.get_DAZ()) {
|
||||
r0 = handleDAZ(r0);
|
||||
r1 = handleDAZ(r1);
|
||||
}
|
||||
|
||||
result.xmm32u(0) =
|
||||
float32_to_float64(r0, status_word);
|
||||
result.xmm32u(1) =
|
||||
@ -669,6 +685,12 @@ void BX_CPU_C::CVTPD2PS_VpdWpd(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op.xmm64u(0) = handleDAZ(op.xmm64u(0));
|
||||
op.xmm64u(0) = handleDAZ(op.xmm64u(1));
|
||||
}
|
||||
|
||||
result.xmm32u(0) =
|
||||
float64_to_float32(op.xmm64u(0), status_word);
|
||||
result.xmm32u(1) =
|
||||
@ -710,6 +732,7 @@ void BX_CPU_C::CVTSD2SS_VsdWsd(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
if (MXCSR.get_DAZ()) op = handleDAZ(op);
|
||||
result = float64_to_float32(op, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(), result);
|
||||
@ -744,6 +767,7 @@ void BX_CPU_C::CVTSS2SD_VssWss(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
if (MXCSR.get_DAZ()) op = handleDAZ(op);
|
||||
result = float32_to_float64(op, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_QWORD(i->nnn(), result);
|
||||
@ -1020,6 +1044,12 @@ void BX_CPU_C::UCOMISS_VssWss(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
int rc = float32_compare_quiet(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
|
||||
@ -1071,6 +1101,12 @@ void BX_CPU_C::UCOMISD_VsdWsd(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
int rc = float64_compare_quiet(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
|
||||
@ -1122,6 +1158,12 @@ void BX_CPU_C::COMISS_VpsWps(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
int rc = float32_compare(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
|
||||
@ -1173,6 +1215,12 @@ void BX_CPU_C::COMISD_VpdWpd(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
int rc = float64_compare(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
|
||||
@ -1224,6 +1272,14 @@ void BX_CPU_C::SQRTPS_VpsWps(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op.xmm32u(0) = handleDAZ(op.xmm32u(0));
|
||||
op.xmm32u(1) = handleDAZ(op.xmm32u(1));
|
||||
op.xmm32u(2) = handleDAZ(op.xmm32u(2));
|
||||
op.xmm32u(3) = handleDAZ(op.xmm32u(3));
|
||||
}
|
||||
|
||||
result.xmm32u(0) =
|
||||
float32_sqrt(op.xmm32u(0), status_word);
|
||||
result.xmm32u(1) =
|
||||
@ -1266,10 +1322,16 @@ void BX_CPU_C::SQRTPD_VpdWpd(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op.xmm64u(0) = handleDAZ(op.xmm64u(0));
|
||||
op.xmm64u(1) = handleDAZ(op.xmm64u(1));
|
||||
}
|
||||
|
||||
result.xmm64u(0) =
|
||||
float64_sqrt(op.xmm64u(0), status_word);
|
||||
result.xmm64u(1) =
|
||||
float32_sqrt(op.xmm64u(1), status_word);
|
||||
float64_sqrt(op.xmm64u(1), status_word);
|
||||
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
@ -1303,6 +1365,7 @@ void BX_CPU_C::SQRTSD_VsdWsd(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
if (MXCSR.get_DAZ()) op = handleDAZ(op);
|
||||
result = float64_sqrt(op, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_QWORD(i->nnn(), result);
|
||||
@ -1337,6 +1400,7 @@ void BX_CPU_C::SQRTSS_VssWss(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
result = float32_sqrt(op, status_word);
|
||||
if (MXCSR.get_DAZ()) op = handleDAZ(op);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(), result);
|
||||
|
||||
@ -1418,6 +1482,18 @@ void BX_CPU_C::ADDPS_VpsWps(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ()) {
|
||||
op1.xmm32u(0) = handleDAZ(op1.xmm32u(0));
|
||||
op1.xmm32u(1) = handleDAZ(op1.xmm32u(1));
|
||||
op1.xmm32u(2) = handleDAZ(op1.xmm32u(2));
|
||||
op1.xmm32u(3) = handleDAZ(op1.xmm32u(3));
|
||||
|
||||
op2.xmm32u(0) = handleDAZ(op2.xmm32u(0));
|
||||
op2.xmm32u(1) = handleDAZ(op2.xmm32u(1));
|
||||
op2.xmm32u(2) = handleDAZ(op2.xmm32u(2));
|
||||
op2.xmm32u(3) = handleDAZ(op2.xmm32u(3));
|
||||
}
|
||||
|
||||
result.xmm32u(0) =
|
||||
float32_add(op1.xmm32u(0), op2.xmm32u(0), status_word);
|
||||
result.xmm32u(1) =
|
||||
@ -1460,10 +1536,19 @@ void BX_CPU_C::ADDPD_VpdWpd(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1.xmm64u(0) = handleDAZ(op1.xmm64u(0));
|
||||
op1.xmm64u(1) = handleDAZ(op1.xmm64u(1));
|
||||
|
||||
op2.xmm64u(0) = handleDAZ(op2.xmm64u(0));
|
||||
op2.xmm64u(1) = handleDAZ(op2.xmm64u(1));
|
||||
}
|
||||
|
||||
result.xmm64u(0) =
|
||||
float64_add(op1.xmm64u(0), op2.xmm64u(0), status_word);
|
||||
result.xmm64u(1) =
|
||||
float32_add(op1.xmm64u(1), op2.xmm64u(1), status_word);
|
||||
float64_add(op1.xmm64u(1), op2.xmm64u(1), status_word);
|
||||
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
@ -1497,6 +1582,13 @@ void BX_CPU_C::ADDSD_VsdWsd(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
result = float64_add(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_QWORD(i->nnn(), result);
|
||||
@ -1530,6 +1622,13 @@ void BX_CPU_C::ADDSS_VssWss(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
result = float32_add(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(), result);
|
||||
@ -1564,6 +1663,18 @@ void BX_CPU_C::MULPS_VpsWps(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ()) {
|
||||
op1.xmm32u(0) = handleDAZ(op1.xmm32u(0));
|
||||
op1.xmm32u(1) = handleDAZ(op1.xmm32u(1));
|
||||
op1.xmm32u(2) = handleDAZ(op1.xmm32u(2));
|
||||
op1.xmm32u(3) = handleDAZ(op1.xmm32u(3));
|
||||
|
||||
op2.xmm32u(0) = handleDAZ(op2.xmm32u(0));
|
||||
op2.xmm32u(1) = handleDAZ(op2.xmm32u(1));
|
||||
op2.xmm32u(2) = handleDAZ(op2.xmm32u(2));
|
||||
op2.xmm32u(3) = handleDAZ(op2.xmm32u(3));
|
||||
}
|
||||
|
||||
result.xmm32u(0) =
|
||||
float32_mul(op1.xmm32u(0), op2.xmm32u(0), status_word);
|
||||
result.xmm32u(1) =
|
||||
@ -1606,10 +1717,19 @@ void BX_CPU_C::MULPD_VpdWpd(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1.xmm64u(0) = handleDAZ(op1.xmm64u(0));
|
||||
op1.xmm64u(1) = handleDAZ(op1.xmm64u(1));
|
||||
|
||||
op2.xmm64u(0) = handleDAZ(op2.xmm64u(0));
|
||||
op2.xmm64u(1) = handleDAZ(op2.xmm64u(1));
|
||||
}
|
||||
|
||||
result.xmm64u(0) =
|
||||
float64_mul(op1.xmm64u(0), op2.xmm64u(0), status_word);
|
||||
result.xmm64u(1) =
|
||||
float32_mul(op1.xmm64u(1), op2.xmm64u(1), status_word);
|
||||
float64_mul(op1.xmm64u(1), op2.xmm64u(1), status_word);
|
||||
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
@ -1643,6 +1763,13 @@ void BX_CPU_C::MULSD_VsdWsd(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
result = float64_mul(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_QWORD(i->nnn(), result);
|
||||
@ -1676,6 +1803,13 @@ void BX_CPU_C::MULSS_VssWss(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
result = float32_mul(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(), result);
|
||||
@ -1710,6 +1844,18 @@ void BX_CPU_C::SUBPS_VpsWps(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ()) {
|
||||
op1.xmm32u(0) = handleDAZ(op1.xmm32u(0));
|
||||
op1.xmm32u(1) = handleDAZ(op1.xmm32u(1));
|
||||
op1.xmm32u(2) = handleDAZ(op1.xmm32u(2));
|
||||
op1.xmm32u(3) = handleDAZ(op1.xmm32u(3));
|
||||
|
||||
op2.xmm32u(0) = handleDAZ(op2.xmm32u(0));
|
||||
op2.xmm32u(1) = handleDAZ(op2.xmm32u(1));
|
||||
op2.xmm32u(2) = handleDAZ(op2.xmm32u(2));
|
||||
op2.xmm32u(3) = handleDAZ(op2.xmm32u(3));
|
||||
}
|
||||
|
||||
result.xmm32u(0) =
|
||||
float32_sub(op1.xmm32u(0), op2.xmm32u(0), status_word);
|
||||
result.xmm32u(1) =
|
||||
@ -1752,10 +1898,19 @@ void BX_CPU_C::SUBPD_VpdWpd(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1.xmm64u(0) = handleDAZ(op1.xmm64u(0));
|
||||
op1.xmm64u(1) = handleDAZ(op1.xmm64u(1));
|
||||
|
||||
op2.xmm64u(0) = handleDAZ(op2.xmm64u(0));
|
||||
op2.xmm64u(1) = handleDAZ(op2.xmm64u(1));
|
||||
}
|
||||
|
||||
result.xmm64u(0) =
|
||||
float64_sub(op1.xmm64u(0), op2.xmm64u(0), status_word);
|
||||
result.xmm64u(1) =
|
||||
float32_sub(op1.xmm64u(1), op2.xmm64u(1), status_word);
|
||||
float64_sub(op1.xmm64u(1), op2.xmm64u(1), status_word);
|
||||
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
@ -1789,6 +1944,13 @@ void BX_CPU_C::SUBSD_VsdWsd(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
result = float64_sub(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_QWORD(i->nnn(), result);
|
||||
@ -1822,6 +1984,13 @@ void BX_CPU_C::SUBSS_VssWss(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
result = float32_sub(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(), result);
|
||||
@ -1857,6 +2026,18 @@ void BX_CPU_C::MINPS_VpsWps(bxInstruction_c *i)
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
int rc;
|
||||
|
||||
if (MXCSR.get_DAZ()) {
|
||||
op1.xmm32u(0) = handleDAZ(op1.xmm32u(0));
|
||||
op1.xmm32u(1) = handleDAZ(op1.xmm32u(1));
|
||||
op1.xmm32u(2) = handleDAZ(op1.xmm32u(2));
|
||||
op1.xmm32u(3) = handleDAZ(op1.xmm32u(3));
|
||||
|
||||
op2.xmm32u(0) = handleDAZ(op2.xmm32u(0));
|
||||
op2.xmm32u(1) = handleDAZ(op2.xmm32u(1));
|
||||
op2.xmm32u(2) = handleDAZ(op2.xmm32u(2));
|
||||
op2.xmm32u(3) = handleDAZ(op2.xmm32u(3));
|
||||
}
|
||||
|
||||
rc = float32_compare(op1.xmm32u(0), op2.xmm32u(0), status_word);
|
||||
result.xmm32u(0) =
|
||||
(rc == float_relation_less) ? op1.xmm32u(0) : op2.xmm32u(0);
|
||||
@ -1904,6 +2085,15 @@ void BX_CPU_C::MINPD_VpdWpd(bxInstruction_c *i)
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
int rc;
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1.xmm64u(0) = handleDAZ(op1.xmm64u(0));
|
||||
op1.xmm64u(1) = handleDAZ(op1.xmm64u(1));
|
||||
|
||||
op2.xmm64u(0) = handleDAZ(op2.xmm64u(0));
|
||||
op2.xmm64u(1) = handleDAZ(op2.xmm64u(1));
|
||||
}
|
||||
|
||||
rc = float64_compare(op1.xmm64u(0), op2.xmm64u(0), status_word);
|
||||
result.xmm64u(0) =
|
||||
(rc == float_relation_less) ? op1.xmm64u(0) : op2.xmm64u(0);
|
||||
@ -1943,6 +2133,13 @@ void BX_CPU_C::MINSD_VsdWsd(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
int rc = float64_compare(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_QWORD(i->nnn(),
|
||||
@ -1977,6 +2174,13 @@ void BX_CPU_C::MINSS_VssWss(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
int rc = float32_compare(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(),
|
||||
@ -2012,6 +2216,18 @@ void BX_CPU_C::DIVPS_VpsWps(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ()) {
|
||||
op1.xmm32u(0) = handleDAZ(op1.xmm32u(0));
|
||||
op1.xmm32u(1) = handleDAZ(op1.xmm32u(1));
|
||||
op1.xmm32u(2) = handleDAZ(op1.xmm32u(2));
|
||||
op1.xmm32u(3) = handleDAZ(op1.xmm32u(3));
|
||||
|
||||
op2.xmm32u(0) = handleDAZ(op2.xmm32u(0));
|
||||
op2.xmm32u(1) = handleDAZ(op2.xmm32u(1));
|
||||
op2.xmm32u(2) = handleDAZ(op2.xmm32u(2));
|
||||
op2.xmm32u(3) = handleDAZ(op2.xmm32u(3));
|
||||
}
|
||||
|
||||
result.xmm32u(0) =
|
||||
float32_div(op1.xmm32u(0), op2.xmm32u(0), status_word);
|
||||
result.xmm32u(1) =
|
||||
@ -2054,10 +2270,19 @@ void BX_CPU_C::DIVPD_VpdWpd(bxInstruction_c *i)
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1.xmm64u(0) = handleDAZ(op1.xmm64u(0));
|
||||
op1.xmm64u(1) = handleDAZ(op1.xmm64u(1));
|
||||
|
||||
op2.xmm64u(0) = handleDAZ(op2.xmm64u(0));
|
||||
op2.xmm64u(1) = handleDAZ(op2.xmm64u(1));
|
||||
}
|
||||
|
||||
result.xmm64u(0) =
|
||||
float64_div(op1.xmm64u(0), op2.xmm64u(0), status_word);
|
||||
result.xmm64u(1) =
|
||||
float32_div(op1.xmm64u(1), op2.xmm64u(1), status_word);
|
||||
float64_div(op1.xmm64u(1), op2.xmm64u(1), status_word);
|
||||
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
@ -2091,6 +2316,13 @@ void BX_CPU_C::DIVSD_VsdWsd(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
result = float64_div(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_QWORD(i->nnn(), result);
|
||||
@ -2124,6 +2356,13 @@ void BX_CPU_C::DIVSS_VssWss(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
result = float32_div(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(), result);
|
||||
@ -2159,6 +2398,18 @@ void BX_CPU_C::MAXPS_VpsWps(bxInstruction_c *i)
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
int rc;
|
||||
|
||||
if (MXCSR.get_DAZ()) {
|
||||
op1.xmm32u(0) = handleDAZ(op1.xmm32u(0));
|
||||
op1.xmm32u(1) = handleDAZ(op1.xmm32u(1));
|
||||
op1.xmm32u(2) = handleDAZ(op1.xmm32u(2));
|
||||
op1.xmm32u(3) = handleDAZ(op1.xmm32u(3));
|
||||
|
||||
op2.xmm32u(0) = handleDAZ(op2.xmm32u(0));
|
||||
op2.xmm32u(1) = handleDAZ(op2.xmm32u(1));
|
||||
op2.xmm32u(2) = handleDAZ(op2.xmm32u(2));
|
||||
op2.xmm32u(3) = handleDAZ(op2.xmm32u(3));
|
||||
}
|
||||
|
||||
rc = float32_compare(op1.xmm32u(0), op2.xmm32u(0), status_word);
|
||||
result.xmm32u(0) =
|
||||
(rc == float_relation_greater) ? op1.xmm32u(0) : op2.xmm32u(0);
|
||||
@ -2206,6 +2457,15 @@ void BX_CPU_C::MAXPD_VpdWpd(bxInstruction_c *i)
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
int rc;
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1.xmm64u(0) = handleDAZ(op1.xmm64u(0));
|
||||
op1.xmm64u(1) = handleDAZ(op1.xmm64u(1));
|
||||
|
||||
op2.xmm64u(0) = handleDAZ(op2.xmm64u(0));
|
||||
op2.xmm64u(1) = handleDAZ(op2.xmm64u(1));
|
||||
}
|
||||
|
||||
rc = float64_compare(op1.xmm64u(0), op2.xmm64u(0), status_word);
|
||||
result.xmm64u(0) =
|
||||
(rc == float_relation_greater) ? op1.xmm64u(0) : op2.xmm64u(0);
|
||||
@ -2245,6 +2505,13 @@ void BX_CPU_C::MAXSD_VsdWsd(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
int rc = float64_compare(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_QWORD(i->nnn(),
|
||||
@ -2279,6 +2546,13 @@ void BX_CPU_C::MAXSS_VssWss(bxInstruction_c *i)
|
||||
|
||||
softfloat_status_word_t status_word;
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
int rc = float32_compare(op1, op2, status_word);
|
||||
BX_CPU_THIS_PTR check_exceptionsSSE(status_word.float_exception_flags);
|
||||
BX_WRITE_XMM_REG_LO_DWORD(i->nnn(),
|
||||
@ -2315,6 +2589,18 @@ void BX_CPU_C::CMPPS_VpsWpsIb(bxInstruction_c *i)
|
||||
MXCSR_to_softfloat_status_word(status, MXCSR);
|
||||
int ib = i->Ib();
|
||||
|
||||
if (MXCSR.get_DAZ()) {
|
||||
op1.xmm32u(0) = handleDAZ(op1.xmm32u(0));
|
||||
op1.xmm32u(1) = handleDAZ(op1.xmm32u(1));
|
||||
op1.xmm32u(2) = handleDAZ(op1.xmm32u(2));
|
||||
op1.xmm32u(3) = handleDAZ(op1.xmm32u(3));
|
||||
|
||||
op2.xmm32u(0) = handleDAZ(op2.xmm32u(0));
|
||||
op2.xmm32u(1) = handleDAZ(op2.xmm32u(1));
|
||||
op2.xmm32u(2) = handleDAZ(op2.xmm32u(2));
|
||||
op2.xmm32u(3) = handleDAZ(op2.xmm32u(3));
|
||||
}
|
||||
|
||||
if(ib < 4)
|
||||
{
|
||||
result.xmm32u(0) =
|
||||
@ -2377,6 +2663,15 @@ void BX_CPU_C::CMPPD_VpdWpdIb(bxInstruction_c *i)
|
||||
MXCSR_to_softfloat_status_word(status, MXCSR);
|
||||
int ib = i->Ib();
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1.xmm64u(0) = handleDAZ(op1.xmm64u(0));
|
||||
op1.xmm64u(1) = handleDAZ(op1.xmm64u(1));
|
||||
|
||||
op2.xmm64u(0) = handleDAZ(op2.xmm64u(0));
|
||||
op2.xmm64u(1) = handleDAZ(op2.xmm64u(1));
|
||||
}
|
||||
|
||||
if(ib < 4)
|
||||
{
|
||||
result.xmm64u(0) = compare64[ib](op1.xmm64u(0), op2.xmm64u(0), status) ?
|
||||
@ -2431,6 +2726,12 @@ void BX_CPU_C::CMPSD_VsdWsdIb(bxInstruction_c *i)
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
int ib = i->Ib();
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
if(ib < 4) {
|
||||
if(compare64[ib](op1, op2, status_word)) {
|
||||
result = BX_CONST64(0xFFFFFFFFFFFFFFFF);
|
||||
@ -2481,6 +2782,12 @@ void BX_CPU_C::CMPSS_VssWssIb(bxInstruction_c *i)
|
||||
MXCSR_to_softfloat_status_word(status_word, MXCSR);
|
||||
int ib = i->Ib();
|
||||
|
||||
if (MXCSR.get_DAZ())
|
||||
{
|
||||
op1 = handleDAZ(op1);
|
||||
op2 = handleDAZ(op2);
|
||||
}
|
||||
|
||||
if(ib < 4) {
|
||||
if(compare32[ib](op1, op2, status_word)) {
|
||||
result = 0xFFFFFFFF;
|
||||
|
Loading…
Reference in New Issue
Block a user