boot2

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

commit 1a73629687b8843765b1ef6a00e4ee8a6cec6843
parent 6f73803c2215ca80eee97a3c0c85d1238d6113a1
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri, 24 Apr 2026 18:02:46 -0700

Drop parens on zero-arg macro calls

M1pp accepts `%name` as a parenless invocation of any zero-parameter
macro (test 13-parenless covers the contract). Adopt that style across
P1 source: control-flow ops (`%ret`, `%eret`, `%syscall`), syscall-
number macros (`%sys_write`, `%p1_sys_*`), backend-internal helpers
(`%amd_cqo`, `%aa64_ret`, `%rv_ecall`, ...), and paste-dispatch sites
(`%amd_reg_##r`, `%rv_is_sp_##r`, ...). Macro definition headers stay
paren'd — the header parser still requires `%macro NAME(...)`.

Diffstat:
MP1/P1-aarch64.M1pp | 16++++++++--------
MP1/P1-amd64.M1pp | 18+++++++++---------
MP1/P1-riscv64.M1pp | 26+++++++++++++-------------
MP1/P1.M1pp | 50+++++++++++++++++++++++++-------------------------
MP1/P1pp.P1pp | 90++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mtests/P1/argc_exit.P1pp | 4++--
Mtests/P1/double.P1pp | 4++--
Mtests/P1/hello.P1pp | 6+++---
Mtests/P1/p1-aliasing.P1pp | 6+++---
Mtests/P1/p1-call.P1pp | 8++++----
10 files changed, 114 insertions(+), 114 deletions(-)

