From 028109513eae498483afe265baf21b758aca3f0a Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Wed, 27 May 2026 19:29:46 +0900 Subject: [PATCH] lib/strconv: retire workarounds in f32todecf32 (#168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two local-binds were #168 dodges: a CSE before `% 10u32` to avoid the signed-IDIVQ-on-call-result shape that #168 has now fixed. Inline to the natural form, faithful to ftos_ryu.ha:418-421,444-445 — this exercises #168 in real ported code. The dividends are zero-extended u32 (always positive as 64-bit), so IDIVQ and DIVQ agree on the value; the fix is a cs==ww byte-id shape correction, not a value change. strconv is compiler-imported, so this regenerates the w6c/wwdump/smoke amalgamations. --- lib/strconv/ftos.ww | 11 +++-------- selfhost/cmd/w6c/main.combined.ww | 11 +++-------- selfhost/cmd/wwdump/main.combined.ww | 11 +++-------- selfhost/test/smoke.combined.ww | 11 +++-------- 4 files changed, 12 insertions(+), 32 deletions(-) diff --git a/lib/strconv/ftos.ww b/lib/strconv/ftos.ww index 417818f7..26af212c 100644 --- a/lib/strconv/ftos.ww +++ b/lib/strconv/ftos.ww @@ -445,11 +445,8 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = { vm = mulpow5inv_divpow2(mm, q, i); if (q != 0u32 && (vp - 1u32) / 10u32 <= vm / 10u32) { let l: u32 = (F32_POW5_INV_BITCOUNT: u32) + pow5bits(q - 1u32) - 1u32; - // #168 dodge: div/mod on an inline N_CALL result emits a - // signed IDIVQ in wwstage; bind the call to a local first. - let lrd: u32 = mulpow5inv_divpow2(mv, q - 1u32, - -e2 + ((q + l): i32) - 1i32); - last_removed_digit = (lrd % 10u32): u8; + last_removed_digit = (mulpow5inv_divpow2(mv, q - 1u32, + -e2 + ((q + l): i32) - 1i32) % 10u32): u8; }; if (q <= 9u32) { if (mv % 5u32 == 0u32) { @@ -471,9 +468,7 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = { vm = mulpow5_divpow2(mm, i, j); if (q != 0u32 && (vp - 1u32) / 10u32 <= vm / 10u32) { j = (q: i32) - 1i32 - ((pow5bits(i + 1u32): i32) - (F32_POW5_BITCOUNT: i32)); - // #168 dodge (see above): local-bind before the % 10. - let lrd: u32 = mulpow5_divpow2(mv, (i + 1u32), j); - last_removed_digit = (lrd % 10u32): u8; + last_removed_digit = (mulpow5_divpow2(mv, (i + 1u32), j) % 10u32): u8; }; if (q <= 1u32) { vr_trailing_zeroes = true; diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 7f32f28f..f86f3d77 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -3763,11 +3763,8 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = { vm = mulpow5inv_divpow2(mm, q, i); if (q != 0u32 && (vp - 1u32) / 10u32 <= vm / 10u32) { let l: u32 = (F32_POW5_INV_BITCOUNT: u32) + pow5bits(q - 1u32) - 1u32; - // #168 dodge: div/mod on an inline N_CALL result emits a - // signed IDIVQ in wwstage; bind the call to a local first. - let lrd: u32 = mulpow5inv_divpow2(mv, q - 1u32, - -e2 + ((q + l): i32) - 1i32); - last_removed_digit = (lrd % 10u32): u8; + last_removed_digit = (mulpow5inv_divpow2(mv, q - 1u32, + -e2 + ((q + l): i32) - 1i32) % 10u32): u8; }; if (q <= 9u32) { if (mv % 5u32 == 0u32) { @@ -3789,9 +3786,7 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = { vm = mulpow5_divpow2(mm, i, j); if (q != 0u32 && (vp - 1u32) / 10u32 <= vm / 10u32) { j = (q: i32) - 1i32 - ((pow5bits(i + 1u32): i32) - (F32_POW5_BITCOUNT: i32)); - // #168 dodge (see above): local-bind before the % 10. - let lrd: u32 = mulpow5_divpow2(mv, (i + 1u32), j); - last_removed_digit = (lrd % 10u32): u8; + last_removed_digit = (mulpow5_divpow2(mv, (i + 1u32), j) % 10u32): u8; }; if (q <= 1u32) { vr_trailing_zeroes = true; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index f7e54a4d..6f2acc51 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -1786,11 +1786,8 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = { vm = mulpow5inv_divpow2(mm, q, i); if (q != 0u32 && (vp - 1u32) / 10u32 <= vm / 10u32) { let l: u32 = (F32_POW5_INV_BITCOUNT: u32) + pow5bits(q - 1u32) - 1u32; - // #168 dodge: div/mod on an inline N_CALL result emits a - // signed IDIVQ in wwstage; bind the call to a local first. - let lrd: u32 = mulpow5inv_divpow2(mv, q - 1u32, - -e2 + ((q + l): i32) - 1i32); - last_removed_digit = (lrd % 10u32): u8; + last_removed_digit = (mulpow5inv_divpow2(mv, q - 1u32, + -e2 + ((q + l): i32) - 1i32) % 10u32): u8; }; if (q <= 9u32) { if (mv % 5u32 == 0u32) { @@ -1812,9 +1809,7 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = { vm = mulpow5_divpow2(mm, i, j); if (q != 0u32 && (vp - 1u32) / 10u32 <= vm / 10u32) { j = (q: i32) - 1i32 - ((pow5bits(i + 1u32): i32) - (F32_POW5_BITCOUNT: i32)); - // #168 dodge (see above): local-bind before the % 10. - let lrd: u32 = mulpow5_divpow2(mv, (i + 1u32), j); - last_removed_digit = (lrd % 10u32): u8; + last_removed_digit = (mulpow5_divpow2(mv, (i + 1u32), j) % 10u32): u8; }; if (q <= 1u32) { vr_trailing_zeroes = true; diff --git a/selfhost/test/smoke.combined.ww b/selfhost/test/smoke.combined.ww index 6d302631..45bde6fe 100644 --- a/selfhost/test/smoke.combined.ww +++ b/selfhost/test/smoke.combined.ww @@ -1786,11 +1786,8 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = { vm = mulpow5inv_divpow2(mm, q, i); if (q != 0u32 && (vp - 1u32) / 10u32 <= vm / 10u32) { let l: u32 = (F32_POW5_INV_BITCOUNT: u32) + pow5bits(q - 1u32) - 1u32; - // #168 dodge: div/mod on an inline N_CALL result emits a - // signed IDIVQ in wwstage; bind the call to a local first. - let lrd: u32 = mulpow5inv_divpow2(mv, q - 1u32, - -e2 + ((q + l): i32) - 1i32); - last_removed_digit = (lrd % 10u32): u8; + last_removed_digit = (mulpow5inv_divpow2(mv, q - 1u32, + -e2 + ((q + l): i32) - 1i32) % 10u32): u8; }; if (q <= 9u32) { if (mv % 5u32 == 0u32) { @@ -1812,9 +1809,7 @@ fn f32todecf32(mantissa: u32, exponent: u32) decf32 = { vm = mulpow5_divpow2(mm, i, j); if (q != 0u32 && (vp - 1u32) / 10u32 <= vm / 10u32) { j = (q: i32) - 1i32 - ((pow5bits(i + 1u32): i32) - (F32_POW5_BITCOUNT: i32)); - // #168 dodge (see above): local-bind before the % 10. - let lrd: u32 = mulpow5_divpow2(mv, (i + 1u32), j); - last_removed_digit = (lrd % 10u32): u8; + last_removed_digit = (mulpow5_divpow2(mv, (i + 1u32), j) % 10u32): u8; }; if (q <= 1u32) { vr_trailing_zeroes = true;