The f32 coda of Drew's strconv 5-fold plan — f64tos shipped in fold-5a (0e66073); this completes the plan. Re-lands the f32-exclusive Ryū path that fold-5a removed under the dead-code rule (it was #143-blocked): pow5fac32/pow5multiple32/pow2multiple32, mulshift32, mulpow5inv_divpow2/ mulpow5_divpow2, decf32, f32todecf32 (ftos_ryu.ha), and the f32tos driver (ftos.ha:448). Plus F32_POW5_*_BITCOUNT in ftos_data.ww. The f32 path REUSES the shared u64 core (mulshiftall64/u128mul/u128rshift/ log*) and f64computeinvpow5/f64computepow5 — and thus the f64 SPLIT2 tables — exactly as ftos_ryu.ha does; there are no separate f32 tables. Unblocked by #143 (aff7725): f32tos calls math.f32bits(n), passing an f32 arg, which now spills MOVSS (4B) in both stages. Verified: f32tos's arg push/pop is MOVSS, w6c vs w6c_ww 0-diff on the strconv-embedding combined.ww (w6c/wwdump/smoke regenerated). Dodges (cgen bugs still deferred, each cited at-site): decf32.exponent:i64 sidesteps the #169 narrow-second-field struct-return unpack (byte-id gate-confirmed, not an ABI guarantee); #168 div/mod local-bind on the two `%10` sites; *decimal pointer field reads (#170); [32]u8 buffer reuses f64tos's byte-id-clean band over Hare's [14] (#43). mulshift32's U32_MAX bound inlines the literal — ww's types.U32_MAX is package-private (#172). Test: ftostest.ww gains f32 vectors — the tcs G/void rows (shared f32/f64 shortest), the f32-exclusive tcsf32 extremes (1e-45 / 1.1754944e-38 / 3.4028235e38, full 24-bit mantissa), specials, a negative-normal, and 33554432 (the sole e2>=0/q<=9 runtime cover). make test 187/187 incl 908_ftos_run + 990-997 byte-id + combined_ww_fresh.
111 lines
5.4 KiB
Plaintext
111 lines
5.4 KiB
Plaintext
// strconv — Ryū float→string lookup tables + bit-count constants.
|
|
// Mirrors ref/hare/strconv/ftos_ryu.ha:159-222 byte-exact. Pure data
|
|
// fold (strconv #106 fold-5): no logic, consumed by ftos.ww's
|
|
// f64computeinvpow5 / f64computepow5 (the Ryū power-of-five cores).
|
|
//
|
|
// File-organisation divergence: Hare keeps these tables INLINE in
|
|
// ftos_ryu.ha. ww splits data from logic into ftos_data.ww (mirroring
|
|
// the stof.ww / stof_data.ww split) — same `package strconv`, so the
|
|
// tables stay visible to ftos.ww with no qualification.
|
|
//
|
|
// Spelling divergences (same as stof_data.ww, candidate #130 + rule-12):
|
|
// - Hare `const TBL = [...]` → ww module-level `let` (ww has no
|
|
// module-`const` keyword; the values are never written).
|
|
// - every literal carries its element-width suffix (`u64`/`u32`):
|
|
// cstage rejects bare integer literals in `[N]uXX` init while
|
|
// wwstage accepts them; the suffixed form is the only shape both
|
|
// stages agree on.
|
|
// - the [N][2]u64 tables stay faithful 2D (rule-12, not flattened);
|
|
// the 2D module-level static-init + double-index read landed in
|
|
// #156 (cbeffea), proven by stof_data.ww's powers_of_ten[596][2]u64.
|
|
|
|
package strconv;
|
|
|
|
// ref/hare/strconv/ftos_ryu.ha:159-160. Bit-counts of the split
|
|
// power-of-five tables. Defined u8 (faithful); ftos.ww casts to u32/i32
|
|
// at each use site (Hare promotes a u8 def inside mixed-width arithmetic;
|
|
// ww is strict — explicit cast, project_int_machine_word_derived_limits).
|
|
def F64_POW5_INV_BITCOUNT: u8 = 125u8;
|
|
def F64_POW5_BITCOUNT: u8 = 125u8;
|
|
|
|
// ref/hare/strconv/ftos_ryu.ha:162-163. The f32 split-table bit-counts,
|
|
// derived from the f64 siblings (Hare: F64_..._BITCOUNT - 64). Consumed by
|
|
// f32todecf32 (ftos.ww), landed in fold-5b (task #67) — the f32 path reuses
|
|
// the f64 SPLIT2 tables (via f64computeinvpow5/f64computepow5), so no
|
|
// separate F32 tables exist (matches ftos_ryu.ha). u8 like the f64 defs;
|
|
// ftos.ww casts to u32/i32 at each use.
|
|
def F32_POW5_INV_BITCOUNT: u8 = F64_POW5_INV_BITCOUNT - 64u8;
|
|
def F32_POW5_BITCOUNT: u8 = F64_POW5_BITCOUNT - 64u8;
|
|
|
|
// ref/hare/strconv/ftos_ryu.ha:165-181.
|
|
let F64_POW5_INV_SPLIT2: [15][2]u64 = [
|
|
[1u64, 2305843009213693952u64],
|
|
[5955668970331000884u64, 1784059615882449851u64],
|
|
[8982663654677661702u64, 1380349269358112757u64],
|
|
[7286864317269821294u64, 2135987035920910082u64],
|
|
[7005857020398200553u64, 1652639921975621497u64],
|
|
[17965325103354776697u64, 1278668206209430417u64],
|
|
[8928596168509315048u64, 1978643211784836272u64],
|
|
[10075671573058298858u64, 1530901034580419511u64],
|
|
[597001226353042382u64, 1184477304306571148u64],
|
|
[1527430471115325346u64, 1832889850782397517u64],
|
|
[12533209867169019542u64, 1418129833677084982u64],
|
|
[5577825024675947042u64, 2194449627517475473u64],
|
|
[11006974540203867551u64, 1697873161311732311u64],
|
|
[10313493231639821582u64, 1313665730009899186u64],
|
|
[12701016819766672773u64, 2032799256770390445u64],
|
|
];
|
|
|
|
// ref/hare/strconv/ftos_ryu.ha:183-188.
|
|
let POW5_INV_OFFSETS: [19]u32 = [
|
|
0x54544554u32, 0x04055545u32, 0x10041000u32, 0x00400414u32, 0x40010000u32, 0x41155555u32,
|
|
0x00000454u32, 0x00010044u32, 0x40000000u32, 0x44000041u32, 0x50454450u32, 0x55550054u32,
|
|
0x51655554u32, 0x40004000u32, 0x01000001u32, 0x00010500u32, 0x51515411u32, 0x05555554u32,
|
|
0x00000000u32,
|
|
];
|
|
|
|
// ref/hare/strconv/ftos_ryu.ha:190-204.
|
|
let F64_POW5_SPLIT2: [13][2]u64 = [
|
|
[0u64, 1152921504606846976u64],
|
|
[0u64, 1490116119384765625u64],
|
|
[1032610780636961552u64, 1925929944387235853u64],
|
|
[7910200175544436838u64, 1244603055572228341u64],
|
|
[16941905809032713930u64, 1608611746708759036u64],
|
|
[13024893955298202172u64, 2079081953128979843u64],
|
|
[6607496772837067824u64, 1343575221513417750u64],
|
|
[17332926989895652603u64, 1736530273035216783u64],
|
|
[13037379183483547984u64, 2244412773384604712u64],
|
|
[1605989338741628675u64, 1450417759929778918u64],
|
|
[9630225068416591280u64, 1874621017369538693u64],
|
|
[665883850346957067u64, 1211445438634777304u64],
|
|
[14931890668723713708u64, 1565756531257009982u64],
|
|
];
|
|
|
|
// ref/hare/strconv/ftos_ryu.ha:206-211.
|
|
let POW5_OFFSETS: [21]u32 = [
|
|
0x00000000u32, 0x00000000u32, 0x00000000u32, 0x00000000u32, 0x40000000u32, 0x59695995u32,
|
|
0x55545555u32, 0x56555515u32, 0x41150504u32, 0x40555410u32, 0x44555145u32, 0x44504540u32,
|
|
0x45555550u32, 0x40004000u32, 0x96440440u32, 0x55565565u32, 0x54454045u32, 0x40154151u32,
|
|
0x55559155u32, 0x51405555u32, 0x00000105u32,
|
|
];
|
|
|
|
// ref/hare/strconv/ftos_ryu.ha:213. Divisor/index stride in
|
|
// f64computeinvpow5 / f64computepow5 (ftos.ww). Kept as a def for those
|
|
// arithmetic uses; POW5_TABLE's dimension below must be a literal (cstage
|
|
// rejects a def-named array length — "array length must be an integer
|
|
// literal"; wwstage accepts it but emits an empty DATAW — divergence
|
|
// #167, so the literal `26` is the only shape both stages agree on;
|
|
// matches decimal.ww's `[800]u8` array-dimension-literal precedent).
|
|
def POW5_TABLE_SZ: u8 = 26u8;
|
|
|
|
// ref/hare/strconv/ftos_ryu.ha:215-222. 5^0 .. 5^25 (the 5^26 entry is
|
|
// commented out in Hare too — it lives implicitly in the SPLIT2 tables).
|
|
let POW5_TABLE: [26]u64 = [
|
|
1u64, 5u64, 25u64, 125u64, 625u64, 3125u64, 15625u64, 78125u64,
|
|
390625u64, 1953125u64, 9765625u64, 48828125u64, 244140625u64,
|
|
1220703125u64, 6103515625u64, 30517578125u64, 152587890625u64,
|
|
762939453125u64, 3814697265625u64, 19073486328125u64, 95367431640625u64,
|
|
476837158203125u64, 2384185791015625u64, 11920928955078125u64,
|
|
59604644775390625u64, 298023223876953125u64,
|
|
];
|