boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs

commit bf0cbf2005df3b5c84d48c4efa206567563dfa3a
parent aa0c83900e7fb42f42a0361f46597e9bc5aabbaf
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri, 24 Apr 2026 08:09:27 -0700

Require active frame for CALL/CALLR in P1 spec

Previously the spec said call/return correctness didn't depend on a
frame, but the aarch64 and riscv64 backends both lower CALL to a bare
BLR/JALR that clobbers the native link register. A non-leaf caller
without a frame would infinite-loop on RET.

Tighten the contract: any function that issues CALL, CALLR, TAIL, or
TAILR must ENTER a standard frame first. Pure leaves may still omit the
frame. Existing backends are already correct under the new wording.

Diffstat:
Mdocs/P1.md | 9++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/docs/P1.md b/docs/P1.md @@ -126,8 +126,9 @@ Callee-saved: ### Call semantics -A call is valid from any function, including a leaf. Call / return correctness -does not depend on establishing a frame first. +A function that issues any `CALL`, `CALLR`, `TAIL`, or `TAILR` must establish a +standard frame with `ENTER` before its first such op. A leaf that issues none +of those may omit the frame entirely. If a function needs any incoming argument after making a call, it must save it before the call. This matters in particular for `a0`, which is overwritten by @@ -277,9 +278,7 @@ following control-flow op consumes that target. `CALL` transfers control to the target most recently loaded by `LA_BR` and establishes a return continuation such that a subsequent `RET` returns to the -instruction after the `CALL`. `CALL` is valid whether or not the caller has -established a standard frame, except that any call using stack-passed argument -words requires an active standard frame to hold the staged outgoing words. +instruction after the `CALL`. `CALL` requires an active standard frame. `CALLR rs` is the register-indirect form of `CALL`. It transfers control to the code pointer value held in `rs` and establishes the same return