wcc/ww: widen of a module-global struct ident copies the full payload
Widening a global struct into a tagged slot copied word0 only; copy the full payload from g(SB). Both-wrong pair: cstage zero-fills the payload (filed task #43); rows pin ww-runtime-correct with the documented cstage residual. Review item #50.
This commit is contained in:
@@ -21820,6 +21820,60 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
||||
emitline("(BP)\n");
|
||||
return;
|
||||
}; };
|
||||
// #50 (#263 ww-runtime-correct): a module-GLOBAL struct ident source.
|
||||
// rhsstructpayload below is local/literal-only, so a global struct value
|
||||
// fell to the scalar word0 arm — payload truncated. Land g(SB) in SI and
|
||||
// byte-copy the struct words into slot+8; cstage zero-fills the payload
|
||||
// (cstage half #43). Local/literal sources keep the existing arms (byte-id).
|
||||
if (src.kind == nkind.N_IDENT) {
|
||||
if (localfindnode(c, src.str) == nil) {
|
||||
let gtn: *node = letvartnode(c, src.str);
|
||||
if (gtn != nil) { if (gtn.kind == nkind.N_TNAME) {
|
||||
let gsi: *structinfo = structlookupchain(c, gtn);
|
||||
if (gsi != nil) {
|
||||
emitline("\tXORQ\tAX, AX\n");
|
||||
let gz: i32 = 0;
|
||||
for (gz < slot_sz) {
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((slot_off + gz): i64);
|
||||
emitline("(BP)\n");
|
||||
gz += 8;
|
||||
};
|
||||
let gtag: i32 = taggedvariantindext(c, dt, src);
|
||||
if (gtag < 0) { gtag = 0; };
|
||||
if (aggargsrcaddr(c, src, "SI")) {
|
||||
let gtot: i32 = gsi.totsize;
|
||||
let gk: i32 = 0;
|
||||
for (gk + 8 <= gtot) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(gk: i64);
|
||||
emitline("(SI), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((slot_off + 8 + gk): i64);
|
||||
emitline("(BP)\n");
|
||||
gk += 8;
|
||||
};
|
||||
if (gk < gtot) {
|
||||
let gtail: i32 = gtot - gk;
|
||||
let glop: str = "MOVQ";
|
||||
if (gtail == 4) { glop = "MOVL"; }
|
||||
else { if (gtail == 1) { glop = "MOVB"; }; };
|
||||
emitline("\t"); emitline(glop); emitline("\t");
|
||||
emitoff(gk: i64); emitline("(SI), AX\n");
|
||||
emitline("\t"); emitline(glop); emitline("\tAX, ");
|
||||
emitoff((slot_off + 8 + gk): i64); emitline("(BP)\n");
|
||||
};
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(gtag: i64);
|
||||
emitline(", ");
|
||||
emitoff(slot_off: i64);
|
||||
emitline("(BP)\n");
|
||||
return;
|
||||
};
|
||||
};
|
||||
}; };
|
||||
};
|
||||
};
|
||||
// Struct payload (literal or ident).
|
||||
let sname: str = rhsstructpayload(c, src);
|
||||
if (sname.len > 0) {
|
||||
|
||||
@@ -4400,6 +4400,60 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
||||
emitline("(BP)\n");
|
||||
return;
|
||||
}; };
|
||||
// #50 (#263 ww-runtime-correct): a module-GLOBAL struct ident source.
|
||||
// rhsstructpayload below is local/literal-only, so a global struct value
|
||||
// fell to the scalar word0 arm — payload truncated. Land g(SB) in SI and
|
||||
// byte-copy the struct words into slot+8; cstage zero-fills the payload
|
||||
// (cstage half #43). Local/literal sources keep the existing arms (byte-id).
|
||||
if (src.kind == nkind.N_IDENT) {
|
||||
if (localfindnode(c, src.str) == nil) {
|
||||
let gtn: *node = letvartnode(c, src.str);
|
||||
if (gtn != nil) { if (gtn.kind == nkind.N_TNAME) {
|
||||
let gsi: *structinfo = structlookupchain(c, gtn);
|
||||
if (gsi != nil) {
|
||||
emitline("\tXORQ\tAX, AX\n");
|
||||
let gz: i32 = 0;
|
||||
for (gz < slot_sz) {
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((slot_off + gz): i64);
|
||||
emitline("(BP)\n");
|
||||
gz += 8;
|
||||
};
|
||||
let gtag: i32 = taggedvariantindext(c, dt, src);
|
||||
if (gtag < 0) { gtag = 0; };
|
||||
if (aggargsrcaddr(c, src, "SI")) {
|
||||
let gtot: i32 = gsi.totsize;
|
||||
let gk: i32 = 0;
|
||||
for (gk + 8 <= gtot) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(gk: i64);
|
||||
emitline("(SI), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((slot_off + 8 + gk): i64);
|
||||
emitline("(BP)\n");
|
||||
gk += 8;
|
||||
};
|
||||
if (gk < gtot) {
|
||||
let gtail: i32 = gtot - gk;
|
||||
let glop: str = "MOVQ";
|
||||
if (gtail == 4) { glop = "MOVL"; }
|
||||
else { if (gtail == 1) { glop = "MOVB"; }; };
|
||||
emitline("\t"); emitline(glop); emitline("\t");
|
||||
emitoff(gk: i64); emitline("(SI), AX\n");
|
||||
emitline("\t"); emitline(glop); emitline("\tAX, ");
|
||||
emitoff((slot_off + 8 + gk): i64); emitline("(BP)\n");
|
||||
};
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(gtag: i64);
|
||||
emitline(", ");
|
||||
emitoff(slot_off: i64);
|
||||
emitline("(BP)\n");
|
||||
return;
|
||||
};
|
||||
};
|
||||
}; };
|
||||
};
|
||||
};
|
||||
// Struct payload (literal or ident).
|
||||
let sname: str = rhsstructpayload(c, src);
|
||||
if (sname.len > 0) {
|
||||
|
||||
@@ -21820,6 +21820,60 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
||||
emitline("(BP)\n");
|
||||
return;
|
||||
}; };
|
||||
// #50 (#263 ww-runtime-correct): a module-GLOBAL struct ident source.
|
||||
// rhsstructpayload below is local/literal-only, so a global struct value
|
||||
// fell to the scalar word0 arm — payload truncated. Land g(SB) in SI and
|
||||
// byte-copy the struct words into slot+8; cstage zero-fills the payload
|
||||
// (cstage half #43). Local/literal sources keep the existing arms (byte-id).
|
||||
if (src.kind == nkind.N_IDENT) {
|
||||
if (localfindnode(c, src.str) == nil) {
|
||||
let gtn: *node = letvartnode(c, src.str);
|
||||
if (gtn != nil) { if (gtn.kind == nkind.N_TNAME) {
|
||||
let gsi: *structinfo = structlookupchain(c, gtn);
|
||||
if (gsi != nil) {
|
||||
emitline("\tXORQ\tAX, AX\n");
|
||||
let gz: i32 = 0;
|
||||
for (gz < slot_sz) {
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((slot_off + gz): i64);
|
||||
emitline("(BP)\n");
|
||||
gz += 8;
|
||||
};
|
||||
let gtag: i32 = taggedvariantindext(c, dt, src);
|
||||
if (gtag < 0) { gtag = 0; };
|
||||
if (aggargsrcaddr(c, src, "SI")) {
|
||||
let gtot: i32 = gsi.totsize;
|
||||
let gk: i32 = 0;
|
||||
for (gk + 8 <= gtot) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff(gk: i64);
|
||||
emitline("(SI), AX\n");
|
||||
emitline("\tMOVQ\tAX, ");
|
||||
emitoff((slot_off + 8 + gk): i64);
|
||||
emitline("(BP)\n");
|
||||
gk += 8;
|
||||
};
|
||||
if (gk < gtot) {
|
||||
let gtail: i32 = gtot - gk;
|
||||
let glop: str = "MOVQ";
|
||||
if (gtail == 4) { glop = "MOVL"; }
|
||||
else { if (gtail == 1) { glop = "MOVB"; }; };
|
||||
emitline("\t"); emitline(glop); emitline("\t");
|
||||
emitoff(gk: i64); emitline("(SI), AX\n");
|
||||
emitline("\t"); emitline(glop); emitline("\tAX, ");
|
||||
emitoff((slot_off + 8 + gk): i64); emitline("(BP)\n");
|
||||
};
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(gtag: i64);
|
||||
emitline(", ");
|
||||
emitoff(slot_off: i64);
|
||||
emitline("(BP)\n");
|
||||
return;
|
||||
};
|
||||
};
|
||||
}; };
|
||||
};
|
||||
};
|
||||
// Struct payload (literal or ident).
|
||||
let sname: str = rhsstructpayload(c, src);
|
||||
if (sname.len > 0) {
|
||||
|
||||
Reference in New Issue
Block a user