w6a: bare negative constant parses honestly; name(reg) rejects

Two parse.c operand defects. A bare `-8` (no $) double-negated to
+8: a_parsenum lets strtoll consume the sign, and the caller's
`off * sign` re-applied it (the D_INDIR arm never multiplied, which
is why -8(BP) always worked); the wwstage twin was already correct,
so this was a latent cs!=ww on hand-written source. The name(REG)
non-SB arm faked a D_INDIR off an UNCHECKED reg_lookup and silently
discarded the parsed ident and +disp -- both stages; the shape has
no encoding and now rejects loud.
This commit is contained in:
2026-08-09 01:12:41 +09:00
parent 5006bf4fb9
commit 4a5f64fc3d
2 changed files with 17 additions and 11 deletions

View File

@@ -338,12 +338,14 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
out.atype = D_EXTERN;
out.asym = dupstr(p + istart, in_);
out.offset = symdisp;
} else {
out.atype = D_INDIR;
out.reg = r;
out.offset = 0i64;
return cur2 + 1u64;
};
return cur2 + 1u64;
// name(REG) with a non-SB register has no
// encoding here; the old arm faked D_INDIR
// off an UNCHECKED reglookup and silently
// discarded the ident and +disp (rule 7).
perr(a, "unsupported name(reg) operand");
return n;
};
perr(a, "missing ')'");
return n;