feat(asm): Phase 2 — -> @place write-through outputs
An asm result can be STORED through a place (a local / struct field) instead of returned; the place output does not join the result tuple. - parser.zig: `-> @place` parses `@place` as an ordinary address-of expression → an out_place operand (the in-function form; reuses the existing `@` prefix). - inst.zig: AsmOperand gains out_ty (the output slot's value type) so emit can build the combined return struct without re-deriving from Inst.ty. - lower/expr.zig: out_place operand = the lowered @place address, out_ty = the pointee. Read-write (`+`) and indirect-memory (`*`) constraints rejected loudly (not yet implemented) rather than miscompiled. - ops.zig emitInlineAsm: the LLVM return type is built from ALL outputs (out_value + out_place); after the call, out_place slots are stored through their address and out_value slots rebuild the sx result. Fast path when there are no place outputs (the struct return IS the result — pure-value asm IR unchanged). Verified: write-to-local (42), struct field, mixed value+place (v=10 b=20), `+` rejected. Locked with 1649-platform-asm-place-output (mixed, runs on aarch64). zig build test green (657 corpus, 446 unit).
This commit is contained in:
@@ -2780,10 +2780,17 @@ pub const Parser = struct {
|
||||
var payload: *Node = undefined;
|
||||
if (self.current.tag == .arrow) {
|
||||
self.advance();
|
||||
if (self.current.tag == .at)
|
||||
return self.fail("`-> @place` write-through asm outputs are not supported yet (Phase 2); use a `-> Type` value output");
|
||||
role = .out_value;
|
||||
payload = try self.parseTypeExpr();
|
||||
if (self.current.tag == .at) {
|
||||
// `-> @place`: write-through output. `@place` is parsed as an
|
||||
// ordinary address-of expression (a pointer); lowering stores
|
||||
// the asm result through it. The output does NOT join the
|
||||
// result tuple.
|
||||
role = .out_place;
|
||||
payload = try self.parseUnary();
|
||||
} else {
|
||||
role = .out_value;
|
||||
payload = try self.parseTypeExpr();
|
||||
}
|
||||
} else if (self.current.tag == .equal) {
|
||||
self.advance();
|
||||
role = .input;
|
||||
|
||||
Reference in New Issue
Block a user