mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
rep
This commit is contained in:
parent
4083b0a00c
commit
47b2677430
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ all: kas
|
||||
kpc:
|
||||
@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
|
||||
|
||||
DOSK = $(shell find ka -name '*.k')
|
||||
|
33
as/k-as.py
33
as/k-as.py
@ -394,26 +394,25 @@ def parse_instr(line):
|
||||
# Word 2 (rep|cond|ft1|ft2)
|
||||
w2 = 0
|
||||
|
||||
if '.' in instr:
|
||||
w2 |= get_cond_mask(instr.split('.', 1)[1], line)
|
||||
instr = instr.split('.', 1)[0]
|
||||
if len(instr) > 2 and '.' in instr:
|
||||
instr, suf = instr.split('.', 1)
|
||||
|
||||
if len(instr) == 0:
|
||||
print("Missing instruction name before suffixes: {}".format(line))
|
||||
|
||||
else:
|
||||
instr = instr
|
||||
if len(suf) > 2 and suf[:3] == "rep":
|
||||
if len(suf) > 3:
|
||||
suf = suf[3:]
|
||||
|
||||
if instr == "rep":
|
||||
if params == None:
|
||||
print("Missing instruction after rep prefix: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
if len(suf) > 0 and suf[0] == '.':
|
||||
suf = suf[1:]
|
||||
else:
|
||||
suf = ''
|
||||
|
||||
w2 |= 0x8000 # 16th bit
|
||||
|
||||
if len(params.split(' ', 1)) == 2:
|
||||
instr, params = params.split(' ', 1)
|
||||
else:
|
||||
instr = params.split(' ', 1)[0]
|
||||
params = None
|
||||
w2 |= 0x8000 # REP
|
||||
|
||||
if len(suf) > 0:
|
||||
w2 |= get_cond_mask(suf, line)
|
||||
|
||||
instr_name = instr
|
||||
instr_args = ''
|
||||
|
@ -21,7 +21,7 @@ strncmp:
|
||||
mov.cxz rax, 0
|
||||
ret.cxz
|
||||
|
||||
rep.e cmpzsb ax0, ax1
|
||||
cmpzsb.rep.e ax0, ax1
|
||||
|
||||
mov rax, b[ax0]
|
||||
sub rax, b[ax1]
|
||||
|
@ -15,7 +15,7 @@ strncpy:
|
||||
mov rcx, ax2
|
||||
ret.cxz
|
||||
|
||||
rep.nz movsb ax0, ax1
|
||||
movsb.rep.nz ax0, ax1
|
||||
|
||||
ret
|
||||
|
||||
@ -29,7 +29,7 @@ strnzcpy:
|
||||
dec rcx
|
||||
jmp.cxz .1
|
||||
|
||||
rep.nz movsb ax0, ax1
|
||||
movsb.rep.nz ax0, ax1
|
||||
|
||||
.1:
|
||||
mov b[ax0], 0
|
||||
|
@ -6,7 +6,7 @@
|
||||
;
|
||||
strnlen:
|
||||
mov rcx, ax1
|
||||
rep.nz scasb ax0, 0
|
||||
scasb.rep.nz ax0, 0
|
||||
|
||||
mov rax, ax1
|
||||
sub rax, rcx
|
||||
|
@ -16,10 +16,9 @@ strrev:
|
||||
|
||||
; go to str's end, just before
|
||||
; the null terminator
|
||||
.1:
|
||||
test b[ax1+1], b[ax1+1]
|
||||
inc.nz ax1
|
||||
jmp.nz .1
|
||||
mov rcx, STRLEN_MAX
|
||||
scazsb.rep.nz ax1
|
||||
dec ax1
|
||||
|
||||
.2:
|
||||
; copy, going backward though str
|
||||
@ -48,10 +47,9 @@ strrev2:
|
||||
|
||||
; go to str's end, just before
|
||||
; the null terminator
|
||||
.1:
|
||||
test b[ax1+1], b[ax1+1]
|
||||
inc.nz ax1
|
||||
jmp.nz .1
|
||||
mov rcx, STRLEN_MAX
|
||||
scazsb.rep.nz ax1
|
||||
dec ax1
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.2:
|
||||
|
@ -5,7 +5,7 @@
|
||||
; Main function
|
||||
;
|
||||
main:
|
||||
call showoff
|
||||
call itoa_test
|
||||
ret
|
||||
|
||||
showoff:
|
||||
@ -35,12 +35,11 @@ ramdev_test:
|
||||
ret
|
||||
|
||||
stosb_test:
|
||||
cld
|
||||
mov rcx, 11
|
||||
mov rax, 33
|
||||
mov rdi, .buf
|
||||
mov rsi, .buf
|
||||
rep stosb
|
||||
stosb.rep
|
||||
|
||||
mov rbx, rdi
|
||||
sub rbx, rsi
|
||||
|
35
vm/in/INSTRS
35
vm/in/INSTRS
@ -412,10 +412,43 @@ lodsb r r
|
||||
# When one parameter is given, %str = RDI and $val = $1
|
||||
# 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 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)
|
||||
#
|
||||
@ -445,7 +478,7 @@ cmpsb r r
|
||||
# Behaves precisely like CMPSx, except in the following case:
|
||||
# - 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
|
||||
#
|
||||
cmpzsb
|
||||
|
@ -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)
|
||||
{
|
||||
ulong reg1, reg2;
|
||||
|
Loading…
Reference in New Issue
Block a user