diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index cdd1e12d..97226fcc 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -10615,13 +10615,15 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = { // Without this gate the widening scalar branch // hardcodes the param's first-variant tag and // the callee reads a fixed arm on garbage. + // #60: arg.type_ is the checker-stamped element + // tinfo (check.ww indexresult); istaggedtype/ + // slotsize read .type_, so feed the N_INDEX node + // directly. cstage reads the element via + // base->type->sub (cmd/w6c/cgen.c:3518). if (arg.kind == nkind.N_INDEX) { - let etn: *node = indexvaluetnode(c, arg); - if (etn != nil) { - if (istaggedtype(c, etn)) { - if (slotsize(c, etn) == slotsize(c, ptype)) { - aistagged = true; - }; + if (istaggedtype(c, arg)) { + if (slotsize(c, arg) == slotsize(c, ptype)) { + aistagged = true; }; }; }; @@ -10926,18 +10928,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = { }; // #12: N_INDEX of a sum-typed slice element. cgindex above left // the tagged-CALL ABI in AX/DX/CX/R8; the bare PUSHQ AX below - // would only carry the tag word and drop the payload. + // would only carry the tag word and drop the payload. #60: + // arg.type_ is the element tinfo (istaggedtype/slotsize read + // .type_) — feed the N_INDEX node directly, dropping the + // indexvaluetnode walk. if (arg.kind == nkind.N_INDEX) { - let etn: *node = indexvaluetnode(c, arg); - if (etn != nil) { - if (istaggedtype(c, etn)) { - let isz: i32 = slotsize(c, etn); - if (isz > 24) { emitline("\tPUSHQ\tR8\n"); }; - if (isz > 16) { emitline("\tPUSHQ\tCX\n"); }; - if (isz > 8) { emitline("\tPUSHQ\tDX\n"); }; - emitline("\tPUSHQ\tAX\n"); - return rest + isz / 8; - }; + if (istaggedtype(c, arg)) { + let isz: i32 = slotsize(c, arg); + if (isz > 24) { emitline("\tPUSHQ\tR8\n"); }; + if (isz > 16) { emitline("\tPUSHQ\tCX\n"); }; + if (isz > 8) { emitline("\tPUSHQ\tDX\n"); }; + emitline("\tPUSHQ\tAX\n"); + return rest + isz / 8; }; }; emitline("\tPUSHQ\tAX\n"); @@ -14608,10 +14610,15 @@ fn cgindex(c: *cgen, n: *node) void = { } else { if (base.kind == nkind.N_DOT) { esz = indexbaseesz(c, base); } else { if (base.kind == nkind.N_INDEX) { - let bt: *node = indexvaluetnode(c, base); - if (bt != nil) { - esz = elemsizeofc(c, bt); - signed_elem = elemissignedc(c, bt); + // #60: chained `names[i][k]` — n.type_ is the checker- + // stamped outer element tinfo (indexresult over the inner + // index's value type). cstage reads base->type->sub->size + // for esz (cmd/w6c/cgen.c:2070-2071). Drops the + // indexvaluetnode walk. + let et: *tinfo = n.type_: *tinfo; + if (et != nil) { + esz = et.size: i32; + signed_elem = typeissigned(et); }; };};}; }; diff --git a/selfhost/cmd/wcc/cgenexpr.ww b/selfhost/cmd/wcc/cgenexpr.ww index dcd508c2..15674293 100644 --- a/selfhost/cmd/wcc/cgenexpr.ww +++ b/selfhost/cmd/wcc/cgenexpr.ww @@ -723,10 +723,15 @@ fn cgindex(c: *cgen, n: *node) void = { } else { if (base.kind == nkind.N_DOT) { esz = indexbaseesz(c, base); } else { if (base.kind == nkind.N_INDEX) { - let bt: *node = indexvaluetnode(c, base); - if (bt != nil) { - esz = elemsizeofc(c, bt); - signed_elem = elemissignedc(c, bt); + // #60: chained `names[i][k]` — n.type_ is the checker- + // stamped outer element tinfo (indexresult over the inner + // index's value type). cstage reads base->type->sub->size + // for esz (cmd/w6c/cgen.c:2070-2071). Drops the + // indexvaluetnode walk. + let et: *tinfo = n.type_: *tinfo; + if (et != nil) { + esz = et.size: i32; + signed_elem = typeissigned(et); }; };};}; }; diff --git a/selfhost/cmd/wcc/cgenutil.ww b/selfhost/cmd/wcc/cgenutil.ww index 56e5ef63..71866849 100644 --- a/selfhost/cmd/wcc/cgenutil.ww +++ b/selfhost/cmd/wcc/cgenutil.ww @@ -174,13 +174,15 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = { // Without this gate the widening scalar branch // hardcodes the param's first-variant tag and // the callee reads a fixed arm on garbage. + // #60: arg.type_ is the checker-stamped element + // tinfo (check.ww indexresult); istaggedtype/ + // slotsize read .type_, so feed the N_INDEX node + // directly. cstage reads the element via + // base->type->sub (cmd/w6c/cgen.c:3518). if (arg.kind == nkind.N_INDEX) { - let etn: *node = indexvaluetnode(c, arg); - if (etn != nil) { - if (istaggedtype(c, etn)) { - if (slotsize(c, etn) == slotsize(c, ptype)) { - aistagged = true; - }; + if (istaggedtype(c, arg)) { + if (slotsize(c, arg) == slotsize(c, ptype)) { + aistagged = true; }; }; }; @@ -485,18 +487,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = { }; // #12: N_INDEX of a sum-typed slice element. cgindex above left // the tagged-CALL ABI in AX/DX/CX/R8; the bare PUSHQ AX below - // would only carry the tag word and drop the payload. + // would only carry the tag word and drop the payload. #60: + // arg.type_ is the element tinfo (istaggedtype/slotsize read + // .type_) — feed the N_INDEX node directly, dropping the + // indexvaluetnode walk. if (arg.kind == nkind.N_INDEX) { - let etn: *node = indexvaluetnode(c, arg); - if (etn != nil) { - if (istaggedtype(c, etn)) { - let isz: i32 = slotsize(c, etn); - if (isz > 24) { emitline("\tPUSHQ\tR8\n"); }; - if (isz > 16) { emitline("\tPUSHQ\tCX\n"); }; - if (isz > 8) { emitline("\tPUSHQ\tDX\n"); }; - emitline("\tPUSHQ\tAX\n"); - return rest + isz / 8; - }; + if (istaggedtype(c, arg)) { + let isz: i32 = slotsize(c, arg); + if (isz > 24) { emitline("\tPUSHQ\tR8\n"); }; + if (isz > 16) { emitline("\tPUSHQ\tCX\n"); }; + if (isz > 8) { emitline("\tPUSHQ\tDX\n"); }; + emitline("\tPUSHQ\tAX\n"); + return rest + isz / 8; }; }; emitline("\tPUSHQ\tAX\n"); diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 44829cf5..dd994544 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -10615,13 +10615,15 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = { // Without this gate the widening scalar branch // hardcodes the param's first-variant tag and // the callee reads a fixed arm on garbage. + // #60: arg.type_ is the checker-stamped element + // tinfo (check.ww indexresult); istaggedtype/ + // slotsize read .type_, so feed the N_INDEX node + // directly. cstage reads the element via + // base->type->sub (cmd/w6c/cgen.c:3518). if (arg.kind == nkind.N_INDEX) { - let etn: *node = indexvaluetnode(c, arg); - if (etn != nil) { - if (istaggedtype(c, etn)) { - if (slotsize(c, etn) == slotsize(c, ptype)) { - aistagged = true; - }; + if (istaggedtype(c, arg)) { + if (slotsize(c, arg) == slotsize(c, ptype)) { + aistagged = true; }; }; }; @@ -10926,18 +10928,18 @@ fn pushargsrev(c: *cgen, arg: *node, param: *node) i32 = { }; // #12: N_INDEX of a sum-typed slice element. cgindex above left // the tagged-CALL ABI in AX/DX/CX/R8; the bare PUSHQ AX below - // would only carry the tag word and drop the payload. + // would only carry the tag word and drop the payload. #60: + // arg.type_ is the element tinfo (istaggedtype/slotsize read + // .type_) — feed the N_INDEX node directly, dropping the + // indexvaluetnode walk. if (arg.kind == nkind.N_INDEX) { - let etn: *node = indexvaluetnode(c, arg); - if (etn != nil) { - if (istaggedtype(c, etn)) { - let isz: i32 = slotsize(c, etn); - if (isz > 24) { emitline("\tPUSHQ\tR8\n"); }; - if (isz > 16) { emitline("\tPUSHQ\tCX\n"); }; - if (isz > 8) { emitline("\tPUSHQ\tDX\n"); }; - emitline("\tPUSHQ\tAX\n"); - return rest + isz / 8; - }; + if (istaggedtype(c, arg)) { + let isz: i32 = slotsize(c, arg); + if (isz > 24) { emitline("\tPUSHQ\tR8\n"); }; + if (isz > 16) { emitline("\tPUSHQ\tCX\n"); }; + if (isz > 8) { emitline("\tPUSHQ\tDX\n"); }; + emitline("\tPUSHQ\tAX\n"); + return rest + isz / 8; }; }; emitline("\tPUSHQ\tAX\n"); @@ -14608,10 +14610,15 @@ fn cgindex(c: *cgen, n: *node) void = { } else { if (base.kind == nkind.N_DOT) { esz = indexbaseesz(c, base); } else { if (base.kind == nkind.N_INDEX) { - let bt: *node = indexvaluetnode(c, base); - if (bt != nil) { - esz = elemsizeofc(c, bt); - signed_elem = elemissignedc(c, bt); + // #60: chained `names[i][k]` — n.type_ is the checker- + // stamped outer element tinfo (indexresult over the inner + // index's value type). cstage reads base->type->sub->size + // for esz (cmd/w6c/cgen.c:2070-2071). Drops the + // indexvaluetnode walk. + let et: *tinfo = n.type_: *tinfo; + if (et != nil) { + esz = et.size: i32; + signed_elem = typeissigned(et); }; };};}; };