boot2

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

commit 5d78449f72b14b1a16ce75235d12da6c4e14d1c5
parent 2216e63bcd1f8209385688b28c0547a4cf370dff
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri, 24 Apr 2026 17:52:49 -0700

P1.LI: take immediate as a macro arg

Make the front-end `%li(rd, imm)` symmetric with `%la(rd, target)` and
`%addi(rd, ra, imm)`. The backend `p1_li(rd, imm)` now owns both the
opcode prefix and the literal-pool word, so portable source no longer
encodes the literal width inline.

Syscall-number macros (`p1_sys_*`) return integer atoms instead of raw
8-byte emissions so they compose through M1pp's expression evaluator
inside `%li(a0, %sys_write())`.

Diffstat:
MP1/P1-aarch64.M1pp | 23+++++++++++++----------
MP1/P1-amd64.M1pp | 23+++++++++++++----------
MP1/P1-riscv64.M1pp | 23+++++++++++++----------
MP1/P1.M1pp | 4++--
MP1/P1pp.P1pp | 162++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mtests/P1/hello.P1pp | 8++++----
Mtests/P1/p1-aliasing.P1pp | 18+++++++++---------
Mtests/P1/p1-call.P1pp | 8++++----
8 files changed, 139 insertions(+), 130 deletions(-)

