This commit is contained in:
julianb0 2019-06-23 20:56:04 +02:00
parent 97e52b65bb
commit bdb36e2864
No known key found for this signature in database
GPG Key ID: 9C7ACF0C053FB8A1
12 changed files with 288 additions and 19 deletions

9
ka/crt/chr/ctype.k Normal file
View File

@ -0,0 +1,9 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; bool isdigit(int c)
;
isdigit:
ret

View File

@ -1,7 +1,8 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
include "crt/fmt/itoa.k"
include "crt/fmt/ltostr.k"
include "crt/fmt/strtol.k"
include "crt/fmt/doprnt.k"
include "crt/fmt/printf.k"

View File

@ -5,14 +5,25 @@
; void itoa(char *buf, int num, int base)
;
itoa:
mov ax3, 1
jmp ltostr
;
; void utoa(char *buf, int num, int base)
;
sub ax3, ax3
jmp ltostr
;
; void ltostr(char *buf, int num, int base, bool signed)
;
ltostr:
mov rax, ax0
xor lx0, lx0
; make sure base is in [2, 32]
cmp ax2, 2
j.b .bad
cmp ax2, 36
j.a .bad
@ -22,7 +33,8 @@ itoa:
; deal with base 10 signedness
cmp ax2, 10 ; base 10
test ax3, ax3
cmp.nz ax2, 10 ; base 10
j.nz .conv
sgn lx0, ax1 ; extract ax1 sign
@ -70,7 +82,6 @@ itoa:
;
; exceptional cases
;
.bad:
mov q[errno], EINVAL
mov b[ax0], 0

170
ka/crt/fmt/strtol.k Normal file
View File

@ -0,0 +1,170 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; int strtol(const char *str, int base)
;
; rax = integer extracted from str
; rdx = pointer to first invalid byte
;
strtol:
mov ax2, 1
jmp strtoq
;
; int strtoul(const char *str, int base)
;
; rax = integer extracted from str
; rdx = pointer to first invalid byte
;
strtoul:
sub ax2, ax2
jmp strtoq
;
; int strtoq(const char *str, int base, bool signed)
;
; guesses base when 'base'=0
;
strtoq:
xor rax, rax
mov rdx, ax0
; make sure base is in [2, 32]
cmp ax1, 1
j.z .bad
cmp ax1, 36
j.a .bad
; empty string?
cmp b[rdx], 0
jmp.z .done
.skip_spc:
cmp b[rdx], ' '
inc.z rdx
jmp.z .skip_spc
; skip +
cmp b[rdx], '+'
inc.z rdx
; signed?
test ax2, ax2
sub.z lx1, lx1
jmp.z .unsigned
; parse '-'
cmp b[rdx], '-'
inc.z rdx
mov.z lx1, 1
sub.nz lx1, lx1
.unsigned:
; base 0
test ax1, ax1
jmp.z .base_0
; base prefix?
cmp b[rdx], '0'
jmp.nz .main_loop
inc rdx
; string is "0"
cmp b[rdx], 0
jmp.z .done
; "0x" prefix
cmp b[rdx], 'x'
jmp.z .parsed_0x
; "0b" prefix
cmp b[rdx], 'b'
jmp.z .parsed_0b
; may be octal, but we don't care
; we accept "0110101010" (binary) for instance
jmp .main_loop
.parsed_0x:
; are we in base 16?
; if not, leave rax = 0 and *rdx = 'x'
cmp ax1, 16
jmp.nz .done
; else
inc rdx
jmp .main_loop
.parsed_0b:
; are we in base 2?
; if not, leave rax = 0 and *rdx = 'b'
cmp ax1, 2
jmp.nz .done
; else
inc rdx
jmp .main_loop
.base_0:
; guess base
cmp b[rdx], '0'
mov.nz ax1, 10
jmp.nz .main_loop
inc rdx
cmp b[rdx], 'x'
inc.z rdx
mov.z ax1, 16
jmp.z .main_loop
cmp b[rdx], 'b'
inc.z rdx
mov.z ax1, 2
jmp.z .main_loop
mov ax1, 8
.main_loop:
mov lx0, b[rdx]
inc rdx
cmp lx0, '0'
jmp.b .done
cmp.ae lx0, '9'
sub.be lx0, '0'
jmp.be .next
cmp lx0, 'A'
cmp.ae lx0, 'Z'
sub.be lx0, 55 ; 'A' - 10
jmp.be .next
cmp lx0, 'a'
jmp.b .next
cmp.ae lx0, 'z'
sub.be lx0, 87 ; 'a' - 10
jmp.be .next
.next:
; too large for base?
cmp lx0, ax1
jmp.ae .done
mul rax, ax1
add rax, lx0
jmp .main_loop
.done:
; negative?
test lx1, lx1
ret.z
; yes
neg rax
ret
.bad:
mov q[errno], EINVAL
ret

