commit e77067e3f9ee54059d2c6e972d3265b0088f0cc9
parent fba0661c4e9928254ae9b1a9c2eb4d243a3af53e
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Sun, 3 May 2026 16:53:48 -0700
update to run hex2pp.P1, rm 00-hello which used old hex2
Diffstat:
8 files changed, 904 insertions(+), 1386 deletions(-)
diff --git a/Makefile b/Makefile
@@ -210,10 +210,8 @@ P1PP_BUILD_DEPS = scripts/boot-build-p1pp.sh \
vendor/seed/%/ELF.hex2 \
P1/P1-%.M1pp P1/P1.M1pp P1/P1pp.P1pp
-# M1pp is built from its self-hosted .P1 source via the seed M0+hex2-0
-# chain (boot-build-p1.sh). hex2pp.P1 hasn't yet caught up to the new
-# string-emission contract (bare "..." emits decoded bytes; %bytes is
-# gone), so hex2pp is still compiled from hex2pp.c via alpine-gcc.
+# M1pp and hex2pp are both built from their self-hosted .P1 sources via
+# the seed M0+hex2-0 chain (boot-build-p1.sh).
ALPINE_GCC_IMAGES := $(foreach a,$(ALL_ARCHES),build/$(a)/.image-alpine-gcc)
$(ALPINE_GCC_IMAGES): build/%/.image-alpine-gcc: scripts/Containerfile.alpine-gcc
@@ -231,9 +229,8 @@ ALPINE_GCC = podman run --rm --pull=never --platform $(PLATFORM_$(1)) \
$(M1PP_BINS): build/%/M1pp/M1pp: M1pp/M1pp.P1 $(P1_BUILD_DEPS)
$(call PODMAN,$*) sh scripts/boot-build-p1.sh M1pp/M1pp.P1 $@
-$(HEX2PP_BINS): build/%/hex2pp/hex2pp: hex2pp/hex2pp.c build/%/.image-alpine-gcc
- mkdir -p $(@D)
- $(call ALPINE_GCC,$*) cc -O2 -std=c99 -static hex2pp/hex2pp.c -o $@
+$(HEX2PP_BINS): build/%/hex2pp/hex2pp: hex2pp/hex2pp.P1 $(P1_BUILD_DEPS)
+ $(call PODMAN,$*) sh scripts/boot-build-p1.sh hex2pp/hex2pp.P1 $@
$(SCHEME1_BINS): build/%/scheme1/scheme1: $(SCHEME1_SRC) $(P1PP_BUILD_DEPS)
$(call PODMAN,$*) sh scripts/boot-build-p1pp.sh $@ $(SCHEME1_SRC)
diff --git a/P1/P1-aarch64.M1 b/P1/P1-aarch64.M1
@@ -23,7 +23,6 @@ DEFINE la_br 5100001802000014
## ---- Moves
DEFINE mov_a0,a1 E00301AA
-DEFINE mov_a0,a2 E00302AA
DEFINE mov_a0,a3 E00303AA
DEFINE mov_a0,t0 E00309AA
DEFINE mov_a0,t1 E0030AAA
@@ -36,10 +35,12 @@ DEFINE mov_a2,t0 E20309AA
DEFINE mov_a2,t1 E2030AAA
DEFINE mov_t0,a0 E90300AA
DEFINE mov_t1,a0 EA0300AA
+DEFINE mov_t1,t0 EA0309AA
DEFINE mov_t2,a0 EB0300AA
DEFINE mov_t2,t1 EB030AAA
## ---- Register Arithmetic
+DEFINE add_a0,a0,a1 0000018B
DEFINE add_a0,a0,a2 0000028B
DEFINE add_a0,a0,a3 0000038B
DEFINE add_a0,a0,t0 0000098B
@@ -56,7 +57,7 @@ DEFINE add_a1,a1,a0 2100008B
DEFINE add_a1,a1,a2 2100028B
DEFINE add_a1,a1,a3 2100038B
DEFINE add_a1,a1,t0 2100098B
-DEFINE add_a1,a1,t1 21000A8B
+DEFINE add_a1,a1,t2 21000B8B
DEFINE add_a1,a2,t0 4100098B
DEFINE add_a1,a3,a1 6100018B
DEFINE add_a1,t0,a0 2101008B
@@ -66,11 +67,10 @@ DEFINE add_a1,t2,t1 61010A8B
DEFINE add_a2,a1,a3 2200038B
DEFINE add_a2,a1,t0 2200098B
DEFINE add_a2,a2,a0 4200008B
-DEFINE add_a2,a2,a1 4200018B
DEFINE add_a2,a2,a3 4200038B
DEFINE add_a2,a2,t0 4200098B
DEFINE add_a2,a2,t1 42000A8B
-DEFINE add_a2,a2,t2 42000B8B
+DEFINE add_a2,a3,a1 6200018B
DEFINE add_a2,a3,a2 6200028B
DEFINE add_a2,t0,t1 22010A8B
DEFINE add_a2,t2,a0 6201008B
@@ -78,6 +78,7 @@ DEFINE add_a2,t2,a2 6201028B
DEFINE add_a3,a0,a2 0300028B
DEFINE add_a3,a1,t1 23000A8B
DEFINE add_a3,a1,t2 23000B8B
+DEFINE add_a3,a3,a0 6300008B
DEFINE add_a3,a3,a1 6300018B
DEFINE add_a3,a3,a2 6300028B
DEFINE add_a3,a3,t0 6300098B
@@ -108,16 +109,18 @@ DEFINE add_t2,t1,t2 4B010B8B
DEFINE add_t2,t2,a0 6B01008B
DEFINE add_t2,t2,a3 6B01038B
DEFINE add_t2,t2,t1 6B010A8B
+DEFINE sub_a0,a0,a1 000001CB
DEFINE sub_a0,a0,t1 00000ACB
+DEFINE sub_a0,a1,a0 200000CB
DEFINE sub_a0,a1,t2 20000BCB
DEFINE sub_a0,a3,a0 600000CB
DEFINE sub_a1,t0,a0 210100CB
DEFINE sub_a2,a1,a0 220000CB
-DEFINE sub_a2,a1,a3 220003CB
DEFINE sub_a2,a2,a2 420002CB
DEFINE sub_a2,a2,t0 420009CB
DEFINE sub_a2,t0,t1 22010ACB
DEFINE sub_a2,t2,a3 620103CB
+DEFINE sub_a3,a1,a2 230002CB
DEFINE sub_a3,a3,a2 630002CB
DEFINE sub_a3,t0,a2 230102CB
DEFINE sub_a3,t0,a3 230103CB
@@ -128,6 +131,8 @@ DEFINE sub_a3,t2,t1 63010ACB
DEFINE sub_t0,a1,a2 290002CB
DEFINE sub_t0,t0,a1 290101CB
DEFINE sub_t0,t0,t1 29010ACB
+DEFINE sub_t0,t1,t0 490109CB
+DEFINE sub_t1,t1,t0 4A0109CB
DEFINE sub_t2,t1,t0 4B0109CB
DEFINE and_a3,a3,a2 6300028A
DEFINE or_a0,a0,a2 000002AA
@@ -137,13 +142,18 @@ DEFINE xor_a3,a3,a2 630002CA
DEFINE shl_a2,a2,a3 4220C39A
DEFINE sar_a2,a2,a3 4228C39A
DEFINE mul_a0,a0,a3 007C039B
+DEFINE mul_a0,a0,t0 007C099B
DEFINE mul_a0,t1,t2 407D0B9B
+DEFINE mul_a2,a2,t1 427C0A9B
DEFINE mul_a3,a3,a2 637C029B
DEFINE mul_t0,t0,a1 297D019B
+DEFINE mul_t0,t0,t1 297D0A9B
DEFINE mul_t2,t0,a2 2B7D029B
DEFINE div_a0,a0,a1 000CC19A
+DEFINE div_a0,a0,t1 000CCA9A
DEFINE div_a2,a2,a3 420CC39A
DEFINE rem_a2,a0,a1 100CC19A0282019B
+DEFINE rem_a2,a0,t1 100CCA9A02820A9B
DEFINE rem_a2,a2,a3 500CC39A028A039B
## ---- Immediate Arithmetic
@@ -166,6 +176,7 @@ DEFINE addi_a2,a2,24 42600091
DEFINE addi_a2,a2,48 42C00091
DEFINE addi_a2,t0,1 22050091
DEFINE addi_a2,t2,neg48 62C100D1
+DEFINE addi_a3,a3,neg1 630400D1
DEFINE addi_a3,a3,1 63040091
DEFINE addi_a3,a3,32 63800091
DEFINE addi_a3,t0,32 23810091
@@ -193,8 +204,10 @@ DEFINE addi_t2,t2,1 6B050091
DEFINE addi_t2,t2,7 6B1D0091
DEFINE addi_t2,t2,24 6B610091
DEFINE addi_t2,t2,32 6B810091
+DEFINE andi_a0,a0,255 F01F80D20000108A
DEFINE andi_a2,a2,15 F00180D24200108A
DEFINE andi_a3,a3,15 F00180D26300108A
+DEFINE andi_a3,a3,255 F01F80D26300108A
DEFINE andi_a3,t2,255 F01F80D26301108A
DEFINE shli_a0,a0,3 00F07DD3
DEFINE shli_a0,a0,4 00EC7CD3
@@ -202,6 +215,7 @@ DEFINE shli_a1,a1,1 21F87FD3
DEFINE shli_a2,t1,3 42F17DD3
DEFINE shli_a3,t0,1 23F97FD3
DEFINE shli_a3,t0,4 23ED7CD3
+DEFINE shli_t0,t0,4 29ED7CD3
DEFINE shli_t1,a2,3 4AF07DD3
DEFINE shli_t2,t0,3 2BF17DD3
DEFINE shri_a2,a3,4 62FC44D3
@@ -265,11 +279,13 @@ DEFINE ld_a3,t1,8 430540F9
DEFINE ld_t0,a0,0 090040F9
DEFINE ld_t0,a0,8 090440F9
DEFINE ld_t0,a0,16 090840F9
+DEFINE ld_t0,a0,24 090C40F9
DEFINE ld_t0,a1,0 290040F9
DEFINE ld_t0,a1,8 290440F9
DEFINE ld_t0,a1,16 290840F9
DEFINE ld_t0,a1,32 291040F9
DEFINE ld_t0,a2,0 490040F9
+DEFINE ld_t0,a3,0 690040F9
DEFINE ld_t0,t0,0 290140F9
DEFINE ld_t0,t2,0 690140F9
DEFINE ld_t0,t2,16 690940F9
@@ -286,6 +302,7 @@ DEFINE ld_t1,a0,24 0A0C40F9
DEFINE ld_t1,a1,0 2A0040F9
DEFINE ld_t1,a1,8 2A0440F9
DEFINE ld_t1,a1,16 2A0840F9
+DEFINE ld_t1,a2,0 4A0040F9
DEFINE ld_t1,a2,8 4A0440F9
DEFINE ld_t1,a2,16 4A0840F9
DEFINE ld_t1,a3,0 6A0040F9
@@ -317,6 +334,7 @@ DEFINE st_a0,a3,8 600400F9
DEFINE st_a0,a3,16 600800F9
DEFINE st_a0,t0,0 200100F9
DEFINE st_a0,t0,8 200500F9
+DEFINE st_a0,t1,0 400100F9
DEFINE st_a0,t2,0 600100F9
DEFINE st_a0,t2,8 600500F9
DEFINE st_a0,t2,16 600900F9
@@ -353,6 +371,7 @@ DEFINE st_a3,a0,0 030000F9
DEFINE st_a3,a1,0 230000F9
DEFINE st_a3,a2,0 430000F9
DEFINE st_a3,t0,24 230D00F9
+DEFINE st_a3,t1,0 430100F9
DEFINE st_a3,t1,8 430500F9
DEFINE st_a3,t2,0 630100F9
DEFINE st_a3,t2,8 630500F9
@@ -365,7 +384,6 @@ DEFINE st_t0,a0,24 090C00F9
DEFINE st_t0,a1,0 290000F9
DEFINE st_t0,a2,0 490000F9
DEFINE st_t0,a3,0 690000F9
-DEFINE st_t0,a3,8 690400F9
DEFINE st_t0,t1,0 490100F9
DEFINE st_t0,t2,0 690100F9
DEFINE st_t0,sp,0 E90B00F9
@@ -390,6 +408,7 @@ DEFINE st_t2,a3,0 6B0000F9
DEFINE st_t2,t0,0 2B0100F9
DEFINE st_t2,t1,0 4B0100F9
DEFINE lb_a0,a0,0 00004039
+DEFINE lb_a0,a2,0 40004039
DEFINE lb_a0,t0,0 20014039
DEFINE lb_a1,a1,0 21004039
DEFINE lb_a1,a3,0 61004039
@@ -401,10 +420,11 @@ DEFINE lb_a3,a0,0 03004039
DEFINE lb_a3,a1,0 23004039
DEFINE lb_a3,a2,0 43004039
DEFINE lb_a3,a3,0 63004039
-DEFINE lb_t0,a3,0 69004039
-DEFINE lb_t0,a3,1 69044039
+DEFINE lb_t0,a0,0 09004039
+DEFINE lb_t0,a0,1 09044039
DEFINE lb_t0,t0,0 29014039
DEFINE lb_t1,t1,0 4A014039
+DEFINE lb_t2,a2,0 4B004039
DEFINE lb_t2,t0,0 2B014039
DEFINE lb_t2,t2,0 6B014039
DEFINE sb_a0,a1,0 20000039
@@ -452,6 +472,7 @@ DEFINE beq_t2,a2 7F0102EB4100005420021FD6
DEFINE beq_t2,a3 7F0103EB4100005420021FD6
DEFINE beq_t2,t1 7F010AEB4100005420021FD6
DEFINE bne_a0,t0 1F0009EB4000005420021FD6
+DEFINE bne_a0,t1 1F000AEB4000005420021FD6
DEFINE bne_a1,a2 3F0002EB4000005420021FD6
DEFINE bne_a1,t0 3F0009EB4000005420021FD6
DEFINE bne_a2,a1 5F0001EB4000005420021FD6
@@ -460,6 +481,8 @@ DEFINE bne_a3,a0 7F0000EB4000005420021FD6
DEFINE bne_a3,a1 7F0001EB4000005420021FD6
DEFINE bne_a3,a2 7F0002EB4000005420021FD6
DEFINE bne_a3,t0 7F0009EB4000005420021FD6
+DEFINE bne_t0,a0 3F0100EB4000005420021FD6
+DEFINE bne_t0,a2 3F0102EB4000005420021FD6
DEFINE bne_t0,t1 3F010AEB4000005420021FD6
DEFINE bne_t0,t2 3F010BEB4000005420021FD6
DEFINE bne_t1,a2 5F0102EB4000005420021FD6
@@ -468,7 +491,9 @@ DEFINE bne_t1,t2 5F010BEB4000005420021FD6
DEFINE bne_t2,a2 7F0102EB4000005420021FD6
DEFINE bne_t2,a3 7F0103EB4000005420021FD6
DEFINE bne_t2,t0 7F0109EB4000005420021FD6
+DEFINE blt_a0,a1 1F0001EB4A00005420021FD6
DEFINE blt_a0,a2 1F0002EB4A00005420021FD6
+DEFINE blt_a0,t1 1F000AEB4A00005420021FD6
DEFINE blt_a1,a0 3F0000EB4A00005420021FD6
DEFINE blt_a1,a2 3F0002EB4A00005420021FD6
DEFINE blt_a1,t0 3F0009EB4A00005420021FD6
@@ -479,7 +504,10 @@ DEFINE blt_a2,t0 5F0009EB4A00005420021FD6
DEFINE blt_a2,t1 5F000AEB4A00005420021FD6
DEFINE blt_a3,a2 7F0002EB4A00005420021FD6
DEFINE blt_a3,t2 7F000BEB4A00005420021FD6
+DEFINE blt_t0,a0 3F0100EB4A00005420021FD6
+DEFINE blt_t0,a2 3F0102EB4A00005420021FD6
DEFINE blt_t0,t1 3F010AEB4A00005420021FD6
+DEFINE blt_t1,a0 5F0100EB4A00005420021FD6
DEFINE blt_t1,a1 5F0101EB4A00005420021FD6
DEFINE blt_t1,t0 5F0109EB4A00005420021FD6
DEFINE blt_t2,a3 7F0103EB4A00005420021FD6
@@ -494,6 +522,7 @@ DEFINE beqz_t2 4B0000B520021FD6
DEFINE bnez_a0 400000B420021FD6
DEFINE bnez_a1 410000B420021FD6
DEFINE bnez_a2 420000B420021FD6
+DEFINE bnez_a3 430000B420021FD6
DEFINE bnez_t0 490000B420021FD6
DEFINE bnez_t1 4A0000B420021FD6
DEFINE bnez_t2 4B0000B420021FD6
diff --git a/P1/P1-amd64.M1 b/P1/P1-amd64.M1
@@ -23,7 +23,6 @@ DEFINE la_br 41BF
## ---- Moves
DEFINE mov_a0,a1 4889F7
-DEFINE mov_a0,a2 4889D7
DEFINE mov_a0,a3 4889CF
DEFINE mov_a0,t0 4C89D7
DEFINE mov_a0,t1 4C89DF
@@ -36,10 +35,12 @@ DEFINE mov_a2,t0 4C89D2
DEFINE mov_a2,t1 4C89DA
DEFINE mov_t0,a0 4989FA
DEFINE mov_t1,a0 4989FB
+DEFINE mov_t1,t0 4D89D3
DEFINE mov_t2,a0 4989F8
DEFINE mov_t2,t1 4D89D8
## ---- Register Arithmetic
+DEFINE add_a0,a0,a1 4889FF4801F7
DEFINE add_a0,a0,a2 4889FF4801D7
DEFINE add_a0,a0,a3 4889FF4801CF
DEFINE add_a0,a0,t0 4889FF4C01D7
@@ -56,7 +57,7 @@ DEFINE add_a1,a1,a0 4889F64801FE
DEFINE add_a1,a1,a2 4889F64801D6
DEFINE add_a1,a1,a3 4889F64801CE
DEFINE add_a1,a1,t0 4889F64C01D6
-DEFINE add_a1,a1,t1 4889F64C01DE
+DEFINE add_a1,a1,t2 4889F64C01C6
DEFINE add_a1,a2,t0 4889D64C01D6
DEFINE add_a1,a3,a1 4989F14889CE4C01CE
DEFINE add_a1,t0,a0 4C89D64801FE
@@ -66,11 +67,10 @@ DEFINE add_a1,t2,t1 4C89C64C01DE
DEFINE add_a2,a1,a3 4889F24801CA
DEFINE add_a2,a1,t0 4889F24C01D2
DEFINE add_a2,a2,a0 4889D24801FA
-DEFINE add_a2,a2,a1 4889D24801F2
DEFINE add_a2,a2,a3 4889D24801CA
DEFINE add_a2,a2,t0 4889D24C01D2
DEFINE add_a2,a2,t1 4889D24C01DA
-DEFINE add_a2,a2,t2 4889D24C01C2
+DEFINE add_a2,a3,a1 4889CA4801F2
DEFINE add_a2,a3,a2 4989D14889CA4C01CA
DEFINE add_a2,t0,t1 4C89D24C01DA
DEFINE add_a2,t2,a0 4C89C24801FA
@@ -78,6 +78,7 @@ DEFINE add_a2,t2,a2 4989D14C89C24C01CA
DEFINE add_a3,a0,a2 4889F94801D1
DEFINE add_a3,a1,t1 4889F14C01D9
DEFINE add_a3,a1,t2 4889F14C01C1
+DEFINE add_a3,a3,a0 4889C94801F9
DEFINE add_a3,a3,a1 4889C94801F1
DEFINE add_a3,a3,a2 4889C94801D1
DEFINE add_a3,a3,t0 4889C94C01D1
@@ -108,16 +109,18 @@ DEFINE add_t2,t1,t2 4D89C14D89D84D01C8
DEFINE add_t2,t2,a0 4D89C04901F8
DEFINE add_t2,t2,a3 4D89C04901C8
DEFINE add_t2,t2,t1 4D89C04D01D8
+DEFINE sub_a0,a0,a1 4889FF4829F7
DEFINE sub_a0,a0,t1 4889FF4C29DF
+DEFINE sub_a0,a1,a0 4989F94889F74C29CF
DEFINE sub_a0,a1,t2 4889F74C29C7
DEFINE sub_a0,a3,a0 4989F94889CF4C29CF
DEFINE sub_a1,t0,a0 4C89D64829FE
DEFINE sub_a2,a1,a0 4889F24829FA
-DEFINE sub_a2,a1,a3 4889F24829CA
DEFINE sub_a2,a2,a2 4989D14889D24C29CA
DEFINE sub_a2,a2,t0 4889D24C29D2
DEFINE sub_a2,t0,t1 4C89D24C29DA
DEFINE sub_a2,t2,a3 4C89C24829CA
+DEFINE sub_a3,a1,a2 4889F14829D1
DEFINE sub_a3,a3,a2 4889C94829D1
DEFINE sub_a3,t0,a2 4C89D14829D1
DEFINE sub_a3,t0,a3 4989C94C89D14C29C9
@@ -128,6 +131,8 @@ DEFINE sub_a3,t2,t1 4C89C14C29D9
DEFINE sub_t0,a1,a2 4989F24929D2
DEFINE sub_t0,t0,a1 4D89D24929F2
DEFINE sub_t0,t0,t1 4D89D24D29DA
+DEFINE sub_t0,t1,t0 4D89D14D89DA4D29CA
+DEFINE sub_t1,t1,t0 4D89DB4D29D3
DEFINE sub_t2,t1,t0 4D89D84D29D0
DEFINE and_a3,a3,a2 4889C94821D1
DEFINE or_a0,a0,a2 4889FF4809D7
@@ -137,13 +142,18 @@ DEFINE xor_a3,a3,a2 4889C94831D1
DEFINE shl_a2,a2,a3 4889CD4989D14889C949D3E14889E94C89CA
DEFINE sar_a2,a2,a3 4889CD4989D14889C949D3F94889E94C89CA
DEFINE mul_a0,a0,a3 4889FF480FAFF9
+DEFINE mul_a0,a0,t0 4889FF490FAFFA
DEFINE mul_a0,t1,t2 4C89DF490FAFF8
+DEFINE mul_a2,a2,t1 4889D2490FAFD3
DEFINE mul_a3,a3,a2 4889C9480FAFCA
DEFINE mul_t0,t0,a1 4D89D24C0FAFD6
+DEFINE mul_t0,t0,t1 4D89D24D0FAFD3
DEFINE mul_t2,t0,a2 4D89D04C0FAFC2
DEFINE div_a0,a0,a1 4889D54989F14889F8489949F7F94889EA4889C7
+DEFINE div_a0,a0,t1 4889D54D89D94889F8489949F7F94889EA4889C7
DEFINE div_a2,a2,a3 4889D54989C94889D0489949F7F94889EA4889C2
DEFINE rem_a2,a0,a1 4889D54989F14889F8489949F7F94889D04889EA4889C2
+DEFINE rem_a2,a0,t1 4889D54D89D94889F8489949F7F94889D04889EA4889C2
DEFINE rem_a2,a2,a3 4889D54989C94889D0489949F7F94889D04889EA4889C2
## ---- Immediate Arithmetic
@@ -166,6 +176,7 @@ DEFINE addi_a2,a2,24 4889D24883C218
DEFINE addi_a2,a2,48 4889D24883C230
DEFINE addi_a2,t0,1 4C89D24883C201
DEFINE addi_a2,t2,neg48 4C89C24883C2D0
+DEFINE addi_a3,a3,neg1 4889C94883C1FF
DEFINE addi_a3,a3,1 4889C94883C101
DEFINE addi_a3,a3,32 4889C94883C120
DEFINE addi_a3,t0,32 4C89D14883C120
@@ -193,8 +204,10 @@ DEFINE addi_t2,t2,1 4D89C04983C001
DEFINE addi_t2,t2,7 4D89C04983C007
DEFINE addi_t2,t2,24 4D89C04983C018
DEFINE addi_t2,t2,32 4D89C04983C020
+DEFINE andi_a0,a0,255 4889FF4881E7FF000000
DEFINE andi_a2,a2,15 4889D24883E20F
DEFINE andi_a3,a3,15 4889C94883E10F
+DEFINE andi_a3,a3,255 4889C94881E1FF000000
DEFINE andi_a3,t2,255 4C89C14881E1FF000000
DEFINE shli_a0,a0,3 4889FF48C1E703
DEFINE shli_a0,a0,4 4889FF48C1E704
@@ -202,6 +215,7 @@ DEFINE shli_a1,a1,1 4889F648C1E601
DEFINE shli_a2,t1,3 4C89DA48C1E203
DEFINE shli_a3,t0,1 4C89D148C1E101
DEFINE shli_a3,t0,4 4C89D148C1E104
+DEFINE shli_t0,t0,4 4D89D249C1E204
DEFINE shli_t1,a2,3 4989D349C1E303
DEFINE shli_t2,t0,3 4D89D049C1E003
DEFINE shri_a2,a3,4 4889CA48C1EA04
@@ -265,11 +279,13 @@ DEFINE ld_a3,t1,8 498B4B08
DEFINE ld_t0,a0,0 4C8B5700
DEFINE ld_t0,a0,8 4C8B5708
DEFINE ld_t0,a0,16 4C8B5710
+DEFINE ld_t0,a0,24 4C8B5718
DEFINE ld_t0,a1,0 4C8B5600
DEFINE ld_t0,a1,8 4C8B5608
DEFINE ld_t0,a1,16 4C8B5610
DEFINE ld_t0,a1,32 4C8B5620
DEFINE ld_t0,a2,0 4C8B5200
+DEFINE ld_t0,a3,0 4C8B5100
DEFINE ld_t0,t0,0 4D8B5200
DEFINE ld_t0,t2,0 4D8B5000
DEFINE ld_t0,t2,16 4D8B5010
@@ -286,6 +302,7 @@ DEFINE ld_t1,a0,24 4C8B5F18
DEFINE ld_t1,a1,0 4C8B5E00
DEFINE ld_t1,a1,8 4C8B5E08
DEFINE ld_t1,a1,16 4C8B5E10
+DEFINE ld_t1,a2,0 4C8B5A00
DEFINE ld_t1,a2,8 4C8B5A08
DEFINE ld_t1,a2,16 4C8B5A10
DEFINE ld_t1,a3,0 4C8B5900
@@ -317,6 +334,7 @@ DEFINE st_a0,a3,8 48897908
DEFINE st_a0,a3,16 48897910
DEFINE st_a0,t0,0 49897A00
DEFINE st_a0,t0,8 49897A08
+DEFINE st_a0,t1,0 49897B00
DEFINE st_a0,t2,0 49897800
DEFINE st_a0,t2,8 49897808
DEFINE st_a0,t2,16 49897810
@@ -353,6 +371,7 @@ DEFINE st_a3,a0,0 48894F00
DEFINE st_a3,a1,0 48894E00
DEFINE st_a3,a2,0 48894A00
DEFINE st_a3,t0,24 49894A18
+DEFINE st_a3,t1,0 49894B00
DEFINE st_a3,t1,8 49894B08
DEFINE st_a3,t2,0 49894800
DEFINE st_a3,t2,8 49894808
@@ -365,7 +384,6 @@ DEFINE st_t0,a0,24 4C895718
DEFINE st_t0,a1,0 4C895600
DEFINE st_t0,a2,0 4C895200
DEFINE st_t0,a3,0 4C895100
-DEFINE st_t0,a3,8 4C895108
DEFINE st_t0,t1,0 4D895300
DEFINE st_t0,t2,0 4D895000
DEFINE st_t0,sp,0 4C89542410
@@ -390,6 +408,7 @@ DEFINE st_t2,a3,0 4C894100
DEFINE st_t2,t0,0 4D894200
DEFINE st_t2,t1,0 4D894300
DEFINE lb_a0,a0,0 480FB67F00
+DEFINE lb_a0,a2,0 480FB67A00
DEFINE lb_a0,t0,0 490FB67A00
DEFINE lb_a1,a1,0 480FB67600
DEFINE lb_a1,a3,0 480FB67100
@@ -401,10 +420,11 @@ DEFINE lb_a3,a0,0 480FB64F00
DEFINE lb_a3,a1,0 480FB64E00
DEFINE lb_a3,a2,0 480FB64A00
DEFINE lb_a3,a3,0 480FB64900
-DEFINE lb_t0,a3,0 4C0FB65100
-DEFINE lb_t0,a3,1 4C0FB65101
+DEFINE lb_t0,a0,0 4C0FB65700
+DEFINE lb_t0,a0,1 4C0FB65701
DEFINE lb_t0,t0,0 4D0FB65200
DEFINE lb_t1,t1,0 4D0FB65B00
+DEFINE lb_t2,a2,0 4C0FB64200
DEFINE lb_t2,t0,0 4D0FB64200
DEFINE lb_t2,t2,0 4D0FB64000
DEFINE sb_a0,a1,0 48887E00
@@ -452,6 +472,7 @@ DEFINE beq_t2,a2 4939D0750341FFE7
DEFINE beq_t2,a3 4939C8750341FFE7
DEFINE beq_t2,t1 4D39D8750341FFE7
DEFINE bne_a0,t0 4C39D7740341FFE7
+DEFINE bne_a0,t1 4C39DF740341FFE7
DEFINE bne_a1,a2 4839D6740341FFE7
DEFINE bne_a1,t0 4C39D6740341FFE7
DEFINE bne_a2,a1 4839F2740341FFE7
@@ -460,6 +481,8 @@ DEFINE bne_a3,a0 4839F9740341FFE7
DEFINE bne_a3,a1 4839F1740341FFE7
DEFINE bne_a3,a2 4839D1740341FFE7
DEFINE bne_a3,t0 4C39D1740341FFE7
+DEFINE bne_t0,a0 4939FA740341FFE7
+DEFINE bne_t0,a2 4939D2740341FFE7
DEFINE bne_t0,t1 4D39DA740341FFE7
DEFINE bne_t0,t2 4D39C2740341FFE7
DEFINE bne_t1,a2 4939D3740341FFE7
@@ -468,7 +491,9 @@ DEFINE bne_t1,t2 4D39C3740341FFE7
DEFINE bne_t2,a2 4939D0740341FFE7
DEFINE bne_t2,a3 4939C8740341FFE7
DEFINE bne_t2,t0 4D39D0740341FFE7
+DEFINE blt_a0,a1 4839F77D0341FFE7
DEFINE blt_a0,a2 4839D77D0341FFE7
+DEFINE blt_a0,t1 4C39DF7D0341FFE7
DEFINE blt_a1,a0 4839FE7D0341FFE7
DEFINE blt_a1,a2 4839D67D0341FFE7
DEFINE blt_a1,t0 4C39D67D0341FFE7
@@ -479,7 +504,10 @@ DEFINE blt_a2,t0 4C39D27D0341FFE7
DEFINE blt_a2,t1 4C39DA7D0341FFE7
DEFINE blt_a3,a2 4839D17D0341FFE7
DEFINE blt_a3,t2 4C39C17D0341FFE7
+DEFINE blt_t0,a0 4939FA7D0341FFE7
+DEFINE blt_t0,a2 4939D27D0341FFE7
DEFINE blt_t0,t1 4D39DA7D0341FFE7
+DEFINE blt_t1,a0 4939FB7D0341FFE7
DEFINE blt_t1,a1 4939F37D0341FFE7
DEFINE blt_t1,t0 4D39D37D0341FFE7
DEFINE blt_t2,a3 4939C87D0341FFE7
@@ -494,6 +522,7 @@ DEFINE beqz_t2 4D85C0750341FFE7
DEFINE bnez_a0 4885FF740341FFE7
DEFINE bnez_a1 4885F6740341FFE7
DEFINE bnez_a2 4885D2740341FFE7
+DEFINE bnez_a3 4885C9740341FFE7
DEFINE bnez_t0 4D85D2740341FFE7
DEFINE bnez_t1 4D85DB740341FFE7
DEFINE bnez_t2 4D85C0740341FFE7
diff --git a/P1/P1-riscv64.M1 b/P1/P1-riscv64.M1
@@ -23,7 +23,6 @@ DEFINE la_br 970F000083EFCF006F008000
## ---- Moves
DEFINE mov_a0,a1 13850500
-DEFINE mov_a0,a2 13050600
DEFINE mov_a0,a3 13850600
DEFINE mov_a0,t0 13850200
DEFINE mov_a0,t1 13050300
@@ -36,10 +35,12 @@ DEFINE mov_a2,t0 13860200
DEFINE mov_a2,t1 13060300
DEFINE mov_t0,a0 93020500
DEFINE mov_t1,a0 13030500
+DEFINE mov_t1,t0 13830200
DEFINE mov_t2,a0 93030500
DEFINE mov_t2,t1 93030300
## ---- Register Arithmetic
+DEFINE add_a0,a0,a1 3305B500
DEFINE add_a0,a0,a2 3305C500
DEFINE add_a0,a0,a3 3305D500
DEFINE add_a0,a0,t0 33055500
@@ -56,7 +57,7 @@ DEFINE add_a1,a1,a0 B385A500
DEFINE add_a1,a1,a2 B385C500
DEFINE add_a1,a1,a3 B385D500
DEFINE add_a1,a1,t0 B3855500
-DEFINE add_a1,a1,t1 B3856500
+DEFINE add_a1,a1,t2 B3857500
DEFINE add_a1,a2,t0 B3055600
DEFINE add_a1,a3,a1 B385B600
DEFINE add_a1,t0,a0 B385A200
@@ -66,11 +67,10 @@ DEFINE add_a1,t2,t1 B3856300
DEFINE add_a2,a1,a3 3386D500
DEFINE add_a2,a1,t0 33865500
DEFINE add_a2,a2,a0 3306A600
-DEFINE add_a2,a2,a1 3306B600
DEFINE add_a2,a2,a3 3306D600
DEFINE add_a2,a2,t0 33065600
DEFINE add_a2,a2,t1 33066600
-DEFINE add_a2,a2,t2 33067600
+DEFINE add_a2,a3,a1 3386B600
DEFINE add_a2,a3,a2 3386C600
DEFINE add_a2,t0,t1 33866200
DEFINE add_a2,t2,a0 3386A300
@@ -78,6 +78,7 @@ DEFINE add_a2,t2,a2 3386C300
DEFINE add_a3,a0,a2 B306C500
DEFINE add_a3,a1,t1 B3866500
DEFINE add_a3,a1,t2 B3867500
+DEFINE add_a3,a3,a0 B386A600
DEFINE add_a3,a3,a1 B386B600
DEFINE add_a3,a3,a2 B386C600
DEFINE add_a3,a3,t0 B3865600
@@ -108,16 +109,18 @@ DEFINE add_t2,t1,t2 B3037300
DEFINE add_t2,t2,a0 B383A300
DEFINE add_t2,t2,a3 B383D300
DEFINE add_t2,t2,t1 B3836300
+DEFINE sub_a0,a0,a1 3305B540
DEFINE sub_a0,a0,t1 33056540
+DEFINE sub_a0,a1,a0 3385A540
DEFINE sub_a0,a1,t2 33857540
DEFINE sub_a0,a3,a0 3385A640
DEFINE sub_a1,t0,a0 B385A240
DEFINE sub_a2,a1,a0 3386A540
-DEFINE sub_a2,a1,a3 3386D540
DEFINE sub_a2,a2,a2 3306C640
DEFINE sub_a2,a2,t0 33065640
DEFINE sub_a2,t0,t1 33866240
DEFINE sub_a2,t2,a3 3386D340
+DEFINE sub_a3,a1,a2 B386C540
DEFINE sub_a3,a3,a2 B386C640
DEFINE sub_a3,t0,a2 B386C240
DEFINE sub_a3,t0,a3 B386D240
@@ -128,6 +131,8 @@ DEFINE sub_a3,t2,t1 B3866340
DEFINE sub_t0,a1,a2 B382C540
DEFINE sub_t0,t0,a1 B382B240
DEFINE sub_t0,t0,t1 B3826240
+DEFINE sub_t0,t1,t0 B3025340
+DEFINE sub_t1,t1,t0 33035340
DEFINE sub_t2,t1,t0 B3035340
DEFINE and_a3,a3,a2 B3F6C600
DEFINE or_a0,a0,a2 3365C500
@@ -137,13 +142,18 @@ DEFINE xor_a3,a3,a2 B3C6C600
DEFINE shl_a2,a2,a3 3316D600
DEFINE sar_a2,a2,a3 3356D640
DEFINE mul_a0,a0,a3 3305D502
+DEFINE mul_a0,a0,t0 33055502
DEFINE mul_a0,t1,t2 33057302
+DEFINE mul_a2,a2,t1 33066602
DEFINE mul_a3,a3,a2 B386C602
DEFINE mul_t0,t0,a1 B382B202
+DEFINE mul_t0,t0,t1 B3826202
DEFINE mul_t2,t0,a2 B383C202
DEFINE div_a0,a0,a1 3345B502
+DEFINE div_a0,a0,t1 33456502
DEFINE div_a2,a2,a3 3346D602
DEFINE rem_a2,a0,a1 3366B502
+DEFINE rem_a2,a0,t1 33666502
DEFINE rem_a2,a2,a3 3366D602
## ---- Immediate Arithmetic
@@ -166,6 +176,7 @@ DEFINE addi_a2,a2,24 13068601
DEFINE addi_a2,a2,48 13060603
DEFINE addi_a2,t0,1 13861200
DEFINE addi_a2,t2,neg48 138603FD
+DEFINE addi_a3,a3,neg1 9386F6FF
DEFINE addi_a3,a3,1 93861600
DEFINE addi_a3,a3,32 93860602
DEFINE addi_a3,t0,32 93860202
@@ -193,8 +204,10 @@ DEFINE addi_t2,t2,1 93831300
DEFINE addi_t2,t2,7 93837300
DEFINE addi_t2,t2,24 93838301
DEFINE addi_t2,t2,32 93830302
+DEFINE andi_a0,a0,255 1375F50F
DEFINE andi_a2,a2,15 1376F600
DEFINE andi_a3,a3,15 93F6F600
+DEFINE andi_a3,a3,255 93F6F60F
DEFINE andi_a3,t2,255 93F6F30F
DEFINE shli_a0,a0,3 13153500
DEFINE shli_a0,a0,4 13154500
@@ -202,6 +215,7 @@ DEFINE shli_a1,a1,1 93951500
DEFINE shli_a2,t1,3 13163300
DEFINE shli_a3,t0,1 93961200
DEFINE shli_a3,t0,4 93964200
+DEFINE shli_t0,t0,4 93924200
DEFINE shli_t1,a2,3 13133600
DEFINE shli_t2,t0,3 93933200
DEFINE shri_a2,a3,4 13D64600
@@ -265,11 +279,13 @@ DEFINE ld_a3,t1,8 83368300
DEFINE ld_t0,a0,0 83320500
DEFINE ld_t0,a0,8 83328500
DEFINE ld_t0,a0,16 83320501
+DEFINE ld_t0,a0,24 83328501
DEFINE ld_t0,a1,0 83B20500
DEFINE ld_t0,a1,8 83B28500
DEFINE ld_t0,a1,16 83B20501
DEFINE ld_t0,a1,32 83B20502
DEFINE ld_t0,a2,0 83320600
+DEFINE ld_t0,a3,0 83B20600
DEFINE ld_t0,t0,0 83B20200
DEFINE ld_t0,t2,0 83B20300
DEFINE ld_t0,t2,16 83B20301
@@ -286,6 +302,7 @@ DEFINE ld_t1,a0,24 03338501
DEFINE ld_t1,a1,0 03B30500
DEFINE ld_t1,a1,8 03B38500
DEFINE ld_t1,a1,16 03B30501
+DEFINE ld_t1,a2,0 03330600
DEFINE ld_t1,a2,8 03338600
DEFINE ld_t1,a2,16 03330601
DEFINE ld_t1,a3,0 03B30600
@@ -317,6 +334,7 @@ DEFINE st_a0,a3,8 23B4A600
DEFINE st_a0,a3,16 23B8A600
DEFINE st_a0,t0,0 23B0A200
DEFINE st_a0,t0,8 23B4A200
+DEFINE st_a0,t1,0 2330A300
DEFINE st_a0,t2,0 23B0A300
DEFINE st_a0,t2,8 23B4A300
DEFINE st_a0,t2,16 23B8A300
@@ -353,6 +371,7 @@ DEFINE st_a3,a0,0 2330D500
DEFINE st_a3,a1,0 23B0D500
DEFINE st_a3,a2,0 2330D600
DEFINE st_a3,t0,24 23BCD200
+DEFINE st_a3,t1,0 2330D300
DEFINE st_a3,t1,8 2334D300
DEFINE st_a3,t2,0 23B0D300
DEFINE st_a3,t2,8 23B4D300
@@ -365,7 +384,6 @@ DEFINE st_t0,a0,24 233C5500
DEFINE st_t0,a1,0 23B05500
DEFINE st_t0,a2,0 23305600
DEFINE st_t0,a3,0 23B05600
-DEFINE st_t0,a3,8 23B45600
DEFINE st_t0,t1,0 23305300
DEFINE st_t0,t2,0 23B05300
DEFINE st_t0,sp,0 23385100
@@ -390,6 +408,7 @@ DEFINE st_t2,a3,0 23B07600
DEFINE st_t2,t0,0 23B07200
DEFINE st_t2,t1,0 23307300
DEFINE lb_a0,a0,0 03450500
+DEFINE lb_a0,a2,0 03450600
DEFINE lb_a0,t0,0 03C50200
DEFINE lb_a1,a1,0 83C50500
DEFINE lb_a1,a3,0 83C50600
@@ -401,10 +420,11 @@ DEFINE lb_a3,a0,0 83460500
DEFINE lb_a3,a1,0 83C60500
DEFINE lb_a3,a2,0 83460600
DEFINE lb_a3,a3,0 83C60600
-DEFINE lb_t0,a3,0 83C20600
-DEFINE lb_t0,a3,1 83C21600
+DEFINE lb_t0,a0,0 83420500
+DEFINE lb_t0,a0,1 83421500
DEFINE lb_t0,t0,0 83C20200
DEFINE lb_t1,t1,0 03430300
+DEFINE lb_t2,a2,0 83430600
DEFINE lb_t2,t0,0 83C30200
DEFINE lb_t2,t2,0 83C30300
DEFINE sb_a0,a1,0 2380A500
@@ -452,6 +472,7 @@ DEFINE beq_t2,a2 6394C30067800F00
DEFINE beq_t2,a3 6394D30067800F00
DEFINE beq_t2,t1 6394630067800F00
DEFINE bne_a0,t0 6304550067800F00
+DEFINE bne_a0,t1 6304650067800F00
DEFINE bne_a1,a2 6384C50067800F00
DEFINE bne_a1,t0 6384550067800F00
DEFINE bne_a2,a1 6304B60067800F00
@@ -460,6 +481,8 @@ DEFINE bne_a3,a0 6384A60067800F00
DEFINE bne_a3,a1 6384B60067800F00
DEFINE bne_a3,a2 6384C60067800F00
DEFINE bne_a3,t0 6384560067800F00
+DEFINE bne_t0,a0 6384A20067800F00
+DEFINE bne_t0,a2 6384C20067800F00
DEFINE bne_t0,t1 6384620067800F00
DEFINE bne_t0,t2 6384720067800F00
DEFINE bne_t1,a2 6304C30067800F00
@@ -468,7 +491,9 @@ DEFINE bne_t1,t2 6304730067800F00
DEFINE bne_t2,a2 6384C30067800F00
DEFINE bne_t2,a3 6384D30067800F00
DEFINE bne_t2,t0 6384530067800F00
+DEFINE blt_a0,a1 6354B50067800F00
DEFINE blt_a0,a2 6354C50067800F00
+DEFINE blt_a0,t1 6354650067800F00
DEFINE blt_a1,a0 63D4A50067800F00
DEFINE blt_a1,a2 63D4C50067800F00
DEFINE blt_a1,t0 63D4550067800F00
@@ -479,7 +504,10 @@ DEFINE blt_a2,t0 6354560067800F00
DEFINE blt_a2,t1 6354660067800F00
DEFINE blt_a3,a2 63D4C60067800F00
DEFINE blt_a3,t2 63D4760067800F00
+DEFINE blt_t0,a0 63D4A20067800F00
+DEFINE blt_t0,a2 63D4C20067800F00
DEFINE blt_t0,t1 63D4620067800F00
+DEFINE blt_t1,a0 6354A30067800F00
DEFINE blt_t1,a1 6354B30067800F00
DEFINE blt_t1,t0 6354530067800F00
DEFINE blt_t2,a3 63D4D30067800F00
@@ -494,6 +522,7 @@ DEFINE beqz_t2 6394030067800F00
DEFINE bnez_a0 6304050067800F00
DEFINE bnez_a1 6384050067800F00
DEFINE bnez_a2 6304060067800F00
+DEFINE bnez_a3 6384060067800F00
DEFINE bnez_t0 6384020067800F00
DEFINE bnez_t1 6304030067800F00
DEFINE bnez_t2 6384030067800F00
diff --git a/hex2pp/hex2pp.P1 b/hex2pp/hex2pp.P1
@@ -1,9 +1,8 @@
## hex2pp.P1 -- P1 implementation of the hex2++ assembler/linker.
##
-## Mirrors hex2pp/hex2pp.c exactly in observable behaviour. See the C
-## file and docs/HEX2pp.md for the full spec; brief summary:
+## Mirrors hex2pp/hex2pp.c. See docs/HEX2pp.md for the full spec; brief:
##
-## Inputs are concatenated, scanned in two passes. Pass 1 records label
+## Single input file, scanned in two passes. Pass 1 records label
## definitions while advancing a position counter (ip). Pass 2 emits
## bytes, resolving label references against the table built in pass 1.
##
@@ -14,111 +13,87 @@
## .align N [PATTERN] -> pad to N-byte boundary
## .fill N B -> N copies of byte B
## .scope / .endscope -> nestable local-label scope
+## .ptrsize N -> width of '%' and '&' (4 or 8)
## # ... / ; ... -> line comment
##
## Multi-byte reference values are emitted little-endian by default.
##
-## Invocation:
-## hex2pp (-f|--file) FILE [(-f|--file) FILE ...]
-## [-o|--output OUT]
-## [-B|--base-address ADDR]
-## [--big-endian | --little-endian]
-## [-b|--binary]
-## [--non-executable]
-## [-h|--help]
+## Invocation: hex2pp [-B ADDR] [-E|-e] [-b] [-N] IN OUT
##
## P1 ABI: a0..a3 arg/return, t0..t2 caller-saved temps. Non-leaf
## functions use enter_0 / eret. Entry is the portable p1_main
## (a0=argc, a1=argv); the backend-owned :_start stub captures argc/argv
## from the native entry state and sys_exits p1_main's return value.
##
-## chmod note: the seed P1 (P1/P1-<arch>.M1) exposes only sys_openat /
-## sys_read / sys_write / sys_exit. Since there is no chmod() syscall in
-## the seed, we encode the desired final mode (0750 or 0640) directly in
-## openat's mode argument at file-creation time. This achieves the same
-## resulting file permissions as the C reference.
-##
-## Register usage discipline: the seed P1 mnemonic table only defines a
-## restricted subset of (dst,src1,src2) and (dst,base,offset) combos.
-## To stay within that table this file spills almost everything through
-## fixed BSS slots between operations. The naming convention
-## ``<func>_<name>`` keeps per-function spill slots from colliding.
-
-## --- Caps -------------------------------------------------------------------
-## Mirrors hex2pp.c constants (MAX_FILES=64, MAX_INPUT_BYTES=16 MiB,
-## MAX_OUTPUT_BYTES=128 MiB, MAX_LABELS=2^20, MAX_TEXT=8 MiB,
-## MAX_TOKEN=4096, MAX_SCOPE_DEPTH=32). Stored as 8-byte little-endian.
-DEFINE H2_INPUT_CAP 0000000001000000
-DEFINE H2_OUTPUT_CAP 0000000008000000
-DEFINE H2_TEXT_CAP 0000000000800000
-DEFINE H2_LABEL_CAP 0000000000100000
+## chmod note: the seed P1 mnemonic table only exposes openat/read/write/
+## exit. We encode the desired final mode (0750 or 0640) directly in
+## openat's mode argument at file-creation time, achieving the same
+## resulting file permissions as the C reference's fopen+chmod.
+
+## --- Caps ------------------------------------------------------------------
+## Mirrors hex2pp.c constants. Stored as 8-byte little-endian.
+DEFINE H2_INPUT_CAP 0000000100000000
+DEFINE H2_OUTPUT_CAP 0000000800000000
+DEFINE H2_TEXT_CAP 0000800000000000
+DEFINE H2_LABEL_CAP 0000100000000000
DEFINE H2_TOKEN_CAP 0010000000000000
-DEFINE H2_FILES_CAP 4000000000000000
DEFINE H2_SCOPE_CAP 2000000000000000
-## openat / mode constants (Linux generic)
-DEFINE O_RDONLY 0000000000000000
-DEFINE O_WRONLY_CREAT_TRUNC 4102000000000000
-DEFINE MODE_0750 E801000000000000
-DEFINE MODE_0640 A001000000000000
-DEFINE AT_FDCWD 9CFFFFFFFFFFFFFF
+## openat / mode constants (Linux generic).
+DEFINE H2_O_WRONLY_CREAT_TRUNC 4102000000000000
+DEFINE H2_O_RDONLY 0000000000000000
+DEFINE H2_MODE_0750 E801000000000000
+DEFINE H2_MODE_0640 A001000000000000
+DEFINE H2_AT_FDCWD 9CFFFFFFFFFFFFFF
DEFINE ZERO8 '0000000000000000'
DEFINE ZERO4 '00000000'
## --- BSS layout (offsets from ELF_end) -------------------------------------
-##
## Each "_ptr" is a one-word slot in the executable's static data; p1_main's
-## bss_init_loop initializes each to ELF_end + OFF_*. The arenas live past
+## bss_init_loop initializes each to ELF_end + OFF_*. Arenas live past
## ELF_end (covered by the segment's memsz; the loader zero-initializes).
##
-## Sizes (mirroring hex2pp.c caps):
-## input_paths 64 * 8 = 512 B (char * per file)
-## input_starts 64 * 8 = 512 B (offset into input_buf)
-## input_lens 64 * 8 = 512 B
-## scope_stack 32 * 8 = 256 B
-## line_scratch 64 B (decimal render of cur_line)
-## name_buf 4096 B
-## label_buf 4096 B
-## other_buf 4096 B
-## pat_buf 4096 B
-## ev_bytes 8 B
-## df_byte 8 B
-## input_buf 16 MiB
-## output_buf 128 MiB
-## text_buf 8 MiB
-## labels 32 MiB (2^20 * 32 B)
+## Region sizes (matching the C caps):
+## scope_stack 32 * 8 = 256 B
+## line_scratch = 64 B
+## name_buf = 4096 B
+## label_buf = 4096 B
+## other_buf = 4096 B
+## pat_buf = 4096 B
+## ev_bytes = 8 B
+## df_byte = 8 B
+## input_buf = 16 MiB
+## output_buf = 128 MiB
+## text_buf = 8 MiB
+## labels = 32 MiB (1<<20 * 32 B)
##
-## Cumulative offsets, padded for clarity:
-DEFINE OFF_input_paths 0000000000000000
-DEFINE OFF_input_starts 0002000000000000
-DEFINE OFF_input_lens 0004000000000000
-DEFINE OFF_scope_stack 0006000000000000
-DEFINE OFF_line_scratch 0007000000000000
-DEFINE OFF_name_buf 4007000000000000
-DEFINE OFF_label_buf 4017000000000000
-DEFINE OFF_other_buf 4027000000000000
-DEFINE OFF_pat_buf 4037000000000000
-DEFINE OFF_ev_bytes 4047000000000000
-DEFINE OFF_df_byte 5047000000000000
-DEFINE OFF_input_buf 0048000000000000
-DEFINE OFF_output_buf 0048000001000000
-DEFINE OFF_text_buf 0048000009000000
-DEFINE OFF_labels 0048000009800000
-
-## --- Runtime shell: argv parse -> load files -> two passes -> write -> exit
+## Compact cumulative offsets in 8-byte little-endian hex.
+DEFINE H2_OFF_scope_stack 0000000000000000
+DEFINE H2_OFF_line_scratch 0001000000000000
+DEFINE H2_OFF_name_buf 4001000000000000
+DEFINE H2_OFF_label_buf 4011000000000000
+DEFINE H2_OFF_other_buf 4021000000000000
+DEFINE H2_OFF_pat_buf 4031000000000000
+DEFINE H2_OFF_ev_bytes 4041000000000000
+DEFINE H2_OFF_df_byte 5041000000000000
+DEFINE H2_OFF_input_buf 0042000000000000
+DEFINE H2_OFF_output_buf 0042100000000000
+DEFINE H2_OFF_text_buf 0042200000000000
+DEFINE H2_OFF_labels 0042300000000000
+
+## --- p1_main: argv parse -> load input -> two passes -> write -> exit ------
:p1_main
enter_0
- # ---- Save argc / argv FIRST (subsequent setup clobbers a0/a1) ---------
- # On entry a0 = argc, a1 = argv (per the backend :_start stub).
+ # Save argc / argv before anything clobbers them.
la_a2 &saved_argc
st_a0,a2,0
la_a2 &saved_argv
st_a1,a2,0
- # ---- Init BSS pointer slots from ELF_end ------------------------------
+ # Init BSS pointer slots from ELF_end via table walk.
la_t0 &ELF_end
la_t1 &bss_init_tbl
la_t2 &bss_init_tbl_end
@@ -134,25 +109,19 @@ DEFINE OFF_labels 0048000009800000
b
:bss_init_done
- # ---- Default ptrsize = 4 ----------------------------------------------
+ # Default ptrsize = 4.
li_t0 %4 %0
- la_a0 &ptrsize
- st_t0,a0,0
-
-:arg_loop_init
- li_t0 %0 %0
- la_a0 &arg_idx
- st_t0,a0,0
+ la_a2 &ptrsize
+ st_t0,a2,0
+ # ---- Argv loop --------------------------------------------------------
+ # i = 1
+ li_t0 %1 %0
+ la_a2 &arg_idx
+ st_t0,a2,0
:arg_loop
- # i++; if (i >= argc) goto arg_done. arg_idx is bumped here at the
- # top so each handler just `b` back to arg_loop without bookkeeping.
- # arg_advance (used by value-taking flags) also increments, so a
- # `-B ADDR` pair correctly advances by two argv slots per dispatch.
la_a0 &arg_idx
ld_t0,a0,0
- addi_t0,t0,1
- st_t0,a0,0
la_a1 &saved_argc
ld_t1,a1,0
la_br &arg_done
@@ -160,178 +129,156 @@ DEFINE OFF_labels 0048000009800000
la_br &arg_done
blt_t1,t0
- # arg_ptr = argv[i] = *(argv + 8*i)
+ # arg_ptr = argv[i]
la_a0 &saved_argv
- ld_a0,a0,0
- mov_a1,a0 # a1 = argv
- la_a0 &arg_idx
- ld_t0,a0,0
- shli_t2,t0,3 # t2 = 8*i
- add_a0,t2,a1 # a0 = argv + 8*i
- ld_a0,a0,0 # a0 = argv[i]
- la_a1 &arg_ptr
- st_a0,a1,0
-
- # Dispatch on the argument string. Each compare uses str_eq, which
- # checks the trailing NUL of the argv string against the option
- # constant's known length. Anything not matching a known flag (and
- # not starting with '-') is treated as a positional argument: first
- # is the input file, second is the output file.
+ ld_a1,a0,0
+ shli_t2,t0,3
+ add_a1,a1,t2
+ ld_a0,a1,0
+ la_a2 &arg_ptr
+ st_a0,a2,0
- # -B
- la_a0 &arg_ptr
- ld_a0,a0,0
- la_a1 &opt_dash_B
+ # Match against known short flags.
+ la_a1 &opt_B
li_a2 %2 %0
la_br &str_eq
call
- la_br &arg_is_base
+ la_br &arg_is_B
bnez_a0
- # -E
la_a0 &arg_ptr
ld_a0,a0,0
- la_a1 &opt_dash_E
+ la_a1 &opt_E
li_a2 %2 %0
la_br &str_eq
call
la_br &arg_is_big
bnez_a0
- # -e
la_a0 &arg_ptr
ld_a0,a0,0
- la_a1 &opt_dash_e
+ la_a1 &opt_e
li_a2 %2 %0
la_br &str_eq
call
la_br &arg_is_little
bnez_a0
- # -b
la_a0 &arg_ptr
ld_a0,a0,0
- la_a1 &opt_dash_b
+ la_a1 &opt_b
li_a2 %2 %0
la_br &str_eq
call
la_br &arg_is_binary
bnez_a0
- # -N
la_a0 &arg_ptr
ld_a0,a0,0
- la_a1 &opt_dash_N
+ la_a1 &opt_N
li_a2 %2 %0
la_br &str_eq
call
la_br &arg_is_nonexec
bnez_a0
- # Not a known flag. If it begins with '-' (and isn't just "-"),
- # it's an unknown option. Otherwise it's a positional.
+ # Unrecognised. If first byte is '-' (and string len > 1), error.
la_a0 &arg_ptr
ld_a0,a0,0
- lb_a0,a0,0 # a0 = first byte
- li_t0 %45 %0 # t0 = '-'
+ lb_t0,a0,0
+ li_t1 %45 %0
la_br &arg_is_positional
- bne_a0,t0
- la_a0 &arg_ptr
- ld_a0,a0,0
- addi_a0,a0,1
- lb_a0,a0,0 # a0 = second byte
+ bne_t0,t1
+ lb_t0,a0,1
la_br &arg_is_positional
- beqz_a0
+ beqz_t0
la_br &err_unknown_arg
b
:arg_is_positional
- # If input not yet loaded, this is IN. Else if output not yet set,
- # this is OUT. Else extra positional → error.
- la_a0 &input_count
+ # First positional = input path; second = output path; third = error.
+ la_a0 &input_path
ld_t0,a0,0
- la_br &arg_pos_is_out
+ la_br &arg_pos_set_out
bnez_t0
- la_a0 &arg_ptr
- ld_a0,a0,0
- la_br &load_input
- call
- la_br &arg_loop
+ la_a1 &arg_ptr
+ ld_t0,a1,0
+ st_t0,a0,0
+ la_br &arg_loop_next
b
-:arg_pos_is_out
+:arg_pos_set_out
la_a0 &output_path
ld_t0,a0,0
- la_br &err_unknown_arg
+ la_br &err_extra_positional
bnez_t0
- la_a0 &arg_ptr
- ld_a0,a0,0
- la_a1 &output_path
- st_a0,a1,0
- la_br &arg_loop
+ la_a1 &arg_ptr
+ ld_t0,a1,0
+ st_t0,a0,0
+ la_br &arg_loop_next
b
-:arg_is_base
- la_br &arg_advance
- call
- la_a0 &arg_ptr
- ld_a0,a0,0
- la_br &parse_long_arg
+:arg_is_B
+ # -B requires a value in the next argv slot.
+ la_a0 &arg_idx
+ ld_t0,a0,0
+ addi_t0,t0,1
+ st_t0,a0,0
+ la_a1 &saved_argc
+ ld_t1,a1,0
+ la_br &err_missing_value
+ beq_t0,t1
+ la_br &err_missing_value
+ blt_t1,t0
+ la_a0 &saved_argv
+ ld_a1,a0,0
+ shli_t2,t0,3
+ add_a1,a1,t2
+ ld_a0,a1,0
+ la_br &parse_long
call
la_a1 &base_address
st_a0,a1,0
- la_br &arg_loop
+ la_br &arg_loop_next
b
+
:arg_is_big
li_t0 %1 %0
- la_a0 &big_endian
- st_t0,a0,0
- la_br &arg_loop
+ la_a1 &big_endian
+ st_t0,a1,0
+ la_br &arg_loop_next
b
+
:arg_is_little
li_t0 %0 %0
- la_a0 &big_endian
- st_t0,a0,0
- la_br &arg_loop
+ la_a1 &big_endian
+ st_t0,a1,0
+ la_br &arg_loop_next
b
+
:arg_is_binary
li_t0 %1 %0
- la_a0 &byte_mode
- st_t0,a0,0
- la_br &arg_loop
+ la_a1 &byte_mode
+ st_t0,a1,0
+ la_br &arg_loop_next
b
+
:arg_is_nonexec
li_t0 %1 %0
- la_a0 &non_executable
- st_t0,a0,0
- la_br &arg_loop
+ la_a1 &non_executable
+ st_t0,a1,0
+ la_br &arg_loop_next
b
-## arg_advance(): i++; if (i >= argc) usage error; arg_ptr = argv[i].
-:arg_advance
- enter_0
+:arg_loop_next
la_a0 &arg_idx
ld_t0,a0,0
addi_t0,t0,1
st_t0,a0,0
- la_a1 &saved_argc
- ld_t1,a1,0
- la_br &err_missing_arg_value
- beq_t0,t1
- la_br &err_missing_arg_value
- blt_t1,t0
- # arg_ptr = argv[i]
- la_a0 &saved_argv
- ld_a0,a0,0
- mov_a1,a0
- shli_t2,t0,3
- add_a0,t2,a1
- ld_a0,a0,0
- la_a1 &arg_ptr
- st_a0,a1,0
- eret
+ la_br &arg_loop
+ b
:arg_done
- la_a0 &input_count
+ la_a0 &input_path
ld_t0,a0,0
la_br &err_missing_positional
beqz_t0
@@ -340,13 +287,17 @@ DEFINE OFF_labels 0048000009800000
la_br &err_missing_positional
beqz_t0
- # ---- Pass 1: collect labels --------------------------------------------
+ # ---- Load input file -------------------------------------------------
+ la_br &load_input
+ call
+
+ # ---- Pass 1 ----------------------------------------------------------
li_t0 %1 %0
la_a0 &pass
st_t0,a0,0
la_br &reset_pass_state
call
- la_br &run_one_pass
+ la_br &process_input
call
la_a0 &scope_depth
ld_t0,a0,0
@@ -358,13 +309,13 @@ DEFINE OFF_labels 0048000009800000
la_a0 &cur_path
st_t0,a0,0
- # ---- Pass 2: emit ------------------------------------------------------
+ # ---- Pass 2 ----------------------------------------------------------
li_t0 %2 %0
la_a0 &pass
st_t0,a0,0
la_br &reset_pass_state
call
- la_br &run_one_pass
+ la_br &process_input
call
la_a0 &scope_depth
ld_t0,a0,0
@@ -401,84 +352,25 @@ DEFINE OFF_labels 0048000009800000
st_t0,a0,0
eret
-## run_one_pass(): for i in [0, input_count) call process_file(i).
-:run_one_pass
- enter_0
- li_t0 %0 %0
- la_a0 &pass_idx
- st_t0,a0,0
-:run_one_pass_loop
- la_a0 &pass_idx
- ld_t0,a0,0
- la_a1 &input_count
- ld_t1,a1,0
- la_br &run_one_pass_done
- beq_t0,t1
- mov_a0,t0
- la_br &process_file
- call
- la_a0 &pass_idx
- ld_t0,a0,0
- addi_t0,t0,1
- st_t0,a0,0
- la_br &run_one_pass_loop
- b
-:run_one_pass_done
- eret
-
-## --- File loader ------------------------------------------------------------
-## load_input(a0=path): record path, read file appended into input_buf at
-## offset input_total, then advance input_total. Fatal on any I/O failure.
+## --- Input loader ----------------------------------------------------------
+## load_input(): openat(input_path), read into input_buf until EOF.
:load_input
enter_0
- la_a1 &input_count
- ld_t0,a1,0
- li_t1 H2_FILES_CAP
- la_br &err_too_many_files
- beq_t0,t1
-
- # Save path into input_paths[input_count].
- la_a1 &input_paths_ptr
- ld_a1,a1,0
- shli_t2,t0,3
- add_a1,t2,a1
- st_a0,a1,0
-
- # input_starts[input_count] = input_total
- la_a1 &input_total
- ld_t1,a1,0
- la_a2 &input_starts_ptr
- ld_a2,a2,0
- add_a2,t2,a2
- la_a0 &aux_tmp
- st_t1,a0,0
- ld_a3,a0,0
- st_a3,a2,0
-
- # Stash path for the syscall. a0 was clobbered by &aux_tmp above,
- # so re-read the path from input_paths[input_count] (still index 0
- # for our slot since input_count is incremented at li_eof).
- la_a0 &input_paths_ptr
- ld_a0,a0,0
- ld_a0,a0,0
- la_a1 &li_path
- st_a0,a1,0
-
- # fd = openat(AT_FDCWD, path, O_RDONLY, 0)
+ # fd = openat(AT_FDCWD, input_path, O_RDONLY, 0)
li_a0 sys_openat
- li_a1 AT_FDCWD
- la_a2 &li_path
+ li_a1 H2_AT_FDCWD
+ la_a2 &input_path
ld_a2,a2,0
- li_a3 O_RDONLY
+ li_a3 H2_O_RDONLY
li_t0 %0 %0
syscall
la_br &err_open_input
bltz_a0
- la_a1 &li_fd
+ la_a1 &input_fd
st_a0,a1,0
:li_read_loop
- la_a0 &input_total
+ la_a0 &input_len
ld_t0,a0,0
li_t1 H2_INPUT_CAP
la_br &err_input_too_big
@@ -486,13 +378,13 @@ DEFINE OFF_labels 0048000009800000
la_br &err_input_too_big
blt_t1,t0
- # n = read(fd, input_buf + input_total, INPUT_CAP - input_total)
- la_a0 &li_fd
+ # n = read(fd, input_buf + input_len, INPUT_CAP - input_len)
+ la_a0 &input_fd
ld_a1,a0,0
la_a2 &input_buf_ptr
ld_a2,a2,0
add_a2,a2,t0
- sub_a3,t1,t0 # available? sub_a3,t1,t0 — yes
+ sub_a3,t1,t0
li_a0 sys_read
syscall
la_br &li_eof
@@ -500,8 +392,7 @@ DEFINE OFF_labels 0048000009800000
la_br &err_read
bltz_a0
- # input_total += n
- la_a1 &input_total
+ la_a1 &input_len
ld_t0,a1,0
add_t0,t0,a0
st_t0,a1,0
@@ -509,92 +400,30 @@ DEFINE OFF_labels 0048000009800000
b
:li_eof
- # input_lens[input_count] = input_total - input_starts[input_count].
- # The seed has add_a2,a2,t1 but neither add_a2,a2,t2 nor mov_t1,t2,
- # so the stride-by-8 result lives in t2 and is then re-loaded as t1
- # via the li_tmp scratch slot.
- la_a0 &input_count
- ld_t0,a0,0
- shli_t2,t0,3
- la_a3 &li_tmp
- st_t2,a3,0
- ld_t1,a3,0
- la_a2 &input_starts_ptr
- ld_a2,a2,0
- add_a2,a2,t1 # a2 = &input_starts[i]
- ld_a3,a2,0 # a3 = input_starts[i]
- la_a0 &input_total
- ld_a1,a0,0 # a1 = input_total
- # We need (total - start) into a2, but no sub_a2,a1,a3 form exists.
- # Spill start through li_tmp -> a0 so we can use sub_a2,a1,a0.
- la_a0 &li_tmp
- st_a3,a0,0
- ld_a0,a0,0 # a0 = start (re-reads via li_tmp)
- sub_a2,a1,a0 # a2 = total - start
- # Store into input_lens[i] (reuse the same t1 scaling).
- la_a0 &input_lens_ptr
- ld_a0,a0,0
- add_a0,a0,t1
- st_a2,a0,0
-
- la_a0 &input_count
- ld_t0,a0,0
- addi_t0,t0,1
- st_t0,a0,0
eret
-## --- Per-file scanner -------------------------------------------------------
-
-## process_file(a0=file_idx): set cur_path / cur_line / scan_pos / scan_end
-## from the input record, then dispatch character by character.
-:process_file
+## --- Process input: scan one pass over input_buf ---------------------------
+:process_input
enter_0
- mov_t0,a0
- shli_t2,t0,3 # t2 = 8*idx
-
- # cur_path = input_paths[idx]
- la_a3 &li_tmp
- st_t2,a3,0
- ld_t1,a3,0 # t1 = 8*idx
- la_a1 &input_paths_ptr
- ld_a1,a1,0
- add_a1,a1,t1 # available add_a1,a1,t1
- ld_a1,a1,0
- la_a2 &cur_path
- st_a1,a2,0
-
- # cur_line = 1
+ # cur_path = input_path; cur_line = 1
+ la_a0 &input_path
+ ld_t0,a0,0
+ la_a1 &cur_path
+ st_t0,a1,0
li_t0 %1 %0
- la_a2 &cur_line
- st_t0,a2,0
-
- # scan_pos = input_buf + input_starts[idx]
- la_a1 &input_starts_ptr
- ld_a1,a1,0
- add_a1,a1,t1
- ld_a1,a1,0 # a1 = start offset
- la_a2 &input_buf_ptr
- ld_a2,a2,0
- mov_a0,a1
- add_a2,a2,a0 # add_a2,a2,a1 NOT listed. Use a2,a2,a0 with a0=a1.
- la_a3 &li_tmp
- st_a1,a3,0
- ld_a0,a3,0 # a0 = start
- add_a2,a2,a0 # available
- la_a0 &scan_pos
- st_a2,a0,0
+ la_a1 &cur_line
+ st_t0,a1,0
- # scan_end = scan_pos + input_lens[idx]
- la_a1 &input_lens_ptr
- ld_a1,a1,0
- add_a1,a1,t1
- ld_a1,a1,0 # a1 = len
- la_a3 &li_tmp
- st_a1,a3,0
- ld_a0,a3,0
- add_a2,a2,a0
- la_a0 &scan_end
- st_a2,a0,0
+ # scan_pos = input_buf; scan_end = input_buf + input_len
+ la_a0 &input_buf_ptr
+ ld_t0,a0,0
+ la_a1 &scan_pos
+ st_t0,a1,0
+ la_a0 &input_len
+ ld_t1,a0,0
+ add_t0,t0,t1
+ la_a1 &scan_end
+ st_t0,a1,0
:scan_loop
la_br &skip_ws_and_comments
@@ -609,43 +438,44 @@ DEFINE OFF_labels 0048000009800000
blt_t1,t0
lb_a0,t0,0
- # Dispatch on c.
- li_t1 %58 %0 # ':'
- la_br &scan_label_def
+ li_t1 %58 %0
+ la_br &handle_label_def
beq_a0,t1
- li_t1 %46 %0 # '.'
- la_br &scan_directive
+ li_t1 %46 %0
+ la_br &handle_directive
beq_a0,t1
- li_t1 %33 %0 # '!'
- la_br &scan_ref
+ li_t1 %33 %0
+ la_br &handle_ref
beq_a0,t1
- li_t1 %64 %0 # '@'
- la_br &scan_ref
+ li_t1 %64 %0
+ la_br &handle_ref
beq_a0,t1
- li_t1 %36 %0 # '$'
- la_br &scan_ref
+ li_t1 %36 %0
+ la_br &handle_ref
beq_a0,t1
- li_t1 %126 %0 # '~'
- la_br &scan_ref
+ li_t1 %126 %0
+ la_br &handle_ref
beq_a0,t1
- li_t1 %37 %0 # '%'
- la_br &scan_ref
+ li_t1 %37 %0
+ la_br &handle_ref
beq_a0,t1
- li_t1 %38 %0 # '&'
- la_br &scan_ref
+ li_t1 %38 %0
+ la_br &handle_ref
beq_a0,t1
la_br &is_byte_digit
call
- la_br &scan_byte_stream
+ la_br &handle_byte_stream
bnez_a0
la_br &err_unexpected_char
b
-:scan_label_def
+:handle_label_def
+ # consume ':'
la_a0 &scan_pos
ld_t0,a0,0
addi_t0,t0,1
st_t0,a0,0
+ # name = read_name(name_buf, MAX_TOKEN)
la_a0 &name_buf_ptr
ld_a0,a0,0
li_a1 H2_TOKEN_CAP
@@ -653,40 +483,34 @@ DEFINE OFF_labels 0048000009800000
call
la_a1 &name_len
st_a0,a1,0
- # dotted = (name[0] == '.')
- la_a1 &name_buf_ptr
- ld_a1,a1,0
- la_a3 &aux_tmp
- st_a1,a3,0
- ld_a3,a3,0
- lb_t0,a3,0
+ # dotted = (name[0] == '.') AND scope_depth > 0
+ la_a0 &name_buf_ptr
+ ld_a0,a0,0
+ lb_t0,a0,0
li_t1 %46 %0
- la_br &scan_label_undotted
+ la_br &handle_label_global
bne_t0,t1
- # dotted: scope-local only when inside a .scope; otherwise treat as
- # an ordinary global label.
la_a0 &scope_depth
ld_t0,a0,0
- la_br &scan_label_undotted
+ la_br &handle_label_global
beqz_t0
+ # scope_id = scope_stack[scope_depth-1]
addi_t0,t0,neg1
+ la_a1 &scope_stack_ptr
+ ld_a1,a1,0
shli_t2,t0,3
- la_a3 &sl_tmp
- st_t2,a3,0
- ld_t1,a3,0
- la_a0 &scope_stack_ptr
- ld_a0,a0,0
- add_a0,a0,t1 # available
- ld_a0,a0,0 # a0 = scope id of innermost scope
- la_a1 &name_scope
- st_a0,a1,0
- la_br &scan_label_define
+ add_a1,a1,t2
+ ld_t0,a1,0
+ la_a2 &name_scope
+ st_t0,a2,0
+ la_br &handle_label_dispatch
b
-:scan_label_undotted
+:handle_label_global
li_t0 %0 %0
- la_a1 &name_scope
- st_t0,a1,0
-:scan_label_define
+ la_a2 &name_scope
+ st_t0,a2,0
+:handle_label_dispatch
+ # Pass 1 only: define_label(name, len, scope)
la_a0 &pass
ld_t0,a0,0
li_t1 %1 %0
@@ -703,7 +527,8 @@ DEFINE OFF_labels 0048000009800000
la_br &scan_loop
b
-:scan_directive
+:handle_directive
+ # consume '.'
la_a0 &scan_pos
ld_t0,a0,0
addi_t0,t0,1
@@ -716,122 +541,114 @@ DEFINE OFF_labels 0048000009800000
la_a1 &name_len
st_a0,a1,0
- # Compare against the four known directive names.
- li_t1 %5 %0
- la_br &scan_dir_check_4
- la_a3 &aux_tmp
- st_t1,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
+ # Dispatch by length, then memcmp.
+ la_a0 &name_len
ld_t0,a0,0
- bne_a0,t0
+ li_t1 %5 %0
+ la_br &dir_check_4
+ bne_t0,t1
+ # Could be "align" or "scope".
la_a0 &name_buf_ptr
ld_a0,a0,0
- la_a1 &dir_align
+ la_a1 &kw_align
li_a2 %5 %0
la_br &mem_eq
call
- la_br &scan_dir_align
+ la_br &dir_call_align
bnez_a0
la_a0 &name_buf_ptr
ld_a0,a0,0
- la_a1 &dir_scope
+ la_a1 &kw_scope
li_a2 %5 %0
la_br &mem_eq
call
- la_br &scan_dir_scope_open
+ la_br &dir_call_scope
bnez_a0
la_br &err_unknown_directive
b
-:scan_dir_check_4
- la_a0 &name_len
- ld_t0,a0,0
+:dir_check_4
li_t1 %4 %0
- la_br &scan_dir_check_8
+ la_br &dir_check_8
bne_t0,t1
la_a0 &name_buf_ptr
ld_a0,a0,0
- la_a1 &dir_fill
+ la_a1 &kw_fill
li_a2 %4 %0
la_br &mem_eq
call
- la_br &scan_dir_fill
+ la_br &dir_call_fill
bnez_a0
la_br &err_unknown_directive
b
-:scan_dir_check_8
- la_a0 &name_len
- ld_t0,a0,0
+:dir_check_8
li_t1 %8 %0
- la_br &scan_dir_check_7
+ la_br &dir_check_7
bne_t0,t1
la_a0 &name_buf_ptr
ld_a0,a0,0
- la_a1 &dir_endscope
+ la_a1 &kw_endscope
li_a2 %8 %0
la_br &mem_eq
call
- la_br &scan_dir_scope_close
+ la_br &dir_call_endscope
bnez_a0
la_br &err_unknown_directive
b
-:scan_dir_check_7
- la_a0 &name_len
- ld_t0,a0,0
+:dir_check_7
li_t1 %7 %0
la_br &err_unknown_directive
bne_t0,t1
la_a0 &name_buf_ptr
ld_a0,a0,0
- la_a1 &dir_ptrsize
+ la_a1 &kw_ptrsize
li_a2 %7 %0
la_br &mem_eq
call
- la_br &scan_dir_ptrsize
+ la_br &dir_call_ptrsize
bnez_a0
la_br &err_unknown_directive
b
-:scan_dir_align
+:dir_call_align
la_br &do_align
call
la_br &scan_loop
b
-:scan_dir_fill
+:dir_call_fill
la_br &do_fill
call
la_br &scan_loop
b
-:scan_dir_scope_open
+:dir_call_scope
la_br &do_scope_open
call
la_br &scan_loop
b
-:scan_dir_scope_close
+:dir_call_endscope
la_br &do_scope_close
call
la_br &scan_loop
b
-:scan_dir_ptrsize
+:dir_call_ptrsize
la_br &do_ptrsize
call
la_br &scan_loop
b
-:scan_ref
- # a0 holds sigil; advance past it then process_reference.
+:handle_ref
+ # a0 holds the sigil byte; advance past it then process_reference.
la_a1 &cur_sigil
st_a0,a1,0
- la_a1 &scan_pos
- ld_t0,a1,0
+ la_a0 &scan_pos
+ ld_t0,a0,0
addi_t0,t0,1
- st_t0,a1,0
+ st_t0,a0,0
la_br &process_reference
call
la_br &scan_loop
b
-:scan_byte_stream
+:handle_byte_stream
la_br &parse_byte_stream
call
la_br &scan_loop
@@ -840,7 +657,7 @@ DEFINE OFF_labels 0048000009800000
:scan_done
eret
-## --- Lex helpers ------------------------------------------------------------
+## --- Lex helpers -----------------------------------------------------------
## skip_ws_and_comments(): advance scan_pos past whitespace and #/; comments.
## Updates cur_line on '\n'.
@@ -858,38 +675,35 @@ DEFINE OFF_labels 0048000009800000
lb_a0,t0,0
la_br &is_space_any
call
- la_br &swc_after_space_check
+ la_br &swc_after_ws_check
beqz_a0
- # whitespace: advance; if '\n' bump cur_line.
- la_a1 &scan_pos
- ld_t0,a1,0
+ # whitespace: bump cur_line on '\n', advance scan_pos.
+ la_a0 &scan_pos
+ ld_t0,a0,0
lb_a0,t0,0
li_t1 %10 %0
la_br &swc_advance
- la_a3 &aux_tmp
- st_t1,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
- ld_t0,a0,0
- bne_a0,t0
- la_a2 &cur_line
- la_a0 &aux_tmp
- st_a2,a0,0
- ld_t2,a0,0
+ bne_a0,t1
+ la_a1 &cur_line
+ ld_t2,a1,0
addi_t2,t2,1
- st_t2,a2,0
+ st_t2,a1,0
:swc_advance
- la_a1 &scan_pos
- ld_t0,a1,0
+ la_a0 &scan_pos
+ ld_t0,a0,0
addi_t0,t0,1
- st_t0,a1,0
+ st_t0,a0,0
la_br &swc_loop
b
-:swc_after_space_check
- li_t1 %35 %0 # '#'
+:swc_after_ws_check
+ # is_space_any clobbered a0; re-read the byte at scan_pos.
+ la_a0 &scan_pos
+ ld_t0,a0,0
+ lb_a0,t0,0
+ li_t1 %35 %0
la_br &swc_consume_comment
beq_a0,t1
- li_t1 %59 %0 # ';'
+ li_t1 %59 %0
la_br &swc_consume_comment
beq_a0,t1
la_br &swc_done
@@ -909,7 +723,8 @@ DEFINE OFF_labels 0048000009800000
la_br &swc_loop
beq_a0,t1
addi_t0,t0,1
- st_t0,a0,0
+ la_a1 &scan_pos
+ st_t0,a1,0
la_br &swc_cc_loop
b
:swc_done
@@ -952,10 +767,10 @@ DEFINE OFF_labels 0048000009800000
la_br &siw_done
b
:siw_advance
- la_a1 &scan_pos
- ld_t0,a1,0
+ la_a0 &scan_pos
+ ld_t0,a0,0
addi_t0,t0,1
- st_t0,a1,0
+ st_t0,a0,0
la_br &siw_loop
b
:siw_consume_comment
@@ -973,7 +788,8 @@ DEFINE OFF_labels 0048000009800000
la_br &siw_done
beq_a0,t1
addi_t0,t0,1
- st_t0,a0,0
+ la_a1 &scan_pos
+ st_t0,a1,0
la_br &siw_cc_loop
b
:siw_done
@@ -1005,34 +821,35 @@ DEFINE OFF_labels 0048000009800000
li_a0 %1 %0
ret
-## is_name_terminator_c(a0=c) -> a0=0/1. Terminators: whitespace, '-', '#', ';'.
+## is_name_terminator(a0=c) -> a0=0/1. Terminators: ws, '-', '>', '#', ';'.
## Spills c into a BSS slot since is_space_any clobbers a0.
-:is_name_terminator_c
+:is_name_terminator
+ enter_0
la_a1 &nt_c
st_a0,a1,0
la_br &is_space_any
call
la_br &nt_yes
bnez_a0
- la_a1 &nt_c
- ld_a0,a1,0
- li_t0 %45 %0 # '-'
+ la_a0 &nt_c
+ ld_a0,a0,0
+ li_t0 %45 %0
la_br &nt_yes
beq_a0,t0
- li_t0 %62 %0 # '>' (synonym for '-')
+ li_t0 %62 %0
la_br &nt_yes
beq_a0,t0
- li_t0 %35 %0 # '#'
+ li_t0 %35 %0
la_br &nt_yes
beq_a0,t0
- li_t0 %59 %0 # ';'
+ li_t0 %59 %0
la_br &nt_yes
beq_a0,t0
li_a0 %0 %0
- ret
+ eret
:nt_yes
li_a0 %1 %0
- ret
+ eret
## is_byte_digit(a0=c) -> a0=0/1. Mode-aware (HEX vs BINARY).
:is_byte_digit
@@ -1041,45 +858,39 @@ DEFINE OFF_labels 0048000009800000
la_br &ibd_bin
bnez_t0
# HEX: 0-9, a-f, A-F
- li_t0 %48 %0
+ li_t1 %48 %0
la_br &ibd_no
- mov_a2,t0
- blt_a0,a2
- li_t0 %57 %0
+ blt_a0,t1
+ li_t1 %57 %0
la_br &ibd_yes
- mov_a2,t0
- blt_a0,a2
+ blt_a0,t1
la_br &ibd_yes
- beq_a0,t0
- li_t0 %65 %0
+ beq_a0,t1
+ li_t1 %65 %0
la_br &ibd_no
- mov_a2,t0
- blt_a0,a2
- li_t0 %70 %0
+ blt_a0,t1
+ li_t1 %70 %0
la_br &ibd_yes
- mov_a2,t0
- blt_a0,a2
+ blt_a0,t1
la_br &ibd_yes
- beq_a0,t0
- li_t0 %97 %0
+ beq_a0,t1
+ li_t1 %97 %0
la_br &ibd_no
- mov_a2,t0
- blt_a0,a2
- li_t0 %102 %0
+ blt_a0,t1
+ li_t1 %102 %0
la_br &ibd_yes
- mov_a2,t0
- blt_a0,a2
+ blt_a0,t1
la_br &ibd_yes
- beq_a0,t0
+ beq_a0,t1
la_br &ibd_no
b
:ibd_bin
- li_t0 %48 %0
+ li_t1 %48 %0
la_br &ibd_yes
- beq_a0,t0
- li_t0 %49 %0
+ beq_a0,t1
+ li_t1 %49 %0
la_br &ibd_yes
- beq_a0,t0
+ beq_a0,t1
la_br &ibd_no
b
:ibd_yes
@@ -1094,22 +905,20 @@ DEFINE OFF_labels 0048000009800000
:byte_digit_value
li_t0 %57 %0
la_br &bdv_alpha
- mov_t1,a0
- blt_t0,t1 # if c > '9', go alpha
+ blt_t0,a0
li_t1 %48 %0
- sub_a0,a0,t1 # available
+ sub_a0,a0,t1
ret
:bdv_alpha
li_t0 %96 %0
la_br &bdv_lower
- mov_t1,a0
- blt_t0,t1 # if c > 'a' - 1 (= 96), it's lowercase
+ blt_t0,a0
li_t1 %55 %0
- sub_a0,a0,t1 # 'A'(65) - 55 = 10
+ sub_a0,a0,t1
ret
:bdv_lower
li_t1 %87 %0
- sub_a0,a0,t1 # 'a'(97) - 87 = 10
+ sub_a0,a0,t1
ret
## byte_digit_count() -> a0. 2 for HEX, 8 for BINARY.
@@ -1125,7 +934,7 @@ DEFINE OFF_labels 0048000009800000
ret
## read_name(a0=out_buf, a1=max) -> a0=length. Reads scan_pos into out_buf
-## until is_name_terminator_c or scan_end.
+## until is_name_terminator or scan_end. Fatal on overflow / empty.
:read_name
enter_0
la_a2 &rn_out
@@ -1145,43 +954,31 @@ DEFINE OFF_labels 0048000009800000
la_br &rn_done
blt_t1,t0
lb_a0,t0,0
- la_br &is_name_terminator_c
+ la_br &is_name_terminator
call
la_br &rn_done
bnez_a0
- # overflow check
la_a1 &rn_n
ld_t0,a1,0
- la_a2 &rn_max
- la_a0 &aux_tmp
- st_a2,a0,0
+ la_a0 &rn_max
ld_t1,a0,0
la_br &err_name_too_long
beq_t0,t1
- # store char (re-read from scan_pos)
- la_a3 &scan_pos
- ld_a3,a3,0
- la_a2 &aux_tmp
- st_a3,a2,0
- la_a0 &aux_tmp
- st_a2,a0,0
- ld_t1,a0,0
- lb_t1,t1,0
- la_a2 &rn_out
- ld_a2,a2,0
- add_a2,a2,t0
- sb_t1,a2,0
- # n++
+ # store char
+ la_a0 &scan_pos
+ ld_a0,a0,0
+ lb_a3,a0,0
+ la_a1 &rn_out
+ ld_a1,a1,0
+ add_a1,a1,t0
+ sb_a3,a1,0
addi_t0,t0,1
la_a1 &rn_n
st_t0,a1,0
- # scan_pos++
- la_a3 &scan_pos
- la_a0 &aux_tmp
- st_a3,a0,0
+ la_a0 &scan_pos
ld_t0,a0,0
addi_t0,t0,1
- st_t0,a3,0
+ st_t0,a0,0
la_br &rn_loop
b
:rn_done
@@ -1192,7 +989,7 @@ DEFINE OFF_labels 0048000009800000
eret
## read_directive_name(a0=out_buf, a1=max) -> a0=length. Like read_name but
-## terminates on the first non-alpha byte.
+## terminates on first non-alpha byte.
:read_directive_name
enter_0
la_a2 &rn_out
@@ -1212,26 +1009,22 @@ DEFINE OFF_labels 0048000009800000
la_br &rdn_done
blt_t1,t0
lb_a0,t0,0
- # Reject if not [A-Za-z]
+ # accept [A-Za-z]
li_t1 %65 %0
la_br &rdn_check_lower
- mov_a2,t1
- blt_a0,a2
+ blt_a0,t1
li_t1 %90 %0
la_br &rdn_consume
- mov_a2,t1
- blt_a0,a2
+ blt_a0,t1
la_br &rdn_consume
beq_a0,t1
:rdn_check_lower
li_t1 %97 %0
la_br &rdn_done
- mov_a2,t1
- blt_a0,a2
+ blt_a0,t1
li_t1 %122 %0
la_br &rdn_consume
- mov_a2,t1
- blt_a0,a2
+ blt_a0,t1
la_br &rdn_consume
beq_a0,t1
la_br &rdn_done
@@ -1240,9 +1033,7 @@ DEFINE OFF_labels 0048000009800000
la_a1 &rn_n
ld_t0,a1,0
la_a2 &rn_max
- la_a0 &aux_tmp
- st_a2,a0,0
- ld_t1,a0,0
+ ld_t1,a2,0
la_br &err_name_too_long
beq_t0,t1
la_a2 &rn_out
@@ -1252,12 +1043,10 @@ DEFINE OFF_labels 0048000009800000
addi_t0,t0,1
la_a1 &rn_n
st_t0,a1,0
- la_a3 &scan_pos
- la_a0 &aux_tmp
- st_a3,a0,0
+ la_a0 &scan_pos
ld_t0,a0,0
addi_t0,t0,1
- st_t0,a3,0
+ st_t0,a0,0
la_br &rdn_loop
b
:rdn_done
@@ -1267,7 +1056,7 @@ DEFINE OFF_labels 0048000009800000
beqz_a0
eret
-## read_decimal() -> a0=value (i64). Fatal on no digits.
+## read_decimal() -> a0=value. Fatal on no digits.
:read_decimal
enter_0
li_t0 %0 %0
@@ -1287,36 +1076,26 @@ DEFINE OFF_labels 0048000009800000
lb_a0,t0,0
li_t1 %48 %0
la_br &rd_done
- mov_a2,t1
- blt_a0,a2
+ blt_a0,t1
li_t1 %57 %0
la_br &rd_done
- mov_a1,a0
- blt_t1,a1
+ blt_t1,a0
# acc = acc * 10 + (c - '0')
la_a1 &rd_val
- ld_t0,a1,0
+ ld_a2,a1,0
li_t1 %10 %0
- la_a3 &rd_tmp
- st_t1,a3,0
- la_a1 &aux_tmp
- st_a3,a1,0
- ld_a1,a1,0 # a1 = 10
- mul_t0,t0,a1 # t0 = acc * 10
+ mul_a2,a2,t1
li_t1 %48 %0
- sub_a0,a0,t1 # a0 = c - 48
- add_t0,t0,a0
- la_a1 &rd_val
- st_t0,a1,0
+ sub_a0,a0,t1
+ add_a2,a2,a0
+ st_a2,a1,0
li_t0 %1 %0
la_a1 &rd_saw
st_t0,a1,0
- la_a3 &scan_pos
- la_a0 &aux_tmp
- st_a3,a0,0
+ la_a0 &scan_pos
ld_t0,a0,0
addi_t0,t0,1
- st_t0,a3,0
+ st_t0,a0,0
la_br &rd_loop
b
:rd_done
@@ -1330,9 +1109,9 @@ DEFINE OFF_labels 0048000009800000
## --- Byte stream / single byte literal -------------------------------------
-## parse_byte_stream(): consume free-flowing digits (intermixed with
-## whitespace and #/; comments) and emit_byte them. Stops at first non-
-## digit non-whitespace non-comment byte.
+## parse_byte_stream(): consume free-flowing digits (intermixed with ws and
+## #/; comments) and emit_byte them. Stops at first non-digit non-ws
+## non-comment byte.
:parse_byte_stream
enter_0
li_t0 %0 %0
@@ -1354,9 +1133,7 @@ DEFINE OFF_labels 0048000009800000
call
la_br &pbs_consume_ws
bnez_a0
- la_a3 &scan_pos
- la_a0 &aux_tmp
- st_a3,a0,0
+ la_a0 &scan_pos
ld_t0,a0,0
lb_a0,t0,0
li_t1 %35 %0
@@ -1369,46 +1146,42 @@ DEFINE OFF_labels 0048000009800000
call
la_br &pbs_done
beqz_a0
- # Save and consume the digit char.
- la_a3 &scan_pos
- la_a0 &aux_tmp
- st_a3,a0,0
+ # consume one digit
+ la_a0 &scan_pos
ld_t0,a0,0
lb_a0,t0,0
addi_t0,t0,1
- st_t0,a3,0
+ la_a1 &scan_pos
+ st_t0,a1,0
la_a1 &pbs_c
st_a0,a1,0
- # acc = (acc << shift_per_digit) | nibble
+ # acc = (acc << shift) | digit
la_a1 &byte_mode
ld_t1,a1,0
- la_br &pbs_bin_step
+ la_br &pbs_bin
bnez_t1
- # HEX
+ # HEX: shift 4 + digit_value
la_a1 &pbs_acc
ld_t0,a1,0
- shli_a3,t0,4 # a3 = acc << 4
+ shli_a3,t0,4
la_a1 &pbs_c
ld_a0,a1,0
la_br &byte_digit_value
call
- mov_t0,a0
- add_a3,a3,t0 # available
+ add_a3,a3,a0
la_a1 &pbs_acc
st_a3,a1,0
la_br &pbs_bump
b
-:pbs_bin_step
- # BINARY
+:pbs_bin
la_a1 &pbs_acc
ld_t0,a1,0
- shli_a3,t0,1 # a3 = acc << 1
+ shli_a3,t0,1
la_a1 &pbs_c
ld_a0,a1,0
li_t1 %48 %0
sub_a0,a0,t1
- mov_t0,a0
- add_a3,a3,t0
+ add_a3,a3,a0
la_a1 &pbs_acc
st_a3,a1,0
:pbs_bump
@@ -1421,15 +1194,11 @@ DEFINE OFF_labels 0048000009800000
la_a1 &pbs_have
ld_t0,a1,0
la_br &pbs_loop
- la_a3 &aux_tmp
- st_a0,a3,0
- ld_t1,a3,0
- bne_t0,t1
- # have == digits_per_byte: emit and reset
+ bne_t0,a0
+ # full byte: emit
la_a1 &pbs_acc
- ld_t2,a1,0 # t2 = acc
- andi_a3,t2,255
- mov_a0,a3 # available mov_a0,a3
+ ld_a0,a1,0
+ andi_a0,a0,255
la_br &emit_byte
call
li_t0 %0 %0
@@ -1440,32 +1209,21 @@ DEFINE OFF_labels 0048000009800000
la_br &pbs_loop
b
:pbs_consume_ws
- la_a3 &scan_pos
- la_a0 &aux_tmp
- st_a3,a0,0
+ la_a0 &scan_pos
ld_t0,a0,0
lb_a0,t0,0
li_t1 %10 %0
la_br &pbs_ws_advance
- la_a3 &aux_tmp
- st_t1,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
- ld_t0,a0,0
- bne_a0,t0
- la_a2 &cur_line
- la_a0 &aux_tmp
- st_a2,a0,0
- ld_t2,a0,0
+ bne_a0,t1
+ la_a1 &cur_line
+ ld_t2,a1,0
addi_t2,t2,1
- st_t2,a2,0
+ st_t2,a1,0
:pbs_ws_advance
- la_a3 &scan_pos
- la_a0 &aux_tmp
- st_a3,a0,0
+ la_a0 &scan_pos
ld_t0,a0,0
addi_t0,t0,1
- st_t0,a3,0
+ st_t0,a0,0
la_br &pbs_loop
b
:pbs_consume_comment
@@ -1483,19 +1241,19 @@ DEFINE OFF_labels 0048000009800000
la_br &pbs_loop
beq_a0,t1
addi_t0,t0,1
- st_t0,a0,0
+ la_a1 &scan_pos
+ st_t0,a1,0
la_br &pbs_cc_loop
b
:pbs_done
la_a0 &pbs_have
ld_t0,a0,0
- la_br &err_pbs_incomplete
+ la_br &err_byte_stream_short
bnez_t0
eret
-## parse_one_byte(a0=out_byte_addr): read a single byte literal (exactly
-## byte_digit_count contiguous digits, no internal whitespace). Fatal on
-## malformed input.
+## parse_one_byte(a0=out_addr): read a single byte literal (exactly
+## byte_digit_count contiguous digits, no internal whitespace).
:parse_one_byte
enter_0
la_a1 &p1b_out
@@ -1505,33 +1263,26 @@ DEFINE OFF_labels 0048000009800000
st_t0,a1,0
la_a1 &p1b_have
st_t0,a1,0
- la_a1 &p1b_done
- st_t0,a1,0
:p1b_loop
- la_a0 &p1b_done
- ld_t0,a0,0
- la_br &p1b_finish
- bnez_t0
la_a0 &scan_pos
ld_t0,a0,0
la_a1 &scan_end
ld_t1,a1,0
- la_br &p1b_finish
+ la_br &p1b_done
beq_t0,t1
- la_br &p1b_finish
+ la_br &p1b_done
blt_t1,t0
lb_a0,t0,0
la_br &is_byte_digit
call
- la_br &p1b_finish
+ la_br &p1b_done
beqz_a0
- la_a3 &scan_pos
- la_a0 &aux_tmp
- st_a3,a0,0
+ la_a0 &scan_pos
ld_t0,a0,0
lb_a0,t0,0
addi_t0,t0,1
- st_t0,a3,0
+ la_a1 &scan_pos
+ st_t0,a1,0
la_a1 &p1b_c
st_a0,a1,0
la_a1 &byte_mode
@@ -1545,22 +1296,20 @@ DEFINE OFF_labels 0048000009800000
ld_a0,a1,0
la_br &byte_digit_value
call
- mov_t0,a0
- add_a3,a3,t0
+ add_a3,a3,a0
la_a1 &p1b_acc
st_a3,a1,0
la_br &p1b_bump
b
:p1b_bin
+ la_a1 &p1b_acc
+ ld_t0,a1,0
+ shli_a3,t0,1
la_a1 &p1b_c
ld_a0,a1,0
li_t1 %48 %0
sub_a0,a0,t1
- la_a1 &p1b_acc
- ld_t0,a1,0
- shli_a3,t0,1
- mov_t0,a0
- add_a3,a3,t0
+ add_a3,a3,a0
la_a1 &p1b_acc
st_a3,a1,0
:p1b_bump
@@ -1573,37 +1322,27 @@ DEFINE OFF_labels 0048000009800000
la_a1 &p1b_have
ld_t0,a1,0
la_br &p1b_loop
- la_a3 &aux_tmp
- st_a0,a3,0
- ld_t1,a3,0
- bne_t0,t1
- # Got a full byte; record into *p1b_out and mark done.
+ bne_t0,a0
+ # got full byte: write to *out_addr and return
la_a1 &p1b_acc
- ld_t2,a1,0
- andi_a3,t2,255
- la_a0 &p1b_out
- ld_a0,a0,0
- sb_a3,a0,0
- li_t0 %1 %0
- la_a1 &p1b_done
- st_t0,a1,0
- la_br &p1b_loop
- b
-:p1b_finish
- la_a1 &p1b_done
- ld_t0,a1,0
- la_br &err_byte_lit_bad
- beqz_t0
- la_a1 &p1b_have
- ld_t0,a1,0
+ ld_a0,a1,0
+ andi_a0,a0,255
+ la_a1 &p1b_out
+ ld_a1,a1,0
+ sb_a0,a1,0
+ eret
+:p1b_done
+ la_a0 &p1b_have
+ ld_t0,a0,0
la_br &err_byte_lit_bad
bnez_t0
- eret
+ la_br &err_byte_lit_bad
+ b
## --- Label table -----------------------------------------------------------
## intern(a0=src, a1=len) -> a0=offset into text_buf. Copies bytes plus a
-## NUL terminator. Fatal on overflow.
+## NUL terminator.
:intern
enter_0
la_a2 &intern_src
@@ -1615,22 +1354,17 @@ DEFINE OFF_labels 0048000009800000
la_a2 &intern_orig
st_a3,a2,0
# if (text_used + len + 1 > TEXT_CAP) fatal
- add_a2,a1,a3 # a2 = a1 + a3 = len + text_used
+ add_a2,a3,a1
addi_a2,a2,1
li_t0 H2_TEXT_CAP
la_br &err_text_overflow
- mov_t1,a0
- blt_t0,t1
- # dst = text_buf + text_used. There's no add_a0,a0,a3 in the seed,
- # so route the offset through t0.
+ blt_t0,a2
+ # dst = text_buf + text_used
la_a0 &text_buf_ptr
ld_a0,a0,0
- la_a2 &intern_orig
- ld_t0,a2,0
- add_a0,a0,t0
+ add_a0,a0,a3
la_a2 &intern_dst
st_a0,a2,0
- # copy len bytes
li_t0 %0 %0
la_a1 &intern_i
st_t0,a1,0
@@ -1655,12 +1389,12 @@ DEFINE OFF_labels 0048000009800000
la_br &intern_copy_loop
b
:intern_copy_done
- # NUL terminator at dst[len]
+ # NUL terminator
la_a2 &intern_dst
ld_a2,a2,0
la_a1 &intern_len
ld_t0,a1,0
- add_a2,a2,t0 # available add_a2,a2,t0
+ add_a2,a2,t0
li_t1 %0 %0
sb_t1,a2,0
# text_used += len + 1
@@ -1671,33 +1405,20 @@ DEFINE OFF_labels 0048000009800000
add_a3,a3,a1
addi_a3,a3,1
st_a3,a2,0
- # return original text_used
la_a0 &intern_orig
ld_a0,a0,0
eret
-## label_addr(a0=index) -> a0 = &labels[index]. Leaf. labels are 32 B.
-## Result is shipped through la_const_32 since neither mov_a0,a2 nor an
-## add_a0,a*,t* combo with the right operands exists in the seed table.
+## label_addr(a0=index) -> a0 = &labels[index]. Each label is 32 B.
:label_addr
- mov_t0,a0
- la_a3 &la_const_32
- li_t1 %32 %0
- st_t1,a3,0
- la_a1 &aux_tmp
- st_a3,a1,0
+ li_t0 %32 %0
+ mul_a0,a0,t0
+ la_a1 &labels_ptr
ld_a1,a1,0
- mul_t0,t0,a1 # t0 = 32 * index
- la_a2 &labels_ptr
- ld_a2,a2,0
- add_a2,a2,t0 # a2 = labels + 32*index
- la_a3 &la_const_32
- st_a2,a3,0 # spill result
- ld_a0,a3,0 # reload into a0
+ add_a0,a0,a1
ret
-## name_eq(a0=label_addr, a1=src, a2=len) -> a0=0/1. Compares the label's
-## interned name against (src, len). Leaf-ish (calls mem_eq).
+## name_eq(a0=label_ptr, a1=src, a2=len) -> a0=0/1.
:name_eq
enter_0
la_a3 &ne_label
@@ -1709,18 +1430,14 @@ DEFINE OFF_labels 0048000009800000
# if (label->name_len != len) return 0
ld_t0,a0,8
la_br &ne_no
- la_a3 &aux_tmp
- st_a2,a3,0
- ld_t1,a3,0
- bne_t0,t1
- # bytes
- ld_a3,a0,0 # name_off
+ bne_t0,a2
+ # bytes equal?
+ la_a0 &ne_label
+ ld_a0,a0,0
+ ld_a3,a0,0
la_a0 &text_buf_ptr
ld_a0,a0,0
- la_a2 &ne_tmp
- st_a3,a2,0
- ld_t0,a2,0
- add_a0,a0,t0
+ add_a0,a0,a3
la_a1 &ne_src
ld_a1,a1,0
la_a2 &ne_len
@@ -1732,8 +1449,7 @@ DEFINE OFF_labels 0048000009800000
li_a0 %0 %0
eret
-## define_label(a0=src, a1=len, a2=scope_id): record at labels[label_count].
-## Fatal on duplicate (within same scope) or overflow.
+## define_label(a0=src, a1=len, a2=scope_id).
:define_label
enter_0
la_a3 &dl_src
@@ -1742,7 +1458,6 @@ DEFINE OFF_labels 0048000009800000
st_a1,a3,0
la_a3 &dl_scope
st_a2,a3,0
-
li_t0 %0 %0
la_a0 &dl_i
st_t0,a0,0
@@ -1756,15 +1471,10 @@ DEFINE OFF_labels 0048000009800000
mov_a0,t0
la_br &label_addr
call
- # a0 = &labels[i]
la_a3 &dl_label
st_a0,a3,0
# scope match?
- mov_a1,a0
- mov_a2,a1
- addi_a2,a2,24
- ld_a0,a2,0
- mov_t0,a0
+ ld_t0,a0,24
la_a1 &dl_scope
ld_t1,a1,0
la_br &dl_dup_next
@@ -1790,7 +1500,6 @@ DEFINE OFF_labels 0048000009800000
la_br &dl_dup_loop
b
:dl_dup_done
-
la_a0 &label_count
ld_t0,a0,0
li_t1 H2_LABEL_CAP
@@ -1798,7 +1507,6 @@ DEFINE OFF_labels 0048000009800000
beq_t0,t1
la_br &err_too_many_labels
blt_t1,t0
-
# name_off = intern(src, len)
la_a0 &dl_src
ld_a0,a0,0
@@ -1808,7 +1516,6 @@ DEFINE OFF_labels 0048000009800000
call
la_a3 &dl_name_off
st_a0,a3,0
-
# &labels[label_count]
la_a0 &label_count
ld_a0,a0,0
@@ -1820,14 +1527,10 @@ DEFINE OFF_labels 0048000009800000
la_a1 &dl_name_off
ld_t0,a1,0
st_t0,a0,0
- # name_len: st_t0,a0,8 is missing from the seed; the equivalent
- # st_t0,a3,8 IS available, so move the base to a3 first via the
- # dl_label scratch slot.
- la_a3 &dl_label
- ld_a3,a3,0
+ # name_len
la_a1 &dl_len
ld_t0,a1,0
- st_t0,a3,8
+ st_t0,a0,8
# target_ip
la_a1 &ip
ld_t0,a1,0
@@ -1843,26 +1546,20 @@ DEFINE OFF_labels 0048000009800000
st_t0,a0,0
eret
-## lookup_label(a0=src, a1=len) -> a0=target_ip. Fatal on undefined.
+## lookup_label(a0=src, a1=len) -> a0=target_ip.
:lookup_label
enter_0
la_a2 &ll_src
st_a0,a2,0
la_a2 &ll_len
st_a1,a2,0
- la_a3 &aux_tmp
- st_a0,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
- ld_t0,a0,0
- lb_t0,t0,0
+ # dotted? (first byte == '.' AND scope_depth > 0)
+ lb_t0,a0,0
li_t1 %46 %0
la_br &ll_undotted
bne_t0,t1
- # Dotted but only meaningful inside a .scope; otherwise fall through
- # to the global-name lookup.
- la_a0 &scope_depth
- ld_t0,a0,0
+ la_a3 &scope_depth
+ ld_t0,a3,0
la_br &ll_undotted
beqz_t0
addi_t0,t0,neg1
@@ -1871,16 +1568,13 @@ DEFINE OFF_labels 0048000009800000
:ll_dot_outer
la_a0 &ll_d
ld_t0,a0,0
- la_br &ll_undefined_local
+ la_br &err_undefined_local
bltz_t0
la_a1 &scope_stack_ptr
ld_a1,a1,0
shli_t2,t0,3
- la_a3 &ll_tmp
- st_t2,a3,0
- ld_t1,a3,0
- add_a1,a1,t1
- ld_t1,a1,0 # t1 = sid
+ add_a1,a1,t2
+ ld_t1,a1,0
la_a0 &ll_sid
st_t1,a0,0
li_t0 %0 %0
@@ -1898,11 +1592,7 @@ DEFINE OFF_labels 0048000009800000
call
la_a3 &ll_label
st_a0,a3,0
- mov_a1,a0
- mov_a2,a1
- addi_a2,a2,24
- ld_a0,a2,0
- mov_t0,a0
+ ld_t0,a0,24
la_a1 &ll_sid
ld_t1,a1,0
la_br &ll_dot_inner_next
@@ -1919,7 +1609,7 @@ DEFINE OFF_labels 0048000009800000
beqz_a0
la_a0 &ll_label
ld_a0,a0,0
- ld_a0,a0,16 # target_ip
+ ld_a0,a0,16
eret
:ll_dot_inner_next
la_a0 &ll_i
@@ -1945,18 +1635,14 @@ DEFINE OFF_labels 0048000009800000
ld_t0,a0,0
la_a1 &label_count
ld_t1,a1,0
- la_br &ll_undefined_global
+ la_br &err_undefined_label
beq_t0,t1
mov_a0,t0
la_br &label_addr
call
la_a3 &ll_label
st_a0,a3,0
- mov_a1,a0
- mov_a2,a1
- addi_a2,a2,24
- ld_a0,a2,0
- mov_t0,a0
+ ld_t0,a0,24
la_br &ll_undotted_next
bnez_t0
la_a0 &ll_label
@@ -1980,23 +1666,15 @@ DEFINE OFF_labels 0048000009800000
st_t0,a0,0
la_br &ll_undotted_loop
b
-:ll_undefined_local
- la_br &err_undefined_local
- b
-:ll_undefined_global
- la_br &err_undefined_label
- b
-
-## --- Reference processor ----------------------------------------------------
-## process_reference(): cur_sigil already set by the dispatcher; scan_pos
-## already past the sigil byte. Reads label and (optional) -other,
-## advances ip on pass 1, and emits the resolved value on pass 2.
+## --- Reference processor ---------------------------------------------------
+## process_reference(): cur_sigil already set; scan_pos already past sigil.
+## Reads label and (optional) -other, advances ip on pass 1, emits on pass 2.
:process_reference
enter_0
la_br &set_sigil_info
call
- # Require non-terminator.
+ # require non-terminator (label name follows)
la_a0 &scan_pos
ld_t0,a0,0
la_a1 &scan_end
@@ -2006,7 +1684,7 @@ DEFINE OFF_labels 0048000009800000
la_br &err_sigil_no_label
blt_t1,t0
lb_a0,t0,0
- la_br &is_name_terminator_c
+ la_br &is_name_terminator
call
la_br &err_sigil_no_label
bnez_a0
@@ -2021,8 +1699,7 @@ DEFINE OFF_labels 0048000009800000
li_t0 %0 %0
la_a0 &pr_has_other
st_t0,a0,0
- # Optional separator (- or >) followed by OTHER. '>' is a synonym
- # for '-', accepted for hex2 compatibility.
+ # optional '-' or '>' OTHER
la_a0 &scan_pos
ld_t0,a0,0
la_a1 &scan_end
@@ -2032,19 +1709,19 @@ DEFINE OFF_labels 0048000009800000
la_br &pr_after_other
blt_t1,t0
lb_a0,t0,0
- li_t1 %45 %0 # '-'
+ li_t1 %45 %0
la_br &pr_consume_sep
beq_a0,t1
- li_t1 %62 %0 # '>'
+ li_t1 %62 %0
la_br &pr_consume_sep
beq_a0,t1
la_br &pr_after_other
b
:pr_consume_sep
- la_a1 &scan_pos
- ld_t0,a1,0
+ la_a0 &scan_pos
+ ld_t0,a0,0
addi_t0,t0,1
- st_t0,a1,0
+ st_t0,a0,0
la_a1 &scan_end
ld_t1,a1,0
la_br &err_minus_no_label
@@ -2052,7 +1729,7 @@ DEFINE OFF_labels 0048000009800000
la_br &err_minus_no_label
blt_t1,t0
lb_a0,t0,0
- la_br &is_name_terminator_c
+ la_br &is_name_terminator
call
la_br &err_minus_no_label
bnez_a0
@@ -2072,17 +1749,11 @@ DEFINE OFF_labels 0048000009800000
li_t1 %1 %0
la_br &pr_pass2
bne_t0,t1
- # ip += pr_width. Route width through t2 since add_t1,t1,t* (t* in
- # {t0,t2}) is the only fitting form in the seed.
+ # ip += pr_width
la_a0 &ip
ld_t1,a0,0
la_a1 &pr_width
- ld_t0,a1,0
- la_a3 &pr_tmp
- st_t0,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
- ld_t2,a0,0
+ ld_t2,a1,0
add_t1,t1,t2
st_t1,a0,0
eret
@@ -2105,16 +1776,11 @@ DEFINE OFF_labels 0048000009800000
ld_a1,a1,0
la_br &lookup_label
call
- la_a1 &pr_t_other
- st_a0,a1,0
- # value = t_label - t_other
- la_a0 &pr_t_label
- ld_a1,a0,0
- la_a0 &pr_t_other
- ld_a0,a0,0
- sub_a2,a1,a0 # available: a2 = a1 - a0
+ la_a1 &pr_t_label
+ ld_a1,a1,0
+ sub_a0,a1,a0
la_a1 &pr_value
- st_a2,a1,0
+ st_a0,a1,0
la_br &pr_emit
b
:pr_no_other
@@ -2125,20 +1791,14 @@ DEFINE OFF_labels 0048000009800000
# rel: value = t_label - (ip + width)
la_a0 &ip
ld_a1,a0,0
- la_a3 &pr_tmp
la_a0 &pr_width
ld_t0,a0,0
- st_t0,a3,0
- ld_a0,a3,0 # a0 = width
- add_a1,a1,a0 # add_a1,a1,a0 — available
- la_a3 &pr_tmp
- st_a1,a3,0 # save (ip + width)
+ add_a1,a1,t0
la_a0 &pr_t_label
- ld_a1,a0,0 # a1 = t_label
- ld_a0,a3,0 # a0 = ip+width
- sub_a2,a1,a0
+ ld_a0,a0,0
+ sub_a0,a0,a1
la_a1 &pr_value
- st_a2,a1,0
+ st_a0,a1,0
la_br &pr_emit
b
:pr_abs
@@ -2151,8 +1811,6 @@ DEFINE OFF_labels 0048000009800000
la_a3 &pr_value
st_a1,a3,0
:pr_emit
- la_a0 &pr_value
- ld_a0,a0,0
la_a1 &pr_width
ld_a1,a1,0
la_a2 &pr_lo
@@ -2161,7 +1819,6 @@ DEFINE OFF_labels 0048000009800000
ld_a3,a3,0
la_a0 &pr_range_check
ld_t0,a0,0
- # Reload value into a0 since we just clobbered it.
la_a0 &pr_value
ld_a0,a0,0
la_br &emit_value
@@ -2170,14 +1827,6 @@ DEFINE OFF_labels 0048000009800000
## set_sigil_info(): reads cur_sigil; populates pr_width / pr_is_rel /
## pr_lo / pr_hi / pr_range_check.
-##
-## Sigil table:
-## '!' (0x21): width=1, rel, lo=-128, hi=127, check
-## '@' (0x40): width=2, rel, lo=-32768, hi=32767, check
-## '$' (0x24): width=2, abs, lo=0, hi=65535, check
-## '~' (0x7E): width=3, rel, lo=-(1<<23), hi=(1<<23)-1, check
-## '%' (0x25): width=4, rel, no range check
-## '&' (0x26): width=4, abs, no range check
:set_sigil_info
enter_0
la_a0 &cur_sigil
@@ -2210,15 +1859,11 @@ DEFINE OFF_labels 0048000009800000
st_t0,a1,0
la_a1 &pr_range_check
st_t0,a1,0
- # lo = -128 = 0 - 128
li_t0 %128 %0
- la_a3 &ssi_tmp
- st_t0,a3,0
- ld_a3,a3,0 # a3 = 128
- li_t0 %0 %0
- sub_a3,t0,a3 # available: a3 = t0 - a3 = -128
+ li_t1 %0 %0
+ sub_t0,t1,t0
la_a1 &pr_lo
- st_a3,a1,0
+ st_t0,a1,0
li_t0 %127 %0
la_a1 &pr_hi
st_t0,a1,0
@@ -2232,28 +1877,17 @@ DEFINE OFF_labels 0048000009800000
st_t0,a1,0
la_a1 &pr_range_check
st_t0,a1,0
- # 32768 = 256 * 128. The seed has no immediate >= 256 in li_t* (it
- # does, since li_t0 takes a 64-bit value, but we use the available
- # %256 word literal). Stage values through ssi_tmp before each ld.
+ # 32768 = 256 * 128
li_t0 %256 %0
- la_a1 &ssi_tmp
- st_t0,a1,0
- ld_a3,a1,0 # a3 = 256
- li_t0 %128 %0
- st_t0,a1,0
- ld_a2,a1,0 # a2 = 128
- mul_a3,a3,a2 # a3 = 32768
- la_a1 &ssi_tmp2
- st_a3,a1,0
- li_t0 %0 %0
- sub_a3,t0,a3 # a3 = -32768
+ li_t1 %128 %0
+ mul_t0,t0,t1
+ li_t1 %0 %0
+ sub_t1,t1,t0
la_a1 &pr_lo
- st_a3,a1,0
- la_a1 &ssi_tmp2
- ld_t1,a1,0
- addi_t1,t1,neg1 # 32767
- la_a1 &pr_hi
st_t1,a1,0
+ addi_t0,t0,neg1
+ la_a1 &pr_hi
+ st_t0,a1,0
eret
:ssi_dollar
li_t0 %2 %0
@@ -2270,17 +1904,11 @@ DEFINE OFF_labels 0048000009800000
st_t0,a1,0
# 65536 = 256 * 256
li_t0 %256 %0
- la_a1 &ssi_tmp
- st_t0,a1,0
- ld_a3,a1,0
- ld_a2,a1,0
- mul_a3,a3,a2 # a3 = 65536
- la_a1 &ssi_tmp2
- st_a3,a1,0
- ld_t1,a1,0
- addi_t1,t1,neg1 # 65535
+ mov_t1,t0
+ mul_t0,t0,t1
+ addi_t0,t0,neg1
la_a1 &pr_hi
- st_t1,a1,0
+ st_t0,a1,0
eret
:ssi_tilde
li_t0 %3 %0
@@ -2289,30 +1917,21 @@ DEFINE OFF_labels 0048000009800000
li_t0 %1 %0
la_a1 &pr_is_rel
st_t0,a1,0
- la_a1 &pr_range_check
- st_t0,a1,0
- # 8388608 = 256 * 256 * 128
- li_t0 %256 %0
- la_a1 &ssi_tmp
- st_t0,a1,0
- ld_a3,a1,0
- ld_a2,a1,0
- mul_a3,a3,a2 # 65536
- li_t0 %128 %0
- st_t0,a1,0
- ld_a2,a1,0
- mul_a3,a3,a2 # 8388608
- la_a1 &ssi_tmp2
- st_a3,a1,0
- li_t0 %0 %0
- sub_a3,t0,a3 # -8388608
+ la_a1 &pr_range_check
+ st_t0,a1,0
+ # 8388608 = 256 * 256 * 128
+ li_t0 %256 %0
+ mov_t1,t0
+ mul_t0,t0,t1
+ li_t1 %128 %0
+ mul_t0,t0,t1
+ li_t1 %0 %0
+ sub_t1,t1,t0
la_a1 &pr_lo
- st_a3,a1,0
- la_a1 &ssi_tmp2
- ld_t1,a1,0
- addi_t1,t1,neg1 # 8388607
- la_a1 &pr_hi
st_t1,a1,0
+ addi_t0,t0,neg1
+ la_a1 &pr_hi
+ st_t0,a1,0
eret
:ssi_pct
la_a0 &ptrsize
@@ -2322,7 +1941,6 @@ DEFINE OFF_labels 0048000009800000
li_t0 %1 %0
la_a1 &pr_is_rel
st_t0,a1,0
- li_t0 %1 %0
la_a1 &ptrsize_used
st_t0,a1,0
li_t0 %0 %0
@@ -2352,10 +1970,9 @@ DEFINE OFF_labels 0048000009800000
st_t0,a1,0
eret
-## --- Directives -------------------------------------------------------------
+## --- Directives ------------------------------------------------------------
-## do_align(): .align N [PATTERN]. N is a positive power of two; optional
-## byte-mode pattern. Pads with zeros if no pattern.
+## do_align(): .align N [PATTERN]. N positive power of two; optional pattern.
:do_align
enter_0
la_br &skip_inline_ws
@@ -2368,26 +1985,22 @@ DEFINE OFF_labels 0048000009800000
beqz_a0
la_br &err_align_n
bltz_a0
- # Power-of-two check: N & (N-1) == 0
+ # power-of-two: N & (N-1) == 0
la_a0 &da_n
ld_a3,a0,0
+ addi_a3,a3,neg1
la_a0 &da_n
ld_a2,a0,0
- addi_a2,a2,neg1
and_a3,a3,a2
la_br &err_align_n
- mov_a0,a3
- bnez_a0
-
+ bnez_a3
li_t0 %0 %0
la_a0 &da_has_pat
st_t0,a0,0
la_a0 &da_patlen
st_t0,a0,0
-
la_br &skip_inline_ws
call
-
la_a0 &scan_pos
ld_t0,a0,0
la_a1 &scan_end
@@ -2440,17 +2053,13 @@ DEFINE OFF_labels 0048000009800000
ld_a0,a0,0
la_a1 &da_n
ld_a1,a1,0
- rem_a2,a0,a1 # a2 = ip mod N
+ rem_a2,a0,a1
li_t0 %0 %0
la_a3 &da_pad
st_t0,a3,0
la_br &da_emit
beqz_a2
- # pad = N - r
- la_a3 &da_pad
- st_a1,a3,0 # store N
- ld_a3,a3,0 # a3 = N
- sub_a3,a3,a2 # a3 = N - r
+ sub_a3,a1,a2
la_a1 &da_pad
st_a3,a1,0
:da_emit
@@ -2496,7 +2105,7 @@ DEFINE OFF_labels 0048000009800000
:da_emit_done
eret
-## do_fill(): .fill N B. N >= 0 decimal; B is one byte literal.
+## do_fill(): .fill N B.
:do_fill
enter_0
la_br &skip_inline_ws
@@ -2554,16 +2163,25 @@ DEFINE OFF_labels 0048000009800000
la_a1 &scope_stack_ptr
ld_a1,a1,0
shli_t2,t0,3
- add_a1,t2,a1 # available
+ add_a1,a1,t2
st_t1,a1,0
addi_t0,t0,1
la_a0 &scope_depth
st_t0,a0,0
eret
-## do_ptrsize(): .ptrsize N -- N must be 4 or 8. Whole-invocation: the
-## first directive (or first '&'/'%' use) binds the width; later ones
-## must match the bound value.
+## do_scope_close(): scope_depth--.
+:do_scope_close
+ enter_0
+ la_a0 &scope_depth
+ ld_t0,a0,0
+ la_br &err_scope_underflow
+ beqz_t0
+ addi_t0,t0,neg1
+ st_t0,a0,0
+ eret
+
+## do_ptrsize(): .ptrsize N -- N must be 4 or 8.
:do_ptrsize
enter_0
la_br &skip_inline_ws
@@ -2572,17 +2190,15 @@ DEFINE OFF_labels 0048000009800000
call
la_a1 &dp_n
st_a0,a1,0
- # Validate N in {4, 8}
li_t0 %4 %0
- la_br &dp_ok_value
+ la_br &dp_ok
beq_a0,t0
li_t0 %8 %0
- la_br &dp_ok_value
+ la_br &dp_ok
beq_a0,t0
la_br &err_ptrsize_bad
b
-:dp_ok_value
- # If a '&'/'%' has already used ptrsize, N must equal current ptrsize.
+:dp_ok
la_a0 &ptrsize_used
ld_t0,a0,0
la_br &dp_set
@@ -2601,26 +2217,14 @@ DEFINE OFF_labels 0048000009800000
st_t0,a1,0
eret
-## do_scope_close(): scope_depth--; fatal if not in scope.
-:do_scope_close
- enter_0
- la_a0 &scope_depth
- ld_t0,a0,0
- la_br &err_scope_underflow
- beqz_t0
- addi_t0,t0,neg1
- st_t0,a0,0
- eret
-
-## --- Emit -------------------------------------------------------------------
+## --- Emit ------------------------------------------------------------------
## emit_byte(a0=byte): pass 1 only bumps ip; pass 2 also writes to output_buf.
-## Leaf.
:emit_byte
la_a1 &pass
ld_t0,a1,0
li_t1 %2 %0
- la_br &eb_pass1
+ la_br &eb_after_write
bne_t0,t1
la_a1 &output_used
ld_t0,a1,0
@@ -2635,30 +2239,25 @@ DEFINE OFF_labels 0048000009800000
sb_a0,a2,0
addi_t0,t0,1
st_t0,a1,0
-:eb_pass1
+:eb_after_write
la_a0 &ip
ld_t0,a0,0
addi_t0,t0,1
st_t0,a0,0
ret
-## emit_value(a0=value, a1=width, a2=lo, a3=hi, t0=range_check). Range-checks
-## (if requested), packs little-endian into ev_bytes[0..width-1], then emits
-## (in reverse order if big_endian).
+## emit_value(a0=value, a1=width, a2=lo, a3=hi, t0=range_check). Range-checks,
+## packs little-endian into ev_bytes[0..width-1], emits in LE/BE order.
:emit_value
enter_0
la_t1 &ev_value
- mov_t2,t1
- st_a0,t2,0
+ st_a0,t1,0
la_t1 &ev_width
st_a1,t1,0
la_t1 &ev_lo
st_a2,t1,0
la_t1 &ev_hi
- la_a0 &aux_tmp
- st_t1,a0,0
- ld_a0,a0,0
- st_a3,a0,0
+ st_a3,t1,0
la_t1 &ev_range_check
st_t0,t1,0
@@ -2671,8 +2270,7 @@ DEFINE OFF_labels 0048000009800000
la_a1 &ev_lo
ld_a1,a1,0
la_br &err_ref_out_of_range
- mov_a2,a1
- blt_a0,a2
+ blt_a0,a1
la_a0 &ev_value
ld_a0,a0,0
la_a1 &ev_hi
@@ -2695,8 +2293,8 @@ DEFINE OFF_labels 0048000009800000
la_br &ev_emit_dispatch
beq_t0,t1
la_a1 &ev_pack_v
- ld_t2,a1,0
- andi_a3,t2,255
+ ld_a3,a1,0
+ andi_a3,a3,255
la_a2 &ev_bytes_ptr
ld_a2,a2,0
add_a2,a2,t0
@@ -2728,10 +2326,7 @@ DEFINE OFF_labels 0048000009800000
la_a2 &ev_bytes_ptr
ld_a2,a2,0
add_a2,a2,t0
- la_a3 &aux_tmp
- st_a2,a3,0
- ld_a0,a3,0
- lb_a0,a0,0
+ lb_a0,a2,0
la_br &emit_byte
call
la_a0 &ev_i
@@ -2754,10 +2349,7 @@ DEFINE OFF_labels 0048000009800000
la_a2 &ev_bytes_ptr
ld_a2,a2,0
add_a2,a2,t0
- la_a3 &aux_tmp
- st_a2,a3,0
- ld_a0,a3,0
- lb_a0,a0,0
+ lb_a0,a2,0
la_br &emit_byte
call
la_a0 &ev_i
@@ -2769,10 +2361,63 @@ DEFINE OFF_labels 0048000009800000
:ev_done
eret
-## --- Misc helpers -----------------------------------------------------------
+## --- Output writer ---------------------------------------------------------
+:write_output
+ enter_0
+ la_a0 &output_path
+ ld_a2,a0,0
+ li_a0 sys_openat
+ li_a1 H2_AT_FDCWD
+ li_a3 H2_O_WRONLY_CREAT_TRUNC
+ la_t1 &non_executable
+ ld_t1,t1,0
+ la_br &wo_mode_nonexec
+ bnez_t1
+ li_t0 H2_MODE_0750
+ la_br &wo_after_mode
+ b
+:wo_mode_nonexec
+ li_t0 H2_MODE_0640
+:wo_after_mode
+ syscall
+ la_br &err_open_output
+ bltz_a0
+ la_a1 &output_fd
+ st_a0,a1,0
+ li_t0 %0 %0
+ la_a1 &output_written
+ st_t0,a1,0
+:wo_loop
+ la_a0 &output_written
+ ld_t0,a0,0
+ la_a1 &output_used
+ ld_t1,a1,0
+ la_br &wo_done
+ beq_t0,t1
+ la_a0 &output_fd
+ ld_a1,a0,0
+ la_a2 &output_buf_ptr
+ ld_a2,a2,0
+ add_a2,a2,t0
+ sub_a3,t1,t0
+ li_a0 sys_write
+ syscall
+ la_br &err_write
+ bltz_a0
+ la_br &err_write
+ beqz_a0
+ la_a1 &output_written
+ ld_t0,a1,0
+ add_t0,t0,a0
+ st_t0,a1,0
+ la_br &wo_loop
+ b
+:wo_done
+ eret
+
+## --- Misc helpers ----------------------------------------------------------
-## str_eq(a0=p, a1=q, a2=len) -> a0=0/1. Returns 1 iff p[0..len-1] == q[..]
-## AND p[len] == '\0'. Used for argv string compares.
+## str_eq(a0=p, a1=q, a2=len) -> a0=0/1. len bytes equal AND p[len]==NUL.
:str_eq
enter_0
la_t0 &se_p
@@ -2790,18 +2435,13 @@ DEFINE OFF_labels 0048000009800000
la_a0 &se_p
ld_a0,a0,0
add_a0,a0,t1
- lb_a0,a0,0
+ lb_t0,a0,0
la_a2 &se_q
ld_a2,a2,0
add_a2,a2,t1
- lb_a2,a2,0
+ lb_t2,a2,0
la_br &se_no
- la_a3 &aux_tmp
- st_a2,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
- ld_t0,a0,0
- bne_a0,t0
+ bne_t0,t2
addi_t1,t1,1
la_br &se_loop
b
@@ -2809,16 +2449,16 @@ DEFINE OFF_labels 0048000009800000
la_a0 &se_p
ld_a0,a0,0
add_a0,a0,t1
- lb_a0,a0,0
+ lb_t0,a0,0
la_br &se_no
- bnez_a0
+ bnez_t0
li_a0 %1 %0
eret
:se_no
li_a0 %0 %0
eret
-## mem_eq(a0=p, a1=q, a2=len) -> a0=0/1. Plain byte compare, no NUL check.
+## mem_eq(a0=p, a1=q, a2=len) -> a0=0/1.
:mem_eq
enter_0
la_t0 &me_p
@@ -2836,18 +2476,13 @@ DEFINE OFF_labels 0048000009800000
la_a0 &me_p
ld_a0,a0,0
add_a0,a0,t1
- lb_a0,a0,0
+ lb_t0,a0,0
la_a2 &me_q
ld_a2,a2,0
add_a2,a2,t1
- lb_a2,a2,0
+ lb_t2,a2,0
la_br &me_no
- la_a3 &aux_tmp
- st_a2,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
- ld_t0,a0,0
- bne_a0,t0
+ bne_t0,t2
addi_t1,t1,1
la_br &me_loop
b
@@ -2858,104 +2493,104 @@ DEFINE OFF_labels 0048000009800000
li_a0 %0 %0
eret
-## parse_long_arg(a0=str): parse decimal or 0x-prefixed hex i64. Fatal on
-## malformed.
-:parse_long_arg
+## parse_long(a0=cstr) -> a0=value. Decimal or 0x-prefixed hex i64.
+:parse_long
enter_0
- la_t0 &pla_p
+ la_t0 &pl_p
st_a0,t0,0
li_t0 %0 %0
- la_a1 &pla_val
+ la_a1 &pl_val
st_t0,a1,0
- la_a1 &pla_neg
+ la_a1 &pl_neg
st_t0,a1,0
- # detect 0x / 0X
- la_a0 &pla_p
+ # 0x / 0X prefix?
+ la_a0 &pl_p
ld_a0,a0,0
- la_a3 &aux_tmp
- st_a0,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
- ld_t0,a0,0
- lb_t0,t0,0
+ lb_t0,a0,0
li_t1 %48 %0
- la_br &pla_dec_init
+ la_br &pl_dec_init
bne_t0,t1
- la_a3 &aux_tmp
- st_a0,a3,0
- ld_a3,a3,0
- lb_t0,a3,1
+ lb_t0,a0,1
li_t1 %120 %0
- la_br &pla_hex_init
+ la_br &pl_hex_init
beq_t0,t1
li_t1 %88 %0
- la_br &pla_hex_init
+ la_br &pl_hex_init
beq_t0,t1
- la_br &pla_dec_init
+ la_br &pl_dec_init
b
-:pla_hex_init
- la_a0 &pla_p
+:pl_hex_init
+ la_a0 &pl_p
ld_t0,a0,0
- addi_t0,t0,2 # skip "0x" / "0X"
+ addi_t0,t0,2
st_t0,a0,0
-:pla_hex_loop
- la_a0 &pla_p
- ld_a0,a0,0
- la_a3 &aux_tmp
- st_a0,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
+:pl_hex_loop
+ la_a0 &pl_p
ld_t0,a0,0
lb_t0,t0,0
- la_br &pla_finish
+ la_br &pl_finish
beqz_t0
- la_a3 &pla_tmp
- st_t0,a3,0
- ld_a0,a3,0 # a0 = c
+ # accept '0'..'9' / 'A'..'F' / 'a'..'f'; reject anything else
+ li_t1 %48 %0
+ la_br &err_bad_long
+ blt_t0,t1
+ li_t1 %57 %0
+ la_br &pl_hex_acc
+ blt_t0,t1
+ la_br &pl_hex_acc
+ beq_t0,t1
+ li_t1 %65 %0
+ la_br &err_bad_long
+ blt_t0,t1
+ li_t1 %70 %0
+ la_br &pl_hex_acc
+ blt_t0,t1
+ la_br &pl_hex_acc
+ beq_t0,t1
+ li_t1 %97 %0
+ la_br &err_bad_long
+ blt_t0,t1
+ li_t1 %102 %0
+ la_br &pl_hex_acc
+ blt_t0,t1
+ la_br &pl_hex_acc
+ beq_t0,t1
+ la_br &err_bad_long
+ b
+:pl_hex_acc
+ mov_a0,t0
la_br &byte_digit_value
call
- la_a1 &pla_val
+ la_a1 &pl_val
ld_t0,a1,0
- shli_a3,t0,4 # a3 = val << 4
- mov_t0,a0
- add_a3,a3,t0
- st_a3,a1,0
- la_a0 &pla_p
+ shli_t0,t0,4
+ add_t0,t0,a0
+ st_t0,a1,0
+ la_a0 &pl_p
ld_t0,a0,0
addi_t0,t0,1
st_t0,a0,0
- la_br &pla_hex_loop
+ la_br &pl_hex_loop
b
-:pla_dec_init
- # Optional minus
- la_a0 &pla_p
+:pl_dec_init
+ la_a0 &pl_p
ld_a0,a0,0
- la_a3 &aux_tmp
- st_a0,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
- ld_t0,a0,0
- lb_t0,t0,0
+ lb_t0,a0,0
li_t1 %45 %0
- la_br &pla_dec_loop
+ la_br &pl_dec_loop
bne_t0,t1
li_t0 %1 %0
- la_a1 &pla_neg
+ la_a1 &pl_neg
st_t0,a1,0
- la_a0 &pla_p
+ la_a0 &pl_p
ld_t0,a0,0
addi_t0,t0,1
st_t0,a0,0
-:pla_dec_loop
- la_a0 &pla_p
- ld_a0,a0,0
- la_a3 &aux_tmp
- st_a0,a3,0
- la_a0 &aux_tmp
- st_a3,a0,0
+:pl_dec_loop
+ la_a0 &pl_p
ld_t0,a0,0
lb_t0,t0,0
- la_br &pla_finish
+ la_br &pl_finish
beqz_t0
li_t1 %48 %0
la_br &err_bad_long
@@ -2963,107 +2598,41 @@ DEFINE OFF_labels 0048000009800000
li_t1 %57 %0
la_br &err_bad_long
blt_t1,t0
- la_a3 &pla_tmp
- li_t1 %10 %0
- st_t1,a3,0
- la_a1 &aux_tmp
- st_a3,a1,0
- ld_a1,a1,0
- la_a2 &pla_val
- ld_t0,a2,0
- mul_t0,t0,a1 # t0 = val * 10
- la_a0 &pla_p
- ld_a0,a0,0
- lb_a0,a0,0
li_t1 %48 %0
- sub_a0,a0,t1
- add_t0,t0,a0
- la_a2 &pla_val
- st_t0,a2,0
- la_a0 &pla_p
+ sub_t0,t0,t1
+ la_a1 &pl_val
+ ld_a2,a1,0
+ li_t1 %10 %0
+ mul_a2,a2,t1
+ add_a2,a2,t0
+ st_a2,a1,0
+ la_a0 &pl_p
ld_t0,a0,0
addi_t0,t0,1
st_t0,a0,0
- la_br &pla_dec_loop
+ la_br &pl_dec_loop
b
-:pla_finish
- la_a1 &pla_neg
+:pl_finish
+ la_a1 &pl_neg
ld_t0,a1,0
- la_br &pla_done
+ la_br &pl_done
beqz_t0
- la_a2 &pla_val
- ld_a3,a2,0
+ la_a1 &pl_val
+ ld_a3,a1,0
li_t0 %0 %0
- sub_a3,t0,a3 # a3 = -val
- st_a3,a2,0
-:pla_done
- la_a1 &pla_val
+ sub_a3,t0,a3
+ st_a3,a1,0
+:pl_done
+ la_a1 &pl_val
ld_a0,a1,0
eret
-## --- Output writer ----------------------------------------------------------
-
-## write_output(): openat(output_path, O_WRONLY|O_CREAT|O_TRUNC, MODE).
-## MODE = 0750 unless --non-executable, then 0640. Then write loop.
-:write_output
- enter_0
- la_a0 &output_path
- ld_a2,a0,0
- li_a0 sys_openat
- li_a1 AT_FDCWD
- li_a3 O_WRONLY_CREAT_TRUNC
- la_t1 &non_executable
- ld_t1,t1,0
- la_br &wo_mode_nonexec
- bnez_t1
- li_t0 MODE_0750
- la_br &wo_after_mode
- b
-:wo_mode_nonexec
- li_t0 MODE_0640
-:wo_after_mode
- syscall
- la_br &err_open_output
- bltz_a0
- la_a1 &output_fd
- st_a0,a1,0
- li_t0 %0 %0
- la_a1 &output_written
- st_t0,a1,0
-:wo_loop
- la_a0 &output_written
- ld_t0,a0,0
- la_a1 &output_used
- ld_t1,a1,0
- la_br &wo_done
- beq_t0,t1
- la_a0 &output_fd
- ld_a1,a0,0
- la_a2 &output_buf_ptr
- ld_a2,a2,0
- add_a2,a2,t0
- sub_a3,t1,t0 # available
- li_a0 sys_write
- syscall
- la_br &err_write
- bltz_a0
- la_br &err_write
- beqz_a0
- la_a1 &output_written
- ld_t0,a1,0
- add_t0,t0,a0
- st_t0,a1,0
- la_br &wo_loop
- b
-:wo_done
- eret
-
-## --- Errors -----------------------------------------------------------------
+## --- Errors ----------------------------------------------------------------
-## fatal_msg(a0=msg_ptr): write either "hex2pp: <msg>\n" or
-## "<path>:<line>: hex2pp: <msg>\n" to stderr, then exit(1).
-:fatal_msg
- la_a1 &err_saved_msg
+## fatal(a0=msg_ptr): writes "<path>:<line>: hex2pp: <msg>\n" to stderr if
+## cur_path is set, else "hex2pp: <msg>\n", then exits 1.
+:fatal
+ la_a1 &fm_msg
st_a0,a1,0
la_a0 &cur_path
ld_t0,a0,0
@@ -3071,32 +2640,32 @@ DEFINE OFF_labels 0048000009800000
beqz_t0
# write path
mov_a0,t0
- la_br &strlen_cstr
+ la_br &cstrlen
call
- la_a2 &err_saved_len
- st_a0,a2,0
+ la_a3 &fm_tmp
+ st_a0,a3,0
la_a2 &cur_path
ld_a2,a2,0
- la_a3 &err_saved_len
+ la_a3 &fm_tmp
ld_a3,a3,0
li_a0 sys_write
li_a1 %2 %0
syscall
- # write ":"
+ # ":"
li_a0 sys_write
li_a1 %2 %0
la_a2 &str_colon
li_a3 %1 %0
syscall
- # write decimal(cur_line)
+ # decimal cur_line
la_a0 &cur_line
ld_a0,a0,0
la_br &write_decimal_stderr
call
- # write ": hex2pp: "
+ # ": hex2pp: "
li_a0 sys_write
li_a1 %2 %0
- la_a2 &str_colon_hex2pp
+ la_a2 &str_colon_prog
li_a3 %10 %0
syscall
la_br &fm_emit_msg
@@ -3104,19 +2673,19 @@ DEFINE OFF_labels 0048000009800000
:fm_no_path
li_a0 sys_write
li_a1 %2 %0
- la_a2 &str_hex2pp
+ la_a2 &str_prog
li_a3 %8 %0
syscall
:fm_emit_msg
- la_a0 &err_saved_msg
+ la_a0 &fm_msg
ld_a0,a0,0
- la_br &strlen_cstr
+ la_br &cstrlen
call
- la_a2 &err_saved_len
- st_a0,a2,0
- la_a2 &err_saved_msg
+ la_a3 &fm_tmp
+ st_a0,a3,0
+ la_a2 &fm_msg
ld_a2,a2,0
- la_a3 &err_saved_len
+ la_a3 &fm_tmp
ld_a3,a3,0
li_a0 sys_write
li_a1 %2 %0
@@ -3130,23 +2699,22 @@ DEFINE OFF_labels 0048000009800000
li_a1 %1 %0
syscall
-## strlen_cstr(a0=p) -> a0=length. Walks until NUL.
-:strlen_cstr
+## cstrlen(a0=p) -> a0=length. Walks until NUL.
+:cstrlen
li_t0 %0 %0
-:sl_loop
- add_t1,a0,t0 # available
+:cs_loop
+ add_t1,a0,t0
lb_t1,t1,0
- la_br &sl_done
+ la_br &cs_done
beqz_t1
addi_t0,t0,1
- la_br &sl_loop
+ la_br &cs_loop
b
-:sl_done
+:cs_done
mov_a0,t0
ret
## write_decimal_stderr(a0=value): write decimal of unsigned i64 to stderr.
-## Special-cases zero. Uses line_scratch (64 B) as a reverse-fill buffer.
:write_decimal_stderr
enter_0
la_a1 &wd_v
@@ -3160,7 +2728,6 @@ DEFINE OFF_labels 0048000009800000
syscall
eret
:wd_nonzero
- # Render reversed into line_scratch[...], starting near the end.
li_t0 %63 %0
la_a1 &wd_pos
st_t0,a1,0
@@ -3169,18 +2736,13 @@ DEFINE OFF_labels 0048000009800000
ld_a0,a0,0
la_br &wd_emit
beqz_a0
- la_a3 &wd_tmp
li_t1 %10 %0
- st_t1,a3,0
- la_a1 &aux_tmp
- st_a3,a1,0
- ld_a1,a1,0
- rem_a2,a0,a1 # a2 = v mod 10
- div_a0,a0,a1 # a0 = v / 10
+ rem_a2,a0,t1
+ div_a0,a0,t1
la_a3 &wd_v
st_a0,a3,0
li_t1 %48 %0
- add_a3,t1,a2 # ascii = '0' + digit
+ add_a3,t1,a2
la_a0 &wd_pos
ld_t0,a0,0
la_a1 &line_scratch_ptr
@@ -3193,21 +2755,13 @@ DEFINE OFF_labels 0048000009800000
la_br &wd_loop
b
:wd_emit
- # write(2, &line_scratch[wd_pos+1], 64 - (wd_pos+1)) — but wd_pos+1
- # is also our buffer offset, so length = 63 - wd_pos = 64 - (wd_pos+1).
- # Route the buffer pointer (a1) through wd_tmp into a2 (no mov_a2,a1
- # in the seed table).
la_a0 &wd_pos
ld_t0,a0,0
addi_t0,t0,1
la_a1 &line_scratch_ptr
ld_a1,a1,0
add_a1,a1,t0
- la_a3 &wd_tmp
- st_a1,a3,0
- la_a2 &aux_tmp
- st_a3,a2,0
- ld_a2,a2,0
+ mov_a2,a1
li_t1 %64 %0
sub_a3,t1,t0
li_a0 sys_write
@@ -3215,208 +2769,180 @@ DEFINE OFF_labels 0048000009800000
syscall
eret
-## print_usage(): write usage banner to stdout (fd=1).
-:print_usage
- enter_0
- la_a0 &msg_usage
- la_br &strlen_cstr
- call
- la_a3 &pu_tmp
- st_a0,a3,0
- la_a2 &msg_usage
- ld_a3,a3,0
- li_a0 sys_write
- li_a1 %1 %0
- syscall
- eret
-
-## --- Error stubs ------------------------------------------------------------
+## --- Error stubs -----------------------------------------------------------
:err_unknown_arg
la_a0 &msg_unknown_arg
- la_br &fatal_msg
+ la_br &fatal
b
-:err_missing_arg_value
- la_a0 &msg_missing_arg_value
- la_br &fatal_msg
+:err_extra_positional
+ la_a0 &msg_extra_positional
+ la_br &fatal
b
:err_missing_positional
la_a0 &msg_missing_positional
- la_br &fatal_msg
- b
-:err_no_inputs
- la_a0 &msg_no_inputs
- la_br &fatal_msg
+ la_br &fatal
b
-:err_too_many_files
- la_a0 &msg_too_many_files
- la_br &fatal_msg
+:err_missing_value
+ la_a0 &msg_missing_value
+ la_br &fatal
b
:err_open_input
la_a0 &msg_open_input
- la_br &fatal_msg
+ la_br &fatal
b
:err_read
la_a0 &msg_read
- la_br &fatal_msg
+ la_br &fatal
b
:err_input_too_big
la_a0 &msg_input_too_big
- la_br &fatal_msg
+ la_br &fatal
b
:err_open_output
la_a0 &msg_open_output
- la_br &fatal_msg
+ la_br &fatal
b
:err_write
la_a0 &msg_write
- la_br &fatal_msg
+ la_br &fatal
b
:err_text_overflow
la_a0 &msg_text_overflow
- la_br &fatal_msg
+ la_br &fatal
b
:err_too_many_labels
la_a0 &msg_too_many_labels
- la_br &fatal_msg
+ la_br &fatal
b
:err_duplicate_label
la_a0 &msg_duplicate_label
- la_br &fatal_msg
+ la_br &fatal
b
:err_undefined_label
la_a0 &msg_undefined_label
- la_br &fatal_msg
+ la_br &fatal
b
:err_undefined_local
la_a0 &msg_undefined_local
- la_br &fatal_msg
+ la_br &fatal
b
:err_unexpected_char
la_a0 &msg_unexpected_char
- la_br &fatal_msg
+ la_br &fatal
b
:err_unknown_directive
la_a0 &msg_unknown_directive
- la_br &fatal_msg
- b
-:err_dotted_outside_scope
- la_a0 &msg_dotted_outside_scope
- la_br &fatal_msg
+ la_br &fatal
b
:err_scope_overflow
la_a0 &msg_scope_overflow
- la_br &fatal_msg
+ la_br &fatal
b
:err_scope_underflow
la_a0 &msg_scope_underflow
- la_br &fatal_msg
+ la_br &fatal
b
:err_scope_unclosed
la_a0 &msg_scope_unclosed
- la_br &fatal_msg
+ la_br &fatal
b
:err_align_n
la_a0 &msg_align_n
- la_br &fatal_msg
+ la_br &fatal
b
:err_fill_n
la_a0 &msg_fill_n
- la_br &fatal_msg
+ la_br &fatal
b
:err_pattern_too_large
la_a0 &msg_pattern_too_large
- la_br &fatal_msg
+ la_br &fatal
b
:err_byte_lit_bad
la_a0 &msg_byte_lit_bad
- la_br &fatal_msg
+ la_br &fatal
b
-:err_pbs_incomplete
- la_a0 &msg_pbs_incomplete
- la_br &fatal_msg
+:err_byte_stream_short
+ la_a0 &msg_byte_stream_short
+ la_br &fatal
b
:err_sigil_no_label
la_a0 &msg_sigil_no_label
- la_br &fatal_msg
+ la_br &fatal
b
:err_minus_no_label
la_a0 &msg_minus_no_label
- la_br &fatal_msg
+ la_br &fatal
b
:err_bad_sigil
la_a0 &msg_bad_sigil
- la_br &fatal_msg
+ la_br &fatal
b
:err_ref_out_of_range
la_a0 &msg_ref_out_of_range
- la_br &fatal_msg
+ la_br &fatal
b
:err_name_too_long
la_a0 &msg_name_too_long
- la_br &fatal_msg
+ la_br &fatal
b
:err_empty_name
la_a0 &msg_empty_name
- la_br &fatal_msg
+ la_br &fatal
b
:err_empty_directive
la_a0 &msg_empty_directive
- la_br &fatal_msg
+ la_br &fatal
b
:err_expected_decimal
la_a0 &msg_expected_decimal
- la_br &fatal_msg
+ la_br &fatal
b
:err_output_overflow
la_a0 &msg_output_overflow
- la_br &fatal_msg
+ la_br &fatal
b
:err_bad_long
la_a0 &msg_bad_long
- la_br &fatal_msg
+ la_br &fatal
b
:err_ptrsize_bad
la_a0 &msg_ptrsize_bad
- la_br &fatal_msg
+ la_br &fatal
b
:err_ptrsize_conflict
la_a0 &msg_ptrsize_conflict
- la_br &fatal_msg
+ la_br &fatal
b
## Sentinel: end of executable text.
:_text_end
-## --- Rodata -----------------------------------------------------------------
-
-:const_a_out "a.out" '00'
+## --- Rodata ----------------------------------------------------------------
-:opt_dash_B "-B" '00'
-:opt_dash_E "-E" '00'
-:opt_dash_e "-e" '00'
-:opt_dash_b "-b" '00'
-:opt_dash_N "-N" '00'
+:opt_B "-B" '00'
+:opt_E "-E" '00'
+:opt_e "-e" '00'
+:opt_b "-b" '00'
+:opt_N "-N" '00'
-:dir_align "align"
-:dir_fill "fill"
-:dir_scope "scope"
-:dir_endscope "endscope"
-:dir_ptrsize "ptrsize"
+:kw_align "align"
+:kw_fill "fill"
+:kw_scope "scope"
+:kw_endscope "endscope"
+:kw_ptrsize "ptrsize"
:str_colon ":"
-:str_colon_hex2pp ": hex2pp: "
-:str_hex2pp "hex2pp: "
+:str_colon_prog ": hex2pp: "
+:str_prog "hex2pp: "
:str_newline "
"
:str_zero "0"
-:msg_usage "usage: hex2pp [-B ADDR] [-E|-e] [-b] [-N] IN OUT
-" '00'
:msg_unknown_arg "unknown argument" '00'
-:msg_missing_arg_value "missing value for option" '00'
-:msg_no_inputs "no input files" '00'
+:msg_extra_positional "extra positional argument" '00'
:msg_missing_positional "missing IN or OUT positional argument" '00'
-:msg_too_many_files "too many input files" '00'
+:msg_missing_value "missing value for option" '00'
:msg_open_input "failed to open input file" '00'
:msg_read "failed to read input" '00'
:msg_input_too_big "input too large" '00'
@@ -3429,7 +2955,6 @@ DEFINE OFF_labels 0048000009800000
:msg_undefined_local "undefined local label" '00'
:msg_unexpected_char "unexpected character" '00'
:msg_unknown_directive "unknown directive" '00'
-:msg_dotted_outside_scope "dot-prefixed label outside a .scope" '00'
:msg_scope_overflow ".scope: depth overflow" '00'
:msg_scope_underflow ".endscope: not in a scope" '00'
:msg_scope_unclosed ".scope not closed at end of input" '00'
@@ -3437,7 +2962,7 @@ DEFINE OFF_labels 0048000009800000
:msg_fill_n ".fill: N must be non-negative" '00'
:msg_pattern_too_large "pattern too large" '00'
:msg_byte_lit_bad "byte literal: bad digit count" '00'
-:msg_pbs_incomplete "byte stream: incomplete digits at end of run" '00'
+:msg_byte_stream_short "byte stream: incomplete digits at end of run" '00'
:msg_sigil_no_label "sigil not followed by label name" '00'
:msg_minus_no_label "'-' must be followed by label name" '00'
:msg_bad_sigil "internal: bad sigil" '00'
@@ -3451,26 +2976,23 @@ DEFINE OFF_labels 0048000009800000
:msg_ptrsize_bad ".ptrsize: N must be 4 or 8" '00'
:msg_ptrsize_conflict ".ptrsize conflicts with already-used width" '00'
-## --- BSS pointer-init table ------------------------------------------------
+## BSS pointer-slot init table.
:bss_init_tbl
-&input_paths_ptr ZERO4 OFF_input_paths
-&input_starts_ptr ZERO4 OFF_input_starts
-&input_lens_ptr ZERO4 OFF_input_lens
-&scope_stack_ptr ZERO4 OFF_scope_stack
-&line_scratch_ptr ZERO4 OFF_line_scratch
-&name_buf_ptr ZERO4 OFF_name_buf
-&label_buf_ptr ZERO4 OFF_label_buf
-&other_buf_ptr ZERO4 OFF_other_buf
-&pat_buf_ptr ZERO4 OFF_pat_buf
-&ev_bytes_ptr ZERO4 OFF_ev_bytes
-&df_byte_ptr ZERO4 OFF_df_byte
-&input_buf_ptr ZERO4 OFF_input_buf
-&output_buf_ptr ZERO4 OFF_output_buf
-&text_buf_ptr ZERO4 OFF_text_buf
-&labels_ptr ZERO4 OFF_labels
+&scope_stack_ptr ZERO4 H2_OFF_scope_stack
+&name_buf_ptr ZERO4 H2_OFF_name_buf
+&label_buf_ptr ZERO4 H2_OFF_label_buf
+&other_buf_ptr ZERO4 H2_OFF_other_buf
+&pat_buf_ptr ZERO4 H2_OFF_pat_buf
+&line_scratch_ptr ZERO4 H2_OFF_line_scratch
+&ev_bytes_ptr ZERO4 H2_OFF_ev_bytes
+&df_byte_ptr ZERO4 H2_OFF_df_byte
+&input_buf_ptr ZERO4 H2_OFF_input_buf
+&output_buf_ptr ZERO4 H2_OFF_output_buf
+&text_buf_ptr ZERO4 H2_OFF_text_buf
+&labels_ptr ZERO4 H2_OFF_labels
:bss_init_tbl_end
-## --- BSS scalars ------------------------------------------------------------
+## --- BSS scalars ----------------------------------------------------------
:saved_argc
ZERO8
@@ -3480,15 +3002,11 @@ ZERO8
ZERO8
:arg_ptr
ZERO8
-:input_count
+:input_path
ZERO8
-:input_total
+:input_fd
ZERO8
-:li_path
-ZERO8
-:li_fd
-ZERO8
-:li_tmp
+:input_len
ZERO8
:output_path
ZERO8
@@ -3513,8 +3031,6 @@ ZERO8
:pass
ZERO8
-:pass_idx
-ZERO8
:ip
ZERO8
:cur_path
@@ -3534,7 +3050,7 @@ ZERO8
:scope_seq
ZERO8
-## name read scratch
+## name read
:name_len
ZERO8
:name_scope
@@ -3547,16 +3063,12 @@ ZERO8
ZERO8
:rn_n
ZERO8
-:sl_tmp
-ZERO8
## decimal read
:rd_val
ZERO8
:rd_saw
ZERO8
-:rd_tmp
-ZERO8
## byte stream
:pbs_acc
@@ -3573,8 +3085,6 @@ ZERO8
ZERO8
:p1b_have
ZERO8
-:p1b_done
-ZERO8
:p1b_c
ZERO8
@@ -3590,21 +3100,15 @@ ZERO8
:intern_i
ZERO8
-## label_addr scratch
-:la_const_32
-ZERO8
-
-## name_eq scratch
+## name_eq
:ne_label
ZERO8
:ne_src
ZERO8
:ne_len
ZERO8
-:ne_tmp
-ZERO8
-## define_label scratch
+## define_label
:dl_src
ZERO8
:dl_len
@@ -3618,7 +3122,7 @@ ZERO8
:dl_name_off
ZERO8
-## lookup_label scratch
+## lookup_label
:ll_src
ZERO8
:ll_len
@@ -3631,10 +3135,8 @@ ZERO8
ZERO8
:ll_label
ZERO8
-:ll_tmp
-ZERO8
-## process_reference / set_sigil_info scratch
+## process_reference / set_sigil_info
:cur_sigil
ZERO8
:pr_width
@@ -3655,18 +3157,10 @@ ZERO8
ZERO8
:pr_t_label
ZERO8
-:pr_t_other
-ZERO8
:pr_value
ZERO8
-:pr_tmp
-ZERO8
-:ssi_tmp
-ZERO8
-:ssi_tmp2
-ZERO8
-## emit_value scratch
+## emit_value
:ev_value
ZERO8
:ev_width
@@ -3700,7 +3194,7 @@ ZERO8
:dp_n
ZERO8
-## str/mem helpers
+## str/mem
:se_p
ZERO8
:se_q
@@ -3714,20 +3208,18 @@ ZERO8
:me_len
ZERO8
-## parse_long_arg
-:pla_p
-ZERO8
-:pla_val
+## parse_long
+:pl_p
ZERO8
-:pla_neg
+:pl_val
ZERO8
-:pla_tmp
+:pl_neg
ZERO8
-## error/fatal
-:err_saved_msg
+## fatal
+:fm_msg
ZERO8
-:err_saved_len
+:fm_tmp
ZERO8
## write_decimal
@@ -3735,29 +3227,10 @@ ZERO8
ZERO8
:wd_pos
ZERO8
-:wd_tmp
-ZERO8
-
-## print_usage
-:pu_tmp
-ZERO8
-
-## Generic auxiliary scratch used by sequences that route a value through
-## BSS to satisfy the seed P1 mnemonic table.
-:aux_tmp
-ZERO8
-## --- BSS pointer slots ------------------------------------------------------
-:input_paths_ptr
-ZERO8
-:input_starts_ptr
-ZERO8
-:input_lens_ptr
-ZERO8
+## --- BSS pointer slots ----------------------------------------------------
:scope_stack_ptr
ZERO8
-:line_scratch_ptr
-ZERO8
:name_buf_ptr
ZERO8
:label_buf_ptr
@@ -3766,6 +3239,8 @@ ZERO8
ZERO8
:pat_buf_ptr
ZERO8
+:line_scratch_ptr
+ZERO8
:ev_bytes_ptr
ZERO8
:df_byte_ptr
diff --git a/scripts/boot-run-tests.sh b/scripts/boot-run-tests.sh
@@ -126,35 +126,22 @@ run_m1pp_suite() {
run_p1_suite() {
if [ -z "$NAMES" ]; then
- raw=$(discover tests/P1 P1)
- pp=$(discover tests/P1 P1pp)
- NAMES=$(printf '%s\n%s\n' "$raw" "$pp" | sort -u | tr '\n' ' ')
+ NAMES=$(discover tests/P1 P1pp)
fi
for name in $NAMES; do
- raw_src=tests/P1/$name.P1
pp_src=tests/P1/$name.P1pp
expected=tests/P1/$name.expected
if [ ! -e "$expected" ]; then echo " SKIP $name (no .expected)"; continue; fi
+ if [ ! -e "$pp_src" ]; then echo " SKIP $name (no .P1pp)"; continue; fi
expected_content=$(cat "$expected")
label="[$ARCH] $name"
bin=build/$ARCH/tests/P1/$name
log=build/$ARCH/.work/tests/P1/$name/build.log
mkdir -p "$(dirname "$bin")" "$(dirname "$log")"
- if [ -e "$pp_src" ]; then
- if ! sh scripts/boot-build-p1pp.sh "$bin" "$pp_src" \
- >"$log" 2>&1; then
- fail "$label" "" "$log"
- continue
- fi
- elif [ -e "$raw_src" ]; then
- if ! sh scripts/boot-build-p1.sh "$raw_src" "$bin" \
- >"$log" 2>&1; then
- fail "$label" "" "$log"
- continue
- fi
- else
- echo " SKIP $name (no .P1 or .P1pp)"
+ if ! sh scripts/boot-build-p1pp.sh "$bin" "$pp_src" \
+ >"$log" 2>&1; then
+ fail "$label" "" "$log"
continue
fi
actual=$("./$bin" 2>&1 || true)
diff --git a/tests/P1/00-hello.P1 b/tests/P1/00-hello.P1
@@ -1,27 +0,0 @@
-## P1 hello-world smoke fixture.
-##
-## Exercises the build pipeline (lint -> prune -> catm -> M0 -> ELF link ->
-## hex2-0) against build/p1/aarch64/p1_aarch64.M1. Standalone program —
-## does not drive the m1pp expander.
-##
-## P1 syscall ABI:
-## a0 = syscall number on entry, return value on exit
-## a1, a2, a3, t0, s0, s1 = syscall arguments 0..5
-
-:p1_main
- ## write(fd=1, buf=&msg, count=14)
- li_a0 sys_write
- li_a1 %1 %0
- la_a2 &msg
- li_a3 %14 %0
- syscall
-
- ## return 0 (backend :_start stub sys_exits with a0)
- li_a0 %0 %0
- ret
-
-:msg
-"Hello, World!
-"
-
-:ELF_end
diff --git a/tests/P1/00-hello.expected b/tests/P1/00-hello.expected
@@ -1 +0,0 @@
-Hello, World!