commit 449415dd6cf00410a4542f3db9582f163b7e7b59
parent 6853e7a46ad4a95dbab4acfb6b36a256d5aef466
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 29 Apr 2026 11:03:14 -0700
P1: new syscalls lseek, brk, unlinkat
Diffstat:
7 files changed, 191 insertions(+), 0 deletions(-)
diff --git a/P1/P1-aarch64.M1pp b/P1/P1-aarch64.M1pp
@@ -564,3 +564,12 @@ $(imm)
%macro p1_sys_waitid()
95
%endm
+%macro p1_sys_lseek()
+62
+%endm
+%macro p1_sys_brk()
+214
+%endm
+%macro p1_sys_unlinkat()
+35
+%endm
diff --git a/P1/P1-amd64.M1pp b/P1/P1-amd64.M1pp
@@ -918,3 +918,12 @@ $(imm)
%macro p1_sys_waitid()
247
%endm
+%macro p1_sys_lseek()
+8
+%endm
+%macro p1_sys_brk()
+12
+%endm
+%macro p1_sys_unlinkat()
+263
+%endm
diff --git a/P1/P1-riscv64.M1pp b/P1/P1-riscv64.M1pp
@@ -545,3 +545,12 @@ $(imm)
%macro p1_sys_waitid()
95
%endm
+%macro p1_sys_lseek()
+62
+%endm
+%macro p1_sys_brk()
+214
+%endm
+%macro p1_sys_unlinkat()
+35
+%endm
diff --git a/P1/P1.M1pp b/P1/P1.M1pp
@@ -244,6 +244,18 @@ target
%p1_sys_waitid
%endm
+%macro sys_lseek()
+%p1_sys_lseek
+%endm
+
+%macro sys_brk()
+%p1_sys_brk
+%endm
+
+%macro sys_unlinkat()
+%p1_sys_unlinkat
+%endm
+
# ---- Program entry --------------------------------------------------------
#
# The portable P1 program-entry model emits a backend-specific `:_start`
diff --git a/P1/P1pp.P1pp b/P1/P1pp.P1pp
@@ -1018,6 +1018,32 @@
%syscall
%ret
+# sys_lseek(fd=a0, off=a1, whence=a2) -> off (a0)
+:sys_lseek
+ %mov(a3, a2)
+ %mov(a2, a1)
+ %mov(a1, a0)
+ %li(a0, %p1_sys_lseek)
+ %syscall
+ %ret
+
+# sys_brk(addr=a0) -> new_break (a0). addr=0 returns the current break.
+:sys_brk
+ %mov(a1, a0)
+ %li(a0, %p1_sys_brk)
+ %syscall
+ %ret
+
+# sys_unlink(path=a0) -> 0 / -errno (a0).
+# Implemented as unlinkat(AT_FDCWD, path, 0). AT_FDCWD = -100.
+:sys_unlink
+ %li(a3, 0)
+ %mov(a2, a0)
+ %li(a1, -100)
+ %li(a0, %p1_sys_unlinkat)
+ %syscall
+ %ret
+
# sys_exit(code=a0) -> never returns
:sys_exit
%scope sys_exit
diff --git a/tests/P1/sys_calls.P1pp b/tests/P1/sys_calls.P1pp
@@ -0,0 +1,125 @@
+# tests/p1/sys_calls.P1 — exercise the sys_brk/sys_lseek/sys_unlink wrappers
+# added to P1pp.P1pp alongside sys_open/sys_read/sys_write/sys_close.
+#
+# Sequence:
+# 1. sys_brk(0) — fetch current break; succeed if > 0.
+# 2. sys_open(/tmp/...) — create+truncate, write "X", close.
+# 3. reopen RDONLY — sys_lseek(0, SEEK_SET) then sys_read 1 byte;
+# verify the byte is 'X'; close.
+# 4. sys_unlink — remove the temp file.
+# Each successful step prints one byte ("B", "L", "U") so the .expected
+# is a fixed `BLU` line.
+
+:p1_main
+ %enter(0)
+
+ # --- sys_brk -----------------------------------------------------------
+ %li(a0, 0)
+ %call(&sys_brk)
+ %bltz(a0, &::fail)
+ %beqz(a0, &::fail)
+ %la(a0, &b_msg)
+ %li(a1, 1)
+ %call(&write_stdout)
+ %bltz(a0, &::fail)
+
+ # --- create + write "X" ------------------------------------------------
+ %la(a0, &fname)
+ %li(a1, 577) # O_WRONLY|O_CREAT|O_TRUNC
+ %li(a2, 0644)
+ %call(&sys_open)
+ %bltz(a0, &::fail)
+ %mov(s0, a0) # save fd
+
+ %mov(a0, s0)
+ %la(a1, &payload)
+ %li(a2, 1)
+ %call(&sys_write)
+ %bltz(a0, &::fail)
+
+ %mov(a0, s0)
+ %call(&sys_close)
+ %bltz(a0, &::fail)
+
+ # --- reopen, lseek, read, verify, close --------------------------------
+ %la(a0, &fname)
+ %li(a1, 0) # O_RDONLY
+ %li(a2, 0)
+ %call(&sys_open)
+ %bltz(a0, &::fail)
+ %mov(s0, a0)
+
+ %mov(a0, s0)
+ %li(a1, 0)
+ %li(a2, 0) # SEEK_SET
+ %call(&sys_lseek)
+ %bltz(a0, &::fail)
+
+ %mov(a0, s0)
+ %la(a1, &readbuf)
+ %li(a2, 1)
+ %call(&sys_read)
+ %bltz(a0, &::fail)
+
+ %mov(a0, s0)
+ %call(&sys_close)
+ %bltz(a0, &::fail)
+
+ %la(s1, &readbuf)
+ %lb(s1, s1, 0)
+ %li(t0, 88) # 'X'
+ %bne(s1, t0, &::fail)
+
+ %la(a0, &l_msg)
+ %li(a1, 1)
+ %call(&write_stdout)
+ %bltz(a0, &::fail)
+
+ # --- sys_unlink --------------------------------------------------------
+ %la(a0, &fname)
+ %call(&sys_unlink)
+ %bltz(a0, &::fail)
+
+ %la(a0, &u_msg)
+ %li(a1, 2)
+ %call(&write_stdout)
+ %bltz(a0, &::fail)
+
+ %li(a0, 0)
+ %eret
+
+ ::fail
+ %li(a0, 1)
+ %eret
+
+# write_stdout(buf=a0, len=a1) -> n_or_err (a0). Single-shot syscall.
+:write_stdout
+ %enter(0)
+ %mov(a3, a1)
+ %mov(a2, a0)
+ %li(a1, 1)
+ %li(a0, %sys_write)
+ %syscall
+ %eret
+
+:fname
+"/tmp/p1-sys-calls.tmp"
+%(0)
+
+:payload
+"X"
+
+:b_msg
+"B"
+
+:l_msg
+"L"
+
+:u_msg
+"U
+"
+
+:readbuf
+%(0)
+
+:ELF_end
diff --git a/tests/P1/sys_calls.expected b/tests/P1/sys_calls.expected
@@ -0,0 +1 @@
+BLU