selfhost: port float lex + expression cgen — feature parity with C
Lexer: `lexnum` now parses the digit/exponent tail into an f64 via a
new `parsef64` (decimal-only, integer-arith driver + pow-10 multiply,
no strtod). The IEEE bits are also stashed in tok.uval via pointer
reinterpret so cgen consumers stay integer-only.
Parser: TK_FLOAT → N_FLOATLIT, carrying both fval and uval. Parser
state grows curfval to plumb the lexer's f64 through refill.
cgen:
- cgfloatlit reads n.uval and materialises X0 via the standard
MOVQ-PUSHQ-MOVSD-ADDQ trampoline.
- cglet, cgident, cgassign learn float-typed branches: MOVSS/MOVSD
for locals; LEAQ-indirect MOVSS/MOVSD for globals.
- cgbin handles ADDSD/SUBSD/MULSD/DIVSD (+ SS variants) and
UCOMISD/UCOMISS-based comparisons. cgun handles float negate
via the `0 - X0` shape C cgen uses.
- cgcast routes int↔float and f32↔f64 through CVTSI2SD/CVTTSD2SI/
CVTSD2SS/CVTSS2SD and their SS twins.
- cgcall + pushargsrev push float args via SUBQ+MOVSD and pop into
the X0..X7 stream, tracked by a per-class counter alongside the
int DI..R9 stream. cgfnparams loads float params from the same
stream.
- emitletdataw bakes FLOATLIT init bits into DATAW (4B for f32,
8B for f64).
Tests: smoke programs (literal init, reassign, arithmetic, fn args/
returns, casts) produce byte-identical asm through `w6c` and
`wwdump_ww -c`, and the resulting binary exits with the same value
whether compiled by the C or wwstage toolchain. Full `make test` is
26/26 and `make bootstrap` still reaches its byte-identical
ww2==ww3==ww4 fixed point.
This commit is contained in:
@@ -124,9 +124,29 @@ fn scanlocals(c: *cgen, n: *node) i32 = {
|
||||
fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
let p: *node = params;
|
||||
let idx: i32 = 0;
|
||||
let fidx: i32 = 0;
|
||||
for (p != nil) {
|
||||
if (p.kind == nkind.N_PARAM) {
|
||||
let nm: str = p.str;
|
||||
if (isfloattype(c, p.lhs)) {
|
||||
// Float param: SysV uses the XMM stream
|
||||
// (X0..X7). 8B (f64) or 4B (f32) slot.
|
||||
let fsz: i32 = 8;
|
||||
if (isf32type(c, p.lhs)) { fsz = 4; };
|
||||
let off: i32 = localadd(c, nm, fsz, p.lhs);
|
||||
let mov: str = "MOVSD";
|
||||
if (fsz == 4) { mov = "MOVSS"; };
|
||||
emitline("\t");
|
||||
emitline(mov);
|
||||
emitline("\t");
|
||||
emitline(fargregname(fidx));
|
||||
emitline(", ");
|
||||
emitoff(off: i64);
|
||||
emitline("(BP)\n");
|
||||
fidx += 1;
|
||||
p = p.next;
|
||||
continue;
|
||||
};
|
||||
if (istaggedtype(p.lhs)) {
|
||||
// tagged-union param: spill size/8 registers
|
||||
// (tag + value words). Slot sized to match.
|
||||
|
||||
Reference in New Issue
Block a user