View File

@ -10,6 +10,10 @@ start:
call main
call strtol_test
stop
; Wait for and print input indefinitely
.1:
scan rax

View File

@ -13,6 +13,5 @@ PrintBootMsg:
;
main:
call PrintBootMsg
ret

View File

@ -1,6 +1,34 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
strtol_test:
mov ax0, .s1
mov ax1, 10
call strtol
mov nx0, rax
mov ax0, .s2
mov ax1, 16
call strtol
mov nx1, rax
mov ax0, .s3
mov ax1, 0
call strtol
mov nx2, rax
mov ax0, .s4
mov ax1, 10
call strtol
mov nx3, rax
ret
.s1 = "+065536"
.s2 = "0xABCD"
.s3 = "0b100000"
.s4 = "-1"
speed_test:
utime lx0
@ -12,7 +40,7 @@ speed_test:
mov rax, lx1
sub rax, lx0
stop
ret
putc_scroll_test:
mov rdx, 25

View File

@ -58,8 +58,14 @@ xor rm rim
xorf rm rim
# To document
shl rm rim
shr rm rim
shlf rm rim
shrf rm rim
sal rm rim
sar rm rim
salf rm rim
sarf rm rim

View File

@ -4,8 +4,6 @@
#include <in/instrs.h>
#include <pc/console.h>
//----------------------------------------------------------------------------//
IMPL_START_1(prn)
{
if (p1->mlen > 1) {
@ -13,9 +11,7 @@ IMPL_START_1(prn)
}
console_putc(ctx, (char)v1);
}
IMPL_END;
//----------------------------------------------------------------------------//
IMPL_END
IMPL_START_1(scan)
{
@ -23,5 +19,3 @@ IMPL_START_1(scan)
}
IMPL_OUT;
//----------------------------------------------------------------------------//

View File

@ -91,3 +91,49 @@ IMPL_OUT_ZSF;
//--------------------------------------------------------------------------
IMPL_START_2(sal)
{
long w1 = v1;
long w2 = v2;
w1 <<= w2;
v1 = (ulong) w1;
}
IMPL_OUT;
IMPL_START_2(salf)
{
long w1 = v1;
long w2 = v2;
w1 <<= w2;
v1 = (ulong) w1;
}
IMPL_OUT_ZSF;
IMPL_START_2(sar)
{
long w1 = v1;
long w2 = v2;
w1 >>= w2;
v1 = (ulong) w1;
}
IMPL_OUT;
IMPL_START_2(sarf)
{
long w1 = v1;
long w2 = v2;
w1 >>= w2;
v1 = (ulong) w1;
}
IMPL_OUT_ZSF;
//--------------------------------------------------------------------------

View File

@ -101,11 +101,6 @@ static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
addr += cr2; \
ulong real = addr2real(addr)
#define SIGN_EXTEND(val, mask) \
(val & ((mask + 1) >> 1) \
? (val | ~mask) \
: val)
//----------------------------------------------------------------------------//
ulong readmem(ctx_t *ctx, ulong addr, uint len)

View File

@ -21,3 +21,9 @@ void writemem(ctx_t *, ulong val, ulong addr, uint len);
ulong readmemzx(ctx_t *c, ulong addr, uint len);
void writememzx(ctx_t *, ulong val, ulong addr, uint len);
#define SIGN_EXTEND(val, mask) \
(val & ((mask + 1) >> 1) \
? (val | ~mask) \
: val)