forked from TCShenanigans/symphony_stdlib
Add decimal for small (up to 8 digit) numbers
This commit is contained in:
+87
-6
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user