wwstage: sign-extend signed-narrow struct-array-field element load via N_DOT base (#255)
The cgindex N_DOT-base arm set esz from the checker-stamped element tinfo but skipped signedness, so loadopsz saw signed_elem=false and emitted MOVL/MOVZ* (zero-extend) where cstage's fldloadop reads signedness from the element type and emits MOVSXD/MOVSWQ/MOVSBQ. A negative i8/i16/i32 read of `x.o[k]` (struct `[N]T` field) round-tripped with the wrong upper bits — silent cs!=ww, byte-id-blind since bootstrap never indexes signed-narrow struct array-fields. Mirror the sibling N_INDEX-base arm: signed_elem = typeissigned(dt). loadopsz already keys on (signed,sz), so this closes all three narrow widths at once. Pure wwstage-up; cstage unchanged. 949 gains nload_i32/i16/i8 negative-read rows (run + cs==ww byte-id). combined.ww regen'd for w6c + wwdump (the cgen embedders).
This commit is contained in:
@@ -20499,10 +20499,12 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
// checker-stamped element tinfo's natural size, the
|
||||
// same idiom as the N_INDEX-base arm below (#60/#72).
|
||||
// cstage idx_eff(base->type)->sub->size (cmd/w6c/
|
||||
// cgen.c:3517-18). esz-only — N_DOT-base signedness
|
||||
// stays unset, as before.
|
||||
// cgen.c:3517-18). Signedness from the same element tinfo
|
||||
// so a signed-narrow field element sign-extends on load
|
||||
// (loadopsz keys on (signed,sz)); cstage's fldloadop reads
|
||||
// it from the element type — align ww up (#255).
|
||||
let dt: *tinfo = n.type_: *tinfo;
|
||||
if (dt != nil) { esz = dt.size: i32; elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); };
|
||||
if (dt != nil) { esz = dt.size: i32; signed_elem = typeissigned(dt); elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); };
|
||||
elem_isarray = tinfoisarray(dt);
|
||||
} else { if (base.kind == nkind.N_INDEX) {
|
||||
// #60: chained `names[i][k]` — n.type_ is the checker-
|
||||
|
||||
@@ -1201,10 +1201,12 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
// checker-stamped element tinfo's natural size, the
|
||||
// same idiom as the N_INDEX-base arm below (#60/#72).
|
||||
// cstage idx_eff(base->type)->sub->size (cmd/w6c/
|
||||
// cgen.c:3517-18). esz-only — N_DOT-base signedness
|
||||
// stays unset, as before.
|
||||
// cgen.c:3517-18). Signedness from the same element tinfo
|
||||
// so a signed-narrow field element sign-extends on load
|
||||
// (loadopsz keys on (signed,sz)); cstage's fldloadop reads
|
||||
// it from the element type — align ww up (#255).
|
||||
let dt: *tinfo = n.type_: *tinfo;
|
||||
if (dt != nil) { esz = dt.size: i32; elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); };
|
||||
if (dt != nil) { esz = dt.size: i32; signed_elem = typeissigned(dt); elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); };
|
||||
elem_isarray = tinfoisarray(dt);
|
||||
} else { if (base.kind == nkind.N_INDEX) {
|
||||
// #60: chained `names[i][k]` — n.type_ is the checker-
|
||||
|
||||
@@ -20499,10 +20499,12 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
// checker-stamped element tinfo's natural size, the
|
||||
// same idiom as the N_INDEX-base arm below (#60/#72).
|
||||
// cstage idx_eff(base->type)->sub->size (cmd/w6c/
|
||||
// cgen.c:3517-18). esz-only — N_DOT-base signedness
|
||||
// stays unset, as before.
|
||||
// cgen.c:3517-18). Signedness from the same element tinfo
|
||||
// so a signed-narrow field element sign-extends on load
|
||||
// (loadopsz keys on (signed,sz)); cstage's fldloadop reads
|
||||
// it from the element type — align ww up (#255).
|
||||
let dt: *tinfo = n.type_: *tinfo;
|
||||
if (dt != nil) { esz = dt.size: i32; elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); };
|
||||
if (dt != nil) { esz = dt.size: i32; signed_elem = typeissigned(dt); elemisstr = typeisstr(dt); elemisslice = typeisslice(dt); float_elem = typeisfloat(dt); f32_elem = typeisf32(dt); };
|
||||
elem_isarray = tinfoisarray(dt);
|
||||
} else { if (base.kind == nkind.N_INDEX) {
|
||||
// #60: chained `names[i][k]` — n.type_ is the checker-
|
||||
|
||||
Reference in New Issue
Block a user