diff --git a/.gitignore b/.gitignore index 328eeafab..a4d16d119 100644 --- a/.gitignore +++ b/.gitignore @@ -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/ diff --git a/bochs/cpu/avx/avx512_rcp14.cc b/bochs/cpu/avx/avx512_rcp14.cc index 4e3db8f04..ff653f4a8 100644 --- a/bochs/cpu/avx/avx512_rcp14.cc +++ b/bochs/cpu/avx/avx512_rcp14.cc @@ -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 diff --git a/bochs/cpu/fpu/f2xm1.cc b/bochs/cpu/fpu/f2xm1.cc index 42d23516e..d73608800 100644 --- a/bochs/cpu/fpu/f2xm1.cc +++ b/bochs/cpu/fpu/f2xm1.cc @@ -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; } diff --git a/bochs/cpu/fpu/fpatan.cc b/bochs/cpu/fpu/fpatan.cc index d936e880a..df2ce96b0 100644 --- a/bochs/cpu/fpu/fpatan.cc +++ b/bochs/cpu/fpu/fpatan.cc @@ -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; } diff --git a/bochs/cpu/fpu/fprem.cc b/bochs/cpu/fpu/fprem.cc index 83d686c7d..ec59bdd32 100644 --- a/bochs/cpu/fpu/fprem.cc +++ b/bochs/cpu/fpu/fprem.cc @@ -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; diff --git a/bochs/cpu/fpu/fpu.cc b/bochs/cpu/fpu/fpu.cc index 7622d64ea..58f905702 100644 --- a/bochs/cpu/fpu/fpu.cc +++ b/bochs/cpu/fpu/fpu.cc @@ -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], diff --git a/bochs/cpu/fpu/fpu_arith.cc b/bochs/cpu/fpu/fpu_arith.cc index 763450f11..b2a76e30d 100644 --- a/bochs/cpu/fpu/fpu_arith.cc +++ b/bochs/cpu/fpu/fpu_arith.cc @@ -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); diff --git a/bochs/cpu/fpu/fpu_compare.cc b/bochs/cpu/fpu/fpu_compare.cc index 7913c8378..5c706bc43 100644 --- a/bochs/cpu/fpu/fpu_compare.cc +++ b/bochs/cpu/fpu/fpu_compare.cc @@ -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; } diff --git a/bochs/cpu/fpu/fpu_load_store.cc b/bochs/cpu/fpu/fpu_load_store.cc index 131f2e88e..1b2a03fac 100644 --- a/bochs/cpu/fpu/fpu_load_store.cc +++ b/bochs/cpu/fpu/fpu_load_store.cc @@ -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); diff --git a/bochs/cpu/fpu/fsincos.cc b/bochs/cpu/fpu/fsincos.cc index 5a75d0ab6..8dfc7c931 100644 --- a/bochs/cpu/fpu/fsincos.cc +++ b/bochs/cpu/fpu/fsincos.cc @@ -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; } diff --git a/bochs/cpu/fpu/fyl2x.cc b/bochs/cpu/fpu/fyl2x.cc index 03cfb71ee..d50dfcdea 100644 --- a/bochs/cpu/fpu/fyl2x.cc +++ b/bochs/cpu/fpu/fyl2x.cc @@ -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; diff --git a/bochs/cpu/fpu/softfloat-round-pack.cc b/bochs/cpu/fpu/softfloat-round-pack.cc index a164e2f2c..5f9212787 100644 --- a/bochs/cpu/fpu/softfloat-round-pack.cc +++ b/bochs/cpu/fpu/softfloat-round-pack.cc @@ -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<> 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); -} - -/*---------------------------------------------------------------------------- -| 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. This routine is just like -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -float32 normalizeRoundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, float_status_t &status) -{ - int shiftCount = countLeadingZeros32(zSig) - 1; - return roundAndPackFloat32(zSign, zExp - shiftCount, zSig<>10; - zSigRound &= ~(((roundBits ^ 0x200) == 0) & roundNearestEven); - if (zSigRound == 0) zExp = 0; - if (roundBits) { - float_raise(status, float_flag_inexact); - if ((zSigRound << 10) > zSig) set_float_rounding_up(status); - } - return packFloat64(zSign, zExp, zSigRound); -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat64' except that `zSig' does not have to be normalized. -| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -float64 normalizeRoundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, float_status_t &status) -{ - int shiftCount = countLeadingZeros64(zSig) - 1; - return roundAndPackFloat64(zSign, zExp - shiftCount, zSig<>54); } -/*---------------------------------------------------------------------------- -| Takes half-precision floating-point NaN `a' and returns the appropriate -| NaN result. If `a' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float16 propagateFloat16NaN(float16 a, float_status_t &status) -{ - if (float16_is_signaling_nan(a)) - float_raise(status, float_flag_invalid); - - return a | 0x200; -} - #endif /*---------------------------------------------------------------------------- @@ -291,27 +278,6 @@ BX_CPP_INLINE float32 commonNaNToFloat32(commonNaNT a) return (((Bit32u) a.sign)<<31) | 0x7FC00000 | (Bit32u)(a.hi>>41); } -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -float32 propagateFloat32NaN(float32 a, float32 b, float_status_t &status); - -/*---------------------------------------------------------------------------- -| Takes single-precision floating-point NaN `a' and returns the appropriate -| NaN result. If `a' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float32 propagateFloat32NaN(float32 a, float_status_t &status) -{ - if (float32_is_signaling_nan(a)) - float_raise(status, float_flag_invalid); - - return a | 0x00400000; -} - /*---------------------------------------------------------------------------- | Commonly used single-precision floating point constants *----------------------------------------------------------------------------*/ @@ -424,27 +390,6 @@ BX_CPP_INLINE float64 commonNaNToFloat64(commonNaNT a) return (((Bit64u) a.sign)<<63) | BX_CONST64(0x7FF8000000000000) | (a.hi>>12); } -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -float64 propagateFloat64NaN(float64 a, float64 b, float_status_t &status); - -/*---------------------------------------------------------------------------- -| Takes double-precision floating-point NaN `a' and returns the appropriate -| NaN result. If `a' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE float64 propagateFloat64NaN(float64 a, float_status_t &status) -{ - if (float64_is_signaling_nan(a)) - float_raise(status, float_flag_invalid); - - return a | BX_CONST64(0x0008000000000000); -} - #ifdef FLOATX80 /*---------------------------------------------------------------------------- diff --git a/bochs/cpu/fpu/softfloat.cc b/bochs/cpu/fpu/softfloat.cc index 4b50fcd4e..84204e8ec 100644 --- a/bochs/cpu/fpu/softfloat.cc +++ b/bochs/cpu/fpu/softfloat.cc @@ -75,307 +75,6 @@ floatx80 int32_to_floatx80(Bit32s a) return packFloatx80(zSign, 0x403E - shiftCount, zSig< 0x401E) { - float_raise(status, float_flag_invalid); - return (Bit32s)(int32_indefinite); - } - if (aExp < 0x3FFF) { - if (aExp || aSig) float_raise(status, float_flag_inexact); - return 0; - } - shiftCount = 0x403E - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = (Bit32s) aSig; - if (aSign) z = -z; - if ((z < 0) ^ aSign) { - float_raise(status, float_flag_invalid); - return (Bit32s)(int32_indefinite); - } - if ((aSig<>(-shiftCount); - if ((Bit64u) (aSig<<(shiftCount & 63))) { - float_raise(status, float_flag_inexact); - } - if (aSign) z = -z; - return z; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the single-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 floatx80_to_float32(floatx80 a, float_status_t &status) -{ - Bit64u aSig = extractFloatx80Frac(a); - Bit32s aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - float_raise(status, float_flag_invalid); - return float32_default_nan; - } - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) - return commonNaNToFloat32(floatx80ToCommonNaN(a, status)); - - return packFloat32(aSign, 0xFF, 0); - } - aSig = shift64RightJamming(aSig, 33); - if (aExp || aSig) aExp -= 0x3F81; - return roundAndPackFloat32(aSign, aExp, (Bit32u) aSig, status); -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 floatx80_to_float64(floatx80 a, float_status_t &status) -{ - Bit32s aExp; - Bit64u aSig, zSig; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - float_raise(status, float_flag_invalid); - return float64_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) { - return commonNaNToFloat64(floatx80ToCommonNaN(a, status)); - } - return packFloat64(aSign, 0x7FF, 0); - } - zSig = shift64RightJamming(aSig, 1); - if (aExp || aSig) aExp -= 0x3C01; - return roundAndPackFloat64(aSign, aExp, zSig, status); -} - /*---------------------------------------------------------------------------- | Rounds the extended double-precision floating-point value `a' to an integer, | and returns the result as an extended double-precision floating-point @@ -741,168 +440,6 @@ floatx80 floatx80_mul(floatx80 a, floatx80 b, float_status_t &status) zSign, zExp, zSig0, zSig1, status); } -/*---------------------------------------------------------------------------- -| Returns the result of dividing the extended double-precision floating-point -| value `a' by the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_div(floatx80 a, floatx80 b, float_status_t &status) -{ - int aSign, bSign, zSign; - Bit32s aExp, bExp, zExp; - Bit64u aSig, bSig, zSig0, zSig1; - Bit64u rem0, rem1, rem2, term0, term1, term2; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) - { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - bSign = extractFloatx80Sign(b); - - zSign = aSign ^ bSign; - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) return propagateFloatx80NaN(a, b, status); - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal); - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status); - if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal); - return packFloatx80(zSign, 0, 0); - } - if (bExp == 0) { - if (bSig == 0) { - if ((aExp | aSig) == 0) { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - float_raise(status, float_flag_divbyzero); - return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); - } - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - if (aExp == 0) { - if (aSig == 0) return packFloatx80(zSign, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - zExp = aExp - bExp + 0x3FFE; - rem1 = 0; - if (bSig <= aSig) { - shift128Right(aSig, 0, 1, &aSig, &rem1); - ++zExp; - } - zSig0 = estimateDiv128To64(aSig, rem1, bSig); - mul64To128(bSig, zSig0, &term0, &term1); - sub128(aSig, rem1, term0, term1, &rem0, &rem1); - while ((Bit64s) rem0 < 0) { - --zSig0; - add128(rem0, rem1, 0, bSig, &rem0, &rem1); - } - zSig1 = estimateDiv128To64(rem1, 0, bSig); - if ((Bit64u) (zSig1<<1) <= 8) { - mul64To128(bSig, zSig1, &term1, &term2); - sub128(rem1, 0, term1, term2, &rem1, &rem2); - while ((Bit64s) rem1 < 0) { - --zSig1; - add128(rem1, rem2, 0, bSig, &rem1, &rem2); - } - zSig1 |= ((rem1 | rem2) != 0); - } - return - roundAndPackFloatx80(get_float_rounding_precision(status), - zSign, zExp, zSig0, zSig1, status); -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the extended double-precision floating-point -| value `a'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sqrt(floatx80 a, float_status_t &status) -{ - int aSign; - Bit32s aExp, zExp; - Bit64u aSig0, aSig1, zSig0, zSig1, doubleZSig0; - Bit64u rem0, rem1, rem2, rem3, term0, term1, term2, term3; - - // handle unsupported extended double-precision floating encodings - if (floatx80_is_unsupported(a)) - { - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - - aSig0 = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - if (aExp == 0x7FFF) { - if ((Bit64u) (aSig0<<1)) return propagateFloatx80NaN(a, status); - if (! aSign) return a; - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - if (aSign) { - if ((aExp | aSig0) == 0) return a; - float_raise(status, float_flag_invalid); - return floatx80_default_nan; - } - if (aExp == 0) { - if (aSig0 == 0) return packFloatx80(0, 0, 0); - float_raise(status, float_flag_denormal); - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); - } - zExp = ((aExp - 0x3FFF)>>1) + 0x3FFF; - zSig0 = estimateSqrt32(aExp, aSig0>>32); - shift128Right(aSig0, 0, 2 + (aExp & 1), &aSig0, &aSig1); - zSig0 = estimateDiv128To64(aSig0, aSig1, zSig0<<32) + (zSig0<<30); - doubleZSig0 = zSig0<<1; - mul64To128(zSig0, zSig0, &term0, &term1); - sub128(aSig0, aSig1, term0, term1, &rem0, &rem1); - while ((Bit64s) rem0 < 0) { - --zSig0; - doubleZSig0 -= 2; - add128(rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1); - } - zSig1 = estimateDiv128To64(rem1, 0, doubleZSig0); - if ((zSig1 & BX_CONST64(0x3FFFFFFFFFFFFFFF)) <= 5) { - if (zSig1 == 0) zSig1 = 1; - mul64To128(doubleZSig0, zSig1, &term1, &term2); - sub128(rem1, 0, term1, term2, &rem1, &rem2); - mul64To128(zSig1, zSig1, &term2, &term3); - sub192(rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3); - while ((Bit64s) rem1 < 0) { - --zSig1; - shortShift128Left(0, zSig1, 1, &term2, &term3); - term3 |= 1; - term2 |= doubleZSig0; - add192(rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3); - } - zSig1 |= ((rem1 | rem2 | rem3) != 0); - } - shortShift128Left(0, zSig1, 1, &zSig0, &zSig1); - zSig0 |= doubleZSig0; - return - roundAndPackFloatx80(get_float_rounding_precision(status), - 0, zExp, zSig0, zSig1, status); -} - #endif #ifdef FLOAT128 diff --git a/bochs/cpu/fpu/softfloat.h b/bochs/cpu/fpu/softfloat.h index ba4e29680..4d611602f 100644 --- a/bochs/cpu/fpu/softfloat.h +++ b/bochs/cpu/fpu/softfloat.h @@ -199,26 +199,6 @@ BX_CPP_INLINE void set_float_rounding_up(float_status_t &status) } #endif -/*---------------------------------------------------------------------------- -| Returns 1 if the feature is supported; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int get_denormals_are_zeros(const float_status_t &status) -{ - return status.denormals_are_zeros; -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the feature is supported; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE int get_flush_underflow_to_zero(const float_status_t &status) -{ - return status.flush_underflow_to_zero; -} - /*---------------------------------------------------------------------------- | Software IEC/IEEE single-precision operations. *----------------------------------------------------------------------------*/ @@ -235,41 +215,10 @@ int float64_is_nan(float64); #ifdef FLOATX80 -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point types. -*----------------------------------------------------------------------------*/ - -#ifdef BX_BIG_ENDIAN -struct floatx80 { // leave alignment to compiler - Bit16u exp; - Bit64u fraction; -}; -#else -struct floatx80 { - Bit64u fraction; - Bit16u exp; -}; -#endif - /*---------------------------------------------------------------------------- | Software IEC/IEEE integer-to-floating-point conversion routines. *----------------------------------------------------------------------------*/ floatx80 int32_to_floatx80(Bit32s); -floatx80 int64_to_floatx80(Bit64s); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision conversion routines. -*----------------------------------------------------------------------------*/ -floatx80 float32_to_floatx80(float32, float_status_t &status); -floatx80 float64_to_floatx80(float64, float_status_t &status); - -Bit32s floatx80_to_int32(floatx80, float_status_t &status); -Bit32s floatx80_to_int32_round_to_zero(floatx80, float_status_t &status); -Bit64s floatx80_to_int64(floatx80, float_status_t &status); -Bit64s floatx80_to_int64_round_to_zero(floatx80, float_status_t &status); - -float32 floatx80_to_float32(floatx80, float_status_t &status); -float64 floatx80_to_float64(floatx80, float_status_t &status); /*---------------------------------------------------------------------------- | Software IEC/IEEE extended double-precision operations. @@ -278,8 +227,6 @@ floatx80 floatx80_round_to_int(floatx80, float_status_t &status); floatx80 floatx80_add(floatx80, floatx80, float_status_t &status); floatx80 floatx80_sub(floatx80, floatx80, float_status_t &status); floatx80 floatx80_mul(floatx80, floatx80, float_status_t &status); -floatx80 floatx80_div(floatx80, floatx80, float_status_t &status); -floatx80 floatx80_sqrt(floatx80, float_status_t &status); float_class_t floatx80_class(floatx80); int floatx80_is_signaling_nan(floatx80); @@ -288,7 +235,7 @@ int floatx80_is_nan(floatx80); #endif /* FLOATX80 */ #ifdef FLOAT128 - +/* #ifdef BX_BIG_ENDIAN struct float128 { Bit64u hi, lo; @@ -298,7 +245,7 @@ struct float128 { Bit64u lo, hi; }; #endif - +*/ /*---------------------------------------------------------------------------- | Software IEC/IEEE quadruple-precision conversion routines. *----------------------------------------------------------------------------*/ diff --git a/bochs/cpu/fpu/softfloatx80.cc b/bochs/cpu/fpu/softfloatx80.cc index f54beb3b0..207036d61 100644 --- a/bochs/cpu/fpu/softfloatx80.cc +++ b/bochs/cpu/fpu/softfloatx80.cc @@ -27,58 +27,6 @@ these four paragraphs for those parts of this code that are retained. #include "softfloat-round-pack.h" #include "softfloat-macros.h" -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 16-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic - which means in particular that the conversion -| is rounded according to the current rounding mode. If `a' is a NaN or the -| conversion overflows, the integer indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit16s floatx80_to_int16(floatx80 a, float_status_t &status) -{ - if (floatx80_is_unsupported(a)) { - float_raise(status, float_flag_invalid); - return int16_indefinite; - } - - Bit32s v32 = floatx80_to_int32(a, status); - - if ((v32 > 32767) || (v32 < -32768)) { - status.float_exception_flags = float_flag_invalid; // throw away other flags - return int16_indefinite; - } - - return (Bit16s) v32; -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 16-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic, except that the conversion is always rounded -| toward zero. If `a' is a NaN or the conversion overflows, the integer -| indefinite value is returned. -*----------------------------------------------------------------------------*/ - -Bit16s floatx80_to_int16_round_to_zero(floatx80 a, float_status_t &status) -{ - if (floatx80_is_unsupported(a)) { - float_raise(status, float_flag_invalid); - return int16_indefinite; - } - - Bit32s v32 = floatx80_to_int32_round_to_zero(a, status); - - if ((v32 > 32767) || (v32 < -32768)) { - status.float_exception_flags = float_flag_invalid; // throw away other flags - return int16_indefinite; - } - - return (Bit16s) v32; -} - /*---------------------------------------------------------------------------- | Separate the source extended double-precision floating point value `a' | into its exponent and significand, store the significant back to the @@ -204,99 +152,3 @@ floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status_t &status) return roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0, status); } - -/*---------------------------------------------------------------------------- -| Determine extended-precision floating-point number class. -*----------------------------------------------------------------------------*/ - -float_class_t floatx80_class(floatx80 a) -{ - Bit32s aExp = extractFloatx80Exp(a); - Bit64u aSig = extractFloatx80Frac(a); - - if(aExp == 0) { - if (aSig == 0) - return float_zero; - - /* denormal or pseudo-denormal */ - return float_denormal; - } - - /* valid numbers have the MS bit set */ - if (!(aSig & BX_CONST64(0x8000000000000000))) - return float_SNaN; /* report unsupported as SNaNs */ - - if(aExp == 0x7fff) { - int aSign = extractFloatx80Sign(a); - - if (((Bit64u) (aSig<< 1)) == 0) - return (aSign) ? float_negative_inf : float_positive_inf; - - return (aSig & BX_CONST64(0x4000000000000000)) ? float_QNaN : float_SNaN; - } - - return float_normalized; -} - -/*---------------------------------------------------------------------------- -| Compare between two extended precision floating point numbers. Returns -| 'float_relation_equal' if the operands are equal, 'float_relation_less' if -| the value 'a' is less than the corresponding value `b', -| 'float_relation_greater' if the value 'a' is greater than the corresponding -| value `b', or 'float_relation_unordered' otherwise. -*----------------------------------------------------------------------------*/ - -int floatx80_compare(floatx80 a, floatx80 b, int quiet, float_status_t &status) -{ - float_class_t aClass = floatx80_class(a); - float_class_t bClass = floatx80_class(b); - - if (aClass == float_SNaN || bClass == float_SNaN) - { - /* unsupported reported as SNaN */ - float_raise(status, float_flag_invalid); - return float_relation_unordered; - } - - if (aClass == float_QNaN || bClass == float_QNaN) { - if (! quiet) float_raise(status, float_flag_invalid); - return float_relation_unordered; - } - - if (aClass == float_denormal || bClass == float_denormal) { - float_raise(status, float_flag_denormal); - } - - int aSign = extractFloatx80Sign(a); - int bSign = extractFloatx80Sign(b); - - if (aClass == float_zero) { - if (bClass == float_zero) return float_relation_equal; - return bSign ? float_relation_greater : float_relation_less; - } - - if (bClass == float_zero || aSign != bSign) { - return aSign ? float_relation_less : float_relation_greater; - } - - Bit64u aSig = extractFloatx80Frac(a); - Bit32s aExp = extractFloatx80Exp(a); - Bit64u bSig = extractFloatx80Frac(b); - Bit32s bExp = extractFloatx80Exp(b); - - if (aClass == float_denormal) - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - - if (bClass == float_denormal) - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - - if (aExp == bExp && aSig == bSig) - return float_relation_equal; - - int less_than = - aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig))) - : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig))); - - if (less_than) return float_relation_less; - return float_relation_greater; -} diff --git a/bochs/cpu/fpu/softfloatx80.h b/bochs/cpu/fpu/softfloatx80.h index d0692c352..7468c9a01 100644 --- a/bochs/cpu/fpu/softfloatx80.h +++ b/bochs/cpu/fpu/softfloatx80.h @@ -29,18 +29,10 @@ these four paragraphs for those parts of this code that are retained. #include "softfloat.h" #include "softfloat-specialize.h" -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ - -Bit16s floatx80_to_int16(floatx80, float_status_t &status); -Bit16s floatx80_to_int16_round_to_zero(floatx80, float_status_t &status); - /*---------------------------------------------------------------------------- | Software IEC/IEEE extended double-precision operations. *----------------------------------------------------------------------------*/ -float_class_t floatx80_class(floatx80); floatx80 floatx80_extract(floatx80 &a, float_status_t &status); floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status_t &status); int floatx80_remainder(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, float_status_t &status); @@ -59,22 +51,6 @@ int fsin(floatx80 &a, float_status_t &status); int fcos(floatx80 &a, float_status_t &status); int ftan(floatx80 &a, float_status_t &status); -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision compare. -*----------------------------------------------------------------------------*/ - -int floatx80_compare(floatx80, floatx80, int quiet, float_status_t &status); - -BX_CPP_INLINE int floatx80_compare(floatx80 a, floatx80 b, float_status_t &status) -{ - return floatx80_compare(a, b, 0, status); -} - -BX_CPP_INLINE int floatx80_compare_quiet(floatx80 a, floatx80 b, float_status_t &status) -{ - return floatx80_compare(a, b, 1, status); -} - /*----------------------------------------------------------------------------- | Calculates the absolute value of the extended double-precision floating-point | value `a'. The operation is performed according to the IEC/IEEE Standard diff --git a/bochs/cpu/i387.h b/bochs/cpu/i387.h index 7a00a1051..c34580236 100644 --- a/bochs/cpu/i387.h +++ b/bochs/cpu/i387.h @@ -27,7 +27,7 @@ #if BX_SUPPORT_FPU #include "fpu/softfloat.h" -#include "softfloat3e/include/softfloat.h" +#include "softfloat3e/include/softfloat_types.h" #define BX_FPU_REG(index) \ (BX_CPU_THIS_PTR the_i387.st_space[index & 0x7]) diff --git a/bochs/cpu/softfloat3e/Makefile.in b/bochs/cpu/softfloat3e/Makefile.in index 57170edda..527058c16 100644 --- a/bochs/cpu/softfloat3e/Makefile.in +++ b/bochs/cpu/softfloat3e/Makefile.in @@ -119,6 +119,7 @@ OBJS_OTHERS = \ s_addMagsF64$(OBJ) \ s_subMagsF64$(OBJ) \ s_mulAddF64$(OBJ) \ + s_packToExtF80$(OBJ) \ s_normSubnormalExtF80Sig$(OBJ) \ s_roundPackToExtF80$(OBJ) \ s_normRoundPackToExtF80$(OBJ) \ diff --git a/bochs/cpu/softfloat3e/extF80_addsub.c b/bochs/cpu/softfloat3e/extF80_addsub.c index bdc9917b4..58a968772 100644 --- a/bochs/cpu/softfloat3e/extF80_addsub.c +++ b/bochs/cpu/softfloat3e/extF80_addsub.c @@ -39,6 +39,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "specialize.h" #include "softfloat.h" +extern extFloat80_t softfloat_addMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *); +extern extFloat80_t softfloat_subMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *); + extFloat80_t extF80_add(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status) { uint16_t uiA64; diff --git a/bochs/cpu/softfloat3e/extF80_class.c b/bochs/cpu/softfloat3e/extF80_class.c index 1f49ef6d8..6de12a5e3 100644 --- a/bochs/cpu/softfloat3e/extF80_class.c +++ b/bochs/cpu/softfloat3e/extF80_class.c @@ -52,8 +52,8 @@ softfloat_class_t extF80_class(extFloat80_t a) expA = expExtF80UI64(uiA64); sigA = uiA0; - if(expA == 0) { - if (sigA == 0) return softfloat_zero; + if (! expA) { + if (! sigA) return softfloat_zero; return softfloat_denormal; /* denormal or pseudo-denormal */ } @@ -62,7 +62,7 @@ softfloat_class_t extF80_class(extFloat80_t a) return softfloat_SNaN; /* report unsupported as SNaNs */ if (expA == 0x7FFF) { - if (((uint64_t) (sigA<<1)) == 0) + if ((sigA<<1) == 0) return (signA) ? softfloat_negative_inf : softfloat_positive_inf; return (sigA & UINT64_C(0x4000000000000000)) ? softfloat_QNaN : softfloat_SNaN; diff --git a/bochs/cpu/softfloat3e/extF80_compare.c b/bochs/cpu/softfloat3e/extF80_compare.c index eda23fb8b..7369d90e3 100644 --- a/bochs/cpu/softfloat3e/extF80_compare.c +++ b/bochs/cpu/softfloat3e/extF80_compare.c @@ -111,12 +111,12 @@ int extF80_compare(extFloat80_t a, extFloat80_t b, int quiet, softfloat_status_t *------------------------------------------------------------------------*/ if (aClass == softfloat_denormal) { normExpSig = softfloat_normSubnormalExtF80Sig(sigA); - expA += normExpSig.exp; + expA += normExpSig.exp + 1; sigA = normExpSig.sig; } if (bClass == softfloat_denormal) { normExpSig = softfloat_normSubnormalExtF80Sig(sigB); - expB += normExpSig.exp; + expB += normExpSig.exp + 1; sigB = normExpSig.sig; } diff --git a/bochs/cpu/softfloat3e/extF80_div.c b/bochs/cpu/softfloat3e/extF80_div.c index fedb52ede..b4b761a74 100644 --- a/bochs/cpu/softfloat3e/extF80_div.c +++ b/bochs/cpu/softfloat3e/extF80_div.c @@ -63,9 +63,6 @@ extFloat80_t extF80_div(extFloat80_t a, extFloat80_t b, struct softfloat_status_ struct uint128 term; uint64_t sigZExtra; struct uint128 uiZ; - uint16_t uiZ64; - uint64_t uiZ0; - extFloat80_t z; // handle unsupported extended double-precision floating encodings if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) @@ -92,29 +89,41 @@ extFloat80_t extF80_div(extFloat80_t a, extFloat80_t b, struct softfloat_status_ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; goto invalid; } - goto infinity; + if (! expB && sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000)); } if (expB == 0x7FFF) { if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; - goto zero; + if (! expA && sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ, 0, 0); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - if (! expB) expB = 1; + if (! expB) { + expB = 1; + if (sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } if (! (sigB & UINT64_C(0x8000000000000000))) { if (! sigB) { if (! sigA) goto invalid; softfloat_raiseFlags(status, softfloat_flag_infinite); - goto infinity; + return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000)); } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalExtF80Sig(sigB); expB += normExpSig.exp; sigB = normExpSig.sig; } - if (! expA) expA = 1; + if (! expA) { + expA = 1; + if (sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } if (! (sigA & UINT64_C(0x8000000000000000))) { - if (! sigA) goto zero; + if (! sigA) return packToExtF80(signZ, 0, 0); softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalExtF80Sig(sigA); expA += normExpSig.exp; @@ -172,29 +181,10 @@ extFloat80_t extF80_div(extFloat80_t a, extFloat80_t b, struct softfloat_status_ *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - goto uiZ; + return packToExtF80(uiZ.v64, uiZ.v0); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags(status, softfloat_flag_invalid); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infinity: - uiZ64 = packToExtF80UI64(signZ, 0x7FFF); - uiZ0 = UINT64_C(0x8000000000000000); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ64 = packToExtF80UI64(signZ, 0); - uiZ0 = 0; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(defaultNaNExtF80UI64, defaultNaNExtF80UI0); } diff --git a/bochs/cpu/softfloat3e/extF80_mul.c b/bochs/cpu/softfloat3e/extF80_mul.c index a6d2f8d07..e56396fba 100644 --- a/bochs/cpu/softfloat3e/extF80_mul.c +++ b/bochs/cpu/softfloat3e/extF80_mul.c @@ -58,14 +58,11 @@ extFloat80_t extF80_mul(extFloat80_t a, extFloat80_t b, struct softfloat_status_ struct uint128 sig128Z, uiZ; uint16_t uiZ64; uint64_t uiZ0; - extFloat80_t z; // handle unsupported extended double-precision floating encodings if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { softfloat_raiseFlags(status, softfloat_flag_invalid); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; + return packToExtF80(defaultNaNExtF80UI64, defaultNaNExtF80UI0); } /*------------------------------------------------------------------------ @@ -97,17 +94,29 @@ extFloat80_t extF80_mul(extFloat80_t a, extFloat80_t b, struct softfloat_status_ } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - if (! expA) expA = 1; + if (! expA) { + expA = 1; + if (sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } if (! (sigA & UINT64_C(0x8000000000000000))) { - if (! sigA) goto zero; + if (! sigA) { + if (! expB && sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ, 0, 0); + } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalExtF80Sig(sigA); expA += normExpSig.exp; sigA = normExpSig.sig; } - if (! expB) expB = 1; + if (! expB) { + expB = 1; + if (sigB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } if (! (sigB & UINT64_C(0x8000000000000000))) { - if (! sigB) goto zero; + if (! sigB) return packToExtF80(signZ, 0, 0); softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalExtF80Sig(sigB); expB += normExpSig.exp; @@ -127,9 +136,7 @@ extFloat80_t extF80_mul(extFloat80_t a, extFloat80_t b, struct softfloat_status_ *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - goto uiZ; + return packToExtF80(uiZ.v64, uiZ.v0); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ infArg: @@ -138,17 +145,10 @@ extFloat80_t extF80_mul(extFloat80_t a, extFloat80_t b, struct softfloat_status_ uiZ64 = defaultNaNExtF80UI64; uiZ0 = defaultNaNExtF80UI0; } else { + if ((! expA && sigA) || (! expB && sigB)) + softfloat_raiseFlags(status, softfloat_flag_denormal); uiZ64 = packToExtF80UI64(signZ, 0x7FFF); uiZ0 = UINT64_C(0x8000000000000000); } - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ64 = packToExtF80UI64(signZ, 0); - uiZ0 = 0; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(uiZ64, uiZ0); } diff --git a/bochs/cpu/softfloat3e/extF80_rem.c b/bochs/cpu/softfloat3e/extF80_rem.c index a60018f33..43c24276f 100644 --- a/bochs/cpu/softfloat3e/extF80_rem.c +++ b/bochs/cpu/softfloat3e/extF80_rem.c @@ -58,9 +58,6 @@ extFloat80_t extF80_rem(extFloat80_t a, extFloat80_t b, struct softfloat_status_ struct uint128 term, altRem, meanRem; bool signRem; struct uint128 uiZ; - uint16_t uiZ64; - uint64_t uiZ0; - extFloat80_t z; // handle unsupported extended double-precision floating encodings if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) @@ -181,16 +178,12 @@ extFloat80_t extF80_rem(extFloat80_t a, extFloat80_t b, struct softfloat_status_ *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - goto uiZ; + return packToExtF80(uiZ.v64, uiZ.v0); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags(status, softfloat_flag_invalid); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; + return packToExtF80(defaultNaNExtF80UI64, defaultNaNExtF80UI0); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ copyA: @@ -198,11 +191,5 @@ extFloat80_t extF80_rem(extFloat80_t a, extFloat80_t b, struct softfloat_status_ sigA >>= 1 - expA; expA = 0; } - uiZ64 = packToExtF80UI64(signA, expA); - uiZ0 = sigA; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(signA, expA, sigA); } - diff --git a/bochs/cpu/softfloat3e/extF80_roundToInt.c b/bochs/cpu/softfloat3e/extF80_roundToInt.c index 903b6d538..9d912896e 100644 --- a/bochs/cpu/softfloat3e/extF80_roundToInt.c +++ b/bochs/cpu/softfloat3e/extF80_roundToInt.c @@ -50,14 +50,11 @@ extFloat80_t struct exp32_sig64 normExpSig; struct uint128 uiZ; uint64_t lastBitMask, roundBitsMask; - extFloat80_t z; // handle unsupported extended double-precision floating encodings if (extF80_isUnsupported(a)) { softfloat_raiseFlags(status, softfloat_flag_invalid); - uiZ64 = defaultNaNExtF80UI64; - sigZ = defaultNaNExtF80UI0; - goto uiZ; + return packToExtF80(defaultNaNExtF80UI64, defaultNaNExtF80UI0); } /*------------------------------------------------------------------------ @@ -70,9 +67,7 @@ extFloat80_t *------------------------------------------------------------------------*/ if (!(sigA & UINT64_C(0x8000000000000000)) && (exp != 0x7FFF)) { if (!sigA) { - uiZ64 = signUI64; - sigZ = 0; - goto uiZ; + return packToExtF80(signUI64, 0, 0); } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalExtF80Sig(sigA); @@ -85,16 +80,13 @@ extFloat80_t if (exp == 0x7FFF) { if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) { uiZ = softfloat_propagateNaNExtF80UI(uiA64, sigA, 0, 0, status); - uiZ64 = uiZ.v64; - sigZ = uiZ.v0; - goto uiZ; + return packToExtF80(uiZ.v64, uiZ.v0); } sigZ = UINT64_C(0x8000000000000000); } else { sigZ = sigA; } - uiZ64 = signUI64 | exp; - goto uiZ; + return packToExtF80(signUI64, exp, sigZ); } if (exp <= 0x3FFE) { if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); @@ -111,13 +103,10 @@ extFloat80_t if (!signUI64) goto mag1; break; } - uiZ64 = signUI64; - sigZ = 0; - goto uiZ; + return packToExtF80(signUI64, 0, 0); mag1: - uiZ64 = signUI64 | 0x3FFF; - sigZ = UINT64_C(0x8000000000000000); - goto uiZ; + softfloat_setRoundingUp(status); + return packToExtF80(signUI64, 0x3FFF, UINT64_C(0x8000000000000000)); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -137,12 +126,12 @@ extFloat80_t if (!sigZ) { ++uiZ64; sigZ = UINT64_C(0x8000000000000000); + softfloat_setRoundingUp(status); } if (sigZ != sigA) { if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sigZ > sigA) + softfloat_setRoundingUp(status); } - uiZ: - z.signExp = uiZ64; - z.signif = sigZ; - return z; + return packToExtF80(uiZ64, sigZ); } diff --git a/bochs/cpu/softfloat3e/extF80_sqrt.c b/bochs/cpu/softfloat3e/extF80_sqrt.c index 71d5e8eeb..1853c957f 100644 --- a/bochs/cpu/softfloat3e/extF80_sqrt.c +++ b/bochs/cpu/softfloat3e/extF80_sqrt.c @@ -56,7 +56,6 @@ extFloat80_t extF80_sqrt(extFloat80_t a, struct softfloat_status_t *status) uint64_t q, x64, sigZ; struct uint128 y, term; uint64_t sigZExtra; - extFloat80_t z; // handle unsupported extended double-precision floating encodings if (extF80_isUnsupported(a)) @@ -74,9 +73,7 @@ extFloat80_t extF80_sqrt(extFloat80_t a, struct softfloat_status_t *status) if (expA == 0x7FFF) { if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) { uiZ = softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - goto uiZ; + return packToExtF80(uiZ.v64, uiZ.v0); } if (! signA) return a; goto invalid; @@ -84,15 +81,18 @@ extFloat80_t extF80_sqrt(extFloat80_t a, struct softfloat_status_t *status) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if (signA) { - if (! sigA) goto zero; + if ((expA | sigA) == 0) return packToExtF80(signA, 0, 0); goto invalid; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - if (! expA) expA = 1; + if (! expA) { + expA = 1; + if (sigA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + } if (! (sigA & UINT64_C(0x8000000000000000))) { - if (! sigA) goto zero; - softfloat_raiseFlags(status, softfloat_flag_denormal); + if (! sigA) return packToExtF80(signA, 0, 0); normExpSig = softfloat_normSubnormalExtF80Sig(sigA); expA += normExpSig.exp; sigA = normExpSig.sig; @@ -154,22 +154,10 @@ extFloat80_t extF80_sqrt(extFloat80_t a, struct softfloat_status_t *status) } } return - softfloat_roundPackToExtF80( - 0, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status); + softfloat_roundPackToExtF80(0, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags(status, softfloat_flag_invalid); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ64 = packToExtF80UI64(signA, 0); - uiZ0 = 0; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(defaultNaNExtF80UI64, defaultNaNExtF80UI0); } diff --git a/bochs/cpu/softfloat3e/extF80_to_f128.c b/bochs/cpu/softfloat3e/extF80_to_f128.c index 0663a4558..03976038c 100644 --- a/bochs/cpu/softfloat3e/extF80_to_f128.c +++ b/bochs/cpu/softfloat3e/extF80_to_f128.c @@ -49,14 +49,13 @@ float128_t extF80_to_f128(extFloat80_t a, struct softfloat_status_t *status) struct uint128 uiZ; bool sign; struct uint128 frac128; - union ui128_f128 uZ; // handle unsupported extended double-precision floating encodings if (extF80_isUnsupported(a)) { softfloat_raiseFlags(status, softfloat_flag_invalid); uiZ.v64 = defaultNaNF128UI64; uiZ.v0 = defaultNaNF128UI0; - goto uiZ; + return uiZ; } uiA64 = a.signExp; @@ -72,7 +71,5 @@ float128_t extF80_to_f128(extFloat80_t a, struct softfloat_status_t *status) uiZ.v64 = packToF128UI64(sign, exp, frac128.v64); uiZ.v0 = frac128.v0; } -uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/f128_addsub.c b/bochs/cpu/softfloat3e/f128_addsub.c index 891d9759f..ad65cfdf7 100644 --- a/bochs/cpu/softfloat3e/f128_addsub.c +++ b/bochs/cpu/softfloat3e/f128_addsub.c @@ -38,23 +38,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "internals.h" #include "softfloat.h" +extern float128_t + softfloat_addMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *); +extern float128_t + softfloat_subMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *); + float128_t f128_add(float128_t a, float128_t b, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool signA; - union ui128_f128 uB; uint64_t uiB64, uiB0; bool signB; - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; signA = signF128UI64(uiA64); - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; + uiB64 = b.v64; + uiB0 = b.v0; signB = signF128UI64(uiB64); if (signA == signB) { @@ -66,21 +67,17 @@ float128_t f128_add(float128_t a, float128_t b, struct softfloat_status_t *statu float128_t f128_sub(float128_t a, float128_t b, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool signA; - union ui128_f128 uB; uint64_t uiB64, uiB0; bool signB; - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; signA = signF128UI64(uiA64); - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; + uiB64 = b.v64; + uiB0 = b.v0; signB = signF128UI64(uiB64); if (signA == signB) { diff --git a/bochs/cpu/softfloat3e/f128_div.c b/bochs/cpu/softfloat3e/f128_div.c index 79b5b8252..f709ae0d3 100644 --- a/bochs/cpu/softfloat3e/f128_div.c +++ b/bochs/cpu/softfloat3e/f128_div.c @@ -41,12 +41,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float128_t f128_div(float128_t a, float128_t b, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool signA; int32_t expA; struct uint128 sigA; - union ui128_f128 uB; uint64_t uiB64, uiB0; bool signB; int32_t expB; @@ -63,20 +61,17 @@ float128_t f128_div(float128_t a, float128_t b, struct softfloat_status_t *statu uint32_t qs[3]; uint64_t sigZExtra; struct uint128 sigZ, uiZ; - union ui128_f128 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; signA = signF128UI64(uiA64); expA = expF128UI64(uiA64); sigA.v64 = fracF128UI64(uiA64); sigA.v0 = uiA0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; + uiB64 = b.v64; + uiB0 = b.v0; signB = signF128UI64(uiB64); expB = expF128UI64(uiB64); sigB.v64 = fracF128UI64(uiB64); @@ -168,26 +163,24 @@ float128_t f128_div(float128_t a, float128_t b, struct softfloat_status_t *statu *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); - goto uiZ; + return uiZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags(status, softfloat_flag_invalid); uiZ.v64 = defaultNaNF128UI64; uiZ.v0 = defaultNaNF128UI0; - goto uiZ; + return uiZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ infinity: uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0); - goto uiZ0; + uiZ.v0 = 0; + return uiZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zero: uiZ.v64 = packToF128UI64(signZ, 0, 0); - uiZ0: uiZ.v0 = 0; - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/f128_mul.c b/bochs/cpu/softfloat3e/f128_mul.c index b2df6e8b1..2c302eb5e 100644 --- a/bochs/cpu/softfloat3e/f128_mul.c +++ b/bochs/cpu/softfloat3e/f128_mul.c @@ -41,12 +41,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool signA; int32_t expA; struct uint128 sigA; - union ui128_f128 uB; uint64_t uiB64, uiB0; bool signB; int32_t expB; @@ -60,20 +58,17 @@ float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *statu struct uint128 sigZ; struct uint128_extra sig128Extra; struct uint128 uiZ; - union ui128_f128 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; signA = signF128UI64(uiA64); expA = expF128UI64(uiA64); sigA.v64 = fracF128UI64(uiA64); sigA.v0 = uiA0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; + uiB64 = b.v64; + uiB0 = b.v0; signB = signF128UI64(uiB64); expB = expF128UI64(uiB64); sigB.v64 = fracF128UI64(uiB64); @@ -82,9 +77,7 @@ float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *statu /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if (expA == 0x7FFF) { - if ( - (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0)) - ) { + if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) { goto propagateNaN; } magBits = expB | sigB.v64 | sigB.v0; @@ -131,7 +124,7 @@ float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *statu *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); - goto uiZ; + return uiZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ infArg: @@ -139,17 +132,15 @@ float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *statu softfloat_raiseFlags(status, softfloat_flag_invalid); uiZ.v64 = defaultNaNF128UI64; uiZ.v0 = defaultNaNF128UI0; - goto uiZ; + return uiZ; } uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0); - goto uiZ0; + uiZ.v0 = 0; + return uiZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zero: uiZ.v64 = packToF128UI64(signZ, 0, 0); - uiZ0: uiZ.v0 = 0; - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/f128_mulAdd.c b/bochs/cpu/softfloat3e/f128_mulAdd.c index 5d267f4cf..8ca9d66c8 100644 --- a/bochs/cpu/softfloat3e/f128_mulAdd.c +++ b/bochs/cpu/softfloat3e/f128_mulAdd.c @@ -39,21 +39,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float128_t f128_mulAdd(float128_t a, float128_t b, float128_t c, uint8_t op, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; - union ui128_f128 uB; uint64_t uiB64, uiB0; - union ui128_f128 uC; uint64_t uiC64, uiC0; - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - uC.f = c; - uiC64 = uC.ui.v64; - uiC0 = uC.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; + uiB64 = b.v64; + uiB0 = b.v0; + uiC64 = c.v64; + uiC0 = c.v0; + return softfloat_mulAddF128(uiA64, uiA0, uiB64, uiB0, uiC64, uiC0, op, status); } diff --git a/bochs/cpu/softfloat3e/f128_roundToInt.c b/bochs/cpu/softfloat3e/f128_roundToInt.c index 97fd4cb3c..5b8c19024 100644 --- a/bochs/cpu/softfloat3e/f128_roundToInt.c +++ b/bochs/cpu/softfloat3e/f128_roundToInt.c @@ -42,20 +42,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float128_t f128_roundToInt(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; int32_t exp; struct uint128 uiZ; uint64_t lastBitMask0, roundBitsMask; bool roundNearEven; uint64_t lastBitMask64; - union ui128_f128 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; exp = expF128UI64(uiA64); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -65,7 +62,7 @@ float128_t if (0x406F <= exp) { if ((exp == 0x7FFF) && (fracF128UI64(uiA64) | uiA0)) { uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, 0, 0, status); - goto uiZ; + return uiZ; } return a; } @@ -116,7 +113,7 @@ float128_t if (!uiZ.v64) uiZ.v64 = packToF128UI64(0, 0x3FFF, 0); break; } - goto uiZ; + return uiZ; } /*-------------------------------------------------------------------- *--------------------------------------------------------------------*/ @@ -140,7 +137,5 @@ float128_t if ((uiZ.v64 != uiA64) || (uiZ.v0 != uiA0)) { if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); } - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/f128_sqrt.c b/bochs/cpu/softfloat3e/f128_sqrt.c index aa2765376..91c854843 100644 --- a/bochs/cpu/softfloat3e/f128_sqrt.c +++ b/bochs/cpu/softfloat3e/f128_sqrt.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float128_t f128_sqrt(float128_t a, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool signA; int32_t expA; @@ -56,13 +55,11 @@ float128_t f128_sqrt(float128_t a, struct softfloat_status_t *status) struct uint128 y, term; uint64_t sigZExtra; struct uint128 sigZ; - union ui128_f128 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; signA = signF128UI64(uiA64); expA = expF128UI64(uiA64); sigA.v64 = fracF128UI64(uiA64); @@ -72,7 +69,7 @@ float128_t f128_sqrt(float128_t a, struct softfloat_status_t *status) if (expA == 0x7FFF) { if (sigA.v64 | sigA.v0) { uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, 0, 0, status); - goto uiZ; + return uiZ; } if (! signA) return a; goto invalid; @@ -192,7 +189,5 @@ float128_t f128_sqrt(float128_t a, struct softfloat_status_t *status) softfloat_raiseFlags(status, softfloat_flag_invalid); uiZ.v64 = defaultNaNF128UI64; uiZ.v0 = defaultNaNF128UI0; - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/f128_to_extF80.c b/bochs/cpu/softfloat3e/f128_to_extF80.c index 83487ec09..357067ac3 100644 --- a/bochs/cpu/softfloat3e/f128_to_extF80.c +++ b/bochs/cpu/softfloat3e/f128_to_extF80.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. extFloat80_t f128_to_extF80(float128_t a, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -52,13 +51,11 @@ extFloat80_t f128_to_extF80(float128_t a, struct softfloat_status_t *status) uint64_t uiZ0; struct exp32_sig128 normExpSig; struct uint128 sig128; - extFloat80_t z; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); frac64 = fracF128UI64(uiA64); @@ -75,15 +72,13 @@ extFloat80_t f128_to_extF80(float128_t a, struct softfloat_status_t *status) uiZ64 = packToExtF80UI64(sign, 0x7FFF); uiZ0 = UINT64_C(0x8000000000000000); } - goto uiZ; + return packToExtF80(uiZ64, uiZ0); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if (! exp) { if (! (frac64 | frac0)) { - uiZ64 = packToExtF80UI64(sign, 0); - uiZ0 = 0; - goto uiZ; + return packToExtF80(sign, 0, 0); } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalF128Sig(frac64, frac0); @@ -95,10 +90,4 @@ extFloat80_t f128_to_extF80(float128_t a, struct softfloat_status_t *status) *------------------------------------------------------------------------*/ sig128 = softfloat_shortShiftLeft128(frac64 | UINT64_C(0x0001000000000000), frac0, 15); return softfloat_roundPackToExtF80(sign, exp, sig128.v64, sig128.v0, 80, status); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; } diff --git a/bochs/cpu/softfloat3e/f128_to_f32.c b/bochs/cpu/softfloat3e/f128_to_f32.c index ddf91c762..caa60efc0 100644 --- a/bochs/cpu/softfloat3e/f128_to_f32.c +++ b/bochs/cpu/softfloat3e/f128_to_f32.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float32_t f128_to_f32(float128_t a, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -51,9 +50,8 @@ float32_t f128_to_f32(float128_t a, struct softfloat_status_t *status) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); frac64 = fracF128UI64(uiA64) | (uiA0 != 0); diff --git a/bochs/cpu/softfloat3e/f128_to_f64.c b/bochs/cpu/softfloat3e/f128_to_f64.c index 9e97c3dcf..705640625 100644 --- a/bochs/cpu/softfloat3e/f128_to_f64.c +++ b/bochs/cpu/softfloat3e/f128_to_f64.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. float64_t f128_to_f64(float128_t a, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -52,9 +51,8 @@ float64_t f128_to_f64(float128_t a, struct softfloat_status_t *status) /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); frac64 = fracF128UI64(uiA64); diff --git a/bochs/cpu/softfloat3e/f128_to_i32.c b/bochs/cpu/softfloat3e/f128_to_i32.c index 95120d796..4bf149786 100644 --- a/bochs/cpu/softfloat3e/f128_to_i32.c +++ b/bochs/cpu/softfloat3e/f128_to_i32.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. int32_t f128_to_i32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -50,9 +49,8 @@ int32_t f128_to_i32(float128_t a, uint8_t roundingMode, bool exact, struct softf /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); sig64 = fracF128UI64(uiA64); diff --git a/bochs/cpu/softfloat3e/f128_to_i32_r_minMag.c b/bochs/cpu/softfloat3e/f128_to_i32_r_minMag.c index 2420672ce..a62233d4d 100644 --- a/bochs/cpu/softfloat3e/f128_to_i32_r_minMag.c +++ b/bochs/cpu/softfloat3e/f128_to_i32_r_minMag.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. int32_t f128_to_i32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; int32_t exp; uint64_t sig64; @@ -51,9 +50,8 @@ int32_t f128_to_i32_r_minMag(float128_t a, bool exact, struct softfloat_status_t /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; exp = expF128UI64(uiA64); sig64 = fracF128UI64(uiA64) | (uiA0 != 0); /*------------------------------------------------------------------------ diff --git a/bochs/cpu/softfloat3e/f128_to_i64.c b/bochs/cpu/softfloat3e/f128_to_i64.c index 3207a1979..29e2ca93a 100644 --- a/bochs/cpu/softfloat3e/f128_to_i64.c +++ b/bochs/cpu/softfloat3e/f128_to_i64.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. int64_t f128_to_i64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -52,9 +51,8 @@ int64_t f128_to_i64(float128_t a, uint8_t roundingMode, bool exact, struct softf /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); sig64 = fracF128UI64(uiA64); diff --git a/bochs/cpu/softfloat3e/f128_to_i64_r_minMag.c b/bochs/cpu/softfloat3e/f128_to_i64_r_minMag.c index eda6211a8..4c384c628 100644 --- a/bochs/cpu/softfloat3e/f128_to_i64_r_minMag.c +++ b/bochs/cpu/softfloat3e/f128_to_i64_r_minMag.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. int64_t f128_to_i64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -52,9 +51,8 @@ int64_t f128_to_i64_r_minMag(float128_t a, bool exact, struct softfloat_status_t /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); sig64 = fracF128UI64(uiA64); diff --git a/bochs/cpu/softfloat3e/f128_to_ui32.c b/bochs/cpu/softfloat3e/f128_to_ui32.c index 1139ce4f5..c6c60333a 100644 --- a/bochs/cpu/softfloat3e/f128_to_ui32.c +++ b/bochs/cpu/softfloat3e/f128_to_ui32.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. uint32_t f128_to_ui32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -50,9 +49,8 @@ uint32_t f128_to_ui32(float128_t a, uint8_t roundingMode, bool exact, struct sof /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); sig64 = fracF128UI64(uiA64) | (uiA0 != 0); diff --git a/bochs/cpu/softfloat3e/f128_to_ui32_r_minMag.c b/bochs/cpu/softfloat3e/f128_to_ui32_r_minMag.c index 1730a6fcd..96007f6a1 100644 --- a/bochs/cpu/softfloat3e/f128_to_ui32_r_minMag.c +++ b/bochs/cpu/softfloat3e/f128_to_ui32_r_minMag.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. uint32_t f128_to_ui32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; int32_t exp; uint64_t sig64; @@ -51,9 +50,8 @@ uint32_t f128_to_ui32_r_minMag(float128_t a, bool exact, struct softfloat_status /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; exp = expF128UI64(uiA64); sig64 = fracF128UI64(uiA64) | (uiA0 != 0); /*------------------------------------------------------------------------ diff --git a/bochs/cpu/softfloat3e/f128_to_ui64.c b/bochs/cpu/softfloat3e/f128_to_ui64.c index 582850a2f..82f166232 100644 --- a/bochs/cpu/softfloat3e/f128_to_ui64.c +++ b/bochs/cpu/softfloat3e/f128_to_ui64.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. uint64_t f128_to_ui64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -52,9 +51,8 @@ uint64_t f128_to_ui64(float128_t a, uint8_t roundingMode, bool exact, struct sof /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); sig64 = fracF128UI64(uiA64); diff --git a/bochs/cpu/softfloat3e/f128_to_ui64_r_minMag.c b/bochs/cpu/softfloat3e/f128_to_ui64_r_minMag.c index 72408c1f2..8d30420b0 100644 --- a/bochs/cpu/softfloat3e/f128_to_ui64_r_minMag.c +++ b/bochs/cpu/softfloat3e/f128_to_ui64_r_minMag.c @@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. uint64_t f128_to_ui64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status) { - union ui128_f128 uA; uint64_t uiA64, uiA0; bool sign; int32_t exp; @@ -52,9 +51,8 @@ uint64_t f128_to_ui64_r_minMag(float128_t a, bool exact, struct softfloat_status /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; + uiA64 = a.v64; + uiA0 = a.v0; sign = signF128UI64(uiA64); exp = expF128UI64(uiA64); sig64 = fracF128UI64(uiA64); diff --git a/bochs/cpu/softfloat3e/f16_addsub.c b/bochs/cpu/softfloat3e/f16_addsub.c index 3513bd269..90d45b9e8 100644 --- a/bochs/cpu/softfloat3e/f16_addsub.c +++ b/bochs/cpu/softfloat3e/f16_addsub.c @@ -38,6 +38,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "internals.h" #include "softfloat.h" +extern float16_t softfloat_addMagsF16(uint16_t, uint16_t, struct softfloat_status_t *); +extern float16_t softfloat_subMagsF16(uint16_t, uint16_t, struct softfloat_status_t *); + float16_t f16_add(float16_t a, float16_t b, struct softfloat_status_t *status) { if (signF16UI((uint16_t) a ^ (uint16_t) b)) { diff --git a/bochs/cpu/softfloat3e/f16_to_extF80.c b/bochs/cpu/softfloat3e/f16_to_extF80.c index 5c5a8a47b..fe027c405 100644 --- a/bochs/cpu/softfloat3e/f16_to_extF80.c +++ b/bochs/cpu/softfloat3e/f16_to_extF80.c @@ -49,7 +49,6 @@ extFloat80_t f16_to_extF80(float16_t a, struct softfloat_status_t *status) uint16_t uiZ64; uint64_t uiZ0; struct exp8_sig16 normExpSig; - extFloat80_t z; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -68,15 +67,13 @@ extFloat80_t f16_to_extF80(float16_t a, struct softfloat_status_t *status) uiZ64 = packToExtF80UI64(sign, 0x7FFF); uiZ0 = UINT64_C(0x8000000000000000); } - goto uiZ; + return packToExtF80(uiZ64, uiZ0); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if (! exp) { if (! frac) { - uiZ64 = packToExtF80UI64(sign, 0); - uiZ0 = 0; - goto uiZ; + return packToExtF80(sign, 0, 0); } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalF16Sig(frac); @@ -87,8 +84,5 @@ extFloat80_t f16_to_extF80(float16_t a, struct softfloat_status_t *status) *------------------------------------------------------------------------*/ uiZ64 = packToExtF80UI64(sign, exp + 0x3FF0); uiZ0 = (uint64_t) (frac | 0x0400)<<53; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(uiZ64, uiZ0); } diff --git a/bochs/cpu/softfloat3e/f32_addsub.c b/bochs/cpu/softfloat3e/f32_addsub.c index 66e0c253b..938100e02 100644 --- a/bochs/cpu/softfloat3e/f32_addsub.c +++ b/bochs/cpu/softfloat3e/f32_addsub.c @@ -38,6 +38,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "internals.h" #include "softfloat.h" +extern float32_t softfloat_addMagsF32(uint32_t, uint32_t, struct softfloat_status_t *); +extern float32_t softfloat_subMagsF32(uint32_t, uint32_t, struct softfloat_status_t *); + float32_t f32_add(float32_t a, float32_t b, struct softfloat_status_t *status) { if (signF32UI((uint32_t) a ^ (uint32_t) b)) { diff --git a/bochs/cpu/softfloat3e/f32_to_extF80.c b/bochs/cpu/softfloat3e/f32_to_extF80.c index 832424631..6b7ce1b50 100644 --- a/bochs/cpu/softfloat3e/f32_to_extF80.c +++ b/bochs/cpu/softfloat3e/f32_to_extF80.c @@ -49,7 +49,6 @@ extFloat80_t f32_to_extF80(float32_t a, struct softfloat_status_t *status) uint16_t uiZ64; uint64_t uiZ0; struct exp16_sig32 normExpSig; - extFloat80_t z; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -68,15 +67,13 @@ extFloat80_t f32_to_extF80(float32_t a, struct softfloat_status_t *status) uiZ64 = packToExtF80UI64(sign, 0x7FFF); uiZ0 = UINT64_C(0x8000000000000000); } - goto uiZ; + return packToExtF80(uiZ64, uiZ0); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if (! exp) { if (! frac) { - uiZ64 = packToExtF80UI64(sign, 0); - uiZ0 = 0; - goto uiZ; + return packToExtF80(sign, 0, 0); } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalF32Sig(frac); @@ -87,8 +84,5 @@ extFloat80_t f32_to_extF80(float32_t a, struct softfloat_status_t *status) *------------------------------------------------------------------------*/ uiZ64 = packToExtF80UI64(sign, exp + 0x3F80); uiZ0 = (uint64_t) (frac | 0x00800000)<<40; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(uiZ64, uiZ0); } diff --git a/bochs/cpu/softfloat3e/f32_to_f128.c b/bochs/cpu/softfloat3e/f32_to_f128.c index 61ffb4cfb..9b105f39c 100644 --- a/bochs/cpu/softfloat3e/f32_to_f128.c +++ b/bochs/cpu/softfloat3e/f32_to_f128.c @@ -47,7 +47,6 @@ float128_t f32_to_f128(float32_t a, struct softfloat_status_t *status) struct commonNaN commonNaN; struct uint128 uiZ; struct exp16_sig32 normExpSig; - union ui128_f128 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -64,7 +63,7 @@ float128_t f32_to_f128(float32_t a, struct softfloat_status_t *status) uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0); uiZ.v0 = 0; } - goto uiZ; + return uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -72,7 +71,7 @@ float128_t f32_to_f128(float32_t a, struct softfloat_status_t *status) if (! frac) { uiZ.v64 = packToF128UI64(sign, 0, 0); uiZ.v0 = 0; - goto uiZ; + return uiZ; } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalF32Sig(frac); @@ -83,7 +82,5 @@ float128_t f32_to_f128(float32_t a, struct softfloat_status_t *status) *------------------------------------------------------------------------*/ uiZ.v64 = packToF128UI64(sign, exp + 0x3F80, (uint64_t) frac<<25); uiZ.v0 = 0; - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/f64_addsub.c b/bochs/cpu/softfloat3e/f64_addsub.c index 34cd5dfab..865059dcb 100644 --- a/bochs/cpu/softfloat3e/f64_addsub.c +++ b/bochs/cpu/softfloat3e/f64_addsub.c @@ -38,6 +38,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "internals.h" #include "softfloat.h" +extern float64_t softfloat_addMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *); +extern float64_t softfloat_subMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *); + float64_t f64_add(float64_t a, float64_t b, struct softfloat_status_t *status) { bool signA; diff --git a/bochs/cpu/softfloat3e/f64_to_extF80.c b/bochs/cpu/softfloat3e/f64_to_extF80.c index 0fd035b4c..6fab74d0b 100644 --- a/bochs/cpu/softfloat3e/f64_to_extF80.c +++ b/bochs/cpu/softfloat3e/f64_to_extF80.c @@ -49,7 +49,6 @@ extFloat80_t f64_to_extF80(float64_t a, struct softfloat_status_t *status) uint16_t uiZ64; uint64_t uiZ0; struct exp16_sig64 normExpSig; - extFloat80_t z; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -68,15 +67,13 @@ extFloat80_t f64_to_extF80(float64_t a, struct softfloat_status_t *status) uiZ64 = packToExtF80UI64(sign, 0x7FFF); uiZ0 = UINT64_C(0x8000000000000000); } - goto uiZ; + return packToExtF80(uiZ64, uiZ0); } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if (! exp) { if (! frac) { - uiZ64 = packToExtF80UI64(sign, 0); - uiZ0 = 0; - goto uiZ; + return packToExtF80(sign, 0, 0); } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalF64Sig(frac); @@ -87,8 +84,5 @@ extFloat80_t f64_to_extF80(float64_t a, struct softfloat_status_t *status) *------------------------------------------------------------------------*/ uiZ64 = packToExtF80UI64(sign, exp + 0x3C00); uiZ0 = (frac | UINT64_C(0x0010000000000000))<<11; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(uiZ64, uiZ0); } diff --git a/bochs/cpu/softfloat3e/f64_to_f128.c b/bochs/cpu/softfloat3e/f64_to_f128.c index 757585e0a..b6472fe4a 100644 --- a/bochs/cpu/softfloat3e/f64_to_f128.c +++ b/bochs/cpu/softfloat3e/f64_to_f128.c @@ -48,7 +48,6 @@ float128_t f64_to_f128(float64_t a, struct softfloat_status_t *status) struct uint128 uiZ; struct exp16_sig64 normExpSig; struct uint128 frac128; - union ui128_f128 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -65,7 +64,7 @@ float128_t f64_to_f128(float64_t a, struct softfloat_status_t *status) uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0); uiZ.v0 = 0; } - goto uiZ; + return uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -73,7 +72,7 @@ float128_t f64_to_f128(float64_t a, struct softfloat_status_t *status) if (! frac) { uiZ.v64 = packToF128UI64(sign, 0, 0); uiZ.v0 = 0; - goto uiZ; + return uiZ; } softfloat_raiseFlags(status, softfloat_flag_denormal); normExpSig = softfloat_normSubnormalF64Sig(frac); @@ -85,7 +84,5 @@ float128_t f64_to_f128(float64_t a, struct softfloat_status_t *status) frac128 = softfloat_shortShiftLeft128(0, frac, 60); uiZ.v64 = packToF128UI64(sign, exp + 0x3C00, frac128.v64); uiZ.v0 = frac128.v0; - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/i32_to_f128.c b/bochs/cpu/softfloat3e/i32_to_f128.c index 2bc36c569..e2a57b68b 100644 --- a/bochs/cpu/softfloat3e/i32_to_f128.c +++ b/bochs/cpu/softfloat3e/i32_to_f128.c @@ -43,7 +43,7 @@ float128_t i32_to_f128(int32_t a) bool sign; uint32_t absA; int8_t shiftDist; - union ui128_f128 uZ; + float128_t z; uiZ64 = 0; if (a) { @@ -52,7 +52,7 @@ float128_t i32_to_f128(int32_t a) shiftDist = softfloat_countLeadingZeros32(absA) + 17; uiZ64 = packToF128UI64(sign, 0x402E - shiftDist, (uint64_t) absA<>63)) @@ -158,10 +148,6 @@ float128_t float128_t softfloat_normRoundPackToF128(bool, int32_t, uint64_t, uint64_t, struct softfloat_status_t *); -float128_t - softfloat_addMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *); -float128_t - softfloat_subMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *); float128_t softfloat_mulAddF128( uint64_t, diff --git a/bochs/cpu/softfloat3e/include/softfloat.h b/bochs/cpu/softfloat3e/include/softfloat.h index f329171eb..531e1e412 100644 --- a/bochs/cpu/softfloat3e/include/softfloat.h +++ b/bochs/cpu/softfloat3e/include/softfloat.h @@ -48,6 +48,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "softfloat_types.h" +#include "softfloat-extra.h" + +#define FLOATX80 + struct softfloat_status_t { uint8_t softfloat_roundingMode; @@ -104,6 +108,10 @@ enum softfloat_exception_flag_t { softfloat_flag_inexact = 0x20 }; +#ifdef FLOATX80 +#define RAISE_SW_C1 0x0200 +#endif + /*---------------------------------------------------------------------------- | Software IEC/IEEE floating-point ordering relations *----------------------------------------------------------------------------*/ @@ -141,6 +149,10 @@ enum { softfloat_muladd_negate_result = softfloat_muladd_negate_c | softfloat_muladd_negate_product }; +BX_CPP_INLINE void softfloat_setFlags(struct softfloat_status_t *status, int flags) { + status->softfloat_exceptionFlags = flags; +} + /*---------------------------------------------------------------------------- | Routine to raise any or all of the software floating-point exception flags. *----------------------------------------------------------------------------*/ @@ -151,7 +163,7 @@ BX_CPP_INLINE void softfloat_raiseFlags(struct softfloat_status_t *status, int f /*---------------------------------------------------------------------------- | Check if exception is masked. *----------------------------------------------------------------------------*/ -BX_CPP_INLINE int softfloat_isMaskedException(struct softfloat_status_t *status, int flags) { +BX_CPP_INLINE int softfloat_isMaskedException(const struct softfloat_status_t *status, int flags) { return status->softfloat_exceptionMasks & flags; } @@ -165,38 +177,47 @@ BX_CPP_INLINE void softfloat_suppressException(struct softfloat_status_t *status /*---------------------------------------------------------------------------- | Obtain current rounding mode. *----------------------------------------------------------------------------*/ -BX_CPP_INLINE uint8_t softfloat_getRoundingMode(struct softfloat_status_t *status) { +BX_CPP_INLINE uint8_t softfloat_getRoundingMode(const struct softfloat_status_t *status) { return status->softfloat_roundingMode; } /*---------------------------------------------------------------------------- | Read denormals-are-zeroes flag. *----------------------------------------------------------------------------*/ -BX_CPP_INLINE bool softfloat_denormalsAreZeros(struct softfloat_status_t *status) { +BX_CPP_INLINE bool softfloat_denormalsAreZeros(const struct softfloat_status_t *status) { return status->softfloat_denormals_are_zeros; } /*---------------------------------------------------------------------------- | Read flush-underflow-to-zero flag. *----------------------------------------------------------------------------*/ -BX_CPP_INLINE bool softfloat_flushUnderflowToZero(struct softfloat_status_t *status) { +BX_CPP_INLINE bool softfloat_flushUnderflowToZero(const struct softfloat_status_t *status) { return status->softfloat_flush_underflow_to_zero; } /*---------------------------------------------------------------------------- | Obtain current rounding precision for F80. *----------------------------------------------------------------------------*/ -BX_CPP_INLINE uint8_t softfloat_extF80_roundingPrecision(struct softfloat_status_t *status) { +BX_CPP_INLINE uint8_t softfloat_extF80_roundingPrecision(const struct softfloat_status_t *status) { return status->extF80_roundingPrecision; } /*---------------------------------------------------------------------------- | Returns raised IEC/IEEE floating-point exception flags. *----------------------------------------------------------------------------*/ -BX_CPP_INLINE int softfloat_getExceptionFlags(struct softfloat_status_t *status) { +BX_CPP_INLINE int softfloat_getExceptionFlags(const struct softfloat_status_t *status) { return status->softfloat_exceptionFlags & ~status->softfloat_suppressException; } +/*---------------------------------------------------------------------------- +| Raise floating point precision lost up flag (floatx80 only). +*----------------------------------------------------------------------------*/ +#ifdef FLOATX80 +BX_CPP_INLINE void softfloat_setRoundingUp(struct softfloat_status_t *status) { + status->softfloat_exceptionFlags |= RAISE_SW_C1; +} +#endif + /*---------------------------------------------------------------------------- | Integer-to-floating-point conversion routines. *----------------------------------------------------------------------------*/ @@ -283,87 +304,87 @@ BX_CPP_INLINE float16_t f16_roundToInt(float16_t a, struct softfloat_status_t *s return f16_roundToInt(a, 0, softfloat_getRoundingMode(status), true, status); } +BX_CPP_INLINE int64_t f16_to_i64(float16_t a, struct softfloat_status_t *status) { + return f16_to_i64(a, softfloat_getRoundingMode(status), true, status); +} +BX_CPP_INLINE int32_t f16_to_i32(float16_t a, struct softfloat_status_t *status) { + return f16_to_i32(a, softfloat_getRoundingMode(status), true, status); +} + BX_CPP_INLINE int16_t f16_to_i16(float16_t a, softfloat_status_t *status) { - int32_t val_32 = f16_to_i32(a, softfloat_getRoundingMode(status), false, status); + int32_t val_32 = f16_to_i32(a, status); int16_t val_16 = (int16_t) val_32; if ((int32_t)(val_16) != val_32) { - softfloat_raiseFlags(status, softfloat_flag_invalid); + softfloat_setFlags(status, softfloat_flag_invalid); return (int16_t) 0x8000; } return val_16; } -BX_CPP_INLINE int32_t f16_to_i32(float16_t a, struct softfloat_status_t *status) { - return f16_to_i32(a, softfloat_getRoundingMode(status), true, status); +BX_CPP_INLINE int64_t f16_to_i64_round_to_zero(float16_t a, struct softfloat_status_t *status) { + return f16_to_i64_r_minMag(a, true, status); } -BX_CPP_INLINE int64_t f16_to_i64(float16_t a, struct softfloat_status_t *status) { - return f16_to_i64(a, softfloat_getRoundingMode(status), true, status); +BX_CPP_INLINE int32_t f16_to_i32_round_to_zero(float16_t a, struct softfloat_status_t *status) { + return f16_to_i32_r_minMag(a, true, status); } BX_CPP_INLINE int16_t f16_to_i16_round_to_zero(float16_t a, softfloat_status_t *status) { - int32_t val_32 = f16_to_i32_r_minMag(a, false, status); + int32_t val_32 = f16_to_i32_round_to_zero(a, status); int16_t val_16 = (int16_t) val_32; if ((int32_t)(val_16) != val_32) { - softfloat_raiseFlags(status, softfloat_flag_invalid); + softfloat_setFlags(status, softfloat_flag_invalid); return (int16_t) 0x8000; } - return val_16; + return val_16; } -BX_CPP_INLINE int32_t f16_to_i32_round_to_zero(float16_t a, struct softfloat_status_t *status) { - return f16_to_i32_r_minMag(a, true, status); +BX_CPP_INLINE uint64_t f16_to_ui64(float16_t a, struct softfloat_status_t *status) { + return f16_to_ui64(a, softfloat_getRoundingMode(status), true, status); } -BX_CPP_INLINE int64_t f16_to_i64_round_to_zero(float16_t a, struct softfloat_status_t *status) { - return f16_to_i64_r_minMag(a, true, status); +BX_CPP_INLINE uint32_t f16_to_ui32(float16_t a, struct softfloat_status_t *status) { + return f16_to_ui32(a, softfloat_getRoundingMode(status), true, status); } BX_CPP_INLINE uint16_t f16_to_ui16(float16_t a, softfloat_status_t *status) { - uint32_t val_32 = f16_to_ui32(a, softfloat_getRoundingMode(status), false, status); + uint32_t val_32 = f16_to_ui32(a, status); if (val_32 > 0xFFFF) { - softfloat_raiseFlags(status, softfloat_flag_invalid); + softfloat_setFlags(status, softfloat_flag_invalid); return 0xFFFF; } return (uint16_t) val_32; } -BX_CPP_INLINE uint32_t f16_to_ui32(float16_t a, struct softfloat_status_t *status) { - return f16_to_ui32(a, softfloat_getRoundingMode(status), true, status); +BX_CPP_INLINE uint64_t f16_to_ui64_round_to_zero(float16_t a, struct softfloat_status_t *status) { + return f16_to_ui64_r_minMag(a, true, status); } -BX_CPP_INLINE uint64_t f16_to_ui64(float16_t a, struct softfloat_status_t *status) { - return f16_to_ui64(a, softfloat_getRoundingMode(status), true, status); +BX_CPP_INLINE uint32_t f16_to_ui32_round_to_zero(float16_t a, struct softfloat_status_t *status) { + return f16_to_ui32_r_minMag(a, true, status); } BX_CPP_INLINE uint16_t f16_to_ui16_round_to_zero(float16_t a, softfloat_status_t *status) { - uint32_t val_32 = f16_to_ui32_r_minMag(a, false, status); + uint32_t val_32 = f16_to_ui32_round_to_zero(a, status); if (val_32 > 0xFFFF) { - softfloat_raiseFlags(status, softfloat_flag_invalid); + softfloat_setFlags(status, softfloat_flag_invalid); return 0xFFFF; } return (uint16_t) val_32; } -BX_CPP_INLINE uint32_t f16_to_ui32_round_to_zero(float16_t a, struct softfloat_status_t *status) { - return f16_to_ui32_r_minMag(a, true, status); -} -BX_CPP_INLINE uint64_t f16_to_ui64_round_to_zero(float16_t a, struct softfloat_status_t *status) { - return f16_to_ui64_r_minMag(a, true, status); -} - BX_CPP_INLINE float16_t f16_fmadd(float16_t a, float16_t b, float16_t c, softfloat_status_t *status) { - return f16_mulAdd(a, b, c, 0, status); + return f16_mulAdd(a, b, c, 0, status); } BX_CPP_INLINE float16_t f16_fmsub(float16_t a, float16_t b, float16_t c, softfloat_status_t *status) { - return f16_mulAdd(a, b, c, softfloat_muladd_negate_c, status); + return f16_mulAdd(a, b, c, softfloat_muladd_negate_c, status); } BX_CPP_INLINE float16_t f16_fnmadd(float16_t a, float16_t b, float16_t c, softfloat_status_t *status) { - return f16_mulAdd(a, b, c, softfloat_muladd_negate_product, status); + return f16_mulAdd(a, b, c, softfloat_muladd_negate_product, status); } BX_CPP_INLINE float16_t f16_fnmsub(float16_t a, float16_t b, float16_t c, softfloat_status_t *status) { - return f16_mulAdd(a, b, c, softfloat_muladd_negate_result, status); + return f16_mulAdd(a, b, c, softfloat_muladd_negate_result, status); } /*---------------------------------------------------------------------------- @@ -407,11 +428,11 @@ uint32_t f32_fraction(float32_t); float32_t f32_denormal_to_zero(float32_t); BX_CPP_INLINE int f32_compare(float32_t a, float32_t b, softfloat_status_t *status) { - return f32_compare(a, b, 0, status); + return f32_compare(a, b, 0, status); } BX_CPP_INLINE int f32_compare_quiet(float32_t a, float32_t b, softfloat_status_t *status) { - return f32_compare(a, b, 1, status); + return f32_compare(a, b, 1, status); } BX_CPP_INLINE float32_t f32_roundToInt(float32_t a, uint8_t scale, struct softfloat_status_t *status) { @@ -450,16 +471,16 @@ BX_CPP_INLINE uint64_t f32_to_ui64_round_to_zero(float32_t a, struct softfloat_s } BX_CPP_INLINE float32_t f32_fmadd(float32_t a, float32_t b, float32_t c, softfloat_status_t *status) { - return f32_mulAdd(a, b, c, 0, status); + return f32_mulAdd(a, b, c, 0, status); } BX_CPP_INLINE float32_t f32_fmsub(float32_t a, float32_t b, float32_t c, softfloat_status_t *status) { - return f32_mulAdd(a, b, c, softfloat_muladd_negate_c, status); + return f32_mulAdd(a, b, c, softfloat_muladd_negate_c, status); } BX_CPP_INLINE float32_t f32_fnmadd(float32_t a, float32_t b, float32_t c, softfloat_status_t *status) { - return f32_mulAdd(a, b, c, softfloat_muladd_negate_product, status); + return f32_mulAdd(a, b, c, softfloat_muladd_negate_product, status); } BX_CPP_INLINE float32_t f32_fnmsub(float32_t a, float32_t b, float32_t c, softfloat_status_t *status) { - return f32_mulAdd(a, b, c, softfloat_muladd_negate_result, status); + return f32_mulAdd(a, b, c, softfloat_muladd_negate_result, status); } /*---------------------------------------------------------------------------- @@ -503,11 +524,11 @@ uint64_t f64_fraction(float64_t); float64_t f64_denormal_to_zero(float64_t); BX_CPP_INLINE int f64_compare(float64_t a, float64_t b, softfloat_status_t *status) { - return f64_compare(a, b, 0, status); + return f64_compare(a, b, 0, status); } BX_CPP_INLINE int f64_compare_quiet(float64_t a, float64_t b, softfloat_status_t *status) { - return f64_compare(a, b, 1, status); + return f64_compare(a, b, 1, status); } BX_CPP_INLINE float64_t f64_roundToInt(float64_t a, uint8_t scale, struct softfloat_status_t *status) { @@ -546,16 +567,16 @@ BX_CPP_INLINE uint64_t f64_to_ui64_round_to_zero(float64_t a, struct softfloat_s } BX_CPP_INLINE float64_t f64_fmadd(float64_t a, float64_t b, float64_t c, softfloat_status_t *status) { - return f64_mulAdd(a, b, c, 0, status); + return f64_mulAdd(a, b, c, 0, status); } BX_CPP_INLINE float64_t f64_fmsub(float64_t a, float64_t b, float64_t c, softfloat_status_t *status) { - return f64_mulAdd(a, b, c, softfloat_muladd_negate_c, status); + return f64_mulAdd(a, b, c, softfloat_muladd_negate_c, status); } BX_CPP_INLINE float64_t f64_fnmadd(float64_t a, float64_t b, float64_t c, softfloat_status_t *status) { - return f64_mulAdd(a, b, c, softfloat_muladd_negate_product, status); + return f64_mulAdd(a, b, c, softfloat_muladd_negate_product, status); } BX_CPP_INLINE float64_t f64_fnmsub(float64_t a, float64_t b, float64_t c, softfloat_status_t *status) { - return f64_mulAdd(a, b, c, softfloat_muladd_negate_result, status); + return f64_mulAdd(a, b, c, softfloat_muladd_negate_result, status); } /*---------------------------------------------------------------------------- @@ -584,13 +605,56 @@ int extF80_compare(extFloat80_t, extFloat80_t, int, softfloat_status_t *); softfloat_class_t extF80_class(extFloat80_t); BX_CPP_INLINE int extF80_compare(extFloat80_t a, extFloat80_t b, softfloat_status_t *status) { - return extF80_compare(a, b, 0, status); + return extF80_compare(a, b, 0, status); } BX_CPP_INLINE int extF80_compare_quiet(extFloat80_t a, extFloat80_t b, softfloat_status_t *status) { - return extF80_compare(a, b, 1, status); + return extF80_compare(a, b, 1, status); } +BX_CPP_INLINE extFloat80_t extF80_roundToInt(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_roundToInt(a, softfloat_getRoundingMode(status), true, status); +} + +BX_CPP_INLINE int64_t extF80_to_i64(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_to_i64(a, softfloat_getRoundingMode(status), true, status); +} +BX_CPP_INLINE int32_t extF80_to_i32(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_to_i32(a, softfloat_getRoundingMode(status), true, status); +} + +BX_CPP_INLINE int32_t extF80_to_i16(extFloat80_t a, struct softfloat_status_t *status) +{ + int32_t v32 = extF80_to_i32(a, status); + int16_t v16 = (int16_t) v32; + + if ((int32_t)(v16) != v32) { + softfloat_setFlags(status, softfloat_flag_invalid); + return (int16_t) 0x8000; + } + return v16; +} + +BX_CPP_INLINE int64_t extF80_to_i64_round_to_zero(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_to_i64_r_minMag(a, true, status); +} +BX_CPP_INLINE int32_t extF80_to_i32_round_to_zero(extFloat80_t a, struct softfloat_status_t *status) { + return extF80_to_i32_r_minMag(a, true, status); +} + +BX_CPP_INLINE int32_t extF80_to_i16_round_to_zero(extFloat80_t a, struct softfloat_status_t *status) +{ + int32_t v32 = extF80_to_i32_round_to_zero(a, status); + int16_t v16 = (int16_t) v32; + + if ((int32_t)(v16) != v32) { + softfloat_setFlags(status, softfloat_flag_invalid); + return (int16_t) 0x8000; + } + return v16; +} + +bool extF80_isUnsupported(extFloat80_t); bool extF80_isSignalingNaN(extFloat80_t); bool extF80_isNaN(extFloat80_t); @@ -618,6 +682,4 @@ float128_t f128_sqrt(float128_t, struct softfloat_status_t *); bool f128_isSignalingNaN(float128_t); bool f128_isNaN(float128_t); -#include "softfloat-extra.h" - #endif diff --git a/bochs/cpu/softfloat3e/include/softfloat_types.h b/bochs/cpu/softfloat3e/include/softfloat_types.h index d611a5da8..e2f819e5d 100644 --- a/bochs/cpu/softfloat3e/include/softfloat_types.h +++ b/bochs/cpu/softfloat3e/include/softfloat_types.h @@ -48,26 +48,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | (typically 'float' and 'double', and possibly 'long double'). *----------------------------------------------------------------------------*/ typedef struct f16_t { - uint16_t v; - f16_t(uint64_t v16): v(v16) {} - operator uint16_t() const { return v; } + uint16_t v; + f16_t(uint64_t v16): v(v16) {} + operator uint16_t() const { return v; } } float16_t; typedef struct f32_t { - uint32_t v; - f32_t(uint64_t v32): v(v32) {} - operator uint32_t() const { return v; } + uint32_t v; + f32_t(uint64_t v32): v(v32) {} + operator uint32_t() const { return v; } } float32_t; typedef struct f64_t { - uint64_t v; - f64_t(uint64_t v64): v(v64) {} - operator uint64_t() const { return v; } + uint64_t v; + f64_t(uint64_t v64): v(v64) {} + operator uint64_t() const { return v; } } float64_t; -typedef struct f128_t { - uint64_t v[2]; -} float128_t; +#ifdef BX_BIG_ENDIAN +struct float128 { + Bit64u hi, lo; +}; +#else +struct float128 { + Bit64u lo, hi; +}; +#endif + +#include "primitiveTypes.h" + +typedef uint128 f128_t, float128_t; /*---------------------------------------------------------------------------- | The format of an 80-bit extended floating-point number in memory. This @@ -75,14 +85,26 @@ typedef struct f128_t { | named 'signif'. *----------------------------------------------------------------------------*/ +#ifdef BX_BIG_ENDIAN +struct floatx80 { // leave alignment to compiler + Bit16u exp; + Bit64u fraction; +}; +#else +struct floatx80 { + Bit64u fraction; + Bit16u exp; +}; +#endif + #ifdef BX_LITTLE_ENDIAN struct extFloat80M { uint64_t signif; uint16_t signExp; extFloat80M(): signif(0), signExp(0) {} -//extFloat80M(struct floatx80 a): signif(a.fraction), signExp(a.exp) {} -//operator floatx80() const { floatx80 x; x.fraction = signif; x.exp = signExp; return x; } + extFloat80M(struct floatx80 a): signif(a.fraction), signExp(a.exp) {} + operator floatx80() const { floatx80 x; x.fraction = signif; x.exp = signExp; return x; } }; #else struct extFloat80M { @@ -90,8 +112,8 @@ struct extFloat80M { uint64_t signif; extFloat80M(): signExp(0), signif(0) {} -//extFloat80M(struct floatx80 a): signExp(a.exp), signif(a.fraction) {} -//operator floatx80() const { floatx80 x; x.fraction = signif; x.exp = signExp; return x; } + extFloat80M(struct floatx80 a): signExp(a.exp), signif(a.fraction) {} + operator floatx80() const { floatx80 x; x.fraction = signif; x.exp = signExp; return x; } }; #endif diff --git a/bochs/cpu/softfloat3e/isNaN.c b/bochs/cpu/softfloat3e/isNaN.c index 43d3abb3f..c10014d04 100644 --- a/bochs/cpu/softfloat3e/isNaN.c +++ b/bochs/cpu/softfloat3e/isNaN.c @@ -60,8 +60,5 @@ bool extF80_isNaN(extFloat80_t a) bool f128_isNaN(float128_t a) { - union ui128_f128 uA; - - uA.f = a; - return isNaNF128UI(uA.ui.v64, uA.ui.v0); + return isNaNF128UI(a.v64, a.v0); } diff --git a/bochs/cpu/softfloat3e/isSignalingNaN.c b/bochs/cpu/softfloat3e/isSignalingNaN.c index 45b4685d9..4e0a58acc 100644 --- a/bochs/cpu/softfloat3e/isSignalingNaN.c +++ b/bochs/cpu/softfloat3e/isSignalingNaN.c @@ -60,8 +60,5 @@ bool extF80_isSignalingNaN(extFloat80_t a) bool f128_isSignalingNaN(float128_t a) { - union ui128_f128 uA; - - uA.f = a; - return softfloat_isSigNaNF128UI(uA.ui.v64, uA.ui.v0); + return softfloat_isSigNaNF128UI(a.v64, a.v0); } diff --git a/bochs/cpu/softfloat3e/s_addMagsExtF80.c b/bochs/cpu/softfloat3e/s_addMagsExtF80.c index c60464016..a845e9b42 100644 --- a/bochs/cpu/softfloat3e/s_addMagsExtF80.c +++ b/bochs/cpu/softfloat3e/s_addMagsExtF80.c @@ -46,13 +46,12 @@ extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB int32_t expB; uint64_t sigB; int32_t expDiff; - uint16_t uiZ64; - uint64_t uiZ0, sigZ, sigZExtra; + uint64_t sigZ, sigZExtra; struct exp32_sig64 normExpSig; int32_t expZ; struct uint64_extra sig64Extra; struct uint128 uiZ; - extFloat80_t z; + bool overflow; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -62,66 +61,75 @@ extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB sigB = uiB0; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if (! expDiff) { - if (expA == 0x7FFF) { - if ((sigA | sigB) & UINT64_C(0x7FFFFFFFFFFFFFFF)) { - goto propagateNaN; + if (expA == 0x7FFF) { + if ((sigA << 1) || ((expB == 0x7FFF) && (sigB << 1))) + goto propagateNaN; + if (sigB && ! expB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(uiA64, uiA0); + } + if (expB == 0x7FFF) { + if (sigB << 1) goto propagateNaN; + if (sigA && ! expA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000)); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (! expB && sigB) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; } - uiZ64 = uiA64; - uiZ0 = uiA0; - goto uiZ; - } - sigZ = sigA + sigB; - sigZExtra = 0; - if (! expA) { - if (sigA | sigB) softfloat_raiseFlags(status, softfloat_flag_denormal); - normExpSig = softfloat_normSubnormalExtF80Sig(sigZ); - expZ = normExpSig.exp + 1; - sigZ = normExpSig.sig; + expZ = expB; + sigZ = sigB; + sigZExtra = 0; goto roundAndPack; } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA = normExpSig.exp + 1; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (expB == 0) { + if (sigB == 0) { + expZ = expA; + sigZ = sigA; + sigZExtra = 0; + goto roundAndPack; + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expA - expB; + if (! expDiff) { + sigZ = sigA + sigB; + sigZExtra = 0; expZ = expA; goto shiftRight1; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if (expDiff < 0) { - if (expB == 0x7FFF) { - if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; - uiZ64 = packToExtF80UI64(signZ, 0x7FFF); - uiZ0 = uiB0; - goto uiZ; - } expZ = expB; - if (! expA) { - if (sigA) softfloat_raiseFlags(status, softfloat_flag_denormal); - ++expDiff; - sigZExtra = 0; - if (! expDiff) goto newlyAligned; - } sig64Extra = softfloat_shiftRightJam64Extra(sigA, 0, -expDiff); sigA = sig64Extra.v; sigZExtra = sig64Extra.extra; } else { - if (expA == 0x7FFF) { - if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; - uiZ64 = uiA64; - uiZ0 = uiA0; - goto uiZ; - } expZ = expA; - if (! expB) { - if (sigB) softfloat_raiseFlags(status, softfloat_flag_denormal); - --expDiff; - sigZExtra = 0; - if (! expDiff) goto newlyAligned; - } sig64Extra = softfloat_shiftRightJam64Extra(sigB, 0, expDiff); sigB = sig64Extra.v; sigZExtra = sig64Extra.extra; } - newlyAligned: sigZ = sigA + sigB; if (sigZ & UINT64_C(0x8000000000000000)) goto roundAndPack; /*------------------------------------------------------------------------ @@ -137,10 +145,5 @@ extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(uiZ.v64, uiZ.v0); } diff --git a/bochs/cpu/softfloat3e/s_addMagsF128.c b/bochs/cpu/softfloat3e/s_addMagsF128.c index f6c128797..6bae85ba0 100644 --- a/bochs/cpu/softfloat3e/s_addMagsF128.c +++ b/bochs/cpu/softfloat3e/s_addMagsF128.c @@ -49,7 +49,6 @@ float128_t softfloat_addMagsF128(uint64_t uiA64, uint64_t uiA0, uint64_t uiB64, int32_t expZ; uint64_t sigZExtra; struct uint128_extra sig128Extra; - union ui128_f128 uZ; expA = expF128UI64(uiA64); sigA.v64 = fracF128UI64(uiA64); @@ -63,13 +62,13 @@ float128_t softfloat_addMagsF128(uint64_t uiA64, uint64_t uiA0, uint64_t uiB64, if (sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0) goto propagateNaN; uiZ.v64 = uiA64; uiZ.v0 = uiA0; - goto uiZ; + return uiZ; } sigZ = softfloat_add128(sigA.v64, sigA.v0, sigB.v64, sigB.v0); if (! expA) { uiZ.v64 = packToF128UI64(signZ, 0, sigZ.v64); uiZ.v0 = sigZ.v0; - goto uiZ; + return uiZ; } expZ = expA; sigZ.v64 |= UINT64_C(0x0002000000000000); @@ -81,7 +80,7 @@ float128_t softfloat_addMagsF128(uint64_t uiA64, uint64_t uiA0, uint64_t uiB64, if (sigB.v64 | sigB.v0) goto propagateNaN; uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0); uiZ.v0 = 0; - goto uiZ; + return uiZ; } expZ = expB; if (expA) { @@ -100,7 +99,7 @@ float128_t softfloat_addMagsF128(uint64_t uiA64, uint64_t uiA0, uint64_t uiB64, if (sigA.v64 | sigA.v0) goto propagateNaN; uiZ.v64 = uiA64; uiZ.v0 = uiA0; - goto uiZ; + return uiZ; } expZ = expA; if (expB) { @@ -134,7 +133,5 @@ float128_t softfloat_addMagsF128(uint64_t uiA64, uint64_t uiA0, uint64_t uiB64, softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status); propagateNaN: uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/s_mulAddF128.c b/bochs/cpu/softfloat3e/s_mulAddF128.c index 0835581da..cdb4311ff 100644 --- a/bochs/cpu/softfloat3e/s_mulAddF128.c +++ b/bochs/cpu/softfloat3e/s_mulAddF128.c @@ -72,7 +72,6 @@ float128_t uint64_t sig256C[4]; static uint64_t zero256[4] = INIT_UINTM4(0, 0, 0, 0); uint64_t sigZExtra, sig256Z0; - union ui128_f128 uZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -111,7 +110,7 @@ float128_t } uiZ.v64 = uiC64; uiZ.v0 = uiC0; - goto uiZ; + return uiZ; } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -309,15 +308,15 @@ float128_t if (magBits) { uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0); uiZ.v0 = 0; - if (expC != 0x7FFF) goto uiZ; - if (signZ == signC) goto uiZ; + if (expC != 0x7FFF) return uiZ; + if (signZ == signC) return uiZ; } softfloat_raiseFlags(status, softfloat_flag_invalid); uiZ.v64 = defaultNaNF128UI64; uiZ.v0 = defaultNaNF128UI0; propagateNaN_ZC: uiZ = softfloat_propagateNaNF128UI(uiZ.v64, uiZ.v0, uiC64, uiC0, status); - goto uiZ; + return uiZ; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ zeroProd: @@ -328,7 +327,5 @@ float128_t uiZ.v64 = packToF128UI64((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); uiZ.v0 = 0; } - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/s_normRoundPackToExtF80.c b/bochs/cpu/softfloat3e/s_normRoundPackToExtF80.c index ce3dc46dd..a32250019 100644 --- a/bochs/cpu/softfloat3e/s_normRoundPackToExtF80.c +++ b/bochs/cpu/softfloat3e/s_normRoundPackToExtF80.c @@ -63,6 +63,5 @@ extFloat80_t sigExtra = sig128.v0; } return - softfloat_roundPackToExtF80( - sign, exp, sig, sigExtra, roundingPrecision, status); + softfloat_roundPackToExtF80(sign, exp, sig, sigExtra, roundingPrecision, status); } diff --git a/bochs/cpu/softfloat3e/s_normRoundPackToF128.c b/bochs/cpu/softfloat3e/s_normRoundPackToF128.c index 44d73663c..3f726c97c 100644 --- a/bochs/cpu/softfloat3e/s_normRoundPackToF128.c +++ b/bochs/cpu/softfloat3e/s_normRoundPackToF128.c @@ -42,9 +42,9 @@ float128_t softfloat_normRoundPackToF128(bool sign, int32_t exp, uint64_t sig64, { int8_t shiftDist; struct uint128 sig128; - union ui128_f128 uZ; uint64_t sigExtra; struct uint128_extra sig128Extra; + float128_t z; if (! sig64) { exp -= 64; @@ -60,9 +60,9 @@ float128_t softfloat_normRoundPackToF128(bool sign, int32_t exp, uint64_t sig64, sig0 = sig128.v0; } if ((uint32_t) exp < 0x7FFD) { - uZ.ui.v64 = packToF128UI64(sign, sig64 | sig0 ? exp : 0, sig64); - uZ.ui.v0 = sig0; - return uZ.f; + z.v64 = packToF128UI64(sign, sig64 | sig0 ? exp : 0, sig64); + z.v0 = sig0; + return z; } sigExtra = 0; } else { diff --git a/bochs/cpu/softfloat3e/s_normSubnormalF128SigM.c b/bochs/cpu/softfloat3e/s_packToExtF80.c similarity index 76% rename from bochs/cpu/softfloat3e/s_normSubnormalF128SigM.c rename to bochs/cpu/softfloat3e/s_packToExtF80.c index 26e1e036c..9ec034e88 100644 --- a/bochs/cpu/softfloat3e/s_normSubnormalF128SigM.c +++ b/bochs/cpu/softfloat3e/s_packToExtF80.c @@ -3,7 +3,7 @@ This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic Package, Release 3e, by John R. Hauser. -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -33,25 +33,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================*/ +#include #include #include "internals.h" +#include "softfloat.h" -int softfloat_normSubnormalF128SigM(uint32_t *sigPtr) +extFloat80_t packToExtF80(uint16_t signExp, uint64_t sig) { - const uint32_t *ptr; - int16_t shiftDist; - uint32_t wordSig; - - ptr = sigPtr + indexWordHi(4); - shiftDist = 0; - for (;;) { - wordSig = *ptr; - if (wordSig) break; - shiftDist += 32; - if (128 <= shiftDist) return 1; - ptr -= wordIncr; - } - shiftDist += softfloat_countLeadingZeros32(wordSig) - 15; - if (shiftDist) softfloat_shiftLeft128M(sigPtr, shiftDist, sigPtr); - return 1 - shiftDist; + extFloat80_t z; + z.signExp = signExp; + z.signif = sig; + return z; +} + +extFloat80_t packToExtF80(bool sign, uint16_t exp, uint64_t sig) +{ + extFloat80_t z; + z.signExp = packToExtF80UI64(sign, exp); + z.signif = sig; + return z; } diff --git a/bochs/cpu/softfloat3e/s_roundPackToExtF80.c b/bochs/cpu/softfloat3e/s_roundPackToExtF80.c index 89a4fc54a..596ba9495 100644 --- a/bochs/cpu/softfloat3e/s_roundPackToExtF80.c +++ b/bochs/cpu/softfloat3e/s_roundPackToExtF80.c @@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "softfloat.h" extFloat80_t - softfloat_roundPackToExtF80(bool sign, int32_t exp, uint64_t sig, uint64_t sigExtra, uint8_t roundingPrecision, struct softfloat_status_t *status) + SoftFloat_roundPackToExtF80(bool sign, int32_t exp, uint64_t sig, uint64_t sigExtra, uint8_t roundingPrecision, struct softfloat_status_t *status) { uint8_t roundingMode; bool roundNearEven; @@ -47,6 +47,7 @@ extFloat80_t bool isTiny, doIncrement; struct uint64_extra sig64Extra; extFloat80_t z; + uint64_t sigExact; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -76,11 +77,8 @@ extFloat80_t *----------------------------------------------------------------*/ isTiny = (exp < 0) || (sig <= (uint64_t) (sig + roundIncrement)); sig = softfloat_shiftRightJam64(sig, 1 - exp); + sigExact = sig; roundBits = sig & roundMask; - if (roundBits) { - if (isTiny) softfloat_raiseFlags(status, softfloat_flag_underflow); - softfloat_raiseFlags(status, softfloat_flag_inexact); - } sig += roundIncrement; exp = ((sig & UINT64_C(0x8000000000000000)) != 0); roundIncrement = roundMask + 1; @@ -88,7 +86,15 @@ extFloat80_t roundMask |= roundIncrement; } sig &= ~roundMask; - goto packReturn; + if (isTiny) { + if (roundBits || (sig && ! softfloat_isMaskedException(status, softfloat_flag_underflow))) + softfloat_raiseFlags(status, softfloat_flag_underflow); + } + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sig > sigExact) softfloat_setRoundingUp(status); + } + return packToExtF80(sign, exp, sig); } if ((0x7FFE < exp) || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))) { goto overflow; @@ -99,17 +105,20 @@ extFloat80_t if (roundBits) { softfloat_raiseFlags(status, softfloat_flag_inexact); } + sigExact = sig; sig = (uint64_t) (sig + roundIncrement); if (sig < roundIncrement) { ++exp; sig = UINT64_C(0x8000000000000000); + sigExact >>= 1; // must scale also, or else later tests will fail } roundIncrement = roundMask + 1; if (roundNearEven && (roundBits<<1 == roundIncrement)) { roundMask |= roundIncrement; } sig &= ~roundMask; - goto packReturn; + if (sig > sigExact) softfloat_setRoundingUp(status); + return packToExtF80(sign, exp, sig); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ precision80: @@ -129,21 +138,26 @@ extFloat80_t exp = 0; sig = sig64Extra.v; sigExtra = sig64Extra.extra; - if (sigExtra) { - if (isTiny) softfloat_raiseFlags(status, softfloat_flag_underflow); - softfloat_raiseFlags(status, softfloat_flag_inexact); + if (isTiny) { + if (sigExtra || (sig && ! softfloat_isMaskedException(status, softfloat_flag_underflow))) + softfloat_raiseFlags(status, softfloat_flag_underflow); } + if (sigExtra) + softfloat_raiseFlags(status, softfloat_flag_inexact); doIncrement = (UINT64_C(0x8000000000000000) <= sigExtra); if (! roundNearEven && (roundingMode != softfloat_round_near_maxMag)) { doIncrement = (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) && sigExtra; } if (doIncrement) { + sigExact = sig; ++sig; sig &= ~(uint64_t) (! (sigExtra & UINT64_C(0x7FFFFFFFFFFFFFFF)) & roundNearEven); exp = ((sig & UINT64_C(0x8000000000000000)) != 0); + if (sig > sigExact) + softfloat_setRoundingUp(status); } - goto packReturn; + return packToExtF80(sign, exp, sig); } if ((0x7FFE < exp) || ((exp == 0x7FFE) && (sig == UINT64_C(0xFFFFFFFFFFFFFFFF)) && doIncrement)) { /*---------------------------------------------------------------- @@ -154,14 +168,15 @@ extFloat80_t if (roundNearEven || (roundingMode == softfloat_round_near_maxMag) || (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) - ) { + ) { exp = 0x7FFF; sig = UINT64_C(0x8000000000000000); + softfloat_setRoundingUp(status); } else { exp = 0x7FFE; sig = ~roundMask; } - goto packReturn; + return packToExtF80(sign, exp, sig); } } /*------------------------------------------------------------------------ @@ -170,18 +185,40 @@ extFloat80_t softfloat_raiseFlags(status, softfloat_flag_inexact); } if (doIncrement) { + sigExact = sig; ++sig; if (! sig) { ++exp; sig = UINT64_C(0x8000000000000000); + sigExact >>= 1; // must scale also, or else later tests will fail } else { sig &= ~(uint64_t) (! (sigExtra & UINT64_C(0x7FFFFFFFFFFFFFFF)) & roundNearEven); } + if (sig > sigExact) + softfloat_setRoundingUp(status); } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - packReturn: - z.signExp = packToExtF80UI64(sign, exp); - z.signif = sig; - return z; + return packToExtF80(sign, exp, sig); +} + +extFloat80_t + softfloat_roundPackToExtF80(bool sign, int32_t exp, uint64_t sig, uint64_t sigExtra, uint8_t roundingPrecision, struct softfloat_status_t *status) +{ + softfloat_status_t round_status = *status; + extFloat80_t result = SoftFloat_roundPackToExtF80(sign, exp, sig, sigExtra, roundingPrecision, status); + + // bias unmasked underflow + if (status->softfloat_exceptionFlags & ~status->softfloat_exceptionMasks & softfloat_flag_underflow) { + softfloat_raiseFlags(&round_status, softfloat_flag_underflow); + result = SoftFloat_roundPackToExtF80(sign, exp + 0x6000, sig, sigExtra, roundingPrecision, &round_status); + *status = round_status; + } + + // bias unmasked overflow + if (status->softfloat_exceptionFlags & ~status->softfloat_exceptionMasks & softfloat_flag_overflow) { + softfloat_raiseFlags(&round_status, softfloat_flag_overflow); + result = SoftFloat_roundPackToExtF80(sign, exp - 0x6000, sig, sigExtra, roundingPrecision, &round_status); + *status = round_status; + } + + return result; } diff --git a/bochs/cpu/softfloat3e/s_roundPackToF128.c b/bochs/cpu/softfloat3e/s_roundPackToF128.c index 371a5e382..c3aa86ff8 100644 --- a/bochs/cpu/softfloat3e/s_roundPackToF128.c +++ b/bochs/cpu/softfloat3e/s_roundPackToF128.c @@ -53,7 +53,7 @@ float128_t struct uint128_extra sig128Extra; uint64_t uiZ64, uiZ0; struct uint128 sig128; - union ui128_f128 uZ; + float128_t z; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -122,11 +122,10 @@ float128_t } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ - packReturn: uiZ64 = packToF128UI64(sign, exp, sig64); uiZ0 = sig0; uiZ: - uZ.ui.v64 = uiZ64; - uZ.ui.v0 = uiZ0; - return uZ.f; + z.v64 = uiZ64; + z.v0 = uiZ0; + return z; } diff --git a/bochs/cpu/softfloat3e/s_roundPackToF16.c b/bochs/cpu/softfloat3e/s_roundPackToF16.c index c2cdbdeee..3705b5055 100644 --- a/bochs/cpu/softfloat3e/s_roundPackToF16.c +++ b/bochs/cpu/softfloat3e/s_roundPackToF16.c @@ -46,6 +46,7 @@ float16_t uint8_t roundIncrement, roundBits; bool isTiny; uint16_t uiZ; + uint16_t sigRef; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -82,6 +83,7 @@ float16_t softfloat_raiseFlags(status, softfloat_flag_overflow); if (roundBits || softfloat_isMaskedException(status, softfloat_flag_overflow)) { softfloat_raiseFlags(status, softfloat_flag_inexact); + if (roundIncrement != 0) softfloat_setRoundingUp(status); } uiZ = packToF16UI(sign, 0x1F, 0) - ! roundIncrement; return uiZ; @@ -89,12 +91,14 @@ float16_t } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ + sigRef = sig; sig = (sig + roundIncrement)>>4; - if (roundBits) { - softfloat_raiseFlags(status, softfloat_flag_inexact); - } sig &= ~(uint16_t) (! (roundBits ^ 8) & roundNearEven); if (! sig) exp = 0; + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if ((sig << 4) > sigRef) softfloat_setRoundingUp(status); + } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ packReturn: diff --git a/bochs/cpu/softfloat3e/s_roundPackToF32.c b/bochs/cpu/softfloat3e/s_roundPackToF32.c index 265fad06f..b13421955 100644 --- a/bochs/cpu/softfloat3e/s_roundPackToF32.c +++ b/bochs/cpu/softfloat3e/s_roundPackToF32.c @@ -46,6 +46,7 @@ float32_t uint8_t roundIncrement, roundBits; bool isTiny; uint32_t uiZ; + uint32_t sigRef; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -86,6 +87,7 @@ float32_t softfloat_raiseFlags(status, softfloat_flag_overflow); if (roundBits || softfloat_isMaskedException(status, softfloat_flag_overflow)) { softfloat_raiseFlags(status, softfloat_flag_inexact); + if (roundIncrement != 0) softfloat_setRoundingUp(status); } uiZ = packToF32UI(sign, 0xFF, 0) - ! roundIncrement; return uiZ; @@ -93,12 +95,14 @@ float32_t } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ + sigRef = sig; sig = (sig + roundIncrement)>>7; - if (roundBits) { - softfloat_raiseFlags(status, softfloat_flag_inexact); - } sig &= ~(uint32_t) (! (roundBits ^ 0x40) & roundNearEven); if (! sig) exp = 0; + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if ((sig << 7) > sigRef) softfloat_setRoundingUp(status); + } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ packReturn: diff --git a/bochs/cpu/softfloat3e/s_roundPackToF64.c b/bochs/cpu/softfloat3e/s_roundPackToF64.c index 15d4ab384..dd9bfe027 100644 --- a/bochs/cpu/softfloat3e/s_roundPackToF64.c +++ b/bochs/cpu/softfloat3e/s_roundPackToF64.c @@ -46,6 +46,7 @@ float64_t uint16_t roundIncrement, roundBits; bool isTiny; uint64_t uiZ; + uint64_t sigRef; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -86,6 +87,7 @@ float64_t softfloat_raiseFlags(status, softfloat_flag_overflow); if (roundBits || softfloat_isMaskedException(status, softfloat_flag_overflow)) { softfloat_raiseFlags(status, softfloat_flag_inexact); + if (roundIncrement != 0) softfloat_setRoundingUp(status); } uiZ = packToF64UI(sign, 0x7FF, 0) - ! roundIncrement; return uiZ; @@ -93,12 +95,14 @@ float64_t } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ + sigRef = sig; sig = (sig + roundIncrement)>>10; - if (roundBits) { - softfloat_raiseFlags(status, softfloat_flag_inexact); - } sig &= ~(uint64_t) (! (roundBits ^ 0x200) & roundNearEven); if (! sig) exp = 0; + if (roundBits) { + softfloat_raiseFlags(status, softfloat_flag_inexact); + if ((sig << 10) > sigRef) softfloat_setRoundingUp(status); + } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ packReturn: diff --git a/bochs/cpu/softfloat3e/s_roundToI32.c b/bochs/cpu/softfloat3e/s_roundToI32.c index 6824386c7..0295d8688 100644 --- a/bochs/cpu/softfloat3e/s_roundToI32.c +++ b/bochs/cpu/softfloat3e/s_roundToI32.c @@ -45,6 +45,7 @@ int32_t softfloat_roundToI32(bool sign, uint64_t sig, uint8_t roundingMode, bool uint32_t sig32; union { uint32_t ui; int32_t i; } uZ; int32_t z; + uint64_t absSigExact = sig; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -67,6 +68,8 @@ int32_t softfloat_roundToI32(bool sign, uint64_t sig, uint8_t roundingMode, bool if (z && ((z < 0) ^ sign)) goto invalid; if (roundBits) { if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (((uint64_t)sig32 << 12) > absSigExact) + softfloat_setRoundingUp(status); } return z; /*------------------------------------------------------------------------ diff --git a/bochs/cpu/softfloat3e/s_roundToI64.c b/bochs/cpu/softfloat3e/s_roundToI64.c index 4cb097a29..25a8f66e9 100644 --- a/bochs/cpu/softfloat3e/s_roundToI64.c +++ b/bochs/cpu/softfloat3e/s_roundToI64.c @@ -40,16 +40,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "softfloat.h" int64_t - softfloat_roundToI64( - bool sign, - uint64_t sig, - uint64_t sigExtra, - uint8_t roundingMode, - bool exact, - struct softfloat_status_t *status) + softfloat_roundToI64(bool sign, uint64_t sig, uint64_t sigExtra, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) { union { uint64_t ui; int64_t i; } uZ; int64_t z; + uint64_t absSigExact = sig; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -71,6 +66,8 @@ int64_t if (z && ((z < 0) ^ sign)) goto invalid; if (sigExtra) { if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sig > absSigExact) + softfloat_setRoundingUp(status); } return z; /*------------------------------------------------------------------------ diff --git a/bochs/cpu/softfloat3e/s_roundToUI32.c b/bochs/cpu/softfloat3e/s_roundToUI32.c index cef7ae671..fa4b3935b 100644 --- a/bochs/cpu/softfloat3e/s_roundToUI32.c +++ b/bochs/cpu/softfloat3e/s_roundToUI32.c @@ -44,6 +44,7 @@ uint32_t { uint16_t roundIncrement, roundBits; uint32_t z; + uint64_t absSigExact = sig; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -67,6 +68,8 @@ uint32_t if (sign && z) goto invalid; if (roundBits) { if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (((uint64_t)z << 12) > absSigExact) + softfloat_setRoundingUp(status); } return z; /*------------------------------------------------------------------------ diff --git a/bochs/cpu/softfloat3e/s_roundToUI64.c b/bochs/cpu/softfloat3e/s_roundToUI64.c index 83aa98bb4..dc442971f 100644 --- a/bochs/cpu/softfloat3e/s_roundToUI64.c +++ b/bochs/cpu/softfloat3e/s_roundToUI64.c @@ -40,14 +40,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "softfloat.h" uint64_t - softfloat_roundToUI64( - bool sign, - uint64_t sig, - uint64_t sigExtra, - uint8_t roundingMode, - bool exact, - struct softfloat_status_t *status) + softfloat_roundToUI64(bool sign, uint64_t sig, uint64_t sigExtra, uint8_t roundingMode, bool exact, struct softfloat_status_t *status) { + uint64_t absSigExact = sig; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ if ((roundingMode == softfloat_round_near_maxMag) || (roundingMode == softfloat_round_near_even)) { @@ -70,6 +65,8 @@ uint64_t if (sign && sig) goto invalid; if (sigExtra) { if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact); + if (sig > absSigExact) + softfloat_setRoundingUp(status); } return sig; /*------------------------------------------------------------------------ diff --git a/bochs/cpu/softfloat3e/s_subMagsExtF80.c b/bochs/cpu/softfloat3e/s_subMagsExtF80.c index 4bdefd947..e0c1542a9 100644 --- a/bochs/cpu/softfloat3e/s_subMagsExtF80.c +++ b/bochs/cpu/softfloat3e/s_subMagsExtF80.c @@ -40,21 +40,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "softfloat.h" extFloat80_t - softfloat_subMagsExtF80(uint16_t uiA64, uint64_t uiA0, - uint16_t uiB64, uint64_t uiB0, - bool signZ, struct softfloat_status_t *status) + softfloat_subMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status) { int32_t expA; uint64_t sigA; int32_t expB; uint64_t sigB; int32_t expDiff; - uint16_t uiZ64; - uint64_t uiZ0; int32_t expZ; uint64_t sigExtra; struct uint128 sig128, uiZ; - extFloat80_t z; + struct exp32_sig64 normExpSig; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ @@ -64,46 +60,73 @@ extFloat80_t sigB = uiB0; /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ + if (expA == 0x7FFF) { + if ((sigA<<1)) goto propagateNaN; + if (expB == 0x7FFF) { + if ((sigB<<1)) goto propagateNaN; + softfloat_raiseFlags(status, softfloat_flag_invalid); + return packToExtF80(defaultNaNExtF80UI64, defaultNaNExtF80UI0); + } + if (sigB && ! expB) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(uiA64, uiA0); + } + if (expB == 0x7FFF) { + if ((sigB<<1)) goto propagateNaN; + if (sigA && ! expA) + softfloat_raiseFlags(status, softfloat_flag_denormal); + return packToExtF80(signZ ^ 1, 0x7FFF, UINT64_C(0x8000000000000000)); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expA) { + if (! sigA) { + if (! expB) { + if (sigB) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; + return softfloat_roundPackToExtF80(signZ ^ 1, expB, sigB, 0, softfloat_extF80_roundingPrecision(status), status); + } + return packToExtF80((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); + } + return softfloat_roundPackToExtF80(signZ ^ 1, expB, sigB, 0, softfloat_extF80_roundingPrecision(status), status); + } + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigA); + expA = normExpSig.exp + 1; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if (! expB) { + if (! sigB) + return softfloat_roundPackToExtF80(signZ, expA, sigA, 0, softfloat_extF80_roundingPrecision(status), status); + + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(sigB); + expB = normExpSig.exp + 1; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ expDiff = expA - expB; if (0 < expDiff) goto expABigger; if (expDiff < 0) goto expBBigger; - if (expA == 0x7FFF) { - if ((sigA | sigB) & UINT64_C(0x7FFFFFFFFFFFFFFF)) { - goto propagateNaN; - } - softfloat_raiseFlags(status, softfloat_flag_invalid); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; - } /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ expZ = expA; - if (! expZ) expZ = 1; sigExtra = 0; if (sigB < sigA) goto aBigger; if (sigA < sigB) goto bBigger; - uiZ64 = packToExtF80UI64((softfloat_getRoundingMode(status) == softfloat_round_min), 0); - uiZ0 = 0; - goto uiZ; + return packToExtF80((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ expBBigger: - if (expB == 0x7FFF) { - if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; - uiZ64 = packToExtF80UI64(signZ ^ 1, 0x7FFF); - uiZ0 = UINT64_C(0x8000000000000000); - goto uiZ; - } - if (! expA) { - ++expDiff; - sigExtra = 0; - if (! expDiff) goto newlyAlignedBBigger; - } sig128 = softfloat_shiftRightJam128(sigA, 0, -expDiff); sigA = sig128.v64; sigExtra = sig128.v0; - newlyAlignedBBigger: expZ = expB; bBigger: signZ = ! signZ; @@ -112,21 +135,9 @@ extFloat80_t /*------------------------------------------------------------------------ *------------------------------------------------------------------------*/ expABigger: - if (expA == 0x7FFF) { - if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN; - uiZ64 = uiA64; - uiZ0 = uiA0; - goto uiZ; - } - if (! expB) { - --expDiff; - sigExtra = 0; - if (! expDiff) goto newlyAlignedABigger; - } sig128 = softfloat_shiftRightJam128(sigB, 0, expDiff); sigB = sig128.v64; sigExtra = sig128.v0; - newlyAlignedABigger: expZ = expA; aBigger: sig128 = softfloat_sub128(sigA, 0, sigB, sigExtra); @@ -140,10 +151,5 @@ extFloat80_t *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - uiZ: - z.signExp = uiZ64; - z.signif = uiZ0; - return z; + return packToExtF80(uiZ.v64, uiZ.v0); } diff --git a/bochs/cpu/softfloat3e/s_subMagsF128.c b/bochs/cpu/softfloat3e/s_subMagsF128.c index 875ad6e57..e26fce6f6 100644 --- a/bochs/cpu/softfloat3e/s_subMagsF128.c +++ b/bochs/cpu/softfloat3e/s_subMagsF128.c @@ -55,7 +55,6 @@ float128_t struct uint128 sigB, sigZ; int32_t expDiff, expZ; struct uint128 uiZ; - union ui128_f128 uZ; expA = expF128UI64(uiA64); sigA.v64 = fracF128UI64(uiA64); @@ -73,7 +72,7 @@ float128_t softfloat_raiseFlags(status, softfloat_flag_invalid); uiZ.v64 = defaultNaNF128UI64; uiZ.v0 = defaultNaNF128UI0; - goto uiZ; + return uiZ; } expZ = expA; if (! expZ) expZ = 1; @@ -83,13 +82,13 @@ float128_t if (sigA.v0 < sigB.v0) goto bBigger; uiZ.v64 = packToF128UI64((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0); uiZ.v0 = 0; - goto uiZ; + return uiZ; expBBigger: if (expB == 0x7FFF) { if (sigB.v64 | sigB.v0) goto propagateNaN; uiZ.v64 = packToF128UI64(signZ ^ 1, 0x7FFF, 0); uiZ.v0 = 0; - goto uiZ; + return uiZ; } if (expA) { sigA.v64 |= UINT64_C(0x0010000000000000); @@ -110,7 +109,7 @@ float128_t if (sigA.v64 | sigA.v0) goto propagateNaN; uiZ.v64 = uiA64; uiZ.v0 = uiA0; - goto uiZ; + return uiZ; } if (expB) { sigB.v64 |= UINT64_C(0x0010000000000000); @@ -128,7 +127,5 @@ float128_t return softfloat_normRoundPackToF128(signZ, expZ - 5, sigZ.v64, sigZ.v0, status); propagateNaN: uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status); - uiZ: - uZ.ui = uiZ; - return uZ.f; + return uiZ; } diff --git a/bochs/cpu/softfloat3e/ui32_to_f128.c b/bochs/cpu/softfloat3e/ui32_to_f128.c index 2f1573859..a4111ae22 100644 --- a/bochs/cpu/softfloat3e/ui32_to_f128.c +++ b/bochs/cpu/softfloat3e/ui32_to_f128.c @@ -41,14 +41,14 @@ float128_t ui32_to_f128(uint32_t a) { uint64_t uiZ64; int8_t shiftDist; - union ui128_f128 uZ; + float128_t z; uiZ64 = 0; if (a) { shiftDist = softfloat_countLeadingZeros32(a) + 17; uiZ64 = packToF128UI64(0, 0x402E - shiftDist, (uint64_t) a<