diff --git a/P1/P1-aarch64.M1pp b/P1/P1-aarch64.M1pp @@ -356,8 +356,9 @@ # ---- P1 operation lowering ----------------------------------------------- -%macro p1_li(rd) +%macro p1_li(rd, imm) %aa64_lit64_prefix(rd) +$(imm) %endm %macro p1_la(rd) @@ -535,29 +536,31 @@ %aa64_mov_rr(a3, save2) %endm -# ---- Linux syscall number data words ------------------------------------- +# ---- 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())`). %macro p1_sys_read() -$(63) +63 %endm %macro p1_sys_write() -$(64) +64 %endm %macro p1_sys_close() -$(57) +57 %endm %macro p1_sys_openat() -$(56) +56 %endm %macro p1_sys_exit() -$(93) +93 %endm %macro p1_sys_clone() -$(220) +220 %endm %macro p1_sys_execve() -$(221) +221 %endm %macro p1_sys_waitid() -$(95) +95 %endm diff --git a/P1/P1-amd64.M1pp b/P1/P1-amd64.M1pp @@ -569,8 +569,9 @@ # ---- P1 operation lowering --------------------------------------------- -%macro p1_li(rd) +%macro p1_li(rd, imm) %amd_mov_imm64_prefix(rd) +$(imm) %endm %macro p1_la(rd) @@ -889,29 +890,31 @@ %amd_mov_rr(rdi, rax) %endm -# ---- Linux amd64 syscall number data words ------------------------------ +# ---- 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())`). %macro p1_sys_read() -$(0) +0 %endm %macro p1_sys_write() -$(1) +1 %endm %macro p1_sys_close() -$(3) +3 %endm %macro p1_sys_openat() -$(257) +257 %endm %macro p1_sys_exit() -$(60) +60 %endm %macro p1_sys_clone() -$(56) +56 %endm %macro p1_sys_execve() -$(59) +59 %endm %macro p1_sys_waitid() -$(247) +247 %endm diff --git a/P1/P1-riscv64.M1pp b/P1/P1-riscv64.M1pp @@ -318,8 +318,9 @@ # ---- P1 operation lowering ----------------------------------------------- -%macro p1_li(rd) +%macro p1_li(rd, imm) %rv_lit64_prefix(rd) +$(imm) %endm %macro p1_la(rd) @@ -516,29 +517,31 @@ %rv_mov_rr(a3, save2) %endm -# ---- Linux riscv64 syscall number data words ----------------------------- +# ---- 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())`). %macro p1_sys_read() -$(63) +63 %endm %macro p1_sys_write() -$(64) +64 %endm %macro p1_sys_close() -$(57) +57 %endm %macro p1_sys_openat() -$(56) +56 %endm %macro p1_sys_exit() -$(93) +93 %endm %macro p1_sys_clone() -$(220) +220 %endm %macro p1_sys_execve() -$(221) +221 %endm %macro p1_sys_waitid() -$(95) +95 %endm diff --git a/P1/P1.M1pp b/P1/P1.M1pp @@ -9,8 +9,8 @@ # ---- Materialization ------------------------------------------------------ -%macro li(rd) -%p1_li(rd) +%macro li(rd, imm) +%p1_li(rd, imm) %endm %macro la(rd, target) diff --git a/P1/P1pp.P1pp b/P1/P1pp.P1pp @@ -251,7 +251,7 @@ body # ---- %for_lt ------------------------------------------------------------ %macro for_lt(i_reg, n_reg, body) -%li(i_reg) $(0) +%li(i_reg, 0) %b(&@test) :@body body @@ -345,7 +345,7 @@ body %endm %macro for_lt_tag(tag, i_reg, n_reg, body) -%li(i_reg) $(0) +%li(i_reg, 0) %b(& ## tag ## _test) :@body body @@ -448,7 +448,7 @@ body :memcpy %scope memcpy %mov(a3, a0) -%li(t0) $(0) +%li(t0, 0) ::loop %beq(t0, a2, &::done) %add(t1, a1, t0) @@ -466,7 +466,7 @@ body :memset %scope memset %mov(a3, a0) -%li(t0) $(0) +%li(t0, 0) ::loop %beq(t0, a2, &::done) %add(t1, a3, t0) @@ -481,7 +481,7 @@ body # memcmp(a=a0, b=a1, n=a2) -> -1/0/1 (a0) :memcmp %scope memcmp -%li(t0) $(0) +%li(t0, 0) ::loop %beq(t0, a2, &::eq) %add(t1, a0, t0) @@ -493,13 +493,13 @@ body %addi(t0, t0, 1) %b(&::loop) ::lt -%li(a0) $(-1) +%li(a0, -1) %ret() ::gt -%li(a0) $(1) +%li(a0, 1) %ret() ::eq -%li(a0) $(0) +%li(a0, 0) %ret() %endscope @@ -529,10 +529,10 @@ body %addi(a1, a1, 1) %b(&::loop) ::ne -%li(a0) $(0) +%li(a0, 0) %ret() ::eq -%li(a0) $(1) +%li(a0, 1) %ret() %endscope @@ -549,13 +549,13 @@ body %addi(a1, a1, 1) %b(&::loop) ::lt -%li(a0) $(-1) +%li(a0, -1) %ret() ::gt -%li(a0) $(1) +%li(a0, 1) %ret() ::eq -%li(a0) $(0) +%li(a0, 0) %ret() %endscope @@ -572,14 +572,14 @@ body %st(a0, sp, 0) %add(a3, a0, a1) %mov(a2, a0) -%li(t0) $(0) -%li(t1) $(0) +%li(t0, 0) +%li(t1, 0) %beq(a2, a3, &::after_sign) %lb(t2, a2, 0) %addi(t2, t2, -45) %bnez(t2, &::after_sign) -%li(t0) $(1) +%li(t0, 1) %addi(a2, a2, 1) ::after_sign @@ -590,9 +590,9 @@ body %lb(t2, a2, 0) %addi(t2, t2, -48) %bltz(t2, &::digits_done) -%li(a0) $(9) +%li(a0, 9) %bltu(a0, t2, &::digits_done) -%li(a0) $(10) +%li(a0, 10) %mul(t1, t1, a0) %add(t1, t1, t2) %addi(a2, a2, 1) @@ -604,7 +604,7 @@ body %bnez(t0, &::apply_sign) %b(&::compute_return) ::apply_sign -%li(a0) $(0) +%li(a0, 0) %sub(t1, a0, t1) ::compute_return @@ -614,8 +614,8 @@ body %eret() ::no_digits -%li(a0) $(0) -%li(a1) $(0) +%li(a0, 0) +%li(a1, 0) %eret() %endscope @@ -626,7 +626,7 @@ body %st(a0, sp, 0) %add(a3, a0, a1) %mov(a2, a0) -%li(t1) $(0) +%li(t1, 0) %mov(a1, a2) ::loop @@ -635,14 +635,14 @@ body %addi(t0, t2, -48) %bltz(t0, &::check_lower) -%li(a0) $(9) +%li(a0, 9) %bltu(a0, t0, &::check_lower) %b(&::accept) ::check_lower %addi(t0, t2, -97) %bltz(t0, &::check_upper) -%li(a0) $(5) +%li(a0, 5) %bltu(a0, t0, &::check_upper) %addi(t0, t0, 10) %b(&::accept) @@ -650,7 +650,7 @@ body ::check_upper %addi(t0, t2, -65) %bltz(t0, &::done) -%li(a0) $(5) +%li(a0, 5) %bltu(a0, t0, &::done) %addi(t0, t0, 10) @@ -668,8 +668,8 @@ body %eret() ::no_digits -%li(a0) $(0) -%li(a1) $(0) +%li(a0, 0) +%li(a1, 0) %eret() %endscope @@ -686,14 +686,14 @@ body %bltz(a1, &::is_neg) %b(&::count) ::is_neg -%li(t0) $(45) +%li(t0, 45) %sb(t0, a0, 0) %addi(a0, a0, 1) ::count %mov(t0, a1) -%li(a2) $(1) -%li(t1) $(10) +%li(a2, 1) +%li(t1, 10) ::count_loop %div(t0, t0, t1) %beqz(t0, &::count_done) @@ -709,7 +709,7 @@ body %bltz(t0, &::neg_digit) %b(&::write_digit) ::neg_digit -%li(t2) $(0) +%li(t2, 0) %sub(t0, t2, t0) ::write_digit %addi(t0, t0, 48) @@ -730,14 +730,14 @@ body %st(a0, sp, 0) %bnez(a1, &::nonzero) -%li(t0) $(48) +%li(t0, 48) %sb(t0, a0, 0) -%li(a0) $(1) +%li(a0, 1) %eret() ::nonzero %mov(t0, a1) -%li(a2) $(0) +%li(a2, 0) ::count_loop %addi(a2, a2, 1) %shri(t0, t0, 4) @@ -748,7 +748,7 @@ body ::dig_loop %addi(a3, a3, -1) %andi(t0, a1, 15) -%li(t1) $(10) +%li(t1, 10) %bltu(t0, t1, &::is_letter) %addi(t0, t0, -10) %addi(t0, t0, 97) @@ -774,10 +774,10 @@ body :is_digit %scope is_digit %addi(t0, a0, -48) -%li(t1) $(10) -%li(a0) $(1) +%li(t1, 10) +%li(a0, 1) %bltu(t0, t1, &::done) -%li(a0) $(0) +%li(a0, 0) ::done %ret() %endscope @@ -785,16 +785,16 @@ body # is_hex_digit(c=a0) -> 0 or 1 :is_hex_digit %scope is_hex_digit -%li(t2) $(1) +%li(t2, 1) %addi(t0, a0, -48) -%li(t1) $(10) +%li(t1, 10) %bltu(t0, t1, &::done) %addi(t0, a0, -97) -%li(t1) $(6) +%li(t1, 6) %bltu(t0, t1, &::done) %addi(t0, a0, -65) %bltu(t0, t1, &::done) -%li(t2) $(0) +%li(t2, 0) ::done %mov(a0, t2) %ret() @@ -803,13 +803,13 @@ body # is_space(c=a0) -> 0 or 1 :is_space %scope is_space -%li(t2) $(1) +%li(t2, 1) %addi(t0, a0, -32) %beqz(t0, &::done) %addi(t0, a0, -9) -%li(t1) $(5) +%li(t1, 5) %bltu(t0, t1, &::done) -%li(t2) $(0) +%li(t2, 0) ::done %mov(a0, t2) %ret() @@ -818,13 +818,13 @@ body # is_alpha(c=a0) -> 0 or 1 :is_alpha %scope is_alpha -%li(t2) $(1) +%li(t2, 1) %addi(t0, a0, -97) -%li(t1) $(26) +%li(t1, 26) %bltu(t0, t1, &::done) %addi(t0, a0, -65) %bltu(t0, t1, &::done) -%li(t2) $(0) +%li(t2, 0) ::done %mov(a0, t2) %ret() @@ -833,16 +833,16 @@ body # is_alnum(c=a0) -> 0 or 1 :is_alnum %scope is_alnum -%li(t2) $(1) +%li(t2, 1) %addi(t0, a0, -48) -%li(t1) $(10) +%li(t1, 10) %bltu(t0, t1, &::done) %addi(t0, a0, -97) -%li(t1) $(26) +%li(t1, 26) %bltu(t0, t1, &::done) %addi(t0, a0, -65) %bltu(t0, t1, &::done) -%li(t2) $(0) +%li(t2, 0) ::done %mov(a0, t2) %ret() @@ -862,7 +862,7 @@ body %mov(a3, a2) %mov(a2, a1) %mov(a1, a0) -%li(a0) %p1_sys_read() +%li(a0, %p1_sys_read()) %syscall() %ret() @@ -871,7 +871,7 @@ body %mov(a3, a2) %mov(a2, a1) %mov(a1, a0) -%li(a0) %p1_sys_write() +%li(a0, %p1_sys_write()) %syscall() %ret() @@ -881,15 +881,15 @@ body %mov(t0, a2) %mov(a3, a1) %mov(a2, a0) -%li(a1) $(-100) -%li(a0) %p1_sys_openat() +%li(a1, -100) +%li(a0, %p1_sys_openat()) %syscall() %ret() # sys_close(fd=a0) -> r (a0) :sys_close %mov(a1, a0) -%li(a0) %p1_sys_close() +%li(a0, %p1_sys_close()) %syscall() %ret() @@ -897,7 +897,7 @@ body :sys_exit %scope sys_exit %mov(a1, a0) -%li(a0) %p1_sys_exit() +%li(a0, %p1_sys_exit()) %syscall() ::spin %b(&::spin) @@ -919,7 +919,7 @@ body ::loop %beqz(s1, &::done_ok) -%li(a0) $(1) +%li(a0, 1) %mov(a1, s0) %mov(a2, s1) %call(&sys_write) @@ -929,7 +929,7 @@ body %b(&::loop) ::done_ok -%li(a0) $(0) +%li(a0, 0) ::done %ld(s0, sp, 0) %ld(s1, sp, 8) @@ -943,7 +943,7 @@ body ::loop %beqz(s1, &::done_ok) -%li(a0) $(2) +%li(a0, 2) %mov(a1, s0) %mov(a2, s1) %call(&sys_write) @@ -953,7 +953,7 @@ body %b(&::loop) ::done_ok -%li(a0) $(0) +%li(a0, 0) ::done %ld(s0, sp, 0) %ld(s1, sp, 8) @@ -967,7 +967,7 @@ body %bltz(s0, &::done) %la(a0, &libp1pp__newline) -%li(a1) $(1) +%li(a1, 1) %call(&print) %mov(s0, a0) @@ -984,7 +984,7 @@ body %bltz(s0, &::done) %la(a0, &libp1pp__newline) -%li(a1) $(1) +%li(a1, 1) %call(&eprint) %mov(s0, a0) @@ -1045,8 +1045,8 @@ body %mov(s1, a1) %mov(s2, a2) -%li(a1) $(0) -%li(a2) $(0) +%li(a1, 0) +%li(a2, 0) %call(&sys_open) %bltz(a0, &::open_fail) %mov(s3, a0) @@ -1065,11 +1065,11 @@ body %b(&::done) ::read_fail -%li(a0) $(-1) +%li(a0, -1) %b(&::done) ::open_fail -%li(a0) $(-1) +%li(a0, -1) ::done %ld(s0, sp, 0) @@ -1104,7 +1104,7 @@ body %b(&::loop) ::done_ok -%li(a0) $(0) +%li(a0, 0) ::done %ld(s0, sp, 0) %ld(s1, sp, 8) @@ -1123,8 +1123,8 @@ body %mov(s0, a1) %mov(s1, a2) -%li(a1) $(0x241) -%li(a2) $(0x1A4) +%li(a1, 0x241) +%li(a2, 0x1A4) %call(&sys_open) %bltz(a0, &::open_fail) %mov(s2, a0) @@ -1140,15 +1140,15 @@ body %mov(a0, s0) %bltz(a0, &::fail_ret) -%li(a0) $(0) +%li(a0, 0) %b(&::done) ::fail_ret -%li(a0) $(-1) +%li(a0, -1) %b(&::done) ::open_fail -%li(a0) $(-1) +%li(a0, -1) ::done %ld(s0, sp, 0) @@ -1171,7 +1171,7 @@ body %st(a0, t0, 0) %la(t0, &libp1pp__bump_cap) %st(a1, t0, 0) -%li(a0) $(0) +%li(a0, 0) %ret() # bump_alloc(n=a0) -> ptr (0 on exhaustion) @@ -1182,7 +1182,7 @@ body :bump_alloc %scope bump_alloc %addi(a0, a0, 7) -%li(t0) $(-8) +%li(t0, -8) %and(a0, a0, t0) %la(t0, &libp1pp__bump_cursor) %ld(t1, t0, 0) @@ -1197,7 +1197,7 @@ body %mov(a0, t1) %ret() ::fail -%li(a0) $(0) +%li(a0, 0) %ret() %endscope @@ -1211,7 +1211,7 @@ body :bump_release %la(t0, &libp1pp__bump_cursor) %st(a0, t0, 0) -%li(a0) $(0) +%li(a0, 0) %ret() # bump_reset() -> 0 @@ -1220,7 +1220,7 @@ body %ld(t1, t0, 0) %la(t0, &libp1pp__bump_cursor) %st(t1, t0, 0) -%li(a0) $(0) +%li(a0, 0) %ret() # ========================================================================= @@ -1231,9 +1231,9 @@ body %fn(panic, 0, { %call(&eprint_cstr) %la(a0, &libp1pp__newline) -%li(a1) $(1) +%li(a1, 1) %call(&eprint) -%li(a0) $(1) +%li(a0, 1) %call(&sys_exit) ::spin %b(&::spin) diff --git a/tests/P1/hello.P1pp b/tests/P1/hello.P1pp @@ -11,12 +11,12 @@ # 0 in a0 so the backend stub exits with status 0. :p1_main - %li(a0) %sys_write() - %li(a1) %1 %0 + %li(a0, %sys_write()) + %li(a1, 1) %la(a2, &msg) - %li(a3) %14 %0 + %li(a3, 14) %syscall() - %li(a0) %0 %0 + %li(a0, 0) %ret() :msg diff --git a/tests/P1/p1-aliasing.P1pp b/tests/P1/p1-aliasing.P1pp @@ -25,23 +25,23 @@ %enter(0) # Test 1: ANDI imm=255. 0x2345 & 0xFF = 0x45 (69). - %li(a0) $(0x2345) + %li(a0, 0x2345) %andi(a0, a0, 255) %mov(s0, a0) %addi(s0, s0, -61) # s0 = 8 # Test 2: SHL with rd aliasing rb (both a3), and ra == a0. # a0=1, a3=3. Correct: a3 = 1 << 3 = 8. Buggy (rcx restore wins): a3 = 3. - %li(a0) $(1) - %li(a3) $(3) + %li(a0, 1) + %li(a3, 3) %shl(a3, a0, a3) %sub(s0, a3, s0) # s0 = a3 - 8. Correct: 0. Buggy: -5. # Test 3: DIV with rd aliasing rb (both a2), and ra == a0. # a0=182, a2=7. Correct: a2 = 182 / 7 = 26. Buggy (idiv uses rdx after # cqo; or mov-rdx-restore clobbers quotient): a2 = 7 or 1. - %li(a0) $(182) - %li(a2) $(7) + %li(a0, 182) + %li(a2, 7) %div(a2, a0, a2) %add(s0, s0, a2) # s0 += a2. Correct: 26. Buggy: varies. @@ -53,13 +53,13 @@ %la(t0, &msg_buf) %sb(s0, t0, 0) - %li(a0) %sys_write() - %li(a1) $(1) + %li(a0, %sys_write()) + %li(a1, 1) %la(a2, &msg_buf) - %li(a3) $(2) + %li(a3, 2) %syscall() - %li(a0) $(0) + %li(a0, 0) %eret() # Two-byte output scratch: [0] = computed byte, [1] = newline. The space diff --git a/tests/P1/p1-call.P1pp b/tests/P1/p1-call.P1pp @@ -10,12 +10,12 @@ # write_msg("A\n") %la(a0, &msg_a) - %li(a1) $(2) + %li(a1, 2) %call(&write_msg) # write_msg("BC\n") %la(a0, &msg_bc) - %li(a1) $(3) + %li(a1, 3) %call(&write_msg) # exit status = argc + 1 (so it's always >= 2). @@ -28,8 +28,8 @@ # Shift (a0, a1) -> (a2, a3); fd goes in a1, number in a0. %mov(a2, a0) %mov(a3, a1) - %li(a0) %sys_write() - %li(a1) $(1) + %li(a0, %sys_write()) + %li(a1, 1) %syscall() %eret()