kvisc/ka/fmt/itoa.k

113 lines
1.6 KiB
Plaintext
Raw Normal View History

2019-05-30 18:31:50 +02:00
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
2019-06-05 22:11:45 +02:00
; char *_itoa(char *buf, int num, int base, int unsi)
2019-05-30 18:31:50 +02:00
;
2019-06-05 22:11:45 +02:00
; Acts as itoa if unsi == 0, as utoa otherwise
;
_itoa:
mov rax, ax0
xor rdx, rdx
; make sure base is in [2, 32]
cmp ax2, 2
cjmpb .bad
cmp ax2, 36
cjmpa .bad
; deal with zero
test ax1, ax1
cjmpz .zero
; deal with base 10 signedness
test ax3, ax3 ; unsigned mode
cjmpnz .conv
cmp ax2, 10 ; base 10
cjmpnz .conv
2019-06-05 22:59:32 +02:00
cmp ax1, -9223372036854775808 ; LONG_MIN
2019-06-05 22:11:45 +02:00
cjmpz .min
sgn rdx, ax1 ; extract ax1 sign
cmp rdx, -1 ; negative?
cnotz ax1 ; -x = ~x+1
cincz ax1 ; need "neg" inst...
; main loop
.conv:
test ax1, ax1
cjmpz .fini
mov rsx, ax1
mod rsx, ax2 ; ax1 % base
cmp rsx, 9 ; rsx > 9 ?
2019-06-05 22:59:32 +02:00
cjmpa .nondec
2019-06-05 22:11:45 +02:00
2019-06-05 22:59:32 +02:00
add rsx, 48 ; '0'
jmp .next
.nondec:
2019-06-05 22:11:45 +02:00
add rsx, 87 ; 'a' - 10
.next:
mov b[ax0], rsx
inc ax0
div ax1, ax2
jmp .conv
2019-06-05 22:59:32 +02:00
; add minus flag, null-terminate and reverse
2019-06-05 22:11:45 +02:00
.fini:
2019-06-05 22:59:32 +02:00
cmp rdx, -1
cmovz b[ax0], 45 ; '-'
cincz ax0
2019-06-05 22:11:45 +02:00
mov b[ax0], 0
2019-06-05 22:59:32 +02:00
mov ax0, rax
call strrev2
2019-06-05 22:11:45 +02:00
ret
;
; exceptional cases
;
.bad:
mov q[errno], EINVAL
mov b[rax], 0
ret
.zero:
mov b[ax0], 48 ; '0'
mov b[ax0+1], 0
ret
.min:
mov ax1, .min10
call strcpy
ret
.min10 = "-9223372036854775808"
;
; wrappers
;
itoa:
mov ax3, 0
jmp _itoa
utoa:
mov ax3, 1
jmp _itoa