kvisc/ka/crt/fmt/itoa.k

101 lines
1.3 KiB
Plaintext

; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; wrappers
;
itoa:
mov ax3, 0
jmp _itoa
utoa:
mov ax3, 1
jmp _itoa
;
; void _itoa(char *buf, int num, int base, int unsi)
;
; Behaves as itoa if unsi == 0, as utoa otherwise
;
_itoa:
mov rax, ax0
xor lx0, lx0
; make sure base is in [2, 32]
cmp ax2, 2
jmp.b .bad
cmp ax2, 36
jmp.a .bad
; deal with zero
test ax1, ax1
jmp.z .zero
; deal with base 10 signedness
test ax3, ax3 ; unsigned mode
jmp.nz .conv
cmp ax2, 10 ; base 10
jmp.nz .conv
sgn lx0, ax1 ; extract ax1 sign
cmp lx0, -1 ; negative?
neg.z ax1
; main loop
.conv:
test ax1, ax1
jmp.z .fini
mov lx1, ax1
mod lx1, ax2 ; ax1 % base
cmp lx1, 9 ; lx1 > 9 ?
jmp.a .nondec
add lx1, '0'
jmp .next
.nondec:
add lx1, 55 ; 'A' - 10
.next:
mov b[ax0], lx1
inc ax0
div ax1, ax2
jmp .conv
; add minus flag, null-terminate and reverse
.fini:
cmp lx0, -1
mov.z b[ax0], '-'
inc.z ax0
mov b[ax0], 0
mov ax0, rax
call strrev2
ret
;
; exceptional cases
;
.bad:
mov q[errno], EINVAL
mov b[ax0], 0
ret
.zero:
mov b[ax0], 48 ; '0'
mov b[ax0+1], 0
ret