boot2

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

commit ad86871713a85088c3cb1d3aa5f9f0eb383cd665
parent 6a9a14eca5a5d07f5ed7bfbfd523ec10fb05b02b
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sun, 26 Apr 2026 15:14:08 -0700

P1pp: add ld/st/lda_global and ld/st/lda_array helpers

Hide the la+ld(_,0) and li+mul+add+ld(_,off) idioms behind named
macros so call sites read as a single load/store instead of an
open-coded address computation. Reindent existing macro bodies to
the 4-space style the new macros use.

Diffstat:
MP1/P1pp.P1pp | 1620+++++++++++++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 845 insertions(+), 775 deletions(-)

diff --git a/P1/P1pp.P1pp b/P1/P1pp.P1pp @@ -22,9 +22,79 @@ # scratch = -align (i.e. ~(align-1) for power-of-two align) # rd = rd & scratch %macro alignup(rd, rs, align, scratch) -%addi(rd, rs, (- align 1)) -%li(scratch, (- 0 align)) -%and(rd, rd, scratch) + %addi(rd, rs, (- align 1)) + %li(scratch, (- 0 align)) + %and(rd, rd, scratch) +%endm + +# ========================================================================= +# Global memory access +# ========================================================================= +# +# Shorthand for the la + ld(_,0) / la + st(_,0) idiom that dereferences a +# pointer slot at a labeled global. `name` is a label expression in the +# `&foo` form that %la accepts. +# +# %ld_global -- rd = *name. rd doubles as the address scratch. +# %st_global -- *name = rs. Needs a separate `scratch` since rs holds the +# value being written. +# %lda_global -- rd = *name AND raddr = &name. Use when the address is +# also needed afterward (e.g. load then store back). + +%macro ld_global(rd, name) + %la(rd, name) + %ld(rd, rd, 0) +%endm + +%macro st_global(rs, name, scratch) + %la(scratch, name) + %st(rs, scratch, 0) +%endm + +%macro lda_global(rd, raddr, name) + %la(raddr, name) + %ld(rd, raddr, 0) +%endm + +# ========================================================================= +# Array indexing +# ========================================================================= +# +# Compute *(base + idx * stride + off) for register `base`, register +# `idx`, and constant `stride` and `off`. `stride` is materialized via +# %li and folded into idx via %mul, so it does not need to be a power of +# two. `off` is a constant byte offset within the element (use 0 for +# plain element access; non-zero for field access). +# +# All three macros need a separate scratch to hold the computed address, +# because both `base` and `idx` are register inputs that must survive the +# multiply. `lda_array` reuses its `raddr` output as that scratch. +# +# %ld_array -- rd = *(base + idx*stride + off). +# %st_array -- *(base + idx*stride + off) = rs. +# %lda_array -- rd = *addr AND raddr = base + idx*stride; ld is at +# offset `off`. Use when subsequent code also needs the +# computed address (e.g. for additional field accesses). + +%macro ld_array(rd, base, stride, idx, off, scratch) + %li(scratch, stride) + %mul(scratch, idx, scratch) + %add(scratch, base, scratch) + %ld(rd, scratch, off) +%endm + +%macro st_array(rs, base, stride, idx, off, scratch) + %li(scratch, stride) + %mul(scratch, idx, scratch) + %add(scratch, base, scratch) + %st(rs, scratch, off) +%endm + +%macro lda_array(rd, raddr, base, stride, idx, off) + %li(raddr, stride) + %mul(raddr, idx, raddr) + %add(raddr, base, raddr) + %ld(rd, raddr, off) %endm # ========================================================================= @@ -39,124 +109,124 @@ # ---- %if_<cc> ----------------------------------------------------------- %macro if_eq(ra, rb, body) -%beq(ra, rb, &@body) -%b(&@end) -:@body -body -:@end + %beq(ra, rb, &@body) + %b(&@end) + :@body + body + :@end %endm %macro if_ne(ra, rb, body) -%bne(ra, rb, &@body) -%b(&@end) -:@body -body -:@end + %bne(ra, rb, &@body) + %b(&@end) + :@body + body + :@end %endm %macro if_lt(ra, rb, body) -%blt(ra, rb, &@body) -%b(&@end) -:@body -body -:@end + %blt(ra, rb, &@body) + %b(&@end) + :@body + body + :@end %endm %macro if_ltu(ra, rb, body) -%bltu(ra, rb, &@body) -%b(&@end) -:@body -body -:@end + %bltu(ra, rb, &@body) + %b(&@end) + :@body + body + :@end %endm %macro if_eqz(ra, body) -%beqz(ra, &@body) -%b(&@end) -:@body -body -:@end + %beqz(ra, &@body) + %b(&@end) + :@body + body + :@end %endm %macro if_nez(ra, body) -%bnez(ra, &@body) -%b(&@end) -:@body -body -:@end + %bnez(ra, &@body) + %b(&@end) + :@body + body + :@end %endm %macro if_ltz(ra, body) -%bltz(ra, &@body) -%b(&@end) -:@body -body -:@end + %bltz(ra, &@body) + %b(&@end) + :@body + body + :@end %endm # ---- %ifelse_<cc> ------------------------------------------------------- %macro ifelse_eq(ra, rb, tblk, fblk) -%beq(ra, rb, &@tblk) -fblk -%b(&@end) -:@tblk -tblk -:@end + %beq(ra, rb, &@tblk) + fblk + %b(&@end) + :@tblk + tblk + :@end %endm %macro ifelse_ne(ra, rb, tblk, fblk) -%bne(ra, rb, &@tblk) -fblk -%b(&@end) -:@tblk -tblk -:@end + %bne(ra, rb, &@tblk) + fblk + %b(&@end) + :@tblk + tblk + :@end %endm %macro ifelse_lt(ra, rb, tblk, fblk) -%blt(ra, rb, &@tblk) -fblk -%b(&@end) -:@tblk -tblk -:@end + %blt(ra, rb, &@tblk) + fblk + %b(&@end) + :@tblk + tblk + :@end %endm %macro ifelse_ltu(ra, rb, tblk, fblk) -%bltu(ra, rb, &@tblk) -fblk -%b(&@end) -:@tblk -tblk -:@end + %bltu(ra, rb, &@tblk) + fblk + %b(&@end) + :@tblk + tblk + :@end %endm %macro ifelse_eqz(ra, tblk, fblk) -%beqz(ra, &@tblk) -fblk -%b(&@end) -:@tblk -tblk -:@end + %beqz(ra, &@tblk) + fblk + %b(&@end) + :@tblk + tblk + :@end %endm %macro ifelse_nez(ra, tblk, fblk) -%bnez(ra, &@tblk) -fblk -%b(&@end) -:@tblk -tblk -:@end + %bnez(ra, &@tblk) + fblk + %b(&@end) + :@tblk + tblk + :@end %endm %macro ifelse_ltz(ra, tblk, fblk) -%bltz(ra, &@tblk) -fblk -%b(&@end) -:@tblk -tblk -:@end + %bltz(ra, &@tblk) + fblk + %b(&@end) + :@tblk + tblk + :@end %endm # ---- %while_<cc> ------------------------------------------------------- @@ -166,123 +236,123 @@ tblk # branch at entry. %macro while_eq(ra, rb, body) -%b(&@test) -:@body -body -:@test -%beq(ra, rb, &@body) + %b(&@test) + :@body + body + :@test + %beq(ra, rb, &@body) %endm %macro while_ne(ra, rb, body) -%b(&@test) -:@body -body -:@test -%bne(ra, rb, &@body) + %b(&@test) + :@body + body + :@test + %bne(ra, rb, &@body) %endm %macro while_lt(ra, rb, body) -%b(&@test) -:@body -body -:@test -%blt(ra, rb, &@body) + %b(&@test) + :@body + body + :@test + %blt(ra, rb, &@body) %endm %macro while_ltu(ra, rb, body) -%b(&@test) -:@body -body -:@test -%bltu(ra, rb, &@body) + %b(&@test) + :@body + body + :@test + %bltu(ra, rb, &@body) %endm %macro while_eqz(ra, body) -%b(&@test) -:@body -body -:@test -%beqz(ra, &@body) + %b(&@test) + :@body + body + :@test + %beqz(ra, &@body) %endm %macro while_nez(ra, body) -%b(&@test) -:@body -body -:@test -%bnez(ra, &@body) + %b(&@test) + :@body + body + :@test + %bnez(ra, &@body) %endm %macro while_ltz(ra, body) -%b(&@test) -:@body -body -:@test -%bltz(ra, &@body) + %b(&@test) + :@body + body + :@test + %bltz(ra, &@body) %endm # ---- %do_while_<cc> ---------------------------------------------------- %macro do_while_eq(ra, rb, body) -:@body -body -%beq(ra, rb, &@body) + :@body + body + %beq(ra, rb, &@body) %endm %macro do_while_ne(ra, rb, body) -:@body -body -%bne(ra, rb, &@body) + :@body + body + %bne(ra, rb, &@body) %endm %macro do_while_lt(ra, rb, body) -:@body -body -%blt(ra, rb, &@body) + :@body + body + %blt(ra, rb, &@body) %endm %macro do_while_ltu(ra, rb, body) -:@body -body -%bltu(ra, rb, &@body) + :@body + body + %bltu(ra, rb, &@body) %endm %macro do_while_eqz(ra, body) -:@body -body -%beqz(ra, &@body) + :@body + body + %beqz(ra, &@body) %endm %macro do_while_nez(ra, body) -:@body -body -%bnez(ra, &@body) + :@body + body + %bnez(ra, &@body) %endm %macro do_while_ltz(ra, body) -:@body -body -%bltz(ra, &@body) + :@body + body + %bltz(ra, &@body) %endm # ---- %for_lt ------------------------------------------------------------ %macro for_lt(i_reg, n_reg, body) -%li(i_reg, 0) -%b(&@test) -:@body -body -%addi(i_reg, i_reg, 1) -:@test -%blt(i_reg, n_reg, &@body) + %li(i_reg, 0) + %b(&@test) + :@body + body + %addi(i_reg, i_reg, 1) + :@test + %blt(i_reg, n_reg, &@body) %endm # ---- %loop -------------------------------------------------------------- %macro loop(body) -:@top -body -%b(&@top) + :@top + body + %b(&@top) %endm # ---- Tagged loops ------------------------------------------------------- @@ -292,93 +362,93 @@ body # `%break(tag)` jumps to `tag_end`; `%continue(tag)` jumps to `tag_top`. %macro loop_tag(tag, body) -: ## tag ## _top -body -%b(& ## tag ## _top) -: ## tag ## _end + : ## tag ## _top + body + %b(& ## tag ## _top) + : ## tag ## _end %endm %macro while_tag_eq(tag, ra, rb, body) -%b(& ## tag ## _top) -:@body -body -: ## tag ## _top -%beq(ra, rb, &@body) -: ## tag ## _end + %b(& ## tag ## _top) + :@body + body + : ## tag ## _top + %beq(ra, rb, &@body) + : ## tag ## _end %endm %macro while_tag_ne(tag, ra, rb, body) -%b(& ## tag ## _top) -:@body -body -: ## tag ## _top -%bne(ra, rb, &@body) -: ## tag ## _end + %b(& ## tag ## _top) + :@body + body + : ## tag ## _top + %bne(ra, rb, &@body) + : ## tag ## _end %endm %macro while_tag_lt(tag, ra, rb, body) -%b(& ## tag ## _top) -:@body -body -: ## tag ## _top -%blt(ra, rb, &@body) -: ## tag ## _end + %b(& ## tag ## _top) + :@body + body + : ## tag ## _top + %blt(ra, rb, &@body) + : ## tag ## _end %endm %macro while_tag_ltu(tag, ra, rb, body) -%b(& ## tag ## _top) -:@body -body -: ## tag ## _top -%bltu(ra, rb, &@body) -: ## tag ## _end + %b(& ## tag ## _top) + :@body + body + : ## tag ## _top + %bltu(ra, rb, &@body) + : ## tag ## _end %endm %macro while_tag_eqz(tag, ra, body) -%b(& ## tag ## _top) -:@body -body -: ## tag ## _top -%beqz(ra, &@body) -: ## tag ## _end + %b(& ## tag ## _top) + :@body + body + : ## tag ## _top + %beqz(ra, &@body) + : ## tag ## _end %endm %macro while_tag_nez(tag, ra, body) -%b(& ## tag ## _top) -:@body -body -: ## tag ## _top -%bnez(ra, &@body) -: ## tag ## _end + %b(& ## tag ## _top) + :@body + body + : ## tag ## _top + %bnez(ra, &@body) + : ## tag ## _end %endm %macro while_tag_ltz(tag, ra, body) -%b(& ## tag ## _top) -:@body -body -: ## tag ## _top -%bltz(ra, &@body) -: ## tag ## _end + %b(& ## tag ## _top) + :@body + body + : ## tag ## _top + %bltz(ra, &@body) + : ## tag ## _end %endm %macro for_lt_tag(tag, i_reg, n_reg, body) -%li(i_reg, 0) -%b(& ## tag ## _test) -:@body -body -: ## tag ## _top -%addi(i_reg, i_reg, 1) -: ## tag ## _test -%blt(i_reg, n_reg, &@body) -: ## tag ## _end + %li(i_reg, 0) + %b(& ## tag ## _test) + :@body + body + : ## tag ## _top + %addi(i_reg, i_reg, 1) + : ## tag ## _test + %blt(i_reg, n_reg, &@body) + : ## tag ## _end %endm %macro break(tag) -%b(& ## tag ## _end) + %b(& ## tag ## _end) %endm %macro continue(tag) -%b(& ## tag ## _top) + %b(& ## tag ## _top) %endm # ========================================================================= @@ -390,12 +460,12 @@ body # %eret, so functions defined with %fn always carry a standard frame. %macro fn(name, size, body) -: ## name -%scope name -%enter(size) -body -%eret -%endscope + : ## name + %scope name + %enter(size) + body + %eret + %endscope %endm # ========================================================================= @@ -407,52 +477,52 @@ body # enclosing function to have an established frame. %macro assert_eq(ra, rb, msg) -%beq(ra, rb, &@done) -%la(a0, & ## msg) -%call(&panic) -:@done + %beq(ra, rb, &@done) + %la(a0, & ## msg) + %call(&panic) + :@done %endm %macro assert_ne(ra, rb, msg) -%bne(ra, rb, &@done) -%la(a0, & ## msg) -%call(&panic) -:@done + %bne(ra, rb, &@done) + %la(a0, & ## msg) + %call(&panic) + :@done %endm %macro assert_lt(ra, rb, msg) -%blt(ra, rb, &@done) -%la(a0, & ## msg) -%call(&panic) -:@done + %blt(ra, rb, &@done) + %la(a0, & ## msg) + %call(&panic) + :@done %endm %macro assert_ltu(ra, rb, msg) -%bltu(ra, rb, &@done) -%la(a0, & ## msg) -%call(&panic) -:@done + %bltu(ra, rb, &@done) + %la(a0, & ## msg) + %call(&panic) + :@done %endm %macro assert_eqz(ra, msg) -%beqz(ra, &@done) -%la(a0, & ## msg) -%call(&panic) -:@done + %beqz(ra, &@done) + %la(a0, & ## msg) + %call(&panic) + :@done %endm %macro assert_nez(ra, msg) -%bnez(ra, &@done) -%la(a0, & ## msg) -%call(&panic) -:@done + %bnez(ra, &@done) + %la(a0, & ## msg) + %call(&panic) + :@done %endm %macro assert_ltz(ra, msg) -%bltz(ra, &@done) -%la(a0, & ## msg) -%call(&panic) -:@done + %bltz(ra, &@done) + %la(a0, & ## msg) + %call(&panic) + :@done %endm # ========================================================================= @@ -464,116 +534,116 @@ body # dst > src && dst < src + n. :memcpy %scope memcpy -%mov(a3, a0) -%li(t0, 0) -::loop -%beq(t0, a2, &::done) -%add(t1, a1, t0) -%lb(t1, t1, 0) -%add(t2, a3, t0) -%sb(t1, t2, 0) -%addi(t0, t0, 1) -%b(&::loop) -::done -%mov(a0, a3) -%ret + %mov(a3, a0) + %li(t0, 0) + ::loop + %beq(t0, a2, &::done) + %add(t1, a1, t0) + %lb(t1, t1, 0) + %add(t2, a3, t0) + %sb(t1, t2, 0) + %addi(t0, t0, 1) + %b(&::loop) + ::done + %mov(a0, a3) + %ret %endscope # memset(dst=a0, byte=a1, n=a2) -> dst (a0) :memset %scope memset -%mov(a3, a0) -%li(t0, 0) -::loop -%beq(t0, a2, &::done) -%add(t1, a3, t0) -%sb(a1, t1, 0) -%addi(t0, t0, 1) -%b(&::loop) -::done -%mov(a0, a3) -%ret + %mov(a3, a0) + %li(t0, 0) + ::loop + %beq(t0, a2, &::done) + %add(t1, a3, t0) + %sb(a1, t1, 0) + %addi(t0, t0, 1) + %b(&::loop) + ::done + %mov(a0, a3) + %ret %endscope # memcmp(a=a0, b=a1, n=a2) -> -1/0/1 (a0) :memcmp %scope memcmp -%li(t0, 0) -::loop -%beq(t0, a2, &::eq) -%add(t1, a0, t0) -%lb(t1, t1, 0) -%add(t2, a1, t0) -%lb(t2, t2, 0) -%bltu(t1, t2, &::lt) -%bltu(t2, t1, &::gt) -%addi(t0, t0, 1) -%b(&::loop) -::lt -%li(a0, -1) -%ret -::gt -%li(a0, 1) -%ret -::eq -%li(a0, 0) -%ret + %li(t0, 0) + ::loop + %beq(t0, a2, &::eq) + %add(t1, a0, t0) + %lb(t1, t1, 0) + %add(t2, a1, t0) + %lb(t2, t2, 0) + %bltu(t1, t2, &::lt) + %bltu(t2, t1, &::gt) + %addi(t0, t0, 1) + %b(&::loop) + ::lt + %li(a0, -1) + %ret + ::gt + %li(a0, 1) + %ret + ::eq + %li(a0, 0) + %ret %endscope # strlen(cstr=a0) -> n (a0) :strlen %scope strlen -%mov(a1, a0) -::loop -%lb(t0, a1, 0) -%beqz(t0, &::done) -%addi(a1, a1, 1) -%b(&::loop) -::done -%sub(a0, a1, a0) -%ret + %mov(a1, a0) + ::loop + %lb(t0, a1, 0) + %beqz(t0, &::done) + %addi(a1, a1, 1) + %b(&::loop) + ::done + %sub(a0, a1, a0) + %ret %endscope # streq(a=a0, b=a1) -> 0 or 1 :streq %scope streq -::loop -%lb(t0, a0, 0) -%lb(t1, a1, 0) -%bne(t0, t1, &::ne) -%beqz(t0, &::eq) -%addi(a0, a0, 1) -%addi(a1, a1, 1) -%b(&::loop) -::ne -%li(a0, 0) -%ret -::eq -%li(a0, 1) -%ret + ::loop + %lb(t0, a0, 0) + %lb(t1, a1, 0) + %bne(t0, t1, &::ne) + %beqz(t0, &::eq) + %addi(a0, a0, 1) + %addi(a1, a1, 1) + %b(&::loop) + ::ne + %li(a0, 0) + %ret + ::eq + %li(a0, 1) + %ret %endscope # strcmp(a=a0, b=a1) -> -1/0/1 :strcmp %scope strcmp -::loop -%lb(t0, a0, 0) -%lb(t1, a1, 0) -%bltu(t0, t1, &::lt) -%bltu(t1, t0, &::gt) -%beqz(t0, &::eq) -%addi(a0, a0, 1) -%addi(a1, a1, 1) -%b(&::loop) -::lt -%li(a0, -1) -%ret -::gt -%li(a0, 1) -%ret -::eq -%li(a0, 0) -%ret + ::loop + %lb(t0, a0, 0) + %lb(t1, a1, 0) + %bltu(t0, t1, &::lt) + %bltu(t1, t0, &::gt) + %beqz(t0, &::eq) + %addi(a0, a0, 1) + %addi(a1, a1, 1) + %b(&::loop) + ::lt + %li(a0, -1) + %ret + ::gt + %li(a0, 1) + %ret + ::eq + %li(a0, 0) + %ret %endscope # ========================================================================= @@ -585,109 +655,109 @@ body # in caller-saved registers. :parse_dec %scope parse_dec -%enter(8) -%st(a0, sp, 0) -%add(a3, a0, a1) -%mov(a2, a0) -%li(t0, 0) -%li(t1, 0) - -%beq(a2, a3, &::after_sign) -%lb(t2, a2, 0) -%addi(t2, t2, -45) -%bnez(t2, &::after_sign) -%li(t0, 1) -%addi(a2, a2, 1) - -::after_sign -%mov(a1, a2) - -::digit_loop -%beq(a2, a3, &::digits_done) -%lb(t2, a2, 0) -%addi(t2, t2, -48) -%bltz(t2, &::digits_done) -%li(a0, 9) -%bltu(a0, t2, &::digits_done) -%li(a0, 10) -%mul(t1, t1, a0) -%add(t1, t1, t2) -%addi(a2, a2, 1) -%b(&::digit_loop) - -::digits_done -%beq(a2, a1, &::no_digits) - -%bnez(t0, &::apply_sign) -%b(&::compute_return) -::apply_sign -%li(a0, 0) -%sub(t1, a0, t1) - -::compute_return -%ld(a0, sp, 0) -%sub(a1, a2, a0) -%mov(a0, t1) -%eret - -::no_digits -%li(a0, 0) -%li(a1, 0) -%eret + %enter(8) + %st(a0, sp, 0) + %add(a3, a0, a1) + %mov(a2, a0) + %li(t0, 0) + %li(t1, 0) + + %beq(a2, a3, &::after_sign) + %lb(t2, a2, 0) + %addi(t2, t2, -45) + %bnez(t2, &::after_sign) + %li(t0, 1) + %addi(a2, a2, 1) + + ::after_sign + %mov(a1, a2) + + ::digit_loop + %beq(a2, a3, &::digits_done) + %lb(t2, a2, 0) + %addi(t2, t2, -48) + %bltz(t2, &::digits_done) + %li(a0, 9) + %bltu(a0, t2, &::digits_done) + %li(a0, 10) + %mul(t1, t1, a0) + %add(t1, t1, t2) + %addi(a2, a2, 1) + %b(&::digit_loop) + + ::digits_done + %beq(a2, a1, &::no_digits) + + %bnez(t0, &::apply_sign) + %b(&::compute_return) + ::apply_sign + %li(a0, 0) + %sub(t1, a0, t1) + + ::compute_return + %ld(a0, sp, 0) + %sub(a1, a2, a0) + %mov(a0, t1) + %eret + + ::no_digits + %li(a0, 0) + %li(a1, 0) + %eret %endscope # parse_hex(buf=a0, len=a1) -> (value=a0, consumed=a1) :parse_hex %scope parse_hex -%enter(8) -%st(a0, sp, 0) -%add(a3, a0, a1) -%mov(a2, a0) -%li(t1, 0) -%mov(a1, a2) - -::loop -%beq(a2, a3, &::done) -%lb(t2, a2, 0) - -%addi(t0, t2, -48) -%bltz(t0, &::check_lower) -%li(a0, 9) -%bltu(a0, t0, &::check_lower) -%b(&::accept) - -::check_lower -%addi(t0, t2, -97) -%bltz(t0, &::check_upper) -%li(a0, 5) -%bltu(a0, t0, &::check_upper) -%addi(t0, t0, 10) -%b(&::accept) - -::check_upper -%addi(t0, t2, -65) -%bltz(t0, &::done) -%li(a0, 5) -%bltu(a0, t0, &::done) -%addi(t0, t0, 10) - -::accept -%shli(t1, t1, 4) -%or(t1, t1, t0) -%addi(a2, a2, 1) -%b(&::loop) - -::done -%beq(a2, a1, &::no_digits) -%ld(a0, sp, 0) -%sub(a1, a2, a0) -%mov(a0, t1) -%eret - -::no_digits -%li(a0, 0) -%li(a1, 0) -%eret + %enter(8) + %st(a0, sp, 0) + %add(a3, a0, a1) + %mov(a2, a0) + %li(t1, 0) + %mov(a1, a2) + + ::loop + %beq(a2, a3, &::done) + %lb(t2, a2, 0) + + %addi(t0, t2, -48) + %bltz(t0, &::check_lower) + %li(a0, 9) + %bltu(a0, t0, &::check_lower) + %b(&::accept) + + ::check_lower + %addi(t0, t2, -97) + %bltz(t0, &::check_upper) + %li(a0, 5) + %bltu(a0, t0, &::check_upper) + %addi(t0, t0, 10) + %b(&::accept) + + ::check_upper + %addi(t0, t2, -65) + %bltz(t0, &::done) + %li(a0, 5) + %bltu(a0, t0, &::done) + %addi(t0, t0, 10) + + ::accept + %shli(t1, t1, 4) + %or(t1, t1, t0) + %addi(a2, a2, 1) + %b(&::loop) + + ::done + %beq(a2, a1, &::no_digits) + %ld(a0, sp, 0) + %sub(a1, a2, a0) + %mov(a0, t1) + %eret + + ::no_digits + %li(a0, 0) + %li(a1, 0) + %eret %endscope # fmt_dec(buf=a0, value=a1) -> n_bytes (a0) @@ -697,90 +767,90 @@ body # INT_MIN-overflow trap that `value = -value` would hit. :fmt_dec %scope fmt_dec -%enter(8) -%st(a0, sp, 0) - -%bltz(a1, &::is_neg) -%b(&::count) -::is_neg -%li(t0, 45) -%sb(t0, a0, 0) -%addi(a0, a0, 1) - -::count -%mov(t0, a1) -%li(a2, 1) -%li(t1, 10) -::count_loop -%div(t0, t0, t1) -%beqz(t0, &::count_done) -%addi(a2, a2, 1) -%b(&::count_loop) -::count_done - -%add(a3, a0, a2) - -::dig_loop -%addi(a3, a3, -1) -%rem(t0, a1, t1) -%bltz(t0, &::neg_digit) -%b(&::write_digit) -::neg_digit -%li(t2, 0) -%sub(t0, t2, t0) -::write_digit -%addi(t0, t0, 48) -%sb(t0, a3, 0) -%div(a1, a1, t1) -%bnez(a1, &::dig_loop) - -%ld(t2, sp, 0) -%add(a0, a0, a2) -%sub(a0, a0, t2) -%eret + %enter(8) + %st(a0, sp, 0) + + %bltz(a1, &::is_neg) + %b(&::count) + ::is_neg + %li(t0, 45) + %sb(t0, a0, 0) + %addi(a0, a0, 1) + + ::count + %mov(t0, a1) + %li(a2, 1) + %li(t1, 10) + ::count_loop + %div(t0, t0, t1) + %beqz(t0, &::count_done) + %addi(a2, a2, 1) + %b(&::count_loop) + ::count_done + + %add(a3, a0, a2) + + ::dig_loop + %addi(a3, a3, -1) + %rem(t0, a1, t1) + %bltz(t0, &::neg_digit) + %b(&::write_digit) + ::neg_digit + %li(t2, 0) + %sub(t0, t2, t0) + ::write_digit + %addi(t0, t0, 48) + %sb(t0, a3, 0) + %div(a1, a1, t1) + %bnez(a1, &::dig_loop) + + %ld(t2, sp, 0) + %add(a0, a0, a2) + %sub(a0, a0, t2) + %eret %endscope # fmt_hex(buf=a0, value=a1) -> n_bytes (a0) :fmt_hex %scope fmt_hex -%enter(8) -%st(a0, sp, 0) - -%bnez(a1, &::nonzero) -%li(t0, 48) -%sb(t0, a0, 0) -%li(a0, 1) -%eret - -::nonzero -%mov(t0, a1) -%li(a2, 0) -::count_loop -%addi(a2, a2, 1) -%shri(t0, t0, 4) -%bnez(t0, &::count_loop) - -%add(a3, a0, a2) - -::dig_loop -%addi(a3, a3, -1) -%andi(t0, a1, 15) -%li(t1, 10) -%bltu(t0, t1, &::is_letter) -%addi(t0, t0, -10) -%addi(t0, t0, 97) -%b(&::write_digit) -::is_letter -%addi(t0, t0, 48) -::write_digit -%sb(t0, a3, 0) -%shri(a1, a1, 4) -%bnez(a1, &::dig_loop) - -%ld(t2, sp, 0) -%add(a0, a0, a2) -%sub(a0, a0, t2) -%eret + %enter(8) + %st(a0, sp, 0) + + %bnez(a1, &::nonzero) + %li(t0, 48) + %sb(t0, a0, 0) + %li(a0, 1) + %eret + + ::nonzero + %mov(t0, a1) + %li(a2, 0) + ::count_loop + %addi(a2, a2, 1) + %shri(t0, t0, 4) + %bnez(t0, &::count_loop) + + %add(a3, a0, a2) + + ::dig_loop + %addi(a3, a3, -1) + %andi(t0, a1, 15) + %li(t1, 10) + %bltu(t0, t1, &::is_letter) + %addi(t0, t0, -10) + %addi(t0, t0, 97) + %b(&::write_digit) + ::is_letter + %addi(t0, t0, 48) + ::write_digit + %sb(t0, a3, 0) + %shri(a1, a1, 4) + %bnez(a1, &::dig_loop) + + %ld(t2, sp, 0) + %add(a0, a0, a2) + %sub(a0, a0, t2) + %eret %endscope # ========================================================================= @@ -790,79 +860,79 @@ body # is_digit(c=a0) -> 0 or 1 :is_digit %scope is_digit -%addi(t0, a0, -48) -%li(t1, 10) -%li(a0, 1) -%bltu(t0, t1, &::done) -%li(a0, 0) -::done -%ret + %addi(t0, a0, -48) + %li(t1, 10) + %li(a0, 1) + %bltu(t0, t1, &::done) + %li(a0, 0) + ::done + %ret %endscope # is_hex_digit(c=a0) -> 0 or 1 :is_hex_digit %scope is_hex_digit -%li(t2, 1) -%addi(t0, a0, -48) -%li(t1, 10) -%bltu(t0, t1, &::done) -%addi(t0, a0, -97) -%li(t1, 6) -%bltu(t0, t1, &::done) -%addi(t0, a0, -65) -%bltu(t0, t1, &::done) -%li(t2, 0) -::done -%mov(a0, t2) -%ret + %li(t2, 1) + %addi(t0, a0, -48) + %li(t1, 10) + %bltu(t0, t1, &::done) + %addi(t0, a0, -97) + %li(t1, 6) + %bltu(t0, t1, &::done) + %addi(t0, a0, -65) + %bltu(t0, t1, &::done) + %li(t2, 0) + ::done + %mov(a0, t2) + %ret %endscope # is_space(c=a0) -> 0 or 1 :is_space %scope is_space -%li(t2, 1) -%addi(t0, a0, -32) -%beqz(t0, &::done) -%addi(t0, a0, -9) -%li(t1, 5) -%bltu(t0, t1, &::done) -%li(t2, 0) -::done -%mov(a0, t2) -%ret + %li(t2, 1) + %addi(t0, a0, -32) + %beqz(t0, &::done) + %addi(t0, a0, -9) + %li(t1, 5) + %bltu(t0, t1, &::done) + %li(t2, 0) + ::done + %mov(a0, t2) + %ret %endscope # is_alpha(c=a0) -> 0 or 1 :is_alpha %scope is_alpha -%li(t2, 1) -%addi(t0, a0, -97) -%li(t1, 26) -%bltu(t0, t1, &::done) -%addi(t0, a0, -65) -%bltu(t0, t1, &::done) -%li(t2, 0) -::done -%mov(a0, t2) -%ret + %li(t2, 1) + %addi(t0, a0, -97) + %li(t1, 26) + %bltu(t0, t1, &::done) + %addi(t0, a0, -65) + %bltu(t0, t1, &::done) + %li(t2, 0) + ::done + %mov(a0, t2) + %ret %endscope # is_alnum(c=a0) -> 0 or 1 :is_alnum %scope is_alnum -%li(t2, 1) -%addi(t0, a0, -48) -%li(t1, 10) -%bltu(t0, t1, &::done) -%addi(t0, a0, -97) -%li(t1, 26) -%bltu(t0, t1, &::done) -%addi(t0, a0, -65) -%bltu(t0, t1, &::done) -%li(t2, 0) -::done -%mov(a0, t2) -%ret + %li(t2, 1) + %addi(t0, a0, -48) + %li(t1, 10) + %bltu(t0, t1, &::done) + %addi(t0, a0, -97) + %li(t1, 26) + %bltu(t0, t1, &::done) + %addi(t0, a0, -65) + %bltu(t0, t1, &::done) + %li(t2, 0) + ::done + %mov(a0, t2) + %ret %endscope # ========================================================================= @@ -913,11 +983,11 @@ body # sys_exit(code=a0) -> never returns :sys_exit %scope sys_exit -%mov(a1, a0) -%li(a0, %p1_sys_exit) -%syscall -::spin -%b(&::spin) + %mov(a1, a0) + %li(a0, %p1_sys_exit) + %syscall + ::spin + %b(&::spin) %endscope # ========================================================================= @@ -929,123 +999,123 @@ body # compose on top of those two. %fn(print, 16, { -%st(s0, sp, 0) -%st(s1, sp, 8) -%mov(s0, a0) -%mov(s1, a1) - -::loop -%beqz(s1, &::done_ok) -%li(a0, 1) -%mov(a1, s0) -%mov(a2, s1) -%call(&sys_write) -%bltz(a0, &::done) -%add(s0, s0, a0) -%sub(s1, s1, a0) -%b(&::loop) - -::done_ok -%li(a0, 0) -::done -%ld(s0, sp, 0) -%ld(s1, sp, 8) + %st(s0, sp, 0) + %st(s1, sp, 8) + %mov(s0, a0) + %mov(s1, a1) + + ::loop + %beqz(s1, &::done_ok) + %li(a0, 1) + %mov(a1, s0) + %mov(a2, s1) + %call(&sys_write) + %bltz(a0, &::done) + %add(s0, s0, a0) + %sub(s1, s1, a0) + %b(&::loop) + + ::done_ok + %li(a0, 0) + ::done + %ld(s0, sp, 0) + %ld(s1, sp, 8) }) %fn(eprint, 16, { -%st(s0, sp, 0) -%st(s1, sp, 8) -%mov(s0, a0) -%mov(s1, a1) - -::loop -%beqz(s1, &::done_ok) -%li(a0, 2) -%mov(a1, s0) -%mov(a2, s1) -%call(&sys_write) -%bltz(a0, &::done) -%add(s0, s0, a0) -%sub(s1, s1, a0) -%b(&::loop) - -::done_ok -%li(a0, 0) -::done -%ld(s0, sp, 0) -%ld(s1, sp, 8) + %st(s0, sp, 0) + %st(s1, sp, 8) + %mov(s0, a0) + %mov(s1, a1) + + ::loop + %beqz(s1, &::done_ok) + %li(a0, 2) + %mov(a1, s0) + %mov(a2, s1) + %call(&sys_write) + %bltz(a0, &::done) + %add(s0, s0, a0) + %sub(s1, s1, a0) + %b(&::loop) + + ::done_ok + %li(a0, 0) + ::done + %ld(s0, sp, 0) + %ld(s1, sp, 8) }) %fn(println, 16, { -%st(s0, sp, 0) + %st(s0, sp, 0) -%call(&print) -%mov(s0, a0) -%bltz(s0, &::done) + %call(&print) + %mov(s0, a0) + %bltz(s0, &::done) -%la(a0, &libp1pp__newline) -%li(a1, 1) -%call(&print) -%mov(s0, a0) + %la(a0, &libp1pp__newline) + %li(a1, 1) + %call(&print) + %mov(s0, a0) -::done -%mov(a0, s0) -%ld(s0, sp, 0) + ::done + %mov(a0, s0) + %ld(s0, sp, 0) }) %fn(eprintln, 16, { -%st(s0, sp, 0) + %st(s0, sp, 0) -%call(&eprint) -%mov(s0, a0) -%bltz(s0, &::done) + %call(&eprint) + %mov(s0, a0) + %bltz(s0, &::done) -%la(a0, &libp1pp__newline) -%li(a1, 1) -%call(&eprint) -%mov(s0, a0) + %la(a0, &libp1pp__newline) + %li(a1, 1) + %call(&eprint) + %mov(s0, a0) -::done -%mov(a0, s0) -%ld(s0, sp, 0) + ::done + %mov(a0, s0) + %ld(s0, sp, 0) }) %fn(print_cstr, 16, { -%st(s0, sp, 0) -%mov(s0, a0) -%call(&strlen) -%mov(a1, a0) -%mov(a0, s0) -%call(&print) -%ld(s0, sp, 0) + %st(s0, sp, 0) + %mov(s0, a0) + %call(&strlen) + %mov(a1, a0) + %mov(a0, s0) + %call(&print) + %ld(s0, sp, 0) }) %fn(eprint_cstr, 16, { -%st(s0, sp, 0) -%mov(s0, a0) -%call(&strlen) -%mov(a1, a0) -%mov(a0, s0) -%call(&eprint) -%ld(s0, sp, 0) + %st(s0, sp, 0) + %mov(s0, a0) + %call(&strlen) + %mov(a1, a0) + %mov(a0, s0) + %call(&eprint) + %ld(s0, sp, 0) }) %fn(print_int, 0, { -%mov(a1, a0) -%la(a0, &libp1pp__num_buf) -%call(&fmt_dec) -%mov(a1, a0) -%la(a0, &libp1pp__num_buf) -%call(&print) + %mov(a1, a0) + %la(a0, &libp1pp__num_buf) + %call(&fmt_dec) + %mov(a1, a0) + %la(a0, &libp1pp__num_buf) + %call(&print) }) %fn(print_hex, 0, { -%mov(a1, a0) -%la(a0, &libp1pp__num_buf) -%call(&fmt_hex) -%mov(a1, a0) -%la(a0, &libp1pp__num_buf) -%call(&print) + %mov(a1, a0) + %la(a0, &libp1pp__num_buf) + %call(&fmt_hex) + %mov(a1, a0) + %la(a0, &libp1pp__num_buf) + %call(&print) }) # ========================================================================= @@ -1054,45 +1124,45 @@ body # read_file(path=a0, buf=a1, cap=a2) -> n or -1 %fn(read_file, 32, { -%st(s0, sp, 0) -%st(s1, sp, 8) -%st(s2, sp, 16) -%st(s3, sp, 24) - -%mov(s1, a1) -%mov(s2, a2) - -%li(a1, 0) -%li(a2, 0) -%call(&sys_open) -%bltz(a0, &::open_fail) -%mov(s3, a0) - -%mov(a0, s3) -%mov(a1, s1) -%mov(a2, s2) -%call(&sys_read) -%mov(s0, a0) - -%mov(a0, s3) -%call(&sys_close) - -%mov(a0, s0) -%bltz(a0, &::read_fail) -%b(&::done) - -::read_fail -%li(a0, -1) -%b(&::done) - -::open_fail -%li(a0, -1) - -::done -%ld(s0, sp, 0) -%ld(s1, sp, 8) -%ld(s2, sp, 16) -%ld(s3, sp, 24) + %st(s0, sp, 0) + %st(s1, sp, 8) + %st(s2, sp, 16) + %st(s3, sp, 24) + + %mov(s1, a1) + %mov(s2, a2) + + %li(a1, 0) + %li(a2, 0) + %call(&sys_open) + %bltz(a0, &::open_fail) + %mov(s3, a0) + + %mov(a0, s3) + %mov(a1, s1) + %mov(a2, s2) + %call(&sys_read) + %mov(s0, a0) + + %mov(a0, s3) + %call(&sys_close) + + %mov(a0, s0) + %bltz(a0, &::read_fail) + %b(&::done) + + ::read_fail + %li(a0, -1) + %b(&::done) + + ::open_fail + %li(a0, -1) + + ::done + %ld(s0, sp, 0) + %ld(s1, sp, 8) + %ld(s2, sp, 16) + %ld(s3, sp, 24) }) # libp1pp__write_all(fd=a0, buf=a1, len=a2) -> 0 or <0 on error @@ -1101,31 +1171,31 @@ body # / write_file. Retries partial writes but returns the first negative # kernel return unchanged. %fn(libp1pp__write_all, 24, { -%st(s0, sp, 0) -%st(s1, sp, 8) -%st(s2, sp, 16) - -%mov(s0, a0) -%mov(s1, a1) -%mov(s2, a2) - -::loop -%beqz(s2, &::done_ok) -%mov(a0, s0) -%mov(a1, s1) -%mov(a2, s2) -%call(&sys_write) -%bltz(a0, &::done) -%add(s1, s1, a0) -%sub(s2, s2, a0) -%b(&::loop) - -::done_ok -%li(a0, 0) -::done -%ld(s0, sp, 0) -%ld(s1, sp, 8) -%ld(s2, sp, 16) + %st(s0, sp, 0) + %st(s1, sp, 8) + %st(s2, sp, 16) + + %mov(s0, a0) + %mov(s1, a1) + %mov(s2, a2) + + ::loop + %beqz(s2, &::done_ok) + %mov(a0, s0) + %mov(a1, s1) + %mov(a2, s2) + %call(&sys_write) + %bltz(a0, &::done) + %add(s1, s1, a0) + %sub(s2, s2, a0) + %b(&::loop) + + ::done_ok + %li(a0, 0) + ::done + %ld(s0, sp, 0) + %ld(s1, sp, 8) + %ld(s2, sp, 16) }) # write_file(path=a0, buf=a1, len=a2) -> 0 or -1 @@ -1133,44 +1203,44 @@ body # Flags: O_WRONLY|O_CREAT|O_TRUNC. On Linux these are 0x1 | 0x40 | # 0x200 = 0x241. Mode 0644 octal = 0x1A4. %fn(write_file, 24, { -%st(s0, sp, 0) -%st(s1, sp, 8) -%st(s2, sp, 16) - -%mov(s0, a1) -%mov(s1, a2) - -%li(a1, 0x241) -%li(a2, 0x1A4) -%call(&sys_open) -%bltz(a0, &::open_fail) -%mov(s2, a0) - -%mov(a0, s2) -%mov(a1, s0) -%mov(a2, s1) -%call(&libp1pp__write_all) - -%mov(s0, a0) -%mov(a0, s2) -%call(&sys_close) - -%mov(a0, s0) -%bltz(a0, &::fail_ret) -%li(a0, 0) -%b(&::done) - -::fail_ret -%li(a0, -1) -%b(&::done) - -::open_fail -%li(a0, -1) - -::done -%ld(s0, sp, 0) -%ld(s1, sp, 8) -%ld(s2, sp, 16) + %st(s0, sp, 0) + %st(s1, sp, 8) + %st(s2, sp, 16) + + %mov(s0, a1) + %mov(s1, a2) + + %li(a1, 0x241) + %li(a2, 0x1A4) + %call(&sys_open) + %bltz(a0, &::open_fail) + %mov(s2, a0) + + %mov(a0, s2) + %mov(a1, s0) + %mov(a2, s1) + %call(&libp1pp__write_all) + + %mov(s0, a0) + %mov(a0, s2) + %call(&sys_close) + + %mov(a0, s0) + %bltz(a0, &::fail_ret) + %li(a0, 0) + %b(&::done) + + ::fail_ret + %li(a0, -1) + %b(&::done) + + ::open_fail + %li(a0, -1) + + ::done + %ld(s0, sp, 0) + %ld(s1, sp, 8) + %ld(s2, sp, 16) }) # ========================================================================= @@ -1198,24 +1268,24 @@ body # pre-advance value; on failure, leave the cursor untouched and return 0. :bump_alloc %scope bump_alloc -%addi(a0, a0, 7) -%li(t0, -8) -%and(a0, a0, t0) -%la(t0, &libp1pp__bump_cursor) -%ld(t1, t0, 0) -%add(t2, t1, a0) -%la(a1, &libp1pp__bump_base) -%ld(a2, a1, 0) -%la(a1, &libp1pp__bump_cap) -%ld(a3, a1, 0) -%add(a3, a2, a3) -%bltu(a3, t2, &::fail) -%st(t2, t0, 0) -%mov(a0, t1) -%ret -::fail -%li(a0, 0) -%ret + %addi(a0, a0, 7) + %li(t0, -8) + %and(a0, a0, t0) + %la(t0, &libp1pp__bump_cursor) + %ld(t1, t0, 0) + %add(t2, t1, a0) + %la(a1, &libp1pp__bump_base) + %ld(a2, a1, 0) + %la(a1, &libp1pp__bump_cap) + %ld(a3, a1, 0) + %add(a3, a2, a3) + %bltu(a3, t2, &::fail) + %st(t2, t0, 0) + %mov(a0, t1) + %ret + ::fail + %li(a0, 0) + %ret %endscope # bump_mark() -> saved @@ -1246,14 +1316,14 @@ body # panic(msg_cstr=a0) -> never returns %fn(panic, 0, { -%call(&eprint_cstr) -%la(a0, &libp1pp__newline) -%li(a1, 1) -%call(&eprint) -%li(a0, 1) -%call(&sys_exit) -::spin -%b(&::spin) + %call(&eprint_cstr) + %la(a0, &libp1pp__newline) + %li(a1, 1) + %call(&eprint) + %li(a0, 1) + %call(&sys_exit) + ::spin + %b(&::spin) }) # =========================================================================