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:
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()