Add decimal for small (up to 8 digit) numbers

This commit is contained in:
PleegWat
2026-09-15 21:11:14 +02:00
parent ae5f90456c
commit 016c6f7008
2 changed files with 91 additions and 7 deletions
+87 -6
View File
@@ -17,6 +17,8 @@ cmp r4, 8
je oct je oct
cmp r4, 16 cmp r4, 16
je hex je hex
cmp r4, 10
jmp dec
mov flags, errno.INTTOSTR_BAD_BASE mov flags, errno.INTTOSTR_BAD_BASE
jmp r13 jmp r13
@@ -52,7 +54,7 @@ lsr r5, r1, r4 ; Select bit and advance counter
and r5, r5, 1 and r5, r5, 1
sub r4, r4, 1 sub r4, r4, 1
cmp r4, 0 ; Start printing if last bit ... cmp r4, zr ; Start printing if last bit ...
jl bin_print jl bin_print
cmp r5, zr ; .. or if nonzero cmp r5, zr ; .. or if nonzero
je bin_find_one je bin_find_one
@@ -65,7 +67,7 @@ bin_print:
add r5, r5, 0x30 ; '0' ; Add digit to buffer add r5, r5, 0x30 ; '0' ; Add digit to buffer
store_8 [r2], r5 store_8 [r2], r5
add r2, r2, 1 add r2, r2, 1
cmp r4, 0 ; Done if last bit cmp r4, zr ; Done if last bit
jl done jl done
lsr r5, r1, r4 ; Select bit and advance counter lsr r5, r1, r4 ; Select bit and advance counter
and r5, r5, 1 and r5, r5, 1
@@ -94,7 +96,7 @@ and r5, r5, 7
sub r4, r4, 3 sub r4, r4, 3
sub r6, r6, 1 sub r6, r6, 1
cmp r4, 0 ; Start printing if last bit ... cmp r4, zr ; Start printing if last bit ...
jl oct_print jl oct_print
cmp r5, zr ; .. or if nonzero cmp r5, zr ; .. or if nonzero
je oct_find_one je oct_find_one
@@ -106,7 +108,7 @@ oct_print:
add r5, r5, 0x30 ; '0' ; Add digit to buffer add r5, r5, 0x30 ; '0' ; Add digit to buffer
store_8 [r2], r5 store_8 [r2], r5
add r2, r2, 1 add r2, r2, 1
cmp r4, 0 ; Done if last bit cmp r4, zr ; Done if last bit
jl done jl done
lsr r5, r1, r4 ; Select bit and advance counter lsr r5, r1, r4 ; Select bit and advance counter
and r5, r5, 7 and r5, r5, 7
@@ -132,7 +134,7 @@ lsr r5, r1, r4 ; Select bit and advance counter
and r5, r5, 0xF and r5, r5, 0xF
sub r4, r4, 4 sub r4, r4, 4
cmp r4, 0 ; Start printing if last bit ... cmp r4, zr ; Start printing if last bit ...
jl hex_print jl hex_print
cmp r5, zr ; .. or if nonzero cmp r5, zr ; .. or if nonzero
je hex_find_one je hex_find_one
@@ -150,9 +152,88 @@ add r5, r5, 0x07 ; 'A' - '0' - 10
hex_no_letter: hex_no_letter:
store_8 [r2], r5 store_8 [r2], r5
add r2, r2, 1 add r2, r2, 1
cmp r4, 0 ; Done if last bit cmp r4, zr ; Done if last bit
jl done jl done
lsr r5, r1, r4 ; Select bit and advance counter lsr r5, r1, r4 ; Select bit and advance counter
and r5, r5, 0xF and r5, r5, 0xF
sub r4, r4, 4 sub r4, r4, 4
jmp hex_print jmp hex_print
; Convert integer to decimal string
; Arguments:
; r1 - Integer
; r2 - Start of buffer
; r3 - Buffer length
; Result:
; none
; Clobbers:
; flags
; r4, r5
pub dec:
mov r4, 0x5F5
lsl r4, r4, 16
add r4, r4, 0xE100 ; 100 million; 8 digits
cmp r1, r4
jl dec_small
; TODO large
; Small numbers have at least most 8 digits, thus their BCD form fits in
; one register. Bit 26 is the highest which can be set.
;
; Utilizes double dabble
; r4, r5 are loop counters
;
; for( r4 = 24 ; r4 >= 0 ; r4-- )
; for( r5 = r4 ; r5 <= 28 ; r5+= 4 )
; if( ((r1 >> r5) & 0xF) >= 5 )
; r1 += 3 << r5
dec_small:
mov r4, 24
dec_small_dabble_outer:
mov r5, r4
dec_small_dabble_inner:
lsr flags, r1, r5
and flags, flags, 0xF
cmp flags, 5
jl dec_small_dabble_noinc
mov flags, 3
lsl flags, flags, r5
add r1, r1, flags
dec_small_dabble_noinc:
add r5, r5, 4
cmp r5, 28
jl dec_small_dabble_inner
sub r4, r4, 1
cmp r4, zr
jg dec_small_dabble_outer
; Print the BCD in r1
; r4 is a counter
; r5 is the output character
mov r4, 28
dec_find_one:
lsr r5, r1, r4 ; Select bit and advance counter
and r5, r5, 0xF
sub r4, r4, 4
cmp r4, zr ; Start printing if last bit ...
jl dec_print
cmp r5, zr ; .. or if nonzero
je dec_find_one
lsr flags, r5, 2 ; Check buffer size
add flags, flags, 3
cmp flags, r3
ja badbuffer
dec_print:
add r5, r5, 0x30 ; '0' ; Add digit to buffer
store_8 [r2], r5
add r2, r2, 1
cmp r4, zr ; Done if last bit
jl done
lsr r5, r1, r4 ; Select bit and advance counter
and r5, r5, 0xF
sub r4, r4, 4
jmp dec_print
+4 -1
View File
@@ -52,7 +52,10 @@ tests:
@0x201c0 U32 0x32fF6 U8 16 "32FF6\0" @0x201c0 U32 0x32fF6 U8 16 "32FF6\0"
@0x20200 U32 0xdeadbeef U8 16 "DEADBEEF\0" @0x20200 U32 0xdeadbeef U8 16 "DEADBEEF\0"
@0x20240 U32 0xFFFFFFFF U8 16 "FFFFFFFF\0" @0x20240 U32 0xFFFFFFFF U8 16 "FFFFFFFF\0"
@0x20280 @0x20280 U32 0 U8 10 "0\0"
@0x202c0 U32 42069 U8 10 "42069\0"
@0x20300 U32 12345678 U8 10 "12345678\0"
@0x20340
end_of_tests: end_of_tests:
scratch: U1024 0 scratch: U1024 0