convert to softfloat3e several floatx80 uses (#278)

This commit is contained in:
Stanislav Shwartsman 2024-03-15 22:53:48 +02:00 committed by GitHub
parent aac6dd5d13
commit 9fa35f4596
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
81 changed files with 701 additions and 1973 deletions

3
.gitignore vendored
View File

@ -107,6 +107,9 @@ bochs-msvc-src.zip
# /bochs/cpu/fpu/
/bochs/cpu/fpu/Makefile
# /bochs/cpu/softfloat3e/
/bochs/cpu/softfloat3e/Makefile
# /bochs/iodev/display/
/bochs/iodev/display/Makefile
/bochs/iodev/display/.libs/

View File

@ -8288,7 +8288,7 @@ float16 approximate_rcp14(float16 op, const float_status_t &status)
// the rcp14 handle denormals properly
case float_denormal:
if (get_denormals_are_zeros(status))
if (softfloat_denormalsAreZeros(&status))
return packFloat16(sign, 0x1F, 0);
normExpSig = softfloat_normSubnormalF16Sig(fraction);
@ -8315,7 +8315,7 @@ float16 approximate_rcp14(float16 op, const float_status_t &status)
if (exp <= 0) {
/* underflow */
if (get_flush_underflow_to_zero(status))
if (softfloat_flushUnderflowToZero(&status))
return packFloat16(sign, 0, 0);
fraction32 >>= (1 - exp); // make denormal result, note that -1 <= exp <= 0 so no rounding needed
@ -8355,7 +8355,7 @@ float32 approximate_rcp14(float32 op, const float_status_t &status)
// the rcp14 handle denormals properly
case softfloat_denormal:
if (get_denormals_are_zeros(status))
if (softfloat_denormalsAreZeros(&status))
return packFloat32(sign, 0xFF, 0);
normExpSig = softfloat_normSubnormalF32Sig(fraction);
@ -8378,7 +8378,7 @@ float32 approximate_rcp14(float32 op, const float_status_t &status)
if (exp <= 0) {
/* underflow */
if (get_flush_underflow_to_zero(status))
if (softfloat_flushUnderflowToZero(&status))
return packFloat32(sign, 0, 0);
fraction >>= (1 - exp); // make denormal result, note that -1 <= exp <= 0 so no rounding needed
@ -8412,7 +8412,7 @@ float64 approximate_rcp14(float64 op, const float_status_t &status)
// the rcp14 handle denormals properly
case softfloat_denormal:
if (get_denormals_are_zeros(status))
if (softfloat_denormalsAreZeros(&status))
return packFloat64(sign, 0x7FF, 0);
normExpSig = softfloat_normSubnormalF64Sig(fraction);
@ -8441,7 +8441,7 @@ float64 approximate_rcp14(float64 op, const float_status_t &status)
if (exp <= 0) {
/* underflow */
if (get_flush_underflow_to_zero(status))
if (softfloat_flushUnderflowToZero(&status))
return packFloat64(sign, 0, 0);
fraction >>= (1 - exp); // make denormal result, note that -1 <= exp <= 0 so no rounding needed

View File

@ -120,8 +120,7 @@ floatx80 f2xm1(floatx80 a, float_status_t &status)
Bit64u zSig0, zSig1, zSig2;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a))
{
if (extF80_isUnsupported(a)) {
float_raise(status, float_flag_invalid);
return floatx80_default_nan;
}

View File

@ -136,7 +136,7 @@ static float128 poly_atan(float128 x1, float_status_t &status)
floatx80 fpatan(floatx80 a, floatx80 b, float_status_t &status)
{
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
float_raise(status, float_flag_invalid);
return floatx80_default_nan;
}

View File

@ -53,8 +53,7 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, int rounding
q = 0;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
{
if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
float_raise(status, float_flag_invalid);
r = floatx80_default_nan;
return -1;
@ -83,8 +82,7 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, int rounding
if (aExp == 0 && aSig0) {
float_raise(status, float_flag_denormal);
normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
r = (a.fraction & BX_CONST64(0x8000000000000000)) ?
packFloatx80(aSign, aExp, aSig0) : a;
r = (a.fraction & BX_CONST64(0x8000000000000000)) ? packFloatx80(aSign, aExp, aSig0) : a;
return 0;
}
r = a;

View File

@ -578,7 +578,7 @@ void BX_CPU_C::print_state_FPU(void)
#else
f *= fp.fraction*scale_factor;
#endif
float_class_t f_class = floatx80_class(fp);
softfloat_class_t f_class = extF80_class(fp);
fprintf(stderr, "%sFP%d ST%d(%c): raw 0x%04x:%08x%08x (%.10f) (%s)\n",
i==tos?"=>":" ", i, (i-tos)&7,
"v0se"[tag],

View File

@ -67,7 +67,7 @@ float_status_t i387cw_to_softfloat_status_word(Bit16u control_word)
floatx80 FPU_handle_NaN(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, float_status_t &status)
{
int aIsSignalingNaN = floatx80_is_signaling_nan(a);
int aIsSignalingNaN = extF80_isSignalingNaN(a);
int bIsSignalingNaN = float32_is_signaling_nan(b32);
if (aIsSignalingNaN | bIsSignalingNaN)
@ -80,7 +80,7 @@ floatx80 FPU_handle_NaN(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, float_s
// float32 is NaN so conversion will propagate SNaN to QNaN and raise
// appropriate exception flags
floatx80 b = float32_to_floatx80(b32, status);
floatx80 b = f32_to_extF80(b32, &status);
if (aIsSignalingNaN) {
if (bIsSignalingNaN) goto returnLargerSignificand;
@ -100,13 +100,13 @@ floatx80 FPU_handle_NaN(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, float_s
bool FPU_handle_NaN(floatx80 a, float32 b, floatx80 &r, float_status_t &status)
{
if (floatx80_is_unsupported(a)) {
if (extF80_isUnsupported(a)) {
float_raise(status, float_flag_invalid);
r = floatx80_default_nan;
return true;
}
int aIsNaN = floatx80_is_nan(a), bIsNaN = float32_is_nan(b);
int aIsNaN = extF80_isNaN(a), bIsNaN = f32_isNaN(b);
if (aIsNaN | bIsNaN) {
r = FPU_handle_NaN(a, aIsNaN, b, bIsNaN, status);
return true;
@ -116,7 +116,7 @@ bool FPU_handle_NaN(floatx80 a, float32 b, floatx80 &r, float_status_t &status)
floatx80 FPU_handle_NaN(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, float_status_t &status)
{
int aIsSignalingNaN = floatx80_is_signaling_nan(a);
int aIsSignalingNaN = extF80_isSignalingNaN(a);
int bIsSignalingNaN = float64_is_signaling_nan(b64);
if (aIsSignalingNaN | bIsSignalingNaN)
@ -129,7 +129,7 @@ floatx80 FPU_handle_NaN(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, float_s
// float64 is NaN so conversion will propagate SNaN to QNaN and raise
// appropriate exception flags
floatx80 b = float64_to_floatx80(b64, status);
floatx80 b = f64_to_extF80(b64, &status);
if (aIsSignalingNaN) {
if (bIsSignalingNaN) goto returnLargerSignificand;
@ -149,13 +149,13 @@ floatx80 FPU_handle_NaN(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, float_s
bool FPU_handle_NaN(floatx80 a, float64 b, floatx80 &r, float_status_t &status)
{
if (floatx80_is_unsupported(a)) {
if (extF80_isUnsupported(a)) {
float_raise(status, float_flag_invalid);
r = floatx80_default_nan;
return true;
}
int aIsNaN = floatx80_is_nan(a), bIsNaN = float64_is_nan(b);
int aIsNaN = extF80_isNaN(a), bIsNaN = f64_isNaN(b);
if (aIsNaN | bIsNaN) {
r = FPU_handle_NaN(a, aIsNaN, b, bIsNaN, status);
return true;
@ -182,7 +182,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FADD_ST0_STj(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_add(a, b, status);
floatx80 result = extF80_add(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -211,7 +211,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FADD_STi_ST0(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_add(a, b, status);
floatx80 result = extF80_add(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags)) {
BX_WRITE_FPU_REG(result, i->dst());
@ -243,7 +243,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FADD_SINGLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(a, load_reg, result, status))
result = floatx80_add(a, float32_to_floatx80(load_reg, status), status);
result = extF80_add(a, f32_to_extF80(load_reg, &status), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -272,7 +272,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FADD_DOUBLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(a, load_reg, result, status))
result = floatx80_add(a, float64_to_floatx80(load_reg, status), status);
result = extF80_add(a, f64_to_extF80(load_reg, &status), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -297,12 +297,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIADD_WORD_INTEGER(bxInstruction_c *i)
}
floatx80 a = BX_READ_FPU_REG(0);
floatx80 b = int32_to_floatx80((Bit32s)(load_reg));
floatx80 b = i32_to_extF80((Bit32s)(load_reg));
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_add(a, b, status);
floatx80 result = extF80_add(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -327,12 +327,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIADD_DWORD_INTEGER(bxInstruction_c *i)
}
floatx80 a = BX_READ_FPU_REG(0);
floatx80 b = int32_to_floatx80(load_reg);
floatx80 b = i32_to_extF80(load_reg);
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_add(a, b, status);
floatx80 result = extF80_add(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -359,7 +359,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FMUL_ST0_STj(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_mul(a, b, status);
floatx80 result = extF80_mul(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -388,7 +388,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FMUL_STi_ST0(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_mul(a, b, status);
floatx80 result = extF80_mul(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags)) {
BX_WRITE_FPU_REG(result, i->dst());
@ -420,7 +420,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FMUL_SINGLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(a, load_reg, result, status))
result = floatx80_mul(a, float32_to_floatx80(load_reg, status), status);
result = extF80_mul(a, f32_to_extF80(load_reg, &status), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -449,7 +449,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FMUL_DOUBLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(a, load_reg, result, status))
result = floatx80_mul(a, float64_to_floatx80(load_reg, status), status);
result = extF80_mul(a, f64_to_extF80(load_reg, &status), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -474,12 +474,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIMUL_WORD_INTEGER(bxInstruction_c *i)
}
floatx80 a = BX_READ_FPU_REG(0);
floatx80 b = int32_to_floatx80((Bit32s)(load_reg));
floatx80 b = i32_to_extF80((Bit32s)(load_reg));
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_mul(a, b, status);
floatx80 result = extF80_mul(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -504,12 +504,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIMUL_DWORD_INTEGER(bxInstruction_c *i)
}
floatx80 a = BX_READ_FPU_REG(0);
floatx80 b = int32_to_floatx80(load_reg);
floatx80 b = i32_to_extF80(load_reg);
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_mul(a, b, status);
floatx80 result = extF80_mul(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -536,7 +536,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUB_ST0_STj(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sub(a, b, status);
floatx80 result = extF80_sub(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -563,7 +563,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUBR_ST0_STj(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sub(a, b, status);
floatx80 result = extF80_sub(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -592,7 +592,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUB_STi_ST0(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sub(a, b, status);
floatx80 result = extF80_sub(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags)) {
BX_WRITE_FPU_REG(result, i->dst());
@ -624,7 +624,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUBR_STi_ST0(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sub(a, b, status);
floatx80 result = extF80_sub(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags)) {
BX_WRITE_FPU_REG(result, i->dst());
@ -656,7 +656,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUB_SINGLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(a, load_reg, result, status))
result = floatx80_sub(a, float32_to_floatx80(load_reg, status), status);
result = extF80_sub(a, f32_to_extF80(load_reg, &status), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -685,7 +685,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUBR_SINGLE_REAL(bxInstruction_c *i)
floatx80 b = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(b, load_reg, result, status))
result = floatx80_sub(float32_to_floatx80(load_reg, status), b, status);
result = extF80_sub(f32_to_extF80(load_reg, &status), b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -714,7 +714,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUB_DOUBLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(a, load_reg, result, status))
result = floatx80_sub(a, float64_to_floatx80(load_reg, status), status);
result = extF80_sub(a, f64_to_extF80(load_reg, &status), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -744,7 +744,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUBR_DOUBLE_REAL(bxInstruction_c *i)
floatx80 b = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(b, load_reg, result, status))
result = floatx80_sub(float64_to_floatx80(load_reg, status), b, status);
result = extF80_sub(f64_to_extF80(load_reg, &status), b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -769,12 +769,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISUB_WORD_INTEGER(bxInstruction_c *i)
}
floatx80 a = BX_READ_FPU_REG(0);
floatx80 b = int32_to_floatx80((Bit32s)(load_reg));
floatx80 b = i32_to_extF80((Bit32s)(load_reg));
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sub(a, b, status);
floatx80 result = extF80_sub(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -798,13 +798,13 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISUBR_WORD_INTEGER(bxInstruction_c *i)
BX_NEXT_INSTR(i);
}
floatx80 a = int32_to_floatx80((Bit32s)(load_reg));
floatx80 a = i32_to_extF80((Bit32s)(load_reg));
floatx80 b = BX_READ_FPU_REG(0);
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sub(a, b, status);
floatx80 result = extF80_sub(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -831,7 +831,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISUB_DWORD_INTEGER(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sub(BX_READ_FPU_REG(0), int32_to_floatx80(load_reg), status);
floatx80 result = extF80_sub(BX_READ_FPU_REG(0), i32_to_extF80(load_reg), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -855,13 +855,13 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISUBR_DWORD_INTEGER(bxInstruction_c *i)
BX_NEXT_INSTR(i);
}
floatx80 a = int32_to_floatx80(load_reg);
floatx80 a = i32_to_extF80(load_reg);
floatx80 b = BX_READ_FPU_REG(0);
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sub(a, b, status);
floatx80 result = extF80_sub(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -888,7 +888,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIV_ST0_STj(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_div(a, b, status);
floatx80 result = extF80_div(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -915,7 +915,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIVR_ST0_STj(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_div(a, b, status);
floatx80 result = extF80_div(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -944,7 +944,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIV_STi_ST0(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_div(a, b, status);
floatx80 result = extF80_div(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags)) {
BX_WRITE_FPU_REG(result, i->dst());
@ -976,7 +976,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIVR_STi_ST0(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_div(a, b, status);
floatx80 result = extF80_div(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags)) {
BX_WRITE_FPU_REG(result, i->dst());
@ -1008,7 +1008,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIV_SINGLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(a, load_reg, result, status))
result = floatx80_div(a, float32_to_floatx80(load_reg, status), status);
result = extF80_div(a, f32_to_extF80(load_reg, &status), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1037,7 +1037,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIVR_SINGLE_REAL(bxInstruction_c *i)
floatx80 b = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(b, load_reg, result, status))
result = floatx80_div(float32_to_floatx80(load_reg, status), b, status);
result = extF80_div(f32_to_extF80(load_reg, &status), b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1066,7 +1066,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIV_DOUBLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(a, load_reg, result, status))
result = floatx80_div(a, float64_to_floatx80(load_reg, status), status);
result = extF80_div(a, f64_to_extF80(load_reg, &status), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1095,7 +1095,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIVR_DOUBLE_REAL(bxInstruction_c *i)
floatx80 b = BX_READ_FPU_REG(0), result;
if (! FPU_handle_NaN(b, load_reg, result, status))
result = floatx80_div(float64_to_floatx80(load_reg, status), b, status);
result = extF80_div(f64_to_extF80(load_reg, &status), b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1120,12 +1120,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIDIV_WORD_INTEGER(bxInstruction_c *i)
}
floatx80 a = BX_READ_FPU_REG(0);
floatx80 b = int32_to_floatx80((Bit32s)(load_reg));
floatx80 b = i32_to_extF80((Bit32s)(load_reg));
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_div(a, b, status);
floatx80 result = extF80_div(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1149,13 +1149,13 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIDIVR_WORD_INTEGER(bxInstruction_c *i)
BX_NEXT_INSTR(i);
}
floatx80 a = int32_to_floatx80((Bit32s)(load_reg));
floatx80 a = i32_to_extF80((Bit32s)(load_reg));
floatx80 b = BX_READ_FPU_REG(0);
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_div(a, b, status);
floatx80 result = extF80_div(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1180,12 +1180,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIDIV_DWORD_INTEGER(bxInstruction_c *i)
}
floatx80 a = BX_READ_FPU_REG(0);
floatx80 b = int32_to_floatx80(load_reg);
floatx80 b = i32_to_extF80(load_reg);
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_div(a, b, status);
floatx80 result = extF80_div(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1209,13 +1209,13 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIDIVR_DWORD_INTEGER(bxInstruction_c *i)
BX_NEXT_INSTR(i);
}
floatx80 a = int32_to_floatx80(load_reg);
floatx80 a = i32_to_extF80(load_reg);
floatx80 b = BX_READ_FPU_REG(0);
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_div(a, b, status);
floatx80 result = extF80_div(a, b, &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1238,7 +1238,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSQRT(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_sqrt(BX_READ_FPU_REG(0), status);
floatx80 result = extF80_sqrt(BX_READ_FPU_REG(0), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);
@ -1263,6 +1263,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FRNDINT(bxInstruction_c *i)
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_round_to_int(BX_READ_FPU_REG(0), status);
//floatx80 result = extF80_roundToInt(BX_READ_FPU_REG(0), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);

View File

@ -104,7 +104,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_STi(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->src()), status);
int rc = extF80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->src()), &status);
setcc(status_word_flags_fpu_compare(rc));
if (! FPU_exception(i, status.float_exception_flags)) {
@ -140,7 +140,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOMI_ST0_STj(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->src()), status);
int rc = extF80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->src()), &status);
BX_CPU_THIS_PTR write_eflags_fpu_compare(rc);
if (! FPU_exception(i, status.float_exception_flags)) {
@ -176,7 +176,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOMI_ST0_STj(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->src()), status);
int rc = extF80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->src()), &status);
BX_CPU_THIS_PTR write_eflags_fpu_compare(rc);
if (! FPU_exception(i, status.float_exception_flags)) {
@ -210,7 +210,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOM_STi(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->src()), status);
int rc = extF80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->src()), &status);
setcc(status_word_flags_fpu_compare(rc));
if (! FPU_exception(i, status.float_exception_flags)) {
@ -252,12 +252,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_SINGLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0);
if (floatx80_is_nan(a) || floatx80_is_unsupported(a) || float32_is_nan(load_reg)) {
if (extF80_isNaN(a) || extF80_isUnsupported(a) || f32_isNaN(load_reg)) {
rc = float_relation_unordered;
float_raise(status, float_flag_invalid);
}
else {
rc = floatx80_compare(a, float32_to_floatx80(load_reg, status), status);
rc = extF80_compare(a, f32_to_extF80(load_reg, &status), &status);
}
setcc(status_word_flags_fpu_compare(rc));
@ -300,12 +300,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_DOUBLE_REAL(bxInstruction_c *i)
floatx80 a = BX_READ_FPU_REG(0);
if (floatx80_is_nan(a) || floatx80_is_unsupported(a) || float64_is_nan(load_reg)) {
if (extF80_isNaN(a) || extF80_isUnsupported(a) || f64_isNaN(load_reg)) {
rc = float_relation_unordered;
float_raise(status, float_flag_invalid);
}
else {
rc = floatx80_compare(a, float64_to_floatx80(load_reg, status), status);
rc = extF80_compare(a, f64_to_extF80(load_reg, &status), &status);
}
setcc(status_word_flags_fpu_compare(rc));
@ -346,8 +346,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FICOM_WORD_INTEGER(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0),
int32_to_floatx80((Bit32s)(load_reg)), status);
int rc = extF80_compare(BX_READ_FPU_REG(0),
i32_to_extF80((Bit32s)(load_reg)), &status);
setcc(status_word_flags_fpu_compare(rc));
if (! FPU_exception(i, status.float_exception_flags)) {
@ -387,7 +387,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FICOM_DWORD_INTEGER(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), int32_to_floatx80(load_reg), status);
int rc = extF80_compare(BX_READ_FPU_REG(0), i32_to_extF80(load_reg), &status);
setcc(status_word_flags_fpu_compare(rc));
if (! FPU_exception(i, status.float_exception_flags)) {
@ -425,7 +425,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOMPP(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), quiet, status);
int rc = extF80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), quiet, &status);
setcc(status_word_flags_fpu_compare(rc));
if (! FPU_exception(i, status.float_exception_flags)) {
@ -454,7 +454,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FTST(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
int rc = floatx80_compare(BX_READ_FPU_REG(0), Const_Z, status);
int rc = extF80_compare(BX_READ_FPU_REG(0), Const_Z, &status);
setcc(status_word_flags_fpu_compare(rc));
FPU_exception(i, status.float_exception_flags);
}
@ -483,34 +483,34 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FXAM(bxInstruction_c *i)
}
else
{
float_class_t aClass = floatx80_class(reg);
softfloat_class_t aClass = extF80_class(reg);
switch(aClass)
{
case float_zero:
case softfloat_zero:
setcc(FPU_SW_C3|FPU_SW_C1);
break;
case float_SNaN:
case float_QNaN:
case softfloat_SNaN:
case softfloat_QNaN:
// unsupported handled as NaNs
if (floatx80_is_unsupported(reg)) {
if (extF80_isUnsupported(reg)) {
setcc(FPU_SW_C1);
} else {
setcc(FPU_SW_C1|FPU_SW_C0);
}
break;
case float_negative_inf:
case float_positive_inf:
case softfloat_negative_inf:
case softfloat_positive_inf:
setcc(FPU_SW_C2|FPU_SW_C1|FPU_SW_C0);
break;
case float_denormal:
case softfloat_denormal:
setcc(FPU_SW_C3|FPU_SW_C2|FPU_SW_C1);
break;
case float_normalized:
case softfloat_normalized:
setcc(FPU_SW_C2|FPU_SW_C1);
break;
}

View File

@ -88,7 +88,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_SINGLE_REAL(bxInstruction_c *i)
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
// convert to floatx80 format
floatx80 result = float32_to_floatx80(load_reg, status);
floatx80 result = f32_to_extF80(load_reg, &status);
unsigned unmasked = FPU_exception(i, status.float_exception_flags);
if (! (unmasked & FPU_CW_Invalid)) {
@ -119,7 +119,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_DOUBLE_REAL(bxInstruction_c *i)
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
// convert to floatx80 format
floatx80 result = float64_to_floatx80(load_reg, status);
floatx80 result = f64_to_extF80(load_reg, &status);
unsigned unmasked = FPU_exception(i, status.float_exception_flags);
if (! (unmasked & FPU_CW_Invalid)) {
@ -171,7 +171,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FILD_WORD_INTEGER(bxInstruction_c *i)
FPU_stack_overflow(i);
}
else {
floatx80 result = int32_to_floatx80((Bit32s) load_reg);
extFloat80_t result = i32_to_extF80((Bit32s) load_reg);
BX_CPU_THIS_PTR the_i387.FPU_push();
BX_WRITE_FPU_REG(result, 0);
}
@ -195,7 +195,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FILD_DWORD_INTEGER(bxInstruction_c *i)
FPU_stack_overflow(i);
}
else {
floatx80 result = int32_to_floatx80(load_reg);
extFloat80_t result = i32_to_extF80(load_reg);
BX_CPU_THIS_PTR the_i387.FPU_push();
BX_WRITE_FPU_REG(result, 0);
}
@ -219,7 +219,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FILD_QWORD_INTEGER(bxInstruction_c *i)
FPU_stack_overflow(i);
}
else {
floatx80 result = int64_to_floatx80(load_reg);
extFloat80_t result = i64_to_extF80(load_reg);
BX_CPU_THIS_PTR the_i387.FPU_push();
BX_WRITE_FPU_REG(result, 0);
}
@ -260,7 +260,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FBLD_PACKED_BCD(bxInstruction_c *i)
val64 += (hi2 & 0x0f) * scale;
val64 += ((hi2>>4) & 0x0f) * scale * 10;
floatx80 result = int64_to_floatx80(val64);
floatx80 result = (floatx80) i64_to_extF80(val64);
if (hi2 & 0x8000) // set negative
floatx80_chs(result);
@ -326,7 +326,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FST_SINGLE_REAL(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
save_reg = floatx80_to_float32(BX_READ_FPU_REG(0), status);
save_reg = extF80_to_f32(BX_READ_FPU_REG(0), &status);
if (FPU_exception(i, status.float_exception_flags, 1))
BX_NEXT_INSTR(i);
@ -372,7 +372,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FST_DOUBLE_REAL(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
save_reg = floatx80_to_float64(BX_READ_FPU_REG(0), status);
save_reg = extF80_to_f64(BX_READ_FPU_REG(0), &status);
if (FPU_exception(i, status.float_exception_flags, 1))
BX_NEXT_INSTR(i);
@ -451,7 +451,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIST_WORD_INTEGER(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
save_reg = floatx80_to_int16(BX_READ_FPU_REG(0), status);
save_reg = extF80_to_i16(BX_READ_FPU_REG(0), &status);
if (FPU_exception(i, status.float_exception_flags, 1))
BX_NEXT_INSTR(i);
@ -497,7 +497,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIST_DWORD_INTEGER(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
save_reg = floatx80_to_int32(BX_READ_FPU_REG(0), status);
save_reg = extF80_to_i32(BX_READ_FPU_REG(0), &status);
if (FPU_exception(i, status.float_exception_flags, 1))
BX_NEXT_INSTR(i);
@ -541,7 +541,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISTP_QWORD_INTEGER(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
save_reg = floatx80_to_int64(BX_READ_FPU_REG(0), status);
save_reg = extF80_to_i64(BX_READ_FPU_REG(0), &status);
if (FPU_exception(i, status.float_exception_flags, 1))
BX_NEXT_INSTR(i);
@ -592,8 +592,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FBSTP_PACKED_BCD(bxInstruction_c *i)
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 reg = BX_READ_FPU_REG(0);
Bit64s save_val = floatx80_to_int64(reg, status);
Bit64s save_val = extF80_to_i64(reg, &status);
int sign = (reg.exp & 0x8000) != 0;
if (sign)
@ -664,7 +663,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISTTP16(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
save_reg = floatx80_to_int16_round_to_zero(BX_READ_FPU_REG(0), status);
save_reg = extF80_to_i16_round_to_zero(BX_READ_FPU_REG(0), &status);
if (FPU_exception(i, status.float_exception_flags, 1))
BX_NEXT_INSTR(i);
@ -709,7 +708,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISTTP32(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
save_reg = floatx80_to_int32_round_to_zero(BX_READ_FPU_REG(0), status);
save_reg = extF80_to_i32_round_to_zero(BX_READ_FPU_REG(0), &status);
if (FPU_exception(i, status.float_exception_flags, 1))
BX_NEXT_INSTR(i);
@ -754,7 +753,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISTTP64(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
save_reg = floatx80_to_int64_round_to_zero(BX_READ_FPU_REG(0), status);
save_reg = extF80_to_i64_round_to_zero(BX_READ_FPU_REG(0), &status);
if (FPU_exception(i, status.float_exception_flags, 1))
BX_NEXT_INSTR(i);

View File

@ -228,7 +228,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, float_status_t &status
int q = 0;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a)) {
if (extF80_isUnsupported(a)) {
goto invalid;
}
@ -351,7 +351,7 @@ int ftan(floatx80 &a, float_status_t &status)
int q = 0;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a)) {
if (extF80_isUnsupported(a)) {
goto invalid;
}

View File

@ -137,7 +137,7 @@ static float128 poly_l2p1(float128 x, float_status_t &status)
floatx80 fyl2x(floatx80 a, floatx80 b, float_status_t &status)
{
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
invalid:
float_raise(status, float_flag_invalid);
return floatx80_default_nan;
@ -254,7 +254,7 @@ floatx80 fyl2xp1(floatx80 a, floatx80 b, float_status_t &status)
int aSign, bSign;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
invalid:
float_raise(status, float_flag_invalid);
return floatx80_default_nan;

View File

@ -54,333 +54,6 @@ these four paragraphs for those parts of this code that are retained.
*----------------------------------------------------------------------------*/
#include "softfloat-specialize.h"
/*----------------------------------------------------------------------------
| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
| and 7, and returns the properly rounded 32-bit integer corresponding to the
| input. If `zSign' is 1, the input is negated before being converted to an
| integer. Bit 63 of `absZ' must be zero. 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 exception is raised and the integer
| indefinite value is returned.
*----------------------------------------------------------------------------*/
Bit32s roundAndPackInt32(int zSign, Bit64u exactAbsZ, float_status_t &status)
{
int roundingMode = get_float_rounding_mode(status);
int roundNearestEven = (roundingMode == float_round_nearest_even);
int roundIncrement = 0x40;
if (! roundNearestEven) {
if (roundingMode == float_round_to_zero) roundIncrement = 0;
else {
roundIncrement = 0x7F;
if (zSign) {
if (roundingMode == float_round_up) roundIncrement = 0;
}
else {
if (roundingMode == float_round_down) roundIncrement = 0;
}
}
}
int roundBits = (int)(exactAbsZ & 0x7F);
Bit64u absZ = (exactAbsZ + roundIncrement)>>7;
absZ &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven);
Bit32s z = (Bit32s) absZ;
if (zSign) z = -z;
if ((absZ>>32) || (z && ((z < 0) ^ zSign))) {
float_raise(status, float_flag_invalid);
return (Bit32s)(int32_indefinite);
}
if (roundBits) {
float_raise(status, float_flag_inexact);
if ((absZ << 7) > exactAbsZ)
set_float_rounding_up(status);
}
return z;
}
/*----------------------------------------------------------------------------
| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
| `absZ1', with binary point between bits 63 and 64 (between the input words),
| and returns the properly rounded 64-bit integer corresponding to the input.
| If `zSign' is 1, the input is negated before being converted to an integer.
| 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
| exception is raised and the integer indefinite value is returned.
*----------------------------------------------------------------------------*/
Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, float_status_t &status)
{
Bit64s z;
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 (zSign) {
increment = (roundingMode == float_round_down) && absZ1;
}
else {
increment = (roundingMode == float_round_up) && absZ1;
}
}
}
Bit64u exactAbsZ0 = absZ0;
if (increment) {
++absZ0;
if (absZ0 == 0) goto overflow;
absZ0 &= ~(((Bit64u) (absZ1<<1) == 0) & roundNearestEven);
}
z = absZ0;
if (zSign) z = -z;
if (z && ((z < 0) ^ zSign)) {
overflow:
float_raise(status, float_flag_invalid);
return (Bit64s)(int64_indefinite);
}
if (absZ1) {
float_raise(status, float_flag_inexact);
if (absZ0 > exactAbsZ0)
set_float_rounding_up(status);
}
return z;
}
/*----------------------------------------------------------------------------
| Normalizes the subnormal single-precision floating-point value represented
| by the denormalized significand `aSig'. The normalized exponent and
| significand are stored at the locations pointed to by `zExpPtr' and
| `zSigPtr', respectively.
*----------------------------------------------------------------------------*/
void normalizeFloat32Subnormal(Bit32u aSig, Bit16s *zExpPtr, Bit32u *zSigPtr)
{
int shiftCount = countLeadingZeros32(aSig) - 8;
*zSigPtr = aSig<<shiftCount;
*zExpPtr = 1 - shiftCount;
}
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and significand `zSig', and returns the proper single-precision floating-
| point value corresponding to the abstract input. Ordinarily, the abstract
| value is simply rounded and packed into the single-precision format, with
| the inexact exception raised if the abstract input cannot be represented
| exactly. However, if the abstract value is too large, the overflow and
| inexact exceptions are raised and an infinity or maximal finite value is
| returned. If the abstract value is too small, the input value is rounded to
| a subnormal number, and the underflow and inexact exceptions are raised if
| the abstract input cannot be represented exactly as a subnormal single-
| precision floating-point number.
| The input significand `zSig' has its binary point between bits 30
| and 29, which is 7 bits to the left of the usual location. This shifted
| significand must be normalized or smaller. If `zSig' is not normalized,
| `zExp' must be 0; in that case, the result returned is a subnormal number,
| and it must not require rounding. In the usual case that `zSig' is
| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
| The handling of underflow and overflow follows the IEC/IEEE Standard for
| Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float32 roundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, float_status_t &status)
{
Bit32s roundIncrement, roundBits;
const Bit32s roundMask = 0x7F;
int roundingMode = get_float_rounding_mode(status);
int roundNearestEven = (roundingMode == float_round_nearest_even);
roundIncrement = 0x40;
if (! roundNearestEven) {
if (roundingMode == float_round_to_zero) roundIncrement = 0;
else {
roundIncrement = roundMask;
if (zSign) {
if (roundingMode == float_round_up) roundIncrement = 0;
}
else {
if (roundingMode == float_round_down) roundIncrement = 0;
}
}
}
roundBits = zSig & roundMask;
if (0xFD <= (Bit16u) zExp) {
if ((0xFD < zExp)
|| ((zExp == 0xFD) && ((Bit32s) (zSig + roundIncrement) < 0)))
{
float_raise(status, float_flag_overflow);
if (roundBits || float_exception_masked(status, float_flag_overflow)) {
float_raise(status, float_flag_inexact);
if (roundIncrement != 0) set_float_rounding_up(status);
}
return packFloat32(zSign, 0xFF, 0) - (roundIncrement == 0);
}
if (zExp < 0) {
int isTiny = (zExp < -1) || (zSig + roundIncrement < 0x80000000);
if (isTiny) {
if (!float_exception_masked(status, float_flag_underflow)) {
float_raise(status, float_flag_underflow);
zExp += 192; // bias unmasked underflow
}
}
if (zExp < 0) {
zSig = shift32RightJamming(zSig, -zExp);
zExp = 0;
roundBits = zSig & roundMask;
if (isTiny) {
// masked underflow
if(get_flush_underflow_to_zero(status)) {
float_raise(status, float_flag_underflow | float_flag_inexact);
return packFloat32(zSign, 0, 0);
}
if (roundBits) float_raise(status, float_flag_underflow);
}
}
}
}
Bit32u zSigRound = ((zSig + roundIncrement) & ~roundMask) >> 7;
zSigRound &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven);
if (zSigRound == 0) zExp = 0;
if (roundBits) {
float_raise(status, float_flag_inexact);
if ((zSigRound << 7) > zSig) set_float_rounding_up(status);
}
return packFloat32(zSign, zExp, zSigRound);
}
/*----------------------------------------------------------------------------