feat(asm): Phase C.1 + D — inline asm codegen (runs end-to-end)
lowerAsmExpr stops bailing and builds the inline_asm op: resolves each operand's
effective name (§II.5 — explicit [name] else the {reg} pin), interns
template/constraints/clobbers, lowers input Refs, derives the result TypeId
(0→void, 1→T). Adds the last deferred validation (every %[name] must name an
operand). Multi-output (N>1) bails with a named "Phase E" diagnostic.
emitInlineAsm (backend/llvm/ops.zig) ports Zig's airAssembly: assembles the LLVM
constraint string (outputs → inputs → ~{clobber}, ',' → '|'), rewrites the
template (%[name]→${N}, %%→%, $→$$, %=→${:uid}), then LLVMGetInlineAsm +
LLVMBuildCall2 (AT&T dialect). Dispatch wired in emit_llvm.zig (replacing the C.0
@panic tripwire).
inferType gains an .asm_expr arm (expr_typer.zig) so a bare `x := asm {…-> T}`
binding types correctly — without it the binding inferred .unresolved and
silently produced 0.
llvm_shim.c: LLVMInitializeNativeAsmParser() — the JIT must assemble inline asm
at run time.
Verified end-to-end on the aarch64 host: `mov`/`add` with register-class inputs
and a value output run (exit 42/99), `nop volatile` runs (exit 0). IR is
textbook: `call i64 asm "add ${0},${1},${2}", "=r,r,r"(…)`.
Locked with 1645 (aarch64 add, runs; ir-only on non-aarch64) + 1646 (:= binding).
Updated 1640 (now Phase-E bail) + 1642 (now runs).
zig build test green (654 corpus, 446 unit).
This commit is contained in:
@@ -1563,11 +1563,7 @@ pub const LLVMEmitter = struct {
|
||||
// ── Calls ─────────────────────────────────────────────
|
||||
.objc_msg_send => |msg| self.ops().emitObjcMsgSend(instruction, msg),
|
||||
.jni_msg_send => |msg| self.ops().emitJniMsgSend(instruction, msg),
|
||||
// Tripwire (ASM stream): the IR op exists (Phase C.0) but emit lands
|
||||
// in Phase D. Until then `lowerAsmExpr` still bails, so no inline_asm
|
||||
// op is ever created — reaching here means lowering switched over
|
||||
// before emit was ready. Crash loudly rather than miscompile.
|
||||
.inline_asm => @panic("inline_asm reached LLVM emit before Phase D — lowering must still bail until emitInlineAsm lands"),
|
||||
.inline_asm => |a| self.ops().emitInlineAsm(instruction, a),
|
||||
.call => |call_op| self.ops().emitCall(instruction, call_op),
|
||||
.call_indirect => |call_op| self.ops().emitCallIndirect(instruction, call_op),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user