mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
vm
This commit is contained in:
parent
334053b24c
commit
89ed8fdc0d
16
as/k-as.py
16
as/k-as.py
@ -13,7 +13,7 @@ from collections import OrderedDict
|
||||
|
||||
#print("k-as command line: '{}'".format(sys.argv))
|
||||
|
||||
WANT_DISASM = True
|
||||
WANT_DISASM = False
|
||||
|
||||
if len(sys.argv) != 5:
|
||||
print("Usage: {} (source file) (memory entry point) (output file) (symbols file)"
|
||||
@ -449,8 +449,6 @@ def parse_instr(line):
|
||||
else:
|
||||
params = None
|
||||
|
||||
fellthrough = False
|
||||
|
||||
size = 2
|
||||
|
||||
# Byte 2 (rep|lock|0|cond)
|
||||
@ -486,6 +484,13 @@ def parse_instr(line):
|
||||
|
||||
tok = params.split(',')
|
||||
|
||||
# 'call' special case... temporary
|
||||
if instr_name == 'call':
|
||||
if len(tok) == 2:
|
||||
instr_name = 'xcall2'
|
||||
elif len(tok) == 3:
|
||||
instr_name = 'xcall3'
|
||||
|
||||
#
|
||||
# Parse operands
|
||||
#
|
||||
@ -540,8 +545,6 @@ def parse_instr(line):
|
||||
print("Missing access length modifier: {}".format(line))
|
||||
leave(1)
|
||||
|
||||
instr_name += "_m"
|
||||
|
||||
# cheap way of getting [reg - imm] to work
|
||||
word = word.replace('-', '+ -')
|
||||
|
||||
@ -668,7 +671,6 @@ def parse_instr(line):
|
||||
# immediates
|
||||
if is_number(word):
|
||||
n = int(word, base=0)
|
||||
instr_name += "_i"
|
||||
|
||||
if n < 0 or n > 0xFFFFFFFF:
|
||||
size += 9
|
||||
@ -695,7 +697,6 @@ def parse_instr(line):
|
||||
# register
|
||||
elif word in pregs:
|
||||
size += 1
|
||||
instr_name += "_r"
|
||||
instr_args += word
|
||||
continue
|
||||
|
||||
@ -703,7 +704,6 @@ def parse_instr(line):
|
||||
# ModRM + imm
|
||||
size += 5
|
||||
|
||||
instr_name += "_i"
|
||||
instr_args += "%%imm8 {} ".format(fmts["imm32"])
|
||||
|
||||
if word[0] == '.':
|
||||
|
@ -32,10 +32,9 @@ doprnt:
|
||||
.print_regular:
|
||||
b.z r12, r13, .check_modf
|
||||
|
||||
mov ax0, b[r12]
|
||||
call .doput
|
||||
call .doput, b[r12]
|
||||
|
||||
add r12, r12, 1
|
||||
inc r12, 1
|
||||
jmp .print_regular
|
||||
|
||||
.check_modf:
|
||||
@ -45,7 +44,7 @@ doprnt:
|
||||
|
||||
; we did find a modifier / '%'
|
||||
mov rax, b[r12+1]
|
||||
add r12, r12, 2
|
||||
inc r12, 2
|
||||
|
||||
b.z rax, 's', .modf_s
|
||||
b.z rax, 'c', .modf_c
|
||||
@ -62,24 +61,23 @@ doprnt:
|
||||
.modf_s:
|
||||
; get string address
|
||||
mov r13, q[r14]
|
||||
add r14, r14, 8
|
||||
inc r14, 8
|
||||
|
||||
cmp r13, zero
|
||||
jmp.z .nullstring
|
||||
b.z r13, zero, .nullstring
|
||||
|
||||
.print_string:
|
||||
mov ax0, b[r13]
|
||||
cmp ax0, zero
|
||||
jmp.z .main_loop
|
||||
b.z ax0, zero, .main_loop
|
||||
|
||||
add r13, r13, 1
|
||||
inc r13, 1
|
||||
call .doput
|
||||
|
||||
jmp .print_string
|
||||
|
||||
.modf_c:
|
||||
mov ax0, q[r14]
|
||||
add r14, r14, 8
|
||||
call .doput
|
||||
call .doput, q[r14]
|
||||
inc r14, 8
|
||||
|
||||
jmp .main_loop
|
||||
|
||||
.modf_p:
|
||||
@ -105,23 +103,21 @@ doprnt:
|
||||
|
||||
.print_number:
|
||||
; allocate itoa conversion buffer
|
||||
sub rsp, rsp, 80
|
||||
dec rsp, 80
|
||||
mov r13, rsp
|
||||
|
||||
; assume modifier already set up ax2
|
||||
mov ax0, rsp
|
||||
mov ax1, q[r14]
|
||||
call itoa
|
||||
add r14, r14, 8
|
||||
call itoa, rsp, q[r14]
|
||||
inc r14, 8
|
||||
|
||||
.print_itoa_buf:
|
||||
mov ax0, b[r13]
|
||||
|
||||
cmp ax0, zero
|
||||
add.z rsp, rsp, 80
|
||||
inc.z rsp, 80
|
||||
jmp.z .main_loop
|
||||
|
||||
add r13, r13, 1
|
||||
inc r13, 1
|
||||
call .doput
|
||||
jmp .print_itoa_buf
|
||||
|
||||
@ -164,7 +160,7 @@ doprnt:
|
||||
;
|
||||
.doput:
|
||||
; update print count
|
||||
add r16, r16, 1
|
||||
inc r16, 1
|
||||
|
||||
; if n==0, don't print
|
||||
; we follow the C convention that sprintf()-like functions
|
||||
@ -174,7 +170,7 @@ doprnt:
|
||||
ret.z
|
||||
|
||||
; if n>0, decrement n and print
|
||||
sub r15, r15, 1
|
||||
dec r15, 1
|
||||
call r17
|
||||
|
||||
; did putc fail?
|
||||
|
@ -44,15 +44,15 @@ ltostr:
|
||||
|
||||
b.a rdx, 9, .nondec ; rdx > 9 ?
|
||||
|
||||
add rdx, rdx, '0'
|
||||
inc rdx, '0'
|
||||
jmp .next
|
||||
|
||||
.nondec:
|
||||
add rdx, rdx, 55 ; 'A' - 10
|
||||
inc rdx, 55 ; 'A' - 10
|
||||
|
||||
.next:
|
||||
mov b[ax0], rdx
|
||||
add ax0, ax0, 1
|
||||
inc ax0, 1
|
||||
|
||||
div ax1, ax1, ax2
|
||||
jmp .conv
|
||||
|
@ -39,12 +39,12 @@ strtoq:
|
||||
|
||||
.skip_spc:
|
||||
cmp b[rdx], ' '
|
||||
add.z rdx, rdx, 1
|
||||
inc.z rdx, 1
|
||||
jmp.z .skip_spc
|
||||
|
||||
; skip +
|
||||
cmp b[rdx], '+'
|
||||
add.z rdx, rdx, 1
|
||||
inc.z rdx, 1
|
||||
|
||||
; signed?
|
||||
cmp ax2, zero
|
||||
@ -53,7 +53,7 @@ strtoq:
|
||||
|
||||
; parse '-'
|
||||
cmp b[rdx], '-'
|
||||
add.z rdx, rdx, 1
|
||||
inc.z rdx, 1
|
||||
mov.z rsi, 1
|
||||
mov.nz rsi, zero
|
||||
|
||||
@ -64,7 +64,7 @@ strtoq:
|
||||
; base prefix?
|
||||
b.nz b[rdx], '0', .main_loop
|
||||
|
||||
add rdx, rdx, 1
|
||||
inc rdx, 1
|
||||
movzx rcx, b[rdx]
|
||||
|
||||
; "0x"/"0b" prefix
|
||||
@ -81,7 +81,7 @@ strtoq:
|
||||
; if not, leave rax = 0 and *rdx = 'x'
|
||||
b.nz ax1, 16, .done
|
||||
; else
|
||||
add rdx, rdx, 1
|
||||
inc rdx, 1
|
||||
jmp .main_loop
|
||||
|
||||
.parsed_0b:
|
||||
@ -89,7 +89,7 @@ strtoq:
|
||||
; if not, leave rax = 0 and *rdx = 'b'
|
||||
b.nz ax1, 2, .done
|
||||
; else
|
||||
add rdx, rdx, 1
|
||||
inc rdx, 1
|
||||
jmp .main_loop
|
||||
|
||||
.base_0:
|
||||
@ -98,15 +98,15 @@ strtoq:
|
||||
cmp b[rdx], '0'
|
||||
mov.nz ax1, 10
|
||||
jmp.nz .main_loop
|
||||
add rdx, rdx, 1
|
||||
inc rdx, 1
|
||||
|
||||
cmp b[rdx], 'x'
|
||||
add.z rdx, rdx, 1
|
||||
inc.z rdx, 1
|
||||
mov.z ax1, 16
|
||||
jmp.z .main_loop
|
||||
|
||||
cmp b[rdx], 'b'
|
||||
add.z rdx, rdx, 1
|
||||
inc.z rdx, 1
|
||||
mov.z ax1, 2
|
||||
jmp.z .main_loop
|
||||
|
||||
@ -114,23 +114,23 @@ strtoq:
|
||||
|
||||
.main_loop:
|
||||
movzx rcx, b[rdx]
|
||||
add rdx, rdx, 1
|
||||
inc rdx, 1
|
||||
|
||||
cmp rcx, '0'
|
||||
jmp.b .done
|
||||
cmp.ae rcx, '9'
|
||||
sub.be rcx, rcx, '0'
|
||||
dec.be rcx, '0'
|
||||
jmp.be .next
|
||||
|
||||
cmp rcx, 'A'
|
||||
cmp.ae rcx, 'Z'
|
||||
sub.be rcx, rcx, 55 ; 'A' - 10
|
||||
dec.be rcx, 55 ; 'A' - 10
|
||||
jmp.be .next
|
||||
|
||||
cmp rcx, 'a'
|
||||
jmp.b .next
|
||||
cmp.ae rcx, 'z'
|
||||
sub.be rcx, rcx, 87 ; 'a' - 10
|
||||
dec.be rcx, 87 ; 'a' - 10
|
||||
jmp.be .next
|
||||
|
||||
.next:
|
||||
@ -138,7 +138,7 @@ strtoq:
|
||||
b.ae rcx, ax1, .done
|
||||
|
||||
mul rax, rax, ax1
|
||||
add rax, rax, rcx
|
||||
inc rax, rcx
|
||||
jmp .main_loop
|
||||
|
||||
.done:
|
||||
|
@ -36,7 +36,7 @@ DaysInYear:
|
||||
jmp.cxnz .end
|
||||
|
||||
.leap:
|
||||
add rax, rax, 1
|
||||
inc rax, 1
|
||||
|
||||
.end:
|
||||
ret
|
||||
|
@ -10,11 +10,7 @@ memcpy:
|
||||
|
||||
.l:
|
||||
sub rdx, ax2, rcx
|
||||
|
||||
mov rax, b[ax1+rdx]
|
||||
mov b[ax0+rdx], rax
|
||||
|
||||
mov b[ax0+rdx], b[ax1+rdx]
|
||||
loop .l
|
||||
|
||||
ret
|
||||
|
||||
|
@ -22,11 +22,11 @@ strcmp:
|
||||
add rbx, rax, rdx
|
||||
jmp.bxz .r
|
||||
|
||||
add rcx, rcx, 1
|
||||
inc rcx, 1
|
||||
jmp .l
|
||||
|
||||
.r:
|
||||
sub rax, rax, rdx
|
||||
dec rax, rdx
|
||||
ret
|
||||
|
||||
;
|
||||
@ -43,11 +43,11 @@ strncmp:
|
||||
cmp rax, rdx
|
||||
jmp.nz .r
|
||||
|
||||
add ax0, ax0, 1
|
||||
add ax1, ax1, 1
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
loop .l
|
||||
|
||||
.r:
|
||||
sub rax, rax, rdx
|
||||
dec rax, rdx
|
||||
ret
|
||||
|
||||
|
@ -11,8 +11,8 @@ strcpy:
|
||||
|
||||
ret.cxz
|
||||
|
||||
add ax0, ax0, 1
|
||||
add ax1, ax1, 1
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
|
||||
jmp .l
|
||||
|
||||
@ -24,11 +24,10 @@ strncpy:
|
||||
ret.cxz
|
||||
|
||||
.l:
|
||||
mov rax, b[ax1]
|
||||
mov b[ax0], rax
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
add ax0, ax0, 1
|
||||
add ax1, ax1, 1
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
|
||||
loop .l
|
||||
ret
|
||||
@ -46,8 +45,8 @@ strnzcpy:
|
||||
|
||||
jmp.axz .r
|
||||
|
||||
add ax0, ax0, 1
|
||||
add ax1, ax1, 1
|
||||
inc ax0, 1
|
||||
inc ax1, 1
|
||||
|
||||
loop .l
|
||||
|
||||
|
@ -18,20 +18,19 @@ strrev:
|
||||
; the null terminator
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb.rep.nz ax1, zero
|
||||
sub ax1, ax1, 1
|
||||
dec ax1, 1
|
||||
|
||||
.2:
|
||||
; copy, going backward though str
|
||||
; and forward through buf
|
||||
mov rax, b[ax1]
|
||||
mov b[ax0], rax
|
||||
mov b[ax0], b[ax1]
|
||||
|
||||
cmp ax1, rsi
|
||||
mov.z b[ax0+1], zero
|
||||
ret.z
|
||||
|
||||
add ax0, ax0, 1
|
||||
sub ax1, ax1, 1
|
||||
inc ax0, 1
|
||||
dec ax1, 1
|
||||
jmp .2
|
||||
|
||||
|
||||
@ -50,18 +49,16 @@ strrev2:
|
||||
; the null terminator
|
||||
mov rcx, STRLEN_MAX
|
||||
scasb.rep.nz ax1, zero
|
||||
sub ax1, ax1, 1
|
||||
dec ax1, 1
|
||||
|
||||
; increase ax0 while decreasing ax1, performing exchanges
|
||||
.2:
|
||||
b.ae ax0, ax1, .3
|
||||
|
||||
mov rax, b[ax1]
|
||||
xchg rax, b[ax0]
|
||||
mov b[ax1], rax
|
||||
xchg b[ax0], b[ax1]
|
||||
|
||||
add ax0, ax0, 1
|
||||
sub ax1, ax1, 1
|
||||
inc ax0, 1
|
||||
dec ax1, 1
|
||||
jmp .2
|
||||
|
||||
.3:
|
||||
|
@ -5,9 +5,7 @@ TrapHandlers.prolog:
|
||||
mov rbp, rsp
|
||||
|
||||
; nx0 = caller's cr2
|
||||
mov ax0, r14
|
||||
mov ax1, $cr2
|
||||
call RFS.LoadReg
|
||||
call RFS.LoadReg, r14, $cr2
|
||||
|
||||
; we don't preserve the r12 we got
|
||||
mov r12, rax
|
||||
|
@ -9,10 +9,8 @@ trap0_handler:
|
||||
jmp TrapHandlers.prolog
|
||||
|
||||
.text:
|
||||
mov ax0, r14
|
||||
mov ax1, $rax
|
||||
call RFS.LoadReg
|
||||
call RFS.LoadArgs
|
||||
call RFS.LoadReg, r14, $rax
|
||||
call RFS.LoadArgs, r14
|
||||
|
||||
b.z rax, zero, .handle_Shutdown
|
||||
b.z rax, Sys.Exit, .handle_Exit
|
||||
@ -66,7 +64,7 @@ trap0_handler:
|
||||
call RFS.StoreReg, zero, $cr0
|
||||
|
||||
mov rcx, CMDCOM_LOADP
|
||||
sub rcx, rcx, 0x100000
|
||||
dec rcx, 0x100000
|
||||
|
||||
; Code offset
|
||||
mov ax2, rcx
|
||||
@ -87,17 +85,17 @@ trap0_handler:
|
||||
; Disk API
|
||||
;
|
||||
.handle_FindFirst:
|
||||
add ax0, ax0, r12
|
||||
inc ax0, r12
|
||||
call DISK.FindFirst
|
||||
jmp .fini
|
||||
|
||||
.handle_FindNext:
|
||||
add ax0, ax0, r12
|
||||
inc ax0, r12
|
||||
call DISK.FindNext
|
||||
jmp .fini
|
||||
|
||||
.handle_OpenFile:
|
||||
add ax0, ax0, r12
|
||||
inc ax0, r12
|
||||
call DISK.OpenFile
|
||||
jmp .fini
|
||||
|
||||
@ -106,7 +104,7 @@ trap0_handler:
|
||||
jmp .fini
|
||||
|
||||
.handle_ReadFile:
|
||||
add ax1, ax1, r12
|
||||
inc ax1, r12
|
||||
call DISK.ReadFile
|
||||
jmp .fini
|
||||
|
||||
|
@ -21,7 +21,7 @@ InitSyscalls:
|
||||
call RFS.StoreReg
|
||||
|
||||
mov ax1, ax0
|
||||
add ax0, ax0, 255 # TRAP no. (ax0 - 1)
|
||||
inc ax0, 255 # TRAP no. (ax0 - 1)
|
||||
call IDT.AddHandler
|
||||
|
||||
ret
|
||||
|
@ -10,9 +10,7 @@ builtins.dir:
|
||||
push r12
|
||||
mov r12, zero # no. of files found
|
||||
|
||||
mov rcx, STRLEN_MAX
|
||||
mov rdx, .dirmsg
|
||||
prns.rep.nz rdx
|
||||
call print, .dirmsg
|
||||
|
||||
.dirmsg = "Directory of C:\\\n\n"
|
||||
|
||||
@ -34,7 +32,7 @@ builtins.dir:
|
||||
jmp.axz .end
|
||||
|
||||
; found something
|
||||
add r12, r12, 1
|
||||
inc r12, 1
|
||||
|
||||
; separate extension from file name
|
||||
mov rcx, NAME_MAX
|
||||
@ -48,13 +46,13 @@ builtins.dir:
|
||||
|
||||
; calculate where to put extension
|
||||
sub rdi, rsi, .buf
|
||||
sub rdi, rdi, 1
|
||||
dec rdi, 1
|
||||
|
||||
.ext_pad:
|
||||
; print at least 11 non-space characters before extension
|
||||
b.ae rdi, 11, .print_ext
|
||||
prn ' '
|
||||
add rdi, rdi, 1
|
||||
inc rdi, 1
|
||||
jmp .ext_pad
|
||||
|
||||
.print_ext:
|
||||
@ -69,10 +67,9 @@ builtins.dir:
|
||||
b.z b[rsi], 0, .print_ext.2
|
||||
|
||||
; print and decrease rcx, unless it's already 0
|
||||
mov rbx, b[rsi]
|
||||
prn rbx
|
||||
add rsi, rsi, 1
|
||||
sub.cxnz rcx, rcx, 1
|
||||
prn b[rsi]
|
||||
inc rsi, 1
|
||||
dec.cxnz rcx, 1
|
||||
|
||||
jmp .print_ext.1
|
||||
|
||||
@ -84,9 +81,8 @@ builtins.dir:
|
||||
|
||||
.print_bytes:
|
||||
; print file size in bytes
|
||||
prn ' '
|
||||
prn ' '
|
||||
prn ' '
|
||||
mov rcx, 3
|
||||
prn.rep ' '
|
||||
|
||||
shr rax, rdx, 10
|
||||
and rdx, rdx, 1023
|
||||
@ -94,7 +90,7 @@ builtins.dir:
|
||||
push rdx
|
||||
push rax
|
||||
call printf, .bytesstr
|
||||
add rsp, rsp, 16
|
||||
inc rsp, 16
|
||||
|
||||
.bytesstr = "%d kilobytes + %d bytes"
|
||||
|
||||
@ -106,7 +102,7 @@ builtins.dir:
|
||||
.end:
|
||||
push r12
|
||||
call printf, .endstr1
|
||||
add rsp, rsp, 8
|
||||
inc rsp, 8
|
||||
|
||||
call print, .endstr2
|
||||
|
||||
|
@ -41,7 +41,7 @@ main:
|
||||
jmp.cxz .input_loop ; no
|
||||
|
||||
; yes, delete it
|
||||
sub rcx, rcx, 1
|
||||
dec rcx, 1
|
||||
add rdx, rcx, argbuf
|
||||
mov b[rdx], zero
|
||||
|
||||
@ -63,7 +63,7 @@ main:
|
||||
; add character to buffer and increase iterator (rcx)
|
||||
add rdx, rcx, argbuf
|
||||
mov b[rdx], rax
|
||||
add rcx, rcx, 1
|
||||
inc rcx, 1
|
||||
|
||||
; another one
|
||||
jmp .input_loop
|
||||
@ -87,7 +87,7 @@ main:
|
||||
|
||||
; skip spaces
|
||||
cmp rcx, ' '
|
||||
add.z rsi, rsi, 1
|
||||
inc.z rsi, 1
|
||||
jmp.z .next_space
|
||||
|
||||
; if we're here, we found a
|
||||
@ -105,17 +105,16 @@ main:
|
||||
; how much do we copy?
|
||||
sub rcx, rdx, argbuf
|
||||
jmp.cxz .detect_builtin
|
||||
sub rcx, rcx, 1
|
||||
dec rcx, 1
|
||||
|
||||
mov rdi, argbuf
|
||||
mov rsi, argv0
|
||||
|
||||
.copy_loop:
|
||||
mov rax, b[rdi]
|
||||
mov b[rsi], rax
|
||||
mov b[rsi], b[rdi]
|
||||
|
||||
add rdi, rdi, 1
|
||||
add rsi, rsi, 1
|
||||
inc rdi, 1
|
||||
inc rsi, 1
|
||||
|
||||
loop .copy_loop
|
||||
|
||||
@ -185,7 +184,7 @@ main:
|
||||
|
||||
call printf, .datefmt
|
||||
|
||||
add rsp, rsp, 40
|
||||
inc rsp, 40
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -255,7 +254,7 @@ main:
|
||||
push b[rax+1]
|
||||
push b[rax+2]
|
||||
call printf, .timefmt
|
||||
add rsp, rsp, 24
|
||||
inc rsp, 24
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -307,7 +306,7 @@ main:
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf, .fnf_errmsg
|
||||
add rsp, rsp, 16
|
||||
inc rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -317,7 +316,7 @@ main:
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf, .ef_errmsg
|
||||
add rsp, rsp, 16
|
||||
inc rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
@ -327,7 +326,7 @@ main:
|
||||
push q[argv1pos]
|
||||
push argv0
|
||||
call printf, .cno_errmsg
|
||||
add rsp, rsp, 16
|
||||
inc rsp, 16
|
||||
|
||||
jmp .print_prompt
|
||||
|
||||
|
45
vm/in/ALU
45
vm/in/ALU
@ -12,7 +12,7 @@
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
or r r ri
|
||||
or 3
|
||||
|
||||
#
|
||||
# Bitwise AND operation
|
||||
@ -21,7 +21,7 @@ or r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
and r r ri
|
||||
and 3
|
||||
|
||||
#
|
||||
# Bitwise XOR operation
|
||||
@ -30,7 +30,7 @@ and r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
xor r r ri
|
||||
xor 3
|
||||
|
||||
#
|
||||
# Logical left/right shift (SHL/SHR)
|
||||
@ -40,8 +40,8 @@ xor r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
shl r r ri
|
||||
shr r r ri
|
||||
shl 3
|
||||
shr 3
|
||||
|
||||
#
|
||||
# Arithmetical left/right shift (SAL/SAR)
|
||||
@ -51,8 +51,8 @@ shr r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
sal r r ri
|
||||
sar r r ri
|
||||
sal 3
|
||||
sar 3
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Arithmetic instructions #
|
||||
@ -67,8 +67,7 @@ sar r r ri
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
cmp r ri
|
||||
cmp m ri
|
||||
cmp 2
|
||||
|
||||
#
|
||||
# Arithmetical ADD operation
|
||||
@ -79,8 +78,9 @@ cmp m ri
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
add r r ri
|
||||
addf r r ri
|
||||
inc 2
|
||||
add 3
|
||||
addf 3
|
||||
|
||||
#
|
||||
# Arithmetical SUB operation
|
||||
@ -91,8 +91,9 @@ addf r r ri
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
sub r r ri
|
||||
subf r r ri
|
||||
dec 2
|
||||
sub 3
|
||||
subf 3
|
||||
|
||||
#
|
||||
# Arithmetical ADD/SUB operation, with carry/overflow
|
||||
@ -104,8 +105,8 @@ subf r r ri
|
||||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
adcx r r ri
|
||||
sbbx r r ri
|
||||
adcx 3
|
||||
sbbx 3
|
||||
|
||||
#
|
||||
# Arithmetical MUL operation
|
||||
@ -115,8 +116,8 @@ sbbx r r ri
|
||||
# Preserves ZF and SF
|
||||
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
|
||||
#
|
||||
mul r r ri
|
||||
mulf r r ri
|
||||
mul 3
|
||||
mulf 3
|
||||
|
||||
# Arithmetical unsigned MUL operation
|
||||
#
|
||||
@ -125,7 +126,7 @@ mulf r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
mulhi r r ri
|
||||
mulhi 3
|
||||
|
||||
# Arithmetical signed MUL operation
|
||||
#
|
||||
@ -134,7 +135,7 @@ mulhi r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
imulhi r r ri
|
||||
imulhi 3
|
||||
|
||||
#
|
||||
# Arithmetical unsigned DIV operation
|
||||
@ -143,7 +144,7 @@ imulhi r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
div r r ri
|
||||
div 3
|
||||
|
||||
#
|
||||
# Arithmetical signed DIV operation
|
||||
@ -152,7 +153,7 @@ div r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
idiv r r ri
|
||||
idiv 3
|
||||
|
||||
#
|
||||
# Arithmetical modulo operation (REM)
|
||||
@ -161,5 +162,5 @@ idiv r r ri
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
rem r r ri
|
||||
rem 3
|
||||
|
||||
|
33
vm/in/MEM
33
vm/in/MEM
@ -10,7 +10,7 @@
|
||||
#
|
||||
# RIP = $1
|
||||
#
|
||||
jmp ri
|
||||
jmp 1
|
||||
|
||||
#
|
||||
# RCX-dependent jump (LOOP) instruction
|
||||
@ -20,7 +20,7 @@ jmp ri
|
||||
# RIP = $1
|
||||
# FI
|
||||
#
|
||||
loop ri
|
||||
loop 1
|
||||
|
||||
#
|
||||
# Conditional absolute jumps (B)
|
||||
@ -38,7 +38,7 @@ loop ri
|
||||
#
|
||||
# Suffixing B with the REP suffix results in undefined behavior
|
||||
#
|
||||
b rm ri ri
|
||||
b 3
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -51,9 +51,9 @@ b rm ri ri
|
||||
# PUSH(RIP)
|
||||
# JMP(RIP)
|
||||
#
|
||||
call ri
|
||||
call i ri
|
||||
call i ri ri
|
||||
call 1
|
||||
xcall2 2
|
||||
xcall3 3
|
||||
|
||||
#
|
||||
# Return to caller (RET)
|
||||
@ -69,7 +69,7 @@ ret
|
||||
# RBP = RSP
|
||||
# RSP = RSP - $1
|
||||
#
|
||||
enter i
|
||||
enter 1
|
||||
|
||||
#
|
||||
# Leave stack frame (LEAVE)
|
||||
@ -85,7 +85,7 @@ leave
|
||||
# RSP = RSP - 8
|
||||
# *RSP = $1
|
||||
#
|
||||
push rim
|
||||
push 1
|
||||
|
||||
#
|
||||
# POP value from stack
|
||||
@ -93,7 +93,7 @@ push rim
|
||||
# $1 = *RSP
|
||||
# RSP = RSP + 8
|
||||
#
|
||||
pop r
|
||||
pop 1
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Movement instructions #
|
||||
@ -111,31 +111,30 @@ pop r
|
||||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
lea r m
|
||||
lea 2
|
||||
|
||||
#
|
||||
# Move data (MOV) instruction
|
||||
#
|
||||
# $1 = SignExtend($2)
|
||||
#
|
||||
mov r rim
|
||||
mov m ri
|
||||
mov 2
|
||||
|
||||
#
|
||||
# Load from memory with zero-extension (MOVSX/MOVZX) instruction
|
||||
#
|
||||
# $1 = ZeroExtend($2)
|
||||
#
|
||||
movzx r m
|
||||
movzx 2
|
||||
|
||||
#
|
||||
# Move with sign-extension (MOVSXx) instruction
|
||||
#
|
||||
# $1 = SignExtend($2 & (2^(8 * sizeof(x)) - 1)
|
||||
#
|
||||
movsxb r r
|
||||
movsxw r r
|
||||
movsxd r r
|
||||
movsxb 2
|
||||
movsxw 2
|
||||
movsxd 2
|
||||
|
||||
#
|
||||
# Exchange (XCHG) instruction
|
||||
@ -144,5 +143,5 @@ movsxd r r
|
||||
# $1 = $2
|
||||
# $2 = $_
|
||||
#
|
||||
xchg r rm
|
||||
xchg 2
|
||||
|
||||
|
16
vm/in/MISC
16
vm/in/MISC
@ -38,14 +38,14 @@ into
|
||||
#
|
||||
# Get timestamp in µseconds
|
||||
#
|
||||
utime r r
|
||||
utime 2
|
||||
|
||||
#
|
||||
# $1 = seconds since start of month
|
||||
# $2 = current month
|
||||
# $3 = current year
|
||||
#
|
||||
ytime r r r
|
||||
ytime 3
|
||||
|
||||
#
|
||||
# Clear all GPR registers except RBP/RSP
|
||||
@ -61,9 +61,9 @@ cls
|
||||
#
|
||||
# Change endianness
|
||||
#
|
||||
bswap r r
|
||||
wswap r r
|
||||
dswap r r
|
||||
bswap 2
|
||||
wswap 2
|
||||
dswap 2
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# I/O instructions #
|
||||
@ -72,7 +72,7 @@ dswap r r
|
||||
#
|
||||
# Send a character to standard output (PRN)
|
||||
#
|
||||
prn ri
|
||||
prn 1
|
||||
|
||||
#
|
||||
# Print a string to standard output (PRN)
|
||||
@ -89,10 +89,10 @@ prn ri
|
||||
# FI
|
||||
#
|
||||
#
|
||||
prns r
|
||||
prns 1
|
||||
|
||||
#
|
||||
# Scan a character from standard input (SCAN)
|
||||
#
|
||||
scan r
|
||||
scan 1
|
||||
|
||||
|
16
vm/in/STRING
16
vm/in/STRING
@ -15,10 +15,10 @@
|
||||
# %str = %str - sizeof(x)
|
||||
# FI
|
||||
#
|
||||
stosb r ri
|
||||
stosw r ri
|
||||
stosd r ri
|
||||
stosq r ri
|
||||
stosb 2
|
||||
stosw 2
|
||||
stosd 2
|
||||
stosq 2
|
||||
|
||||
#
|
||||
# Scan string for a particular value (SCASx)
|
||||
@ -42,10 +42,10 @@ stosq r ri
|
||||
# - Does not move past the value when found
|
||||
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
|
||||
#
|
||||
scasb r ri
|
||||
scasw r ri
|
||||
scasd r ri
|
||||
scasq r ri
|
||||
scasb 2
|
||||
scasw 2
|
||||
scasd 2
|
||||
scasq 2
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
|
@ -48,7 +48,7 @@ hlt
|
||||
# #ILL if $1 > 255
|
||||
# #($1+256) otherwise
|
||||
#
|
||||
trap ri
|
||||
trap 1
|
||||
|
||||
#
|
||||
# Return from exception/interrupt (IRET)
|
||||
@ -79,7 +79,7 @@ sti
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
devctl r r
|
||||
devctl 2
|
||||
|
||||
#
|
||||
# Call a device-defined function slot of device (IOCALL)
|
||||
@ -89,5 +89,5 @@ devctl r r
|
||||
# Throws:
|
||||
# #SYS if not in supervisor mode
|
||||
#
|
||||
iocall ri ri
|
||||
iocall 2
|
||||
|
||||
|
49
vm/in/alu.c
49
vm/in/alu.c
@ -8,27 +8,32 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(or) { *r1 = p2->val | p3->val; return 1; }
|
||||
IMPL_START(and) { *r1 = p2->val & p3->val; return 1; }
|
||||
IMPL_START(xor) { *r1 = p2->val ^ p3->val; return 1; }
|
||||
IMPL_START(or) { SRCP(p2); SRCP(p3); *r1 = p2->val | p3->val; return 1; }
|
||||
IMPL_START(and) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; }
|
||||
IMPL_START(xor) { SRCP(p2); SRCP(p3); *r1 = p2->val ^ p3->val; return 1; }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(shl) { *r1 = p2->val << p3->val; return 1; }
|
||||
IMPL_START(shr) { *r1 = p2->val >> p3->val; return 1; }
|
||||
IMPL_START(sal) { *r1 = (ulong)((long)p2->val << (long)p3->val); return 1; }
|
||||
IMPL_START(sar) { *r1 = (ulong)((long)p2->val >> (long)p3->val); return 1; }
|
||||
IMPL_START(shl) { SRCP(p2); SRCP(p3); *r1 = p2->val << p3->val; return 1; }
|
||||
IMPL_START(shr) { SRCP(p2); SRCP(p3); *r1 = p2->val >> p3->val; return 1; }
|
||||
IMPL_START(sal) { SRCP(p2); SRCP(p3); *r1 = (ulong)((long)p2->val << (long)p3->val); return 1; }
|
||||
IMPL_START(sar) { SRCP(p2); SRCP(p3); *r1 = (ulong)((long)p2->val >> (long)p3->val); return 1; }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(add) { *r1 = p2->val + p3->val; return 1; }
|
||||
IMPL_START(addf) { COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->val; return 1; }
|
||||
IMPL_START(inc) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; }
|
||||
IMPL_START(add) { SRCP(p2); SRCP(p3); *r1 = p2->val + p3->val; return 1; }
|
||||
IMPL_START(addf) { SRCP(p2); SRCP(p3); COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->val; return 1; }
|
||||
|
||||
IMPL_START(sub) { *r1 = p2->val - p3->val; return 1; }
|
||||
IMPL_START(subf) { COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->val; return 1; }
|
||||
IMPL_START(dec) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; }
|
||||
IMPL_START(sub) { SRCP(p2); SRCP(p3); *r1 = p2->val - p3->val; return 1; }
|
||||
IMPL_START(subf) { SRCP(p2); SRCP(p3); COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->val; return 1; }
|
||||
|
||||
IMPL_START(adcx)
|
||||
{
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
p3->val += !!(R(RFX)&CF);
|
||||
COMPARE_ADD(p2->val, p3->val);
|
||||
*r1 = p2->val + p3->val;
|
||||
@ -38,6 +43,9 @@ IMPL_START(adcx)
|
||||
|
||||
IMPL_START(sbbx)
|
||||
{
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
p3->val += !!(R(RFX)&CF);
|
||||
COMPARE_SUB(p2->val, p3->val);
|
||||
*r1 = p2->val - p3->val;
|
||||
@ -47,11 +55,14 @@ IMPL_START(sbbx)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(mul) { *r1 = p2->val * p3->val; return 1; }
|
||||
IMPL_START(rem) { *r1 = p2->val % p3->val; return 1; }
|
||||
IMPL_START(mul) { SRCP(p2); SRCP(p3); *r1 = p2->val * p3->val; return 1; }
|
||||
IMPL_START(rem) { SRCP(p2); SRCP(p3); *r1 = p2->val % p3->val; return 1; }
|
||||
|
||||
IMPL_START(div)
|
||||
{
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
if (!p3->val)
|
||||
_except(ctx, E_DIV, "DIV by 0");
|
||||
*r1 = p2->val / p3->val;
|
||||
@ -61,6 +72,9 @@ IMPL_START(div)
|
||||
|
||||
IMPL_START(idiv)
|
||||
{
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
if (!p3->val)
|
||||
_except(ctx, E_DIV, "IDIV by 0");
|
||||
|
||||
@ -81,12 +95,18 @@ static void __unsigned_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||
|
||||
IMPL_START(mulhi)
|
||||
{
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
__unsigned_multiply128(p2->val, p3->val, r1, r2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
IMPL_START(mulf)
|
||||
{
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
ulong tmp;
|
||||
__unsigned_multiply128(p2->val, p3->val, &tmp, r1);
|
||||
R(RFX) = p2->val ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
||||
@ -106,6 +126,9 @@ static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
||||
|
||||
IMPL_START(imulhi)
|
||||
{
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
__signed_multiply128(p2->val, p3->val, r1, r2);
|
||||
return 2;
|
||||
}
|
||||
|
@ -5,25 +5,6 @@
|
||||
|
||||
from tempfile import TemporaryFile
|
||||
|
||||
def getflag(s):
|
||||
if s == "r":
|
||||
return "P_REG"
|
||||
|
||||
if s == "i":
|
||||
return "P_IMM"
|
||||
|
||||
if s == "m":
|
||||
return "P_MEM"
|
||||
|
||||
return "__FLAG_ERROR__"
|
||||
|
||||
def doprnt(fp, i, p1, p2, p3):
|
||||
for c1 in p1:
|
||||
for c2 in p2:
|
||||
for c3 in p3:
|
||||
fp.write("{} {} {} {}".format(i, c1, c2, c3).strip())
|
||||
fp.write('\n')
|
||||
|
||||
def parse_1(fi, fp):
|
||||
global count
|
||||
|
||||
@ -41,36 +22,7 @@ def parse_1(fi, fp):
|
||||
parse_1(fi2, fp)
|
||||
continue
|
||||
|
||||
tok = line.split()
|
||||
|
||||
if len(tok) == 0:
|
||||
continue
|
||||
|
||||
i = tok[0]
|
||||
|
||||
if len(tok) == 1:
|
||||
doprnt(fp, i, ' ', ' ', ' ')
|
||||
continue
|
||||
|
||||
if len(tok) == 2:
|
||||
p = tok[1]
|
||||
doprnt(fp, i, p, ' ', ' ')
|
||||
continue
|
||||
|
||||
if len(tok) == 3:
|
||||
p1 = tok[1]
|
||||
p2 = tok[2]
|
||||
doprnt(fp, i, p1, p2, ' ')
|
||||
continue
|
||||
|
||||
assert(len(tok) == 4)
|
||||
p1 = tok[1]
|
||||
p2 = tok[2]
|
||||
p3 = tok[3]
|
||||
|
||||
doprnt(fp, i, p1, p2, p3)
|
||||
|
||||
fi.close()
|
||||
fp.write("{}\n".format(line))
|
||||
|
||||
def parse_2(fp):
|
||||
global count
|
||||
@ -89,41 +41,19 @@ def parse_2(fp):
|
||||
|
||||
if len(tok) == 1:
|
||||
name = tok[0]
|
||||
p1 = "NOPRM"
|
||||
p2 = "NOPRM"
|
||||
p3 = "NOPRM"
|
||||
|
||||
elif len(tok) == 2:
|
||||
name = "{}_{}".format(tok[0], tok[1])
|
||||
p1 = getflag(tok[1])
|
||||
p2 = "NOPRM"
|
||||
p3 = "NOPRM"
|
||||
|
||||
elif len(tok) == 3:
|
||||
name = "{}_{}_{}".format(tok[0], tok[1], tok[2])
|
||||
p1 = getflag(tok[1])
|
||||
p2 = getflag(tok[2])
|
||||
p3 = "NOPRM"
|
||||
|
||||
elif len(tok) == 4:
|
||||
name = "{}_{}_{}_{}".format(tok[0], tok[1], tok[2], tok[3])
|
||||
p1 = getflag(tok[1])
|
||||
p2 = getflag(tok[2])
|
||||
p3 = getflag(tok[3])
|
||||
n = 0
|
||||
|
||||
else:
|
||||
name = "__TOK_ERROR__"
|
||||
p1 = "__TOK_ERROR__"
|
||||
p2 = "__TOK_ERROR__"
|
||||
p3 = "__TOK_ERROR__"
|
||||
assert(len(tok) == 2)
|
||||
n = tok[1]
|
||||
|
||||
ls.write("{}{}\n".format(deprecated, name))
|
||||
ls.write("{}{}\n".format(deprecated, tok[0]))
|
||||
|
||||
hd.write("#ifdef _NEED_ARCH_I\n")
|
||||
hd.write('{{ "{}{}", "{}{}", {}, {}, {}, i_{} }},\n'\
|
||||
.format(deprecated, tok[0], deprecated, name, p1, p2, p3, tok[0]))
|
||||
hd.write('{{ "{}{}", {}, i_{} }},\n'\
|
||||
.format(deprecated, tok[0], n, tok[0]))
|
||||
hd.write("#else\n")
|
||||
hd.write("#define I_{} {}\n".format(name.upper(), count))
|
||||
hd.write("#define I_{} {}\n".format(tok[0].upper(), count))
|
||||
hd.write("extern bool i_{}(ctx_t *, acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n"
|
||||
.format(tok[0]))
|
||||
hd.write("#endif\n\n")
|
||||
|
@ -9,6 +9,15 @@
|
||||
uint i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
|
||||
ulong *r1, ulong *r2, ulong *r3) \
|
||||
|
||||
#define XSRCP(v, p, x) \
|
||||
if (ACC_FMT_IS_MEM(p->type)) \
|
||||
v = readmem##x(ctx, p->addr, p->mlen); \
|
||||
else v = p->val; \
|
||||
|
||||
#define SRCP(p) \
|
||||
if (__builtin_expect(ACC_FMT_IS_MEM(p->type), 0)) \
|
||||
p->val = readmemsx(ctx, p->addr, p->mlen); \
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define INTO() \
|
||||
|
102
vm/in/mem.c
102
vm/in/mem.c
@ -17,14 +17,10 @@ IMPL_START(loop) {
|
||||
|
||||
IMPL_START(b)
|
||||
{
|
||||
ulong v;
|
||||
SRCP(p1);
|
||||
SRCP(p2);
|
||||
|
||||
if (ACC_FMT_IS_MEM(p1->type))
|
||||
v = readmemsx(ctx, p1->addr, p1->mlen);
|
||||
|
||||
else v = p1->val;
|
||||
|
||||
COMPARE_SUB(v, p2->val);
|
||||
COMPARE_SUB(p1->val, p2->val);
|
||||
|
||||
if (eval_cond(ctx, ctx->cond))
|
||||
R(RIP) = p3->val;
|
||||
@ -34,14 +30,9 @@ IMPL_START(b)
|
||||
|
||||
IMPL_START(cmp)
|
||||
{
|
||||
ulong v;
|
||||
SRCP(p1);
|
||||
|
||||
if (ACC_FMT_IS_MEM(p1->type))
|
||||
v = readmemsx(ctx, p1->addr, p1->mlen);
|
||||
|
||||
else v = p1->val;
|
||||
|
||||
COMPARE_SUB(v, p2->val);
|
||||
COMPARE_SUB(p1->val, p2->val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -49,44 +40,20 @@ IMPL_START(cmp)
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START(lea) { *r1 = p2->addr; return 1; }
|
||||
IMPL_START(mov) { XSRCP(*r1, p2, sx); return 1; }
|
||||
IMPL_START(movzx) { XSRCP(*r1, p2, zx); return 1; }
|
||||
|
||||
IMPL_START(mov)
|
||||
{
|
||||
if (ACC_FMT_IS_MEM(p2->type))
|
||||
*r1 = readmemsx(ctx, p2->addr, p2->mlen);
|
||||
|
||||
else *r1 = p2->val;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
IMPL_START(movzx)
|
||||
{
|
||||
if (ACC_FMT_IS_MEM(p2->type))
|
||||
{
|
||||
if (__builtin_expect(p2->mlen == 8, 0))
|
||||
_except(ctx, E_ILL, "MOVZX with qword memory source");
|
||||
|
||||
*r1 = readmemzx(ctx, p2->addr, p2->mlen);
|
||||
}
|
||||
|
||||
else *r1 = p2->val;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
IMPL_START(movsxb) { *r1 = (ulong)(long)(char)(p2->val & 0xFF); return 1; }
|
||||
IMPL_START(movsxw) { *r1 = (ulong)(long)(short)(p2->val & 0xFFFF); return 1; }
|
||||
IMPL_START(movsxd) { *r1 = (ulong)(long)(int)(p2->val & 0xFFFFFFFF); return 1; }
|
||||
IMPL_START(movsxb) { SRCP(p2); *r1 = (ulong)(long)(char)p2->val; return 1; }
|
||||
IMPL_START(movsxw) { SRCP(p2); *r1 = (ulong)(long)(short)p2->val; return 1; }
|
||||
IMPL_START(movsxd) { SRCP(p2); *r1 = (ulong)(long)(int)p2->val; return 1; }
|
||||
|
||||
IMPL_START(xchg)
|
||||
{
|
||||
SRCP(p1);
|
||||
SRCP(p2);
|
||||
|
||||
*r2 = p1->val;
|
||||
|
||||
if (ACC_FMT_IS_MEM(p2->type))
|
||||
*r1 = readmemsx(ctx, p2->addr, p2->mlen);
|
||||
|
||||
else *r1 = p2->val;
|
||||
*r1 = p2->val;
|
||||
|
||||
return 2;
|
||||
}
|
||||
@ -99,15 +66,10 @@ IMPL_START(xchg)
|
||||
|
||||
IMPL_START(push)
|
||||
{
|
||||
ulong v;
|
||||
|
||||
if (ACC_FMT_IS_MEM(p1->type))
|
||||
v = readmemzx(ctx, p1->addr, p1->mlen);
|
||||
|
||||
else v = p1->val;
|
||||
XSRCP(p1->val, p1, zx);
|
||||
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, v, R(RSP), 8);
|
||||
writemem(ctx, p1->val, R(RSP), 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -122,17 +84,41 @@ IMPL_START(pop)
|
||||
|
||||
IMPL_START(call)
|
||||
{
|
||||
SRCP(p1);
|
||||
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, R(RIP), R(RSP), 8);
|
||||
R(RIP) = p1->val;
|
||||
|
||||
if (p2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(xcall2)
|
||||
{
|
||||
SRCP(p1);
|
||||
SRCP(p2);
|
||||
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, R(RIP), R(RSP), 8);
|
||||
|
||||
R(RIP) = p1->val;
|
||||
R(AX0) = p2->val;
|
||||
|
||||
if (p3)
|
||||
return 0;
|
||||
}
|
||||
|
||||
IMPL_START(xcall3)
|
||||
{
|
||||
SRCP(p1);
|
||||
SRCP(p2);
|
||||
SRCP(p3);
|
||||
|
||||
R(RSP) -= 8;
|
||||
writemem(ctx, R(RIP), R(RSP), 8);
|
||||
|
||||
R(RIP) = p1->val;
|
||||
R(AX0) = p2->val;
|
||||
R(AX1) = p3->val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
11
vm/in/misc.c
11
vm/in/misc.c
@ -81,6 +81,8 @@ IMPL_START(cls)
|
||||
|
||||
IMPL_START(bswap)
|
||||
{
|
||||
SRCP(p2);
|
||||
|
||||
ulong v = p2->val;
|
||||
|
||||
*r1 = ((v & 0xFF00000000000000) >> 56)
|
||||
@ -97,6 +99,8 @@ IMPL_START(bswap)
|
||||
|
||||
IMPL_START(wswap)
|
||||
{
|
||||
SRCP(p2);
|
||||
|
||||
ulong v = p2->val;
|
||||
|
||||
*r1 = ((v & 0xFFFF000000000000) >> 48)
|
||||
@ -109,6 +113,8 @@ IMPL_START(wswap)
|
||||
|
||||
IMPL_START(dswap)
|
||||
{
|
||||
SRCP(p2);
|
||||
|
||||
*r1 = ((p2->val & 0xFFFFFFFF00000000) >> 32)
|
||||
| ((p2->val & 0x00000000FFFFFFFF) << 32);
|
||||
|
||||
@ -121,6 +127,8 @@ IMPL_START(dswap)
|
||||
|
||||
IMPL_START(prn)
|
||||
{
|
||||
SRCP(p1);
|
||||
|
||||
ulong v = p1->val;
|
||||
|
||||
// Magic value? :)
|
||||
@ -135,6 +143,9 @@ IMPL_START(prn)
|
||||
|
||||
IMPL_START(prns)
|
||||
{
|
||||
if (p1->type != A_REG)
|
||||
_except(ctx, E_ILL, "PRNS given a non-REG operand");
|
||||
|
||||
uchar ch = readmemzx(ctx, R(p1->reg), 1);
|
||||
|
||||
COMPARE_SUB(ch, 0);
|
||||
|
@ -13,6 +13,9 @@
|
||||
|
||||
static void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
if (p1->type != A_REG)
|
||||
_except(ctx, E_ILL, "STOSX given a non-REG operand");
|
||||
|
||||
writemem(ctx, p2->val, R(p1->reg), len);
|
||||
STR_MOVE(p1->reg, len);
|
||||
}
|
||||
@ -26,6 +29,9 @@ IMPL_START(stosq) { stos_impl(ctx, p1, p2, 8); return 0; }
|
||||
|
||||
static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
|
||||
{
|
||||
if (p1->type != A_REG)
|
||||
_except(ctx, E_ILL, "SCASX given a non-REG operand");
|
||||
|
||||
ulong x = readmemsx(ctx, R(p1->reg), len);
|
||||
COMPARE_SUB(x, p2->val);
|
||||
|
||||
|
@ -3,18 +3,23 @@
|
||||
|
||||
#include <pc/console.h>
|
||||
|
||||
// FIXME XXX
|
||||
|
||||
//#define _LARGE_SCREEN
|
||||
|
||||
#ifndef _LARGE_SCREEN
|
||||
# define CONSOLE_WIDTH 80
|
||||
# define CONSOLE_HEIGHT 25
|
||||
# define CONSOLE_FONT_SIZE 16
|
||||
# define _MULT 1
|
||||
#else
|
||||
# define CONSOLE_WIDTH 160
|
||||
# define CONSOLE_HEIGHT 50
|
||||
# define CONSOLE_FONT_SIZE 32
|
||||
# define _MULT 2
|
||||
#endif
|
||||
|
||||
#define SCREEN_WIDTH (9 * CONSOLE_WIDTH)
|
||||
#define SCREEN_HEIGHT (16 * CONSOLE_HEIGHT)
|
||||
#define CONSOLE_WIDTH (80)
|
||||
#define CONSOLE_HEIGHT (25)
|
||||
#define CONSOLE_FONT_SIZE (16 * _MULT)
|
||||
#define SCREEN_WIDTH (9 * CONSOLE_WIDTH * _MULT)
|
||||
#define SCREEN_HEIGHT (16 * CONSOLE_HEIGHT * _MULT)
|
||||
|
||||
#define _SURF_H CONSOLE_FONT_SIZE
|
||||
|
||||
SDL_Window *scr_win = NULL;
|
||||
SDL_Renderer *scr_rend = NULL;
|
||||
@ -281,7 +286,7 @@ void console_putc(ctx_t *ctx, char ch)
|
||||
for (y = 0; y < CONSOLE_HEIGHT-1; y++)
|
||||
if (scr_rects[y] != NULL)
|
||||
{
|
||||
scr_rects[y]->y -= 16; // surf->h
|
||||
scr_rects[y]->y -= _SURF_H; // surf->h
|
||||
}
|
||||
|
||||
console_render(ctx);
|
||||
|
@ -62,34 +62,31 @@ static void checkreg(ctx_t *ctx, uint reg)
|
||||
//
|
||||
// Verify that given access length is that of a byte/word/dword/qword
|
||||
//
|
||||
static void checklength(ctx_t *ctx, uint len)
|
||||
static void checklength(ctx_t *ctx, instr_t *in, uint len)
|
||||
{
|
||||
static const int lentab[9] = { 0, 1, 1, 0, 1, 0, 0, 0, 1 };
|
||||
|
||||
if (len > 8 || lentab[len] == 0)
|
||||
_except(ctx, E_ILL, "Invalid memory access length: %u", len);
|
||||
_except(ctx, E_ILL, "%s: Invalid memory access length: %u",
|
||||
in->name, len);
|
||||
}
|
||||
|
||||
//
|
||||
// Extracts one operand
|
||||
//
|
||||
static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
|
||||
static void extract_param(ctx_t *ctx, instr_t *in, acc_t *p)
|
||||
{
|
||||
// Get next operand ModRM-like byte
|
||||
uchar fmt = fetchb(ctx);
|
||||
|
||||
ulong hi = (fmt & 0b11100000) >> 5;
|
||||
ulong lo = fmt & 0b00011111;
|
||||
uchar hi = (fmt & 0b11100000) >> 5;
|
||||
uchar lo = fmt & 0b00011111;
|
||||
|
||||
//
|
||||
// Registers
|
||||
//
|
||||
if (hi == 0)
|
||||
{
|
||||
if (prm != P_REG)
|
||||
_except(ctx, E_ILL, "Not expecting a register: %s",
|
||||
ctx->cur_in->full);
|
||||
|
||||
p->reg = lo;
|
||||
p->type = A_REG;
|
||||
checkreg(ctx, p->reg);
|
||||
@ -104,10 +101,6 @@ static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
|
||||
//
|
||||
if (hi == 7)
|
||||
{
|
||||
if (prm != P_IMM)
|
||||
_except(ctx, E_ILL, "Not expecting an immediate: %s",
|
||||
ctx->cur_in->full);
|
||||
|
||||
switch (lo)
|
||||
{
|
||||
case 1:
|
||||
@ -131,7 +124,8 @@ static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
|
||||
break;
|
||||
|
||||
default:
|
||||
_except(ctx, E_ILL, "Invalid immediate length: %hhu", lo);
|
||||
_except(ctx, E_ILL, "%s: Invalid immediate length: %hhu",
|
||||
in->name, lo);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -141,11 +135,7 @@ static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
|
||||
// Memory operands
|
||||
//
|
||||
|
||||
if (prm != P_MEM)
|
||||
_except(ctx, E_ILL, "Not expecting a memory access: %s",
|
||||
ctx->cur_in->full);
|
||||
|
||||
checklength(ctx, lo);
|
||||
checklength(ctx, in, lo);
|
||||
p->mlen = lo;
|
||||
|
||||
switch (hi)
|
||||
@ -234,31 +224,31 @@ void decode(ctx_t *ctx)
|
||||
ctx->cond = b2 & SUFF_COND;
|
||||
|
||||
// Operand 1?
|
||||
if (in->prm1 == NOPRM)
|
||||
if (in->nprms == 0)
|
||||
{
|
||||
exec_instr(ctx, in, NULL, NULL, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
extract_param(ctx, in->prm1, &p1);
|
||||
extract_param(ctx, in, &p1);
|
||||
|
||||
// Operand 2?
|
||||
if (in->prm2 == NOPRM)
|
||||
if (in->nprms == 1)
|
||||
{
|
||||
exec_instr(ctx, in, &p1, NULL, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
extract_param(ctx, in->prm2, &p2);
|
||||
extract_param(ctx, in, &p2);
|
||||
|
||||
// Operand 1?
|
||||
if (in->prm3 == NOPRM)
|
||||
if (in->nprms == 2)
|
||||
{
|
||||
exec_instr(ctx, in, &p1, &p2, NULL, lock, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
extract_param(ctx, in->prm3, &p3);
|
||||
extract_param(ctx, in, &p3);
|
||||
|
||||
exec_instr(ctx, in, &p1, &p2, &p3, lock, rep);
|
||||
}
|
||||
|
@ -66,12 +66,7 @@ enum { NOPRM, P_REG, P_IMM, P_MEM=4 };
|
||||
struct instr_t
|
||||
{
|
||||
char *name;
|
||||
char *full;
|
||||
|
||||
uint prm1;
|
||||
uint prm2;
|
||||
uint prm3;
|
||||
|
||||
uint nprms;
|
||||
uint (*func)(ctx_t *, acc_t *, acc_t *, acc_t *,
|
||||
ulong *, ulong *, ulong *);
|
||||
};
|
||||
|
@ -41,12 +41,10 @@ bool eval_cond(ctx_t *ctx, uint cond)
|
||||
#define OUTPUT(p, r) { \
|
||||
if (p->type == A_REG) \
|
||||
R(p->reg) = r; \
|
||||
else if (p1->type == A_IMM64) \
|
||||
_except(ctx, E_ACC, "Trying to output to an IMM64"); \
|
||||
else { \
|
||||
assert(ACC_IS_MEM(p)); \
|
||||
else if (ACC_IS_MEM(p)) \
|
||||
writemem(ctx, r, p->addr, p->mlen); \
|
||||
} }
|
||||
else _except(ctx, E_ACC, "Trying to output to an IMM"); \
|
||||
}
|
||||
|
||||
//
|
||||
// Executes an instruction
|
||||
|
@ -62,7 +62,7 @@ int main(int argc, char **argv)
|
||||
main_ctx.r = arch_r;
|
||||
main_ctx.i = arch_i;
|
||||
|
||||
#if 1 && !defined(NDEBUG)
|
||||
#if 0 && !defined(NDEBUG)
|
||||
main_ctx.dumpsw = 1;
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user