diff --git a/P1/P1-aarch64.M1pp b/P1/P1-aarch64.M1pp @@ -73,7 +73,7 @@ %endm %macro aa64_reg(r) -%aa64_reg_##r() +%aa64_reg_##r %endm %macro aa64_is_sp_a0() @@ -144,7 +144,7 @@ %endm %macro aa64_is_sp(r) -%aa64_is_sp_##r() +%aa64_is_sp_##r %endm # ---- Low-level instruction encoders -------------------------------------- @@ -239,15 +239,15 @@ %endm %macro aa64_mem_uimm_base(op) -%aa64_mem_uimm_base_##op() +%aa64_mem_uimm_base_##op %endm %macro aa64_mem_unscaled_base(op) -%aa64_mem_unscaled_base_##op() +%aa64_mem_unscaled_base_##op %endm %macro aa64_mem_size(op) -%aa64_mem_size_##op() +%aa64_mem_size_##op %endm %macro aa64_mem_fallback(op, rt, rn, off) @@ -436,14 +436,14 @@ $(imm) %endm %macro p1_ret() -%aa64_ret() +%aa64_ret %endm %macro p1_eret() %aa64_mem(LD, lr, sp, 0) %aa64_mem(LD, x8, sp, 8) %aa64_mov_rr(sp, x8) -%aa64_ret() +%aa64_ret %endm %macro p1_tail() @@ -538,7 +538,7 @@ $(imm) # ---- Linux aarch64 syscall numbers --------------------------------------- # Each macro returns the syscall number as an integer atom so callers can -# use it inside expressions (e.g. `%li(a0, %sys_write())`). +# use it inside expressions (e.g. `%li(a0, %sys_write)`). %macro p1_sys_read() 63 diff --git a/P1/P1-amd64.M1pp b/P1/P1-amd64.M1pp @@ -109,7 +109,7 @@ %endm %macro amd_reg(r) -%amd_reg_##r() +%amd_reg_##r %endm # Per-P1-name `is this sp?` predicate. Used by p1_mem to decide whether @@ -153,7 +153,7 @@ %endm %macro amd_is_sp(r) -%amd_is_sp_##r() +%amd_is_sp_##r %endm # ---- REX / ModRM helpers ------------------------------------------------ @@ -171,8 +171,8 @@ # Emit REX.B (0x41) iff r is r8-r15. Used by the short-prefix opcodes above. %macro amd_maybe_rex_b(r) %select((>= %amd_reg(r) 8), - %amd_rex_b_short(), - %amd_nobytes()) + %amd_rex_b_short, + %amd_nobytes) %endm # REX.WB: W=1 for 64-bit, B=(r>>3) to extend ModRM.rm / SIB.base. @@ -495,7 +495,7 @@ %amd_mov_rr(rbp, rdx) %amd_mov_rr(scratch, rb) %amd_mov_rr(rax, ra) -%amd_cqo() +%amd_cqo %amd_idiv_r(scratch) %amd_mov_rr(rdx, rbp) %amd_mov_rr(rd, rax) @@ -505,7 +505,7 @@ %amd_mov_rr(rbp, rdx) %amd_mov_rr(scratch, rb) %amd_mov_rr(rax, ra) -%amd_cqo() +%amd_cqo %amd_idiv_r(scratch) %amd_mov_rr(rax, rdx) %amd_mov_rr(rdx, rbp) @@ -717,7 +717,7 @@ $(imm) %endm %macro p1_ret() -%amd_ret() +%amd_ret %endm # ERET -- atomic frame epilogue + return from a framed function. @@ -732,7 +732,7 @@ $(imm) %amd_mem_LD(rax, sp, 8) %amd_mov_rr(sp, rax) %amd_push(scratch) -%amd_ret() +%amd_ret %endm # TAIL / TAILR -- frame epilogue followed by an unconditional jump to the @@ -892,7 +892,7 @@ $(imm) # ---- Linux amd64 syscall numbers ---------------------------------------- # Each macro returns the syscall number as an integer atom so callers can -# use it inside expressions (e.g. `%li(a0, %sys_write())`). +# use it inside expressions (e.g. `%li(a0, %sys_write)`). %macro p1_sys_read() 0 diff --git a/P1/P1-riscv64.M1pp b/P1/P1-riscv64.M1pp @@ -90,7 +90,7 @@ %endm %macro rv_reg(r) -%rv_reg_##r() +%rv_reg_##r %endm %macro rv_is_sp_a0() @@ -167,7 +167,7 @@ %endm %macro rv_is_sp(r) -%rv_is_sp_##r() +%rv_is_sp_##r %endm # ---- Low-level instruction encoders -------------------------------------- @@ -432,25 +432,25 @@ $(imm) %rv_jalr(zero, rs, 0) %endm -# Conditional branch: emit a skip-taken native branch over the `%p1_b()` +# Conditional branch: emit a skip-taken native branch over the `%p1_b` # fall-through, then the jalr(br) that takes the P1 branch. Each native # B-type here uses the inverted condition with a +8 offset so the `jalr` # two insns below is the taken target. %macro p1_condb_BEQ(ra, rb) %rv_b_type_skip8(0x00001063, ra, rb) -%p1_b() +%p1_b %endm %macro p1_condb_BNE(ra, rb) %rv_b_type_skip8(0x00000063, ra, rb) -%p1_b() +%p1_b %endm %macro p1_condb_BLT(ra, rb) %rv_b_type_skip8(0x00005063, ra, rb) -%p1_b() +%p1_b %endm %macro p1_condb_BLTU(ra, rb) %rv_b_type_skip8(0x00007063, ra, rb) -%p1_b() +%p1_b %endm %macro p1_condb(op, ra, rb) %p1_condb_##op(ra, rb) @@ -458,15 +458,15 @@ $(imm) %macro p1_condbz_BEQZ(ra) %rv_b_type_skip8(0x00001063, ra, zero) -%p1_b() +%p1_b %endm %macro p1_condbz_BNEZ(ra) %rv_b_type_skip8(0x00000063, ra, zero) -%p1_b() +%p1_b %endm %macro p1_condbz_BLTZ(ra) %rv_b_type_skip8(0x00005063, ra, zero) -%p1_b() +%p1_b %endm %macro p1_condbz(op, ra) %p1_condbz_##op(ra) @@ -492,7 +492,7 @@ $(imm) &p1_main %rv_jalr(ra, br, 0) %rv_addi(a7, zero, 93) -%rv_ecall() +%rv_ecall %endm %macro p1_syscall() @@ -511,7 +511,7 @@ $(imm) %rv_mov_rr(a3, t0) %rv_mov_rr(a4, s0) %rv_mov_rr(a5, s1) -%rv_ecall() +%rv_ecall %rv_mov_rr(a1, save0) %rv_mov_rr(a2, save1) %rv_mov_rr(a3, save2) @@ -519,7 +519,7 @@ $(imm) # ---- Linux riscv64 syscall numbers --------------------------------------- # Each macro returns the syscall number as an integer atom so callers can -# use it inside expressions (e.g. `%li(a0, %sys_write())`). +# use it inside expressions (e.g. `%li(a0, %sys_write)`). %macro p1_sys_read() 63 diff --git a/P1/P1.M1pp b/P1/P1.M1pp @@ -121,9 +121,9 @@ target # ---- Branching ------------------------------------------------------------ %macro b(target) -%p1_labr() +%p1_labr target -%p1_b() +%p1_b %endm %macro br(rs) @@ -131,43 +131,43 @@ target %endm %macro beq(ra, rb, target) -%p1_labr() +%p1_labr target %p1_condb(BEQ, ra, rb) %endm %macro bne(ra, rb, target) -%p1_labr() +%p1_labr target %p1_condb(BNE, ra, rb) %endm %macro blt(ra, rb, target) -%p1_labr() +%p1_labr target %p1_condb(BLT, ra, rb) %endm %macro bltu(ra, rb, target) -%p1_labr() +%p1_labr target %p1_condb(BLTU, ra, rb) %endm %macro beqz(ra, target) -%p1_labr() +%p1_labr target %p1_condbz(BEQZ, ra) %endm %macro bnez(ra, target) -%p1_labr() +%p1_labr target %p1_condbz(BNEZ, ra) %endm %macro bltz(ra, target) -%p1_labr() +%p1_labr target %p1_condbz(BLTZ, ra) %endm @@ -175,9 +175,9 @@ target # ---- Calls, returns, and frames ------------------------------------------ %macro call(target) -%p1_labr() +%p1_labr target -%p1_call() +%p1_call %endm %macro callr(rs) @@ -185,13 +185,13 @@ target %endm %macro ret() -%p1_ret() +%p1_ret %endm %macro tail(target) -%p1_labr() +%p1_labr target -%p1_tail() +%p1_tail %endm %macro tailr(rs) @@ -203,45 +203,45 @@ target %endm %macro eret() -%p1_eret() +%p1_eret %endm # ---- System --------------------------------------------------------------- %macro syscall() -%p1_syscall() +%p1_syscall %endm %macro sys_read() -%p1_sys_read() +%p1_sys_read %endm %macro sys_write() -%p1_sys_write() +%p1_sys_write %endm %macro sys_close() -%p1_sys_close() +%p1_sys_close %endm %macro sys_openat() -%p1_sys_openat() +%p1_sys_openat %endm %macro sys_exit() -%p1_sys_exit() +%p1_sys_exit %endm %macro sys_clone() -%p1_sys_clone() +%p1_sys_clone %endm %macro sys_execve() -%p1_sys_execve() +%p1_sys_execve %endm %macro sys_waitid() -%p1_sys_waitid() +%p1_sys_waitid %endm # ---- Program entry -------------------------------------------------------- @@ -253,4 +253,4 @@ target # emitted unconditionally here so portable sources only need to define # `:p1_main` as an ordinary P1 function. -%p1_entry() +%p1_entry diff --git a/P1/P1pp.P1pp b/P1/P1pp.P1pp @@ -370,14 +370,14 @@ body # # Pushes a scope named after the function so `::foo` inside the body # mangles to `name__foo`. The body is bracketed by %enter(size) and -# %eret(), so functions defined with %fn always carry a standard frame. +# %eret, so functions defined with %fn always carry a standard frame. %macro fn(name, size, body) : ## name %scope name %enter(size) body -%eret() +%eret %endscope %endm @@ -459,7 +459,7 @@ body %b(&::loop) ::done %mov(a0, a3) -%ret() +%ret %endscope # memset(dst=a0, byte=a1, n=a2) -> dst (a0) @@ -475,7 +475,7 @@ body %b(&::loop) ::done %mov(a0, a3) -%ret() +%ret %endscope # memcmp(a=a0, b=a1, n=a2) -> -1/0/1 (a0) @@ -494,13 +494,13 @@ body %b(&::loop) ::lt %li(a0, -1) -%ret() +%ret ::gt %li(a0, 1) -%ret() +%ret ::eq %li(a0, 0) -%ret() +%ret %endscope # strlen(cstr=a0) -> n (a0) @@ -514,7 +514,7 @@ body %b(&::loop) ::done %sub(a0, a1, a0) -%ret() +%ret %endscope # streq(a=a0, b=a1) -> 0 or 1 @@ -530,10 +530,10 @@ body %b(&::loop) ::ne %li(a0, 0) -%ret() +%ret ::eq %li(a0, 1) -%ret() +%ret %endscope # strcmp(a=a0, b=a1) -> -1/0/1 @@ -550,13 +550,13 @@ body %b(&::loop) ::lt %li(a0, -1) -%ret() +%ret ::gt %li(a0, 1) -%ret() +%ret ::eq %li(a0, 0) -%ret() +%ret %endscope # ========================================================================= @@ -611,12 +611,12 @@ body %ld(a0, sp, 0) %sub(a1, a2, a0) %mov(a0, t1) -%eret() +%eret ::no_digits %li(a0, 0) %li(a1, 0) -%eret() +%eret %endscope # parse_hex(buf=a0, len=a1) -> (value=a0, consumed=a1) @@ -665,12 +665,12 @@ body %ld(a0, sp, 0) %sub(a1, a2, a0) %mov(a0, t1) -%eret() +%eret ::no_digits %li(a0, 0) %li(a1, 0) -%eret() +%eret %endscope # fmt_dec(buf=a0, value=a1) -> n_bytes (a0) @@ -720,7 +720,7 @@ body %ld(t2, sp, 0) %add(a0, a0, a2) %sub(a0, a0, t2) -%eret() +%eret %endscope # fmt_hex(buf=a0, value=a1) -> n_bytes (a0) @@ -733,7 +733,7 @@ body %li(t0, 48) %sb(t0, a0, 0) %li(a0, 1) -%eret() +%eret ::nonzero %mov(t0, a1) @@ -763,7 +763,7 @@ body %ld(t2, sp, 0) %add(a0, a0, a2) %sub(a0, a0, t2) -%eret() +%eret %endscope # ========================================================================= @@ -779,7 +779,7 @@ body %bltu(t0, t1, &::done) %li(a0, 0) ::done -%ret() +%ret %endscope # is_hex_digit(c=a0) -> 0 or 1 @@ -797,7 +797,7 @@ body %li(t2, 0) ::done %mov(a0, t2) -%ret() +%ret %endscope # is_space(c=a0) -> 0 or 1 @@ -812,7 +812,7 @@ body %li(t2, 0) ::done %mov(a0, t2) -%ret() +%ret %endscope # is_alpha(c=a0) -> 0 or 1 @@ -827,7 +827,7 @@ body %li(t2, 0) ::done %mov(a0, t2) -%ret() +%ret %endscope # is_alnum(c=a0) -> 0 or 1 @@ -845,7 +845,7 @@ body %li(t2, 0) ::done %mov(a0, t2) -%ret() +%ret %endscope # ========================================================================= @@ -862,18 +862,18 @@ body %mov(a3, a2) %mov(a2, a1) %mov(a1, a0) -%li(a0, %p1_sys_read()) -%syscall() -%ret() +%li(a0, %p1_sys_read) +%syscall +%ret # sys_write(fd=a0, buf=a1, len=a2) -> n (a0) :sys_write %mov(a3, a2) %mov(a2, a1) %mov(a1, a0) -%li(a0, %p1_sys_write()) -%syscall() -%ret() +%li(a0, %p1_sys_write) +%syscall +%ret # sys_open(path=a0, flags=a1, mode=a2) -> fd (a0) # Implemented as openat(AT_FDCWD, path, flags, mode). AT_FDCWD = -100. @@ -882,23 +882,23 @@ body %mov(a3, a1) %mov(a2, a0) %li(a1, -100) -%li(a0, %p1_sys_openat()) -%syscall() -%ret() +%li(a0, %p1_sys_openat) +%syscall +%ret # sys_close(fd=a0) -> r (a0) :sys_close %mov(a1, a0) -%li(a0, %p1_sys_close()) -%syscall() -%ret() +%li(a0, %p1_sys_close) +%syscall +%ret # sys_exit(code=a0) -> never returns :sys_exit %scope sys_exit %mov(a1, a0) -%li(a0, %p1_sys_exit()) -%syscall() +%li(a0, %p1_sys_exit) +%syscall ::spin %b(&::spin) %endscope @@ -1172,7 +1172,7 @@ body %la(t0, &libp1pp__bump_cap) %st(a1, t0, 0) %li(a0, 0) -%ret() +%ret # bump_alloc(n=a0) -> ptr (0 on exhaustion) # @@ -1195,24 +1195,24 @@ body %bltu(a3, t2, &::fail) %st(t2, t0, 0) %mov(a0, t1) -%ret() +%ret ::fail %li(a0, 0) -%ret() +%ret %endscope # bump_mark() -> saved :bump_mark %la(t0, &libp1pp__bump_cursor) %ld(a0, t0, 0) -%ret() +%ret # bump_release(saved=a0) -> 0 :bump_release %la(t0, &libp1pp__bump_cursor) %st(a0, t0, 0) %li(a0, 0) -%ret() +%ret # bump_reset() -> 0 :bump_reset @@ -1221,7 +1221,7 @@ body %la(t0, &libp1pp__bump_cursor) %st(t1, t0, 0) %li(a0, 0) -%ret() +%ret # ========================================================================= # Panic diff --git a/tests/P1/argc_exit.P1pp b/tests/P1/argc_exit.P1pp @@ -2,9 +2,9 @@ # # The backend-owned `:_start` stub calls `p1_main` with `a0` = argc, # `a1` = argv. Since `a0` is also the one-word return register, a bare -# `%ret()` returns argc unchanged, and the stub hands that to sys_exit. +# `%ret` returns argc unchanged, and the stub hands that to sys_exit. :p1_main - %ret() + %ret :ELF_end diff --git a/tests/P1/double.P1pp b/tests/P1/double.P1pp @@ -8,11 +8,11 @@ :double %shli(a0, a0, 1) - %ret() + %ret :p1_main %enter(0) %call(&double) - %eret() + %eret :ELF_end diff --git a/tests/P1/hello.P1pp b/tests/P1/hello.P1pp @@ -11,13 +11,13 @@ # 0 in a0 so the backend stub exits with status 0. :p1_main - %li(a0, %sys_write()) + %li(a0, %sys_write) %li(a1, 1) %la(a2, &msg) %li(a3, 14) - %syscall() + %syscall %li(a0, 0) - %ret() + %ret :msg "Hello, World! diff --git a/tests/P1/p1-aliasing.P1pp b/tests/P1/p1-aliasing.P1pp @@ -53,14 +53,14 @@ %la(t0, &msg_buf) %sb(s0, t0, 0) - %li(a0, %sys_write()) + %li(a0, %sys_write) %li(a1, 1) %la(a2, &msg_buf) %li(a3, 2) - %syscall() + %syscall %li(a0, 0) - %eret() + %eret # Two-byte output scratch: [0] = computed byte, [1] = newline. The space # placeholder gets overwritten by SB before the write syscall. diff --git a/tests/P1/p1-call.P1pp b/tests/P1/p1-call.P1pp @@ -20,7 +20,7 @@ # exit status = argc + 1 (so it's always >= 2). %addi(a0, s0, 1) - %eret() + %eret # write_msg(buf=a0, len=a1) -> void :write_msg @@ -28,10 +28,10 @@ # Shift (a0, a1) -> (a2, a3); fd goes in a1, number in a0. %mov(a2, a0) %mov(a3, a1) - %li(a0, %sys_write()) + %li(a0, %sys_write) %li(a1, 1) - %syscall() - %eret() + %syscall + %eret :msg_a "A