docs(asm): note x86 %[fn:P] call modifier + checkpoint x86 coverage

This commit is contained in:
agra
2026-06-16 08:37:09 +03:00
parent 17e3b91eb9
commit 79042ab9ab
2 changed files with 22 additions and 0 deletions

View File

@@ -368,6 +368,13 @@ Orthogonal: **issue 0137** (no-`main` segfault).
locked the rejection (replacing an LLVM-verifier crash), then implemented +
flipped to a runnable aarch64 example (objdump-confirmed direct `bl <_cb>`).
`zig build test` green (665 corpus, 446 unit).
- (x86 cross-arch) ir-only x86_64 siblings so each emit path is locked on BOTH
arches: 1657 read-write (`"incq ${0}","=r,0"`), 1658 indirect (`"movq $$42,
${0}","=*m"`(ptr elementtype)), 1659 symbol (`"call ${2:P}"`, direct call). x86
templates validated by cross-emitting an object (integrated assembler accepts;
objdump confirms 1659's direct `call` reloc). **Note:** x86 direct calls need
the `P` operand modifier (`%[fn:P]`); aarch64 `bl %[fn]` needs none. Pure
additive locks. `zig build test` green (668 corpus, 446 unit).
## Known issues
- **0138** — RESOLVED. `@const` (address-of a `::` comptime constant) yielded a

View File

@@ -87,6 +87,21 @@ Two reasons to prefer this over passing a function *pointer* in a plain
- **Portable** — the backend emits the correctly-mangled name, so you
don't hardcode the macOS leading underscore.
On **x86_64**, a direct `call` to a symbol operand needs the `P`
("call-target") operand modifier — `%[name:P]` (the GCC `%P0` idiom):
```sx
return asm volatile {
"call %[fn:P]", // x86_64 — note the :P modifier
[ret] "={rax}" -> i64,
"{rdi}" = n,
[fn] "s" = cb,
clobbers(.rcx, .rdx, .rsi, .r8, .r9, .r10, .r11, .memory),
};
```
aarch64 `bl %[fn]` needs no modifier.
The callee needs a stable, externally-linked symbol — i.e. `export`
(which also gives it the C ABI). A plain or `callconv(.c)`-only function
is `internal` and gets dead-code-eliminated, so the symbol won't link.