commit c576c830a889502cf3a6ee0dfb510cbb21a02a26
parent ef80474926e643782b6684c10ec7367bd2a1ed01
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Sat, 25 Apr 2026 14:51:09 -0700
scheme1: fix parse_dec
Diffstat:
1 file changed, 39 insertions(+), 29 deletions(-)
diff --git a/scheme1/scheme1.P1pp b/scheme1/scheme1.P1pp
@@ -1136,51 +1136,61 @@
# or any non-digit byte. On failure a0 still holds the best-effort
# accumulator (sign-applied, retagged) so reader-style callers that
# don't check ok get the same garbage they got before this routine
-# validated. UB on integer overflow.
+# validated. UB on integer overflow. Uses only t0..t2.
+#
+# Register map:
+# t0 = current ptr a0 = byte / digit / final value
+# t1 = remaining length a1 = ok flag (output)
+# t2 = constant 10 a2 = sign flag (1 = negative)
+# a3 = accumulator (raw value)
:parse_dec
%scope parse_dec
- %li(t4, 0) ; sign flag (0 = positive)
- %li(t0, 0) ; accumulator (raw)
- %beqz(a1, &::fail)
+ %mov(t0, a0)
+ %mov(t1, a1)
+ %li(a2, 0)
+ %li(a3, 0)
+ %beqz(t1, &::fail)
- %lb(t2, a0, 0)
- %li(t3, 45) ; '-'
- %bne(t2, t3, &::loop)
- %li(t4, 1)
- %addi(a0, a0, 1)
- %addi(a1, a1, -1)
- %beqz(a1, &::fail)
+ %lb(a0, t0, 0)
+ %addi(a0, a0, -45) ; '-'
+ %bnez(a0, &::loop_init)
+ %li(a2, 1)
+ %addi(t0, t0, 1)
+ %addi(t1, t1, -1)
+ %beqz(t1, &::fail)
+
+ ::loop_init
+ %li(t2, 10)
::loop
- %beqz(a1, &::done)
- %lb(t2, a0, 0)
- %addi(t2, t2, -48)
- %bltz(t2, &::fail)
- %li(t3, 10)
- %bltu(t2, t3, &::digit_ok)
+ %beqz(t1, &::done)
+ %lb(a0, t0, 0)
+ %addi(a0, a0, -48)
+ %bltz(a0, &::fail)
+ %bltu(a0, t2, &::digit_ok)
%b(&::fail)
::digit_ok
- %mul(t0, t0, t3)
- %add(t0, t0, t2)
- %addi(a0, a0, 1)
- %addi(a1, a1, -1)
+ %mul(a3, a3, t2)
+ %add(a3, a3, a0)
+ %addi(t0, t0, 1)
+ %addi(t1, t1, -1)
%b(&::loop)
::done
- %beqz(t4, &::tag)
- %li(t1, 0)
- %sub(t0, t1, t0)
+ %beqz(a2, &::tag)
+ %li(t2, 0)
+ %sub(a3, t2, a3)
::tag
- %mkfix(a0, t0)
+ %mkfix(a0, a3)
%li(a1, 1)
%ret
::fail
- %beqz(t4, &::fail_tag)
- %li(t1, 0)
- %sub(t0, t1, t0)
+ %beqz(a2, &::fail_tag)
+ %li(t2, 0)
+ %sub(a3, t2, a3)
::fail_tag
- %mkfix(a0, t0)
+ %mkfix(a0, a3)
%li(a1, 0)
%ret
%endscope