test(asm): reject symbol "s" operands cleanly + lock (symbol-op prep)
A symbol operand (constraint "s") feeds a function/global symbol whose mangled name the template emits — enabling a DIRECT `bl %[fn]` (one fewer indirection than register-indirect `blr`). Until now `"s" = fn` fell through to emit and produced an LLVM-verifier crash (param type mismatch). Reject it at lowering with a clear diagnostic instead, and lock that with examples/1656-platform-asm-symbol-operand.sx. The next commit implements it and flips the example to run (→ 42).
This commit is contained in:
@@ -2366,7 +2366,17 @@ pub fn lowerAsmExpr(self: *Lowering, ae: *const ast.AsmExpr, span: ast.Span) Ref
|
||||
var operand_ref: Ref = Ref.none;
|
||||
var out_ty: TypeId = .void;
|
||||
switch (op.role) {
|
||||
.input => operand_ref = self.lowerExpr(op.payload),
|
||||
.input => {
|
||||
// Symbol operands (constraint `"s"`) — feed a function/global
|
||||
// SYMBOL whose mangled name the template emits (e.g. a direct
|
||||
// `bl %[fn]`). Not yet implemented; reject loudly rather than
|
||||
// emit invalid IR (an LLVM-verifier crash). [Phase: symbol ops.]
|
||||
if (std.mem.eql(u8, op.constraint, "s")) {
|
||||
diags.addFmt(.err, span, "symbol asm operands (`\"s\"`) are not yet implemented", .{});
|
||||
return self.emitPlaceholder("inline_asm");
|
||||
}
|
||||
operand_ref = self.lowerExpr(op.payload);
|
||||
},
|
||||
.out_value => out_ty = self.resolveTypeWithBindings(op.payload),
|
||||
.out_place => {
|
||||
// Read-write (`+`) outputs tie an input to the output and seed
|
||||
|
||||
Reference in New Issue
Block a user