1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
This commit is contained in:
julianb0 2019-06-16 21:17:56 +02:00
parent 4083b0a00c
commit 47b2677430
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
9 changed files with 106 additions and 34 deletions

View File

@ -6,7 +6,7 @@ all: kas
kpc: kpc:
@cd vm && make --no-print-directory verbose=no @cd vm && make --no-print-directory verbose=no
kas: kpc as/k-as.py as/regs.lst as/ kas: kpc as/regs.lst as/k-as.py
@cp vm/in/instrs.lst as @cp vm/in/instrs.lst as
DOSK = $(shell find ka -name '*.k') DOSK = $(shell find ka -name '*.k')

View File

@ -394,26 +394,25 @@ def parse_instr(line):
# Word 2 (rep|cond|ft1|ft2) # Word 2 (rep|cond|ft1|ft2)
w2 = 0 w2 = 0
if '.' in instr: if len(instr) > 2 and '.' in instr:
w2 |= get_cond_mask(instr.split('.', 1)[1], line) instr, suf = instr.split('.', 1)
instr = instr.split('.', 1)[0]
if len(instr) == 0:
print("Missing instruction name before suffixes: {}".format(line))
if len(suf) > 2 and suf[:3] == "rep":
if len(suf) > 3:
suf = suf[3:]
if len(suf) > 0 and suf[0] == '.':
suf = suf[1:]
else: else:
instr = instr suf = ''
if instr == "rep": w2 |= 0x8000 # REP
if params == None:
print("Missing instruction after rep prefix: {}".format(line))
leave()
sys.exit(1)
w2 |= 0x8000 # 16th bit if len(suf) > 0:
w2 |= get_cond_mask(suf, line)
if len(params.split(' ', 1)) == 2:
instr, params = params.split(' ', 1)
else:
instr = params.split(' ', 1)[0]
params = None
instr_name = instr instr_name = instr
instr_args = '' instr_args = ''

View File

@ -21,7 +21,7 @@ strncmp:
mov.cxz rax, 0 mov.cxz rax, 0
ret.cxz ret.cxz
rep.e cmpzsb ax0, ax1 cmpzsb.rep.e ax0, ax1
mov rax, b[ax0] mov rax, b[ax0]
sub rax, b[ax1] sub rax, b[ax1]

View File

@ -15,7 +15,7 @@ strncpy:
mov rcx, ax2 mov rcx, ax2
ret.cxz ret.cxz
rep.nz movsb ax0, ax1 movsb.rep.nz ax0, ax1
ret ret
@ -29,7 +29,7 @@ strnzcpy:
dec rcx dec rcx
jmp.cxz .1 jmp.cxz .1
rep.nz movsb ax0, ax1 movsb.rep.nz ax0, ax1
.1: .1:
mov b[ax0], 0 mov b[ax0], 0

View File

@ -6,7 +6,7 @@
; ;
strnlen: strnlen:
mov rcx, ax1 mov rcx, ax1
rep.nz scasb ax0, 0 scasb.rep.nz ax0, 0
mov rax, ax1 mov rax, ax1
sub rax, rcx sub rax, rcx

View File

@ -16,10 +16,9 @@ strrev:
; go to str's end, just before ; go to str's end, just before
; the null terminator ; the null terminator
.1: mov rcx, STRLEN_MAX
test b[ax1+1], b[ax1+1] scazsb.rep.nz ax1
inc.nz ax1 dec ax1
jmp.nz .1
.2: .2:
; copy, going backward though str ; copy, going backward though str
@ -48,10 +47,9 @@ strrev2:
; go to str's end, just before ; go to str's end, just before
; the null terminator ; the null terminator
.1: mov rcx, STRLEN_MAX
test b[ax1+1], b[ax1+1] scazsb.rep.nz ax1
inc.nz ax1 dec ax1
jmp.nz .1
; increase ax0 while decreasing ax1, performing exchanges ; increase ax0 while decreasing ax1, performing exchanges
.2: .2:

View File

@ -5,7 +5,7 @@
; Main function ; Main function
; ;
main: main:
call showoff call itoa_test
ret ret
showoff: showoff:
@ -35,12 +35,11 @@ ramdev_test:
ret ret
stosb_test: stosb_test:
cld
mov rcx, 11 mov rcx, 11
mov rax, 33 mov rax, 33
mov rdi, .buf mov rdi, .buf
mov rsi, .buf mov rsi, .buf
rep stosb stosb.rep
mov rbx, rdi mov rbx, rdi
sub rbx, rsi sub rbx, rsi

View File

@ -412,10 +412,43 @@ lodsb r r
# When one parameter is given, %str = RDI and $val = $1 # When one parameter is given, %str = RDI and $val = $1
# When two parameters are given, %str = $1 and $val = $2 # When two parameters are given, %str = $1 and $val = $2
# #
# Note that SCASx moves in the string no matter whether the value
# was found or not; therefore when the value *is* found, it will
# be sizeof(x) bytes below the current value of %str
#
scasb scasb
scasb rim scasb rim
scasb r rim scasb r rim
#
# Scan string for null terminator (SCAZSx)
#
# CMP([%str], 0)
#
# IF (ZF == 0)
# IF (DF == 0) THEN
# %str = %str + sizeof(x)
# ELSE
# %str = %str - sizeof(x)
# FI
# FI
#
# Sets CF, OF, ZF and SF according to the result of the comparison
#
# When no parameters are given, %str = RDI and $val = RAX
# When one parameter is given, %str = RDI and $val = $1
# When two parameters are given, %str = $1 and $val = $2
#
# Unlike SCASx, this instruction does NOT move forward after
# finding what it was looking for. The instruction:
# REP.NZ SCAZSx %str
# serves as a much faster shorthand for
# REP.NZ SCASx %str
# DEC %str
#
scazsb
scazsb r
# #
# Compare bytes in strings (CMPSx) # Compare bytes in strings (CMPSx)
# #
@ -445,7 +478,7 @@ cmpsb r r
# Behaves precisely like CMPSx, except in the following case: # Behaves precisely like CMPSx, except in the following case:
# - If both [%str1] and [%str2] are zero, clears ZF (indicating NOT EQUAL) # - If both [%str1] and [%str2] are zero, clears ZF (indicating NOT EQUAL)
# #
# This prevents 'rep.e cmpsb' from looping infinitely when both strings # This prevents 'REP.Z CMPZSx' from looping infinitely when both strings
# have the exact same content; this allows for short strcmp's # have the exact same content; this allows for short strcmp's
# #
cmpzsb cmpzsb

View File

@ -170,6 +170,49 @@ IMPL_END;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
static void scazs_impl(ctx_t *ctx, acc_t *p1, uint len)
{
ulong reg;
if (p1)
reg = p1->reg;
else
reg = RDI;
ulong x = readmem(ctx, R(reg), len);
COMPARE(x, 0);
if (!(flg&ZF)) {
STR_MOVE(reg, len);
}
}
IMPL_START_0(scazsb)
{
scazs_impl(ctx, p1, 1);
}
IMPL_END;
IMPL_START_0(scazsw)
{
scazs_impl(ctx, p1, 2);
}
IMPL_END;
IMPL_START_0(scazsl)
{
scazs_impl(ctx, p1, 4);
}
IMPL_END;
IMPL_START_0(scazsq)
{
scazs_impl(ctx, p1, 8);
}
IMPL_END;
//----------------------------------------------------------------------------//
static void cmps_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) static void cmps_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{ {
ulong reg1, reg2; ulong reg1, reg2;