feat(asm): Phase B.1 — operand-name validation (echo + duplicates)
Extends lowerAsmExpr with a pinnedRegister(constraint) helper and two §II.5
operand-naming checks, in the compile path before the codegen bail:
- reject the echo form `[eax] "={eax}"` — a label identical to the register its
own constraint pins is redundant (the operand is already auto-named after the
register); the useful form is a label that differs (`[quot] "={rax}"`);
- reject duplicate operand names (ambiguous %[name] / result field).
Locked with 1643-platform-asm-echo-name and 1644-platform-asm-duplicate-name.
zig build test green (652 corpus, 445 unit).
This commit is contained in:
6
examples/1643-platform-asm-echo-name.sx
Normal file
6
examples/1643-platform-asm-echo-name.sx
Normal file
@@ -0,0 +1,6 @@
|
||||
// ASM stream Phase B — operand naming rule (§II.5): an explicit `[name]` that
|
||||
// just echoes the register its own constraint pins (`[eax] "={eax}"`) carries
|
||||
// no information — the operand is already auto-named after the register. Reject
|
||||
// it. The useful form is a label that DIFFERS (e.g. `[quot] "={rax}"`).
|
||||
f :: () -> u32 { return asm volatile { "cpuid", [eax] "={eax}" -> u32, "{eax}" = 1 }; }
|
||||
main :: () { x := f(); }
|
||||
4
examples/1644-platform-asm-duplicate-name.sx
Normal file
4
examples/1644-platform-asm-duplicate-name.sx
Normal file
@@ -0,0 +1,4 @@
|
||||
// ASM stream Phase B — two asm operands may not share a `[name]`: the `%[name]`
|
||||
// template reference (and the result tuple field) would be ambiguous.
|
||||
f :: () -> u64 { return asm volatile { "nop", [x] "=r" -> u64, [x] "r" = 5 }; }
|
||||
main :: () { v := f(); }
|
||||
1
examples/expected/1643-platform-asm-echo-name.exit
Normal file
1
examples/expected/1643-platform-asm-echo-name.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
5
examples/expected/1643-platform-asm-echo-name.stderr
Normal file
5
examples/expected/1643-platform-asm-echo-name.stderr
Normal file
@@ -0,0 +1,5 @@
|
||||
error: redundant asm operand name `eax` — it already names the pinned register; drop the `[eax]`
|
||||
--> examples/1643-platform-asm-echo-name.sx:5:25
|
||||
|
|
||||
5 | f :: () -> u32 { return asm volatile { "cpuid", [eax] "={eax}" -> u32, "{eax}" = 1 }; }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
1
examples/expected/1643-platform-asm-echo-name.stdout
Normal file
1
examples/expected/1643-platform-asm-echo-name.stdout
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
examples/expected/1644-platform-asm-duplicate-name.exit
Normal file
1
examples/expected/1644-platform-asm-duplicate-name.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,5 @@
|
||||
error: duplicate asm operand name `x`
|
||||
--> examples/1644-platform-asm-duplicate-name.sx:3:25
|
||||
|
|
||||
3 | f :: () -> u64 { return asm volatile { "nop", [x] "=r" -> u64, [x] "r" = 5 }; }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user