Flip the B1.0a emit bail to real emission. The emit_llvm declaration pass now adds LLVM's naked + noinline + nounwind attributes for an is_pure function and skips frame-pointer=all (incompatible with a frameless function); Pass 2 emits the body normally, and the naked attribute makes the backend emit it verbatim (the inline asm + its own ret) with no prologue/epilogue. IR shape verified: ; Function Attrs: naked noinline nounwind define internal i64 @answer() #0 { entry: call void asm sideeffect "...ret...", ""() unreachable } The caller invokes it as an ordinary () -> i64 call (.pure is call_conv == .default). - examples/1800-concurrency-pure-asm.sx: now green, aarch64-pinned (.build macos) -> exit 42 + .ir snapshot. - examples/1801-concurrency-pure-generic.sx (renamed from -bail): the generic .pure now emits a correct naked answer__i64 (exit 42), proving generic.zig produces a naked body, not a framed one. - examples/1802-concurrency-pure-asm-x86.sx: x86_64 cross sibling (.build x86_64-linux, ir-only here); .ir locks naked + movl $42,%eax. - unit test in emit_llvm.test.zig asserts the naked attribute is present and frame-pointer absent on an abi(.pure) function. Suite green (724/0).
26 lines
1.1 KiB
Plaintext
26 lines
1.1 KiB
Plaintext
// Stream B1 (fibers) — `abi(.pure)` emits a naked function end-to-end.
|
|
//
|
|
// An `abi(.pure)` function has no calling-convention prologue/epilogue/frame
|
|
// and no implicit `__sx_ctx`: its body is a single asm block that sets the
|
|
// return register and emits its own `ret`. This is the substrate the per-arch
|
|
// fiber context-switch is built on (design §4.6) — a `.c` epilogue would
|
|
// restore SP from the wrong stack across a switch (SP-in ≠ SP-out by design).
|
|
//
|
|
// Lowered via LLVM's `naked` function attribute: the body is emitted verbatim
|
|
// (the inline asm + its own `ret`) with NO frame setup; the IR shows
|
|
// `attributes #N = { naked noinline nounwind }` and the bare asm. aarch64-pinned
|
|
// (the asm body is per-arch); runs end-to-end here (exit 42), ir-only on a
|
|
// mismatch. See the x86_64 sibling 1802. NOTE: the `.ir` proves the `naked`
|
|
// keyword + asm emitted, NOT register-save correctness (that's the B1.3
|
|
// switch-stress harness's job).
|
|
answer :: () -> i64 abi(.pure) {
|
|
asm volatile {
|
|
#string ASM
|
|
mov x0, #42
|
|
ret
|
|
ASM
|
|
};
|
|
}
|
|
|
|
main :: () -> i64 { return answer(); }
|