feat(asm): portable symbol refs — auto-inject :c operand modifier

A `%[name]` that references a symbol ("s") operand without an explicit
modifier now lowers to `${N:c}` (LLVM 'bare constant — no punctuation')
instead of `${N}`. This makes `bl %[fn]` / `call %[fn]` portable across
targets with no per-arch knowledge: x86 would otherwise render `$cb`
(an invalid call target, requiring a hand-written `:P`); aarch64 is
unaffected. Verified `:c` is equivalent to `:P` for x86-64 calls (both
emit R_X86_64_PLT32), and correct for branch targets, RIP-relative
addressing, and `$`-prefixed absolute immediates.

renderAsmTemplate injects `:c` only for symbol operands lacking an
explicit modifier (asmNamedIsSymbol helper); an explicit `%[name:X]`
still wins (escape hatch). x86 example 1659 drops its `:P` for the same
plain `%[fn]` as aarch64 1656. Snapshots regen to `${N:c}`. zig build
test green (668 corpus, 446 unit).
This commit is contained in:
agra
2026-06-16 09:04:23 +03:00
parent 79042ab9ab
commit 066ba54346
4 changed files with 28 additions and 8 deletions

View File

@@ -15,7 +15,7 @@ entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%asm = call i64 asm sideeffect " stp x29, x30, [sp, #-16]!\0A mov x0, ${1}\0A bl ${2}\0A mov ${0}, x0\0A ldp x29, x30, [sp], #16\0A", "=r,r,s,~{x0},~{x30},~{memory}"(i64 %load, ptr @cb)
%asm = call i64 asm sideeffect " stp x29, x30, [sp, #-16]!\0A mov x0, ${1}\0A bl ${2:c}\0A mov ${0}, x0\0A ldp x29, x30, [sp], #16\0A", "=r,r,s,~{x0},~{x30},~{memory}"(i64 %load, ptr @cb)
ret i64 %asm
}

View File

@@ -15,7 +15,7 @@ entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%asm = call i64 asm sideeffect "call ${2:P}", "={rax},{rdi},s,~{rcx},~{rdx},~{rsi},~{r8},~{r9},~{r10},~{r11},~{memory}"(i64 %load, ptr @cb)
%asm = call i64 asm sideeffect "call ${2:c}", "={rax},{rdi},s,~{rcx},~{rdx},~{rsi},~{r8},~{r9},~{r10},~{r11},~{memory}"(i64 %load, ptr @cb)
ret i64 %asm
}