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
|
||||
cmp r4, 16
|
||||
je hex
|
||||
cmp r4, 10
|
||||
jmp dec
|
||||
mov flags, errno.INTTOSTR_BAD_BASE
|
||||
jmp r13
|
||||
|
||||
@@ -52,7 +54,7 @@ lsr r5, r1, r4 ; Select bit and advance counter
|
||||
and r5, r5, 1
|
||||
sub r4, r4, 1
|
||||
|
||||
cmp r4, 0 ; Start printing if last bit ...
|
||||
cmp r4, zr ; Start printing if last bit ...
|
||||
jl bin_print
|
||||
cmp r5, zr ; .. or if nonzero
|
||||
je bin_find_one
|
||||
@@ -65,7 +67,7 @@ bin_print:
|
||||
add r5, r5, 0x30 ; '0' ; Add digit to buffer
|
||||
store_8 [r2], r5
|
||||
add r2, r2, 1
|
||||
cmp r4, 0 ; Done if last bit
|
||||
cmp r4, zr ; Done if last bit
|
||||
jl done
|
||||
lsr r5, r1, r4 ; Select bit and advance counter
|
||||
and r5, r5, 1
|
||||
@@ -94,7 +96,7 @@ and r5, r5, 7
|
||||
sub r4, r4, 3
|
||||
sub r6, r6, 1
|
||||
|
||||
cmp r4, 0 ; Start printing if last bit ...
|
||||
cmp r4, zr ; Start printing if last bit ...
|
||||
jl oct_print
|
||||
cmp r5, zr ; .. or if nonzero
|
||||
je oct_find_one
|
||||
@@ -106,7 +108,7 @@ oct_print:
|
||||
add r5, r5, 0x30 ; '0' ; Add digit to buffer
|
||||
store_8 [r2], r5
|
||||
add r2, r2, 1
|
||||
cmp r4, 0 ; Done if last bit
|
||||
cmp r4, zr ; Done if last bit
|
||||
jl done
|
||||
lsr r5, r1, r4 ; Select bit and advance counter
|
||||
and r5, r5, 7
|
||||
@@ -132,7 +134,7 @@ lsr r5, r1, r4 ; Select bit and advance counter
|
||||
and r5, r5, 0xF
|
||||
sub r4, r4, 4
|
||||
|
||||
cmp r4, 0 ; Start printing if last bit ...
|
||||
cmp r4, zr ; Start printing if last bit ...
|
||||
jl hex_print
|
||||
cmp r5, zr ; .. or if nonzero
|
||||
je hex_find_one
|
||||
@@ -150,9 +152,88 @@ add r5, r5, 0x07 ; 'A' - '0' - 10
|
||||
hex_no_letter:
|
||||
store_8 [r2], r5
|
||||
add r2, r2, 1
|
||||
cmp r4, 0 ; Done if last bit
|
||||
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 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"
|
||||
@0x20200 U32 0xdeadbeef U8 16 "DEADBEEF\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:
|
||||
scratch: U1024 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user