w6c: append() accepts struct CALL rvalue elements (#34)
Evaluate the call pre-grow into a per-site scratch, receiving by the N_LET matrix (sret / float / odd-tail / GP), then grow, slot, sized ladder. Both stages, byte-identical. The two reject pins graduate to 16B GP accept rows; three new fixtures cover 24B GP, 3B/4B tails, 16B float, and 40B sret.
This commit is contained in:
@@ -3454,6 +3454,60 @@ fn structfloatclass(c: *cgen, t: *syntax.node) i32 = {
|
||||
return enc;
|
||||
};
|
||||
|
||||
// structfloatclassti — tinfo twin of structfloatclass for sites with
|
||||
// no declared tnode (the stamped element type behind an append CALL
|
||||
// source, #34). Same gates and encoding as the tnode form: 0, or
|
||||
// nb + 16/32 per SSE eightbyte. Cite cstage cgen.c struct_float_class
|
||||
// (Type-keyed there, so the tinfo walk IS the aligned shape).
|
||||
fn structfloatclassti(t: *syntax.tinfo) i32 = {
|
||||
t = tichase(t);
|
||||
if (t == nil || t.kind != syntax.tykind.TY_STRUCT) { return 0; };
|
||||
let sz: i32 = t.size: i32;
|
||||
if (sz <= 0 || sz > 16) { return 0; };
|
||||
// SysV classifies aggregates in 8-byte eightbytes; 8 is the
|
||||
// eightbyte stride, not a type footprint.
|
||||
let nb: i32 = 1;
|
||||
if (sz > 8) { nb = 2; };
|
||||
let nflt0: i32 = 0; let nflt1: i32 = 0;
|
||||
let nint0: i32 = 0; let nint1: i32 = 0;
|
||||
let fi: *syntax.tfield = t.fields;
|
||||
for (fi != nil) {
|
||||
let fu: *syntax.tinfo = tichase(fi.type_);
|
||||
if (fu == nil) { return 0; };
|
||||
let foff: i32 = fi.offset: i32;
|
||||
let fsz: i32 = fu.size: i32;
|
||||
let e: i32 = foff / 8;
|
||||
if (e < 0 || e >= nb) { return 0; };
|
||||
if (fu.kind == syntax.tykind.TY_F32) { return 0; };
|
||||
if (fu.kind == syntax.tykind.TY_F64) {
|
||||
if (foff - (foff / 8) * 8 != 0) { return 0; };
|
||||
if (fsz != 8) { return 0; };
|
||||
if (e == 0) { nflt0 += 1; } else { nflt1 += 1; };
|
||||
} else {
|
||||
if (fu.kind == syntax.tykind.TY_STRUCT) { return 0; };
|
||||
if (fu.kind == syntax.tykind.TY_ARRAY) { return 0; };
|
||||
if (fu.kind == syntax.tykind.TY_SLICE) { return 0; };
|
||||
if (fu.kind == syntax.tykind.TY_STR) { return 0; };
|
||||
if (fu.kind == syntax.tykind.TY_TAGGED) { return 0; };
|
||||
if (fu.kind == syntax.tykind.TY_TUPLE) { return 0; };
|
||||
if (fsz > 8) { return 0; };
|
||||
if ((foff + fsz - 1) / 8 != e) { return 0; };
|
||||
if (e == 0) { nint0 += 1; } else { nint1 += 1; };
|
||||
};
|
||||
fi = fi.tnext;
|
||||
};
|
||||
let enc: i32 = nb;
|
||||
let hasfloat: bool = false;
|
||||
if (nflt0 == 1 && nint0 == 0) { enc += 16; hasfloat = true; }
|
||||
else { if (nflt0 != 0) { return 0; }; };
|
||||
if (nb == 2) {
|
||||
if (nflt1 == 1 && nint1 == 0) { enc += 32; hasfloat = true; }
|
||||
else { if (nflt1 != 0) { return 0; }; };
|
||||
};
|
||||
if (!hasfloat) { return 0; };
|
||||
return enc;
|
||||
};
|
||||
|
||||
// istaggedtype — alias-aware. Reads stamped tinfo so `T`,
|
||||
// `type alias = (A|B)`, `type error = !(invalid|overflow)` all
|
||||
// resolve to TY_TAGGED — tinfofornode handles the N_TBANG unwrap
|
||||
|
||||
Reference in New Issue
Block a user