This commit is contained in:
julianb0 2019-08-03 17:41:44 +02:00
parent 334053b24c
commit 89ed8fdc0d
No known key found for this signature in database
GPG Key ID: 9C7ACF0C053FB8A1
30 changed files with 305 additions and 373 deletions

View File

@ -13,7 +13,7 @@ from collections import OrderedDict
#print("k-as command line: '{}'".format(sys.argv)) #print("k-as command line: '{}'".format(sys.argv))
WANT_DISASM = True WANT_DISASM = False
if len(sys.argv) != 5: if len(sys.argv) != 5:
print("Usage: {} (source file) (memory entry point) (output file) (symbols file)" print("Usage: {} (source file) (memory entry point) (output file) (symbols file)"
@ -449,8 +449,6 @@ def parse_instr(line):
else: else:
params = None params = None
fellthrough = False
size = 2 size = 2
# Byte 2 (rep|lock|0|cond) # Byte 2 (rep|lock|0|cond)
@ -486,6 +484,13 @@ def parse_instr(line):
tok = params.split(',') 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 # Parse operands
# #
@ -540,8 +545,6 @@ def parse_instr(line):
print("Missing access length modifier: {}".format(line)) print("Missing access length modifier: {}".format(line))
leave(1) leave(1)
instr_name += "_m"
# cheap way of getting [reg - imm] to work # cheap way of getting [reg - imm] to work
word = word.replace('-', '+ -') word = word.replace('-', '+ -')
@ -668,7 +671,6 @@ def parse_instr(line):
# immediates # immediates
if is_number(word): if is_number(word):
n = int(word, base=0) n = int(word, base=0)
instr_name += "_i"
if n < 0 or n > 0xFFFFFFFF: if n < 0 or n > 0xFFFFFFFF:
size += 9 size += 9
@ -695,7 +697,6 @@ def parse_instr(line):
# register # register
elif word in pregs: elif word in pregs:
size += 1 size += 1
instr_name += "_r"
instr_args += word instr_args += word
continue continue
@ -703,7 +704,6 @@ def parse_instr(line):
# ModRM + imm # ModRM + imm
size += 5 size += 5
instr_name += "_i"
instr_args += "%%imm8 {} ".format(fmts["imm32"]) instr_args += "%%imm8 {} ".format(fmts["imm32"])
if word[0] == '.': if word[0] == '.':

View File

@ -32,10 +32,9 @@ doprnt:
.print_regular: .print_regular:
b.z r12, r13, .check_modf b.z r12, r13, .check_modf
mov ax0, b[r12] call .doput, b[r12]
call .doput
add r12, r12, 1 inc r12, 1
jmp .print_regular jmp .print_regular
.check_modf: .check_modf:
@ -45,7 +44,7 @@ doprnt:
; we did find a modifier / '%' ; we did find a modifier / '%'
mov rax, b[r12+1] mov rax, b[r12+1]
add r12, r12, 2 inc r12, 2
b.z rax, 's', .modf_s b.z rax, 's', .modf_s
b.z rax, 'c', .modf_c b.z rax, 'c', .modf_c
@ -62,24 +61,23 @@ doprnt:
.modf_s: .modf_s:
; get string address ; get string address
mov r13, q[r14] mov r13, q[r14]
add r14, r14, 8 inc r14, 8
cmp r13, zero b.z r13, zero, .nullstring
jmp.z .nullstring
.print_string: .print_string:
mov ax0, b[r13] mov ax0, b[r13]
cmp ax0, zero b.z ax0, zero, .main_loop
jmp.z .main_loop
add r13, r13, 1 inc r13, 1
call .doput call .doput
jmp .print_string jmp .print_string
.modf_c: .modf_c:
mov ax0, q[r14] call .doput, q[r14]
add r14, r14, 8 inc r14, 8
call .doput
jmp .main_loop jmp .main_loop
.modf_p: .modf_p:
@ -105,23 +103,21 @@ doprnt:
.print_number: .print_number:
; allocate itoa conversion buffer ; allocate itoa conversion buffer
sub rsp, rsp, 80 dec rsp, 80
mov r13, rsp mov r13, rsp
; assume modifier already set up ax2 ; assume modifier already set up ax2
mov ax0, rsp call itoa, rsp, q[r14]
mov ax1, q[r14] inc r14, 8
call itoa
add r14, r14, 8
.print_itoa_buf: .print_itoa_buf:
mov ax0, b[r13] mov ax0, b[r13]
cmp ax0, zero cmp ax0, zero
add.z rsp, rsp, 80 inc.z rsp, 80
jmp.z .main_loop jmp.z .main_loop
add r13, r13, 1 inc r13, 1
call .doput call .doput
jmp .print_itoa_buf jmp .print_itoa_buf
@ -164,7 +160,7 @@ doprnt:
; ;
.doput: .doput:
; update print count ; update print count
add r16, r16, 1 inc r16, 1
; if n==0, don't print ; if n==0, don't print
; we follow the C convention that sprintf()-like functions ; we follow the C convention that sprintf()-like functions
@ -174,7 +170,7 @@ doprnt:
ret.z ret.z
; if n>0, decrement n and print ; if n>0, decrement n and print
sub r15, r15, 1 dec r15, 1
call r17 call r17
; did putc fail? ; did putc fail?

View File

@ -44,15 +44,15 @@ ltostr:
b.a rdx, 9, .nondec ; rdx > 9 ? b.a rdx, 9, .nondec ; rdx > 9 ?
add rdx, rdx, '0' inc rdx, '0'
jmp .next jmp .next
.nondec: .nondec:
add rdx, rdx, 55 ; 'A' - 10 inc rdx, 55 ; 'A' - 10
.next: .next:
mov b[ax0], rdx mov b[ax0], rdx
add ax0, ax0, 1 inc ax0, 1
div ax1, ax1, ax2 div ax1, ax1, ax2
jmp .conv jmp .conv

View File

@ -39,12 +39,12 @@ strtoq:
.skip_spc: .skip_spc:
cmp b[rdx], ' ' cmp b[rdx], ' '
add.z rdx, rdx, 1 inc.z rdx, 1
jmp.z .skip_spc jmp.z .skip_spc
; skip + ; skip +
cmp b[rdx], '+' cmp b[rdx], '+'
add.z rdx, rdx, 1 inc.z rdx, 1
; signed? ; signed?
cmp ax2, zero cmp ax2, zero
@ -53,7 +53,7 @@ strtoq:
; parse '-' ; parse '-'
cmp b[rdx], '-' cmp b[rdx], '-'
add.z rdx, rdx, 1 inc.z rdx, 1
mov.z rsi, 1 mov.z rsi, 1
mov.nz rsi, zero mov.nz rsi, zero
@ -64,7 +64,7 @@ strtoq:
; base prefix? ; base prefix?
b.nz b[rdx], '0', .main_loop b.nz b[rdx], '0', .main_loop
add rdx, rdx, 1 inc rdx, 1
movzx rcx, b[rdx] movzx rcx, b[rdx]
; "0x"/"0b" prefix ; "0x"/"0b" prefix
@ -81,7 +81,7 @@ strtoq:
; if not, leave rax = 0 and *rdx = 'x' ; if not, leave rax = 0 and *rdx = 'x'
b.nz ax1, 16, .done b.nz ax1, 16, .done
; else ; else
add rdx, rdx, 1 inc rdx, 1
jmp .main_loop jmp .main_loop
.parsed_0b: .parsed_0b:
@ -89,7 +89,7 @@ strtoq:
; if not, leave rax = 0 and *rdx = 'b' ; if not, leave rax = 0 and *rdx = 'b'
b.nz ax1, 2, .done b.nz ax1, 2, .done
; else ; else
add rdx, rdx, 1 inc rdx, 1
jmp .main_loop jmp .main_loop
.base_0: .base_0:
@ -98,15 +98,15 @@ strtoq:
cmp b[rdx], '0' cmp b[rdx], '0'
mov.nz ax1, 10 mov.nz ax1, 10
jmp.nz .main_loop jmp.nz .main_loop
add rdx, rdx, 1 inc rdx, 1
cmp b[rdx], 'x' cmp b[rdx], 'x'
add.z rdx, rdx, 1 inc.z rdx, 1
mov.z ax1, 16 mov.z ax1, 16
jmp.z .main_loop jmp.z .main_loop
cmp b[rdx], 'b' cmp b[rdx], 'b'
add.z rdx, rdx, 1 inc.z rdx, 1
mov.z ax1, 2 mov.z ax1, 2
jmp.z .main_loop jmp.z .main_loop
@ -114,23 +114,23 @@ strtoq:
.main_loop: .main_loop:
movzx rcx, b[rdx] movzx rcx, b[rdx]
add rdx, rdx, 1 inc rdx, 1
cmp rcx, '0' cmp rcx, '0'
jmp.b .done jmp.b .done
cmp.ae rcx, '9' cmp.ae rcx, '9'
sub.be rcx, rcx, '0' dec.be rcx, '0'
jmp.be .next jmp.be .next
cmp rcx, 'A' cmp rcx, 'A'
cmp.ae rcx, 'Z' cmp.ae rcx, 'Z'
sub.be rcx, rcx, 55 ; 'A' - 10 dec.be rcx, 55 ; 'A' - 10
jmp.be .next jmp.be .next
cmp rcx, 'a' cmp rcx, 'a'
jmp.b .next jmp.b .next
cmp.ae rcx, 'z' cmp.ae rcx, 'z'
sub.be rcx, rcx, 87 ; 'a' - 10 dec.be rcx, 87 ; 'a' - 10
jmp.be .next jmp.be .next
.next: .next:
@ -138,7 +138,7 @@ strtoq:
b.ae rcx, ax1, .done b.ae rcx, ax1, .done
mul rax, rax, ax1 mul rax, rax, ax1
add rax, rax, rcx inc rax, rcx
jmp .main_loop jmp .main_loop
.done: .done:

View File

@ -36,7 +36,7 @@ DaysInYear:
jmp.cxnz .end jmp.cxnz .end
.leap: .leap:
add rax, rax, 1 inc rax, 1
.end: .end:
ret ret

View File

@ -10,11 +10,7 @@ memcpy:
.l: .l:
sub rdx, ax2, rcx sub rdx, ax2, rcx
mov b[ax0+rdx], b[ax1+rdx]
mov rax, b[ax1+rdx]
mov b[ax0+rdx], rax
loop .l loop .l
ret ret

View File

@ -22,11 +22,11 @@ strcmp:
add rbx, rax, rdx add rbx, rax, rdx
jmp.bxz .r jmp.bxz .r
add rcx, rcx, 1 inc rcx, 1
jmp .l jmp .l
.r: .r:
sub rax, rax, rdx dec rax, rdx
ret ret
; ;
@ -43,11 +43,11 @@ strncmp:
cmp rax, rdx cmp rax, rdx
jmp.nz .r jmp.nz .r
add ax0, ax0, 1 inc ax0, 1
add ax1, ax1, 1 inc ax1, 1
loop .l loop .l
.r: .r:
sub rax, rax, rdx dec rax, rdx
ret ret

View File

@ -11,8 +11,8 @@ strcpy:
ret.cxz ret.cxz
add ax0, ax0, 1 inc ax0, 1
add ax1, ax1, 1 inc ax1, 1
jmp .l jmp .l
@ -24,11 +24,10 @@ strncpy:
ret.cxz ret.cxz
.l: .l:
mov rax, b[ax1] mov b[ax0], b[ax1]
mov b[ax0], rax
add ax0, ax0, 1 inc ax0, 1
add ax1, ax1, 1 inc ax1, 1
loop .l loop .l
ret ret
@ -46,8 +45,8 @@ strnzcpy:
jmp.axz .r jmp.axz .r
add ax0, ax0, 1 inc ax0, 1
add ax1, ax1, 1 inc ax1, 1
loop .l loop .l

View File

@ -18,20 +18,19 @@ strrev:
; the null terminator ; the null terminator
mov rcx, STRLEN_MAX mov rcx, STRLEN_MAX
scasb.rep.nz ax1, zero scasb.rep.nz ax1, zero
sub ax1, ax1, 1 dec ax1, 1
.2: .2:
; copy, going backward though str ; copy, going backward though str
; and forward through buf ; and forward through buf
mov rax, b[ax1] mov b[ax0], b[ax1]
mov b[ax0], rax
cmp ax1, rsi cmp ax1, rsi
mov.z b[ax0+1], zero mov.z b[ax0+1], zero
ret.z ret.z
add ax0, ax0, 1 inc ax0, 1
sub ax1, ax1, 1 dec ax1, 1
jmp .2 jmp .2
@ -50,18 +49,16 @@ strrev2:
; the null terminator ; the null terminator
mov rcx, STRLEN_MAX mov rcx, STRLEN_MAX
scasb.rep.nz ax1, zero scasb.rep.nz ax1, zero
sub ax1, ax1, 1 dec ax1, 1
; increase ax0 while decreasing ax1, performing exchanges ; increase ax0 while decreasing ax1, performing exchanges
.2: .2:
b.ae ax0, ax1, .3 b.ae ax0, ax1, .3
mov rax, b[ax1] xchg b[ax0], b[ax1]
xchg rax, b[ax0]
mov b[ax1], rax
add ax0, ax0, 1 inc ax0, 1
sub ax1, ax1, 1 dec ax1, 1
jmp .2 jmp .2
.3: .3:

View File

@ -5,9 +5,7 @@ TrapHandlers.prolog:
mov rbp, rsp mov rbp, rsp
; nx0 = caller's cr2 ; nx0 = caller's cr2
mov ax0, r14 call RFS.LoadReg, r14, $cr2
mov ax1, $cr2
call RFS.LoadReg
; we don't preserve the r12 we got ; we don't preserve the r12 we got
mov r12, rax mov r12, rax

View File

@ -9,10 +9,8 @@ trap0_handler:
jmp TrapHandlers.prolog jmp TrapHandlers.prolog
.text: .text:
mov ax0, r14 call RFS.LoadReg, r14, $rax
mov ax1, $rax call RFS.LoadArgs, r14
call RFS.LoadReg
call RFS.LoadArgs
b.z rax, zero, .handle_Shutdown b.z rax, zero, .handle_Shutdown
b.z rax, Sys.Exit, .handle_Exit b.z rax, Sys.Exit, .handle_Exit
@ -66,7 +64,7 @@ trap0_handler:
call RFS.StoreReg, zero, $cr0 call RFS.StoreReg, zero, $cr0
mov rcx, CMDCOM_LOADP mov rcx, CMDCOM_LOADP
sub rcx, rcx, 0x100000 dec rcx, 0x100000
; Code offset ; Code offset
mov ax2, rcx mov ax2, rcx
@ -87,17 +85,17 @@ trap0_handler:
; Disk API ; Disk API
; ;
.handle_FindFirst: .handle_FindFirst:
add ax0, ax0, r12 inc ax0, r12
call DISK.FindFirst call DISK.FindFirst
jmp .fini jmp .fini
.handle_FindNext: .handle_FindNext:
add ax0, ax0, r12 inc ax0, r12
call DISK.FindNext call DISK.FindNext
jmp .fini jmp .fini
.handle_OpenFile: .handle_OpenFile:
add ax0, ax0, r12 inc ax0, r12
call DISK.OpenFile call DISK.OpenFile
jmp .fini jmp .fini
@ -106,7 +104,7 @@ trap0_handler:
jmp .fini jmp .fini
.handle_ReadFile: .handle_ReadFile:
add ax1, ax1, r12 inc ax1, r12
call DISK.ReadFile call DISK.ReadFile
jmp .fini jmp .fini

View File

@ -21,7 +21,7 @@ InitSyscalls:
call RFS.StoreReg call RFS.StoreReg
mov ax1, ax0 mov ax1, ax0
add ax0, ax0, 255 # TRAP no. (ax0 - 1) inc ax0, 255 # TRAP no. (ax0 - 1)
call IDT.AddHandler call IDT.AddHandler
ret ret

View File

@ -10,9 +10,7 @@ builtins.dir:
push r12 push r12
mov r12, zero # no. of files found mov r12, zero # no. of files found
mov rcx, STRLEN_MAX call print, .dirmsg
mov rdx, .dirmsg
prns.rep.nz rdx
.dirmsg = "Directory of C:\\\n\n" .dirmsg = "Directory of C:\\\n\n"
@ -34,7 +32,7 @@ builtins.dir:
jmp.axz .end jmp.axz .end
; found something ; found something
add r12, r12, 1 inc r12, 1
; separate extension from file name ; separate extension from file name
mov rcx, NAME_MAX mov rcx, NAME_MAX
@ -48,13 +46,13 @@ builtins.dir:
; calculate where to put extension ; calculate where to put extension
sub rdi, rsi, .buf sub rdi, rsi, .buf
sub rdi, rdi, 1 dec rdi, 1
.ext_pad: .ext_pad:
; print at least 11 non-space characters before extension ; print at least 11 non-space characters before extension
b.ae rdi, 11, .print_ext b.ae rdi, 11, .print_ext
prn ' ' prn ' '
add rdi, rdi, 1 inc rdi, 1
jmp .ext_pad jmp .ext_pad
.print_ext: .print_ext:
@ -69,10 +67,9 @@ builtins.dir:
b.z b[rsi], 0, .print_ext.2 b.z b[rsi], 0, .print_ext.2
; print and decrease rcx, unless it's already 0 ; print and decrease rcx, unless it's already 0
mov rbx, b[rsi] prn b[rsi]
prn rbx inc rsi, 1
add rsi, rsi, 1 dec.cxnz rcx, 1
sub.cxnz rcx, rcx, 1
jmp .print_ext.1 jmp .print_ext.1
@ -84,9 +81,8 @@ builtins.dir:
.print_bytes: .print_bytes:
; print file size in bytes ; print file size in bytes
prn ' ' mov rcx, 3
prn ' ' prn.rep ' '
prn ' '
shr rax, rdx, 10 shr rax, rdx, 10
and rdx, rdx, 1023 and rdx, rdx, 1023
@ -94,7 +90,7 @@ builtins.dir:
push rdx push rdx
push rax push rax
call printf, .bytesstr call printf, .bytesstr
add rsp, rsp, 16 inc rsp, 16
.bytesstr = "%d kilobytes + %d bytes" .bytesstr = "%d kilobytes + %d bytes"
@ -106,7 +102,7 @@ builtins.dir:
.end: .end:
push r12 push r12
call printf, .endstr1 call printf, .endstr1
add rsp, rsp, 8 inc rsp, 8
call print, .endstr2 call print, .endstr2

View File

@ -41,7 +41,7 @@ main:
jmp.cxz .input_loop ; no jmp.cxz .input_loop ; no
; yes, delete it ; yes, delete it
sub rcx, rcx, 1 dec rcx, 1
add rdx, rcx, argbuf add rdx, rcx, argbuf
mov b[rdx], zero mov b[rdx], zero
@ -63,7 +63,7 @@ main:
; add character to buffer and increase iterator (rcx) ; add character to buffer and increase iterator (rcx)
add rdx, rcx, argbuf add rdx, rcx, argbuf
mov b[rdx], rax mov b[rdx], rax
add rcx, rcx, 1 inc rcx, 1
; another one ; another one
jmp .input_loop jmp .input_loop
@ -87,7 +87,7 @@ main:
; skip spaces ; skip spaces
cmp rcx, ' ' cmp rcx, ' '
add.z rsi, rsi, 1 inc.z rsi, 1
jmp.z .next_space jmp.z .next_space
; if we're here, we found a ; if we're here, we found a
@ -105,17 +105,16 @@ main:
; how much do we copy? ; how much do we copy?
sub rcx, rdx, argbuf sub rcx, rdx, argbuf
jmp.cxz .detect_builtin jmp.cxz .detect_builtin
sub rcx, rcx, 1 dec rcx, 1
mov rdi, argbuf mov rdi, argbuf
mov rsi, argv0 mov rsi, argv0
.copy_loop: .copy_loop:
mov rax, b[rdi] mov b[rsi], b[rdi]
mov b[rsi], rax
add rdi, rdi, 1 inc rdi, 1
add rsi, rsi, 1 inc rsi, 1
loop .copy_loop loop .copy_loop
@ -185,7 +184,7 @@ main:
call printf, .datefmt call printf, .datefmt
add rsp, rsp, 40 inc rsp, 40
jmp .print_prompt jmp .print_prompt
@ -255,7 +254,7 @@ main:
push b[rax+1] push b[rax+1]
push b[rax+2] push b[rax+2]
call printf, .timefmt call printf, .timefmt
add rsp, rsp, 24 inc rsp, 24
jmp .print_prompt jmp .print_prompt
@ -307,7 +306,7 @@ main:
push q[argv1pos] push q[argv1pos]
push argv0 push argv0
call printf, .fnf_errmsg call printf, .fnf_errmsg
add rsp, rsp, 16 inc rsp, 16
jmp .print_prompt jmp .print_prompt
@ -317,7 +316,7 @@ main:
push q[argv1pos] push q[argv1pos]
push argv0 push argv0
call printf, .ef_errmsg call printf, .ef_errmsg
add rsp, rsp, 16 inc rsp, 16
jmp .print_prompt jmp .print_prompt
@ -327,7 +326,7 @@ main:
push q[argv1pos] push q[argv1pos]
push argv0 push argv0
call printf, .cno_errmsg call printf, .cno_errmsg
add rsp, rsp, 16 inc rsp, 16
jmp .print_prompt jmp .print_prompt

View File

@ -12,7 +12,7 @@
# #
# Preserves all flags # Preserves all flags
# #
or r r ri or 3
# #
# Bitwise AND operation # Bitwise AND operation
@ -21,7 +21,7 @@ or r r ri
# #
# Preserves all flags # Preserves all flags
# #
and r r ri and 3
# #
# Bitwise XOR operation # Bitwise XOR operation
@ -30,7 +30,7 @@ and r r ri
# #
# Preserves all flags # Preserves all flags
# #
xor r r ri xor 3
# #
# Logical left/right shift (SHL/SHR) # Logical left/right shift (SHL/SHR)
@ -40,8 +40,8 @@ xor r r ri
# #
# Preserves all flags # Preserves all flags
# #
shl r r ri shl 3
shr r r ri shr 3
# #
# Arithmetical left/right shift (SAL/SAR) # Arithmetical left/right shift (SAL/SAR)
@ -51,8 +51,8 @@ shr r r ri
# #
# Preserves all flags # Preserves all flags
# #
sal r r ri sal 3
sar r r ri sar 3
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# Arithmetic instructions # # Arithmetic instructions #
@ -67,8 +67,7 @@ sar r r ri
# Sets OF is signed integer overflow occur, clears it otherwise # Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result # Sets ZF and SF according to the result
# #
cmp r ri cmp 2
cmp m ri
# #
# Arithmetical ADD operation # Arithmetical ADD operation
@ -79,8 +78,9 @@ cmp m ri
# Sets OF is signed integer overflow occur, clears it otherwise # Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result # Sets ZF and SF according to the result
# #
add r r ri inc 2
addf r r ri add 3
addf 3
# #
# Arithmetical SUB operation # Arithmetical SUB operation
@ -91,8 +91,9 @@ addf r r ri
# Sets OF is signed integer overflow occur, clears it otherwise # Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result # Sets ZF and SF according to the result
# #
sub r r ri dec 2
subf r r ri sub 3
subf 3
# #
# Arithmetical ADD/SUB operation, with carry/overflow # 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 OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result # Sets ZF and SF according to the result
# #
adcx r r ri adcx 3
sbbx r r ri sbbx 3
# #
# Arithmetical MUL operation # Arithmetical MUL operation
@ -115,8 +116,8 @@ sbbx r r ri
# Preserves ZF and SF # Preserves ZF and SF
# Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise # Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise
# #
mul r r ri mul 3
mulf r r ri mulf 3
# Arithmetical unsigned MUL operation # Arithmetical unsigned MUL operation
# #
@ -125,7 +126,7 @@ mulf r r ri
# #
# Preserves all flags # Preserves all flags
# #
mulhi r r ri mulhi 3
# Arithmetical signed MUL operation # Arithmetical signed MUL operation
# #
@ -134,7 +135,7 @@ mulhi r r ri
# #
# Preserves all flags # Preserves all flags
# #
imulhi r r ri imulhi 3
# #
# Arithmetical unsigned DIV operation # Arithmetical unsigned DIV operation
@ -143,7 +144,7 @@ imulhi r r ri
# #
# Preserves all flags # Preserves all flags
# #
div r r ri div 3
# #
# Arithmetical signed DIV operation # Arithmetical signed DIV operation
@ -152,7 +153,7 @@ div r r ri
# #
# Preserves all flags # Preserves all flags
# #
idiv r r ri idiv 3
# #
# Arithmetical modulo operation (REM) # Arithmetical modulo operation (REM)
@ -161,5 +162,5 @@ idiv r r ri
# #
# Preserves all flags # Preserves all flags
# #
rem r r ri rem 3

View File

@ -10,7 +10,7 @@
# #
# RIP = $1 # RIP = $1
# #
jmp ri jmp 1
# #
# RCX-dependent jump (LOOP) instruction # RCX-dependent jump (LOOP) instruction
@ -20,7 +20,7 @@ jmp ri
# RIP = $1 # RIP = $1
# FI # FI
# #
loop ri loop 1
# #
# Conditional absolute jumps (B) # Conditional absolute jumps (B)
@ -38,7 +38,7 @@ loop ri
# #
# Suffixing B with the REP suffix results in undefined behavior # 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) # PUSH(RIP)
# JMP(RIP) # JMP(RIP)
# #
call ri call 1
call i ri xcall2 2
call i ri ri xcall3 3
# #
# Return to caller (RET) # Return to caller (RET)
@ -69,7 +69,7 @@ ret
# RBP = RSP # RBP = RSP
# RSP = RSP - $1 # RSP = RSP - $1
# #
enter i enter 1
# #
# Leave stack frame (LEAVE) # Leave stack frame (LEAVE)
@ -85,7 +85,7 @@ leave
# RSP = RSP - 8 # RSP = RSP - 8
# *RSP = $1 # *RSP = $1
# #
push rim push 1
# #
# POP value from stack # POP value from stack
@ -93,7 +93,7 @@ push rim
# $1 = *RSP # $1 = *RSP
# RSP = RSP + 8 # RSP = RSP + 8
# #
pop r pop 1
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# Movement instructions # # Movement instructions #
@ -111,31 +111,30 @@ pop r
# #
# Preserves all flags # Preserves all flags
# #
lea r m lea 2
# #
# Move data (MOV) instruction # Move data (MOV) instruction
# #
# $1 = SignExtend($2) # $1 = SignExtend($2)
# #
mov r rim mov 2
mov m ri
# #
# Load from memory with zero-extension (MOVSX/MOVZX) instruction # Load from memory with zero-extension (MOVSX/MOVZX) instruction
# #
# $1 = ZeroExtend($2) # $1 = ZeroExtend($2)
# #
movzx r m movzx 2
# #
# Move with sign-extension (MOVSXx) instruction # Move with sign-extension (MOVSXx) instruction
# #
# $1 = SignExtend($2 & (2^(8 * sizeof(x)) - 1) # $1 = SignExtend($2 & (2^(8 * sizeof(x)) - 1)
# #
movsxb r r movsxb 2
movsxw r r movsxw 2
movsxd r r movsxd 2
# #
# Exchange (XCHG) instruction # Exchange (XCHG) instruction
@ -144,5 +143,5 @@ movsxd r r
# $1 = $2 # $1 = $2
# $2 = $_ # $2 = $_
# #
xchg r rm xchg 2

View File

@ -38,14 +38,14 @@ into
# #
# Get timestamp in µseconds # Get timestamp in µseconds
# #
utime r r utime 2
# #
# $1 = seconds since start of month # $1 = seconds since start of month
# $2 = current month # $2 = current month
# $3 = current year # $3 = current year
# #
ytime r r r ytime 3
# #
# Clear all GPR registers except RBP/RSP # Clear all GPR registers except RBP/RSP
@ -61,9 +61,9 @@ cls
# #
# Change endianness # Change endianness
# #
bswap r r bswap 2
wswap r r wswap 2
dswap r r dswap 2
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
# I/O instructions # # I/O instructions #
@ -72,7 +72,7 @@ dswap r r
# #
# Send a character to standard output (PRN) # Send a character to standard output (PRN)
# #
prn ri prn 1
# #
# Print a string to standard output (PRN) # Print a string to standard output (PRN)
@ -89,10 +89,10 @@ prn ri
# FI # FI
# #
# #
prns r prns 1
# #
# Scan a character from standard input (SCAN) # Scan a character from standard input (SCAN)
# #
scan r scan 1

View File

@ -15,10 +15,10 @@
# %str = %str - sizeof(x) # %str = %str - sizeof(x)
# FI # FI
# #
stosb r ri stosb 2
stosw r ri stosw 2
stosd r ri stosd 2
stosq r ri stosq 2
# #
# Scan string for a particular value (SCASx) # Scan string for a particular value (SCASx)
@ -42,10 +42,10 @@ stosq r ri
# - Does not move past the value when found # - Does not move past the value when found
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()' # - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
# #
scasb r ri scasb 2
scasw r ri scasw 2
scasd r ri scasd 2
scasq r ri scasq 2
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#

View File

@ -48,7 +48,7 @@ hlt
# #ILL if $1 > 255 # #ILL if $1 > 255
# #($1+256) otherwise # #($1+256) otherwise
# #
trap ri trap 1
# #
# Return from exception/interrupt (IRET) # Return from exception/interrupt (IRET)
@ -79,7 +79,7 @@ sti
# Throws: # Throws:
# #SYS if not in supervisor mode # #SYS if not in supervisor mode
# #
devctl r r devctl 2
# #
# Call a device-defined function slot of device (IOCALL) # Call a device-defined function slot of device (IOCALL)
@ -89,5 +89,5 @@ devctl r r
# Throws: # Throws:
# #SYS if not in supervisor mode # #SYS if not in supervisor mode
# #
iocall ri ri iocall 2

View File

@ -8,27 +8,32 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(or) { *r1 = p2->val | p3->val; return 1; } IMPL_START(or) { SRCP(p2); SRCP(p3); *r1 = p2->val | p3->val; return 1; }
IMPL_START(and) { *r1 = p2->val & p3->val; return 1; } IMPL_START(and) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; }
IMPL_START(xor) { *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(shl) { SRCP(p2); SRCP(p3); *r1 = p2->val << p3->val; return 1; }
IMPL_START(shr) { *r1 = p2->val >> p3->val; return 1; } IMPL_START(shr) { SRCP(p2); SRCP(p3); *r1 = p2->val >> p3->val; return 1; }
IMPL_START(sal) { *r1 = (ulong)((long)p2->val << (long)p3->val); return 1; } IMPL_START(sal) { SRCP(p2); SRCP(p3); *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(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(inc) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; }
IMPL_START(addf) { COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->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(dec) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; }
IMPL_START(subf) { COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->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) IMPL_START(adcx)
{ {
SRCP(p2);
SRCP(p3);
p3->val += !!(R(RFX)&CF); p3->val += !!(R(RFX)&CF);
COMPARE_ADD(p2->val, p3->val); COMPARE_ADD(p2->val, p3->val);
*r1 = p2->val + p3->val; *r1 = p2->val + p3->val;
@ -38,6 +43,9 @@ IMPL_START(adcx)
IMPL_START(sbbx) IMPL_START(sbbx)
{ {
SRCP(p2);
SRCP(p3);
p3->val += !!(R(RFX)&CF); p3->val += !!(R(RFX)&CF);
COMPARE_SUB(p2->val, p3->val); COMPARE_SUB(p2->val, p3->val);
*r1 = 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(mul) { SRCP(p2); SRCP(p3); *r1 = p2->val * p3->val; return 1; }
IMPL_START(rem) { *r1 = p2->val % p3->val; return 1; } IMPL_START(rem) { SRCP(p2); SRCP(p3); *r1 = p2->val % p3->val; return 1; }
IMPL_START(div) IMPL_START(div)
{ {
SRCP(p2);
SRCP(p3);
if (!p3->val) if (!p3->val)
_except(ctx, E_DIV, "DIV by 0"); _except(ctx, E_DIV, "DIV by 0");
*r1 = p2->val / p3->val; *r1 = p2->val / p3->val;
@ -61,6 +72,9 @@ IMPL_START(div)
IMPL_START(idiv) IMPL_START(idiv)
{ {
SRCP(p2);
SRCP(p3);
if (!p3->val) if (!p3->val)
_except(ctx, E_DIV, "IDIV by 0"); _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) IMPL_START(mulhi)
{ {
SRCP(p2);
SRCP(p3);
__unsigned_multiply128(p2->val, p3->val, r1, r2); __unsigned_multiply128(p2->val, p3->val, r1, r2);
return 2; return 2;
} }
IMPL_START(mulf) IMPL_START(mulf)
{ {
SRCP(p2);
SRCP(p3);
ulong tmp; ulong tmp;
__unsigned_multiply128(p2->val, p3->val, &tmp, r1); __unsigned_multiply128(p2->val, p3->val, &tmp, r1);
R(RFX) = p2->val ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF); 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) IMPL_START(imulhi)
{ {
SRCP(p2);
SRCP(p3);
__signed_multiply128(p2->val, p3->val, r1, r2); __signed_multiply128(p2->val, p3->val, r1, r2);
return 2; return 2;
} }

View File

@ -5,25 +5,6 @@
from tempfile import TemporaryFile 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): def parse_1(fi, fp):
global count global count
@ -41,36 +22,7 @@ def parse_1(fi, fp):
parse_1(fi2, fp) parse_1(fi2, fp)
continue continue
tok = line.split() fp.write("{}\n".format(line))
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()
def parse_2(fp): def parse_2(fp):
global count global count
@ -89,41 +41,19 @@ def parse_2(fp):
if len(tok) == 1: if len(tok) == 1:
name = tok[0] name = tok[0]
p1 = "NOPRM" n = 0
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])
else: else:
name = "__TOK_ERROR__" assert(len(tok) == 2)
p1 = "__TOK_ERROR__" n = tok[1]
p2 = "__TOK_ERROR__"
p3 = "__TOK_ERROR__"
ls.write("{}{}\n".format(deprecated, name)) ls.write("{}{}\n".format(deprecated, tok[0]))
hd.write("#ifdef _NEED_ARCH_I\n") hd.write("#ifdef _NEED_ARCH_I\n")
hd.write('{{ "{}{}", "{}{}", {}, {}, {}, i_{} }},\n'\ hd.write('{{ "{}{}", {}, i_{} }},\n'\
.format(deprecated, tok[0], deprecated, name, p1, p2, p3, tok[0])) .format(deprecated, tok[0], n, tok[0]))
hd.write("#else\n") 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" hd.write("extern bool i_{}(ctx_t *, acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n"
.format(tok[0])) .format(tok[0]))
hd.write("#endif\n\n") hd.write("#endif\n\n")

View File

@ -9,6 +9,15 @@
uint i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \ uint i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, acc_t *p3, \
ulong *r1, ulong *r2, ulong *r3) \ 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() \ #define INTO() \

View File

@ -17,14 +17,10 @@ IMPL_START(loop) {
IMPL_START(b) IMPL_START(b)
{ {
ulong v; SRCP(p1);
SRCP(p2);
if (ACC_FMT_IS_MEM(p1->type)) COMPARE_SUB(p1->val, p2->val);
v = readmemsx(ctx, p1->addr, p1->mlen);
else v = p1->val;
COMPARE_SUB(v, p2->val);
if (eval_cond(ctx, ctx->cond)) if (eval_cond(ctx, ctx->cond))
R(RIP) = p3->val; R(RIP) = p3->val;
@ -34,14 +30,9 @@ IMPL_START(b)
IMPL_START(cmp) IMPL_START(cmp)
{ {
ulong v; SRCP(p1);
if (ACC_FMT_IS_MEM(p1->type)) COMPARE_SUB(p1->val, p2->val);
v = readmemsx(ctx, p1->addr, p1->mlen);
else v = p1->val;
COMPARE_SUB(v, p2->val);
return 0; return 0;
} }
@ -49,44 +40,20 @@ IMPL_START(cmp)
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START(lea) { *r1 = p2->addr; return 1; } 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) 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; }
if (ACC_FMT_IS_MEM(p2->type)) IMPL_START(movsxd) { SRCP(p2); *r1 = (ulong)(long)(int)p2->val; return 1; }
*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(xchg) IMPL_START(xchg)
{ {
SRCP(p1);
SRCP(p2);
*r2 = p1->val; *r2 = p1->val;
*r1 = p2->val;
if (ACC_FMT_IS_MEM(p2->type))
*r1 = readmemsx(ctx, p2->addr, p2->mlen);
else *r1 = p2->val;
return 2; return 2;
} }
@ -99,15 +66,10 @@ IMPL_START(xchg)
IMPL_START(push) IMPL_START(push)
{ {
ulong v; XSRCP(p1->val, p1, zx);
if (ACC_FMT_IS_MEM(p1->type))
v = readmemzx(ctx, p1->addr, p1->mlen);
else v = p1->val;
R(RSP) -= 8; R(RSP) -= 8;
writemem(ctx, v, R(RSP), 8); writemem(ctx, p1->val, R(RSP), 8);
return 0; return 0;
} }
@ -122,17 +84,41 @@ IMPL_START(pop)
IMPL_START(call) IMPL_START(call)
{ {
SRCP(p1);
R(RSP) -= 8; R(RSP) -= 8;
writemem(ctx, R(RIP), R(RSP), 8); writemem(ctx, R(RIP), R(RSP), 8);
R(RIP) = p1->val; R(RIP) = p1->val;
if (p2) return 0;
{ }
R(AX0) = p2->val;
if (p3) IMPL_START(xcall2)
R(AX1) = p3->val; {
} SRCP(p1);
SRCP(p2);
R(RSP) -= 8;
writemem(ctx, R(RIP), R(RSP), 8);
R(RIP) = p1->val;
R(AX0) = p2->val;
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; return 0;
} }

View File

@ -81,6 +81,8 @@ IMPL_START(cls)
IMPL_START(bswap) IMPL_START(bswap)
{ {
SRCP(p2);
ulong v = p2->val; ulong v = p2->val;
*r1 = ((v & 0xFF00000000000000) >> 56) *r1 = ((v & 0xFF00000000000000) >> 56)
@ -97,6 +99,8 @@ IMPL_START(bswap)
IMPL_START(wswap) IMPL_START(wswap)
{ {
SRCP(p2);
ulong v = p2->val; ulong v = p2->val;
*r1 = ((v & 0xFFFF000000000000) >> 48) *r1 = ((v & 0xFFFF000000000000) >> 48)
@ -109,6 +113,8 @@ IMPL_START(wswap)
IMPL_START(dswap) IMPL_START(dswap)
{ {
SRCP(p2);
*r1 = ((p2->val & 0xFFFFFFFF00000000) >> 32) *r1 = ((p2->val & 0xFFFFFFFF00000000) >> 32)
| ((p2->val & 0x00000000FFFFFFFF) << 32); | ((p2->val & 0x00000000FFFFFFFF) << 32);
@ -121,6 +127,8 @@ IMPL_START(dswap)
IMPL_START(prn) IMPL_START(prn)
{ {
SRCP(p1);
ulong v = p1->val; ulong v = p1->val;
// Magic value? :) // Magic value? :)
@ -135,6 +143,9 @@ IMPL_START(prn)
IMPL_START(prns) 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); uchar ch = readmemzx(ctx, R(p1->reg), 1);
COMPARE_SUB(ch, 0); COMPARE_SUB(ch, 0);

View File

@ -13,6 +13,9 @@
static void stos_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len) 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); writemem(ctx, p2->val, R(p1->reg), len);
STR_MOVE(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) 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); ulong x = readmemsx(ctx, R(p1->reg), len);
COMPARE_SUB(x, p2->val); COMPARE_SUB(x, p2->val);

View File

@ -3,18 +3,23 @@
#include <pc/console.h> #include <pc/console.h>
// FIXME XXX
//#define _LARGE_SCREEN
#ifndef _LARGE_SCREEN #ifndef _LARGE_SCREEN
# define CONSOLE_WIDTH 80 # define _MULT 1
# define CONSOLE_HEIGHT 25
# define CONSOLE_FONT_SIZE 16
#else #else
# define CONSOLE_WIDTH 160 # define _MULT 2
# define CONSOLE_HEIGHT 50
# define CONSOLE_FONT_SIZE 32
#endif #endif
#define SCREEN_WIDTH (9 * CONSOLE_WIDTH) #define CONSOLE_WIDTH (80)
#define SCREEN_HEIGHT (16 * CONSOLE_HEIGHT) #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_Window *scr_win = NULL;
SDL_Renderer *scr_rend = 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++) for (y = 0; y < CONSOLE_HEIGHT-1; y++)
if (scr_rects[y] != NULL) if (scr_rects[y] != NULL)
{ {
scr_rects[y]->y -= 16; // surf->h scr_rects[y]->y -= _SURF_H; // surf->h
} }
console_render(ctx); console_render(ctx);

View File

@ -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 // 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 }; static const int lentab[9] = { 0, 1, 1, 0, 1, 0, 0, 0, 1 };
if (len > 8 || lentab[len] == 0) 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 // 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 // Get next operand ModRM-like byte
uchar fmt = fetchb(ctx); uchar fmt = fetchb(ctx);
ulong hi = (fmt & 0b11100000) >> 5; uchar hi = (fmt & 0b11100000) >> 5;
ulong lo = fmt & 0b00011111; uchar lo = fmt & 0b00011111;
// //
// Registers // Registers
// //
if (hi == 0) if (hi == 0)
{ {
if (prm != P_REG)
_except(ctx, E_ILL, "Not expecting a register: %s",
ctx->cur_in->full);
p->reg = lo; p->reg = lo;
p->type = A_REG; p->type = A_REG;
checkreg(ctx, p->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 (hi == 7)
{ {
if (prm != P_IMM)
_except(ctx, E_ILL, "Not expecting an immediate: %s",
ctx->cur_in->full);
switch (lo) switch (lo)
{ {
case 1: case 1:
@ -131,7 +124,8 @@ static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
break; break;
default: default:
_except(ctx, E_ILL, "Invalid immediate length: %hhu", lo); _except(ctx, E_ILL, "%s: Invalid immediate length: %hhu",
in->name, lo);
} }
return; return;
@ -141,11 +135,7 @@ static void extract_param(ctx_t *ctx, uint prm, acc_t *p)
// Memory operands // Memory operands
// //
if (prm != P_MEM) checklength(ctx, in, lo);
_except(ctx, E_ILL, "Not expecting a memory access: %s",
ctx->cur_in->full);
checklength(ctx, lo);
p->mlen = lo; p->mlen = lo;
switch (hi) switch (hi)
@ -234,31 +224,31 @@ void decode(ctx_t *ctx)
ctx->cond = b2 & SUFF_COND; ctx->cond = b2 & SUFF_COND;
// Operand 1? // Operand 1?
if (in->prm1 == NOPRM) if (in->nprms == 0)
{ {
exec_instr(ctx, in, NULL, NULL, NULL, lock, rep); exec_instr(ctx, in, NULL, NULL, NULL, lock, rep);
return; return;
} }
extract_param(ctx, in->prm1, &p1); extract_param(ctx, in, &p1);
// Operand 2? // Operand 2?
if (in->prm2 == NOPRM) if (in->nprms == 1)
{ {
exec_instr(ctx, in, &p1, NULL, NULL, lock, rep); exec_instr(ctx, in, &p1, NULL, NULL, lock, rep);
return; return;
} }
extract_param(ctx, in->prm2, &p2); extract_param(ctx, in, &p2);
// Operand 1? // Operand 1?
if (in->prm3 == NOPRM) if (in->nprms == 2)
{ {
exec_instr(ctx, in, &p1, &p2, NULL, lock, rep); exec_instr(ctx, in, &p1, &p2, NULL, lock, rep);
return; return;
} }
extract_param(ctx, in->prm3, &p3); extract_param(ctx, in, &p3);
exec_instr(ctx, in, &p1, &p2, &p3, lock, rep); exec_instr(ctx, in, &p1, &p2, &p3, lock, rep);
} }

View File

@ -66,12 +66,7 @@ enum { NOPRM, P_REG, P_IMM, P_MEM=4 };
struct instr_t struct instr_t
{ {
char *name; char *name;
char *full; uint nprms;
uint prm1;
uint prm2;
uint prm3;
uint (*func)(ctx_t *, acc_t *, acc_t *, acc_t *, uint (*func)(ctx_t *, acc_t *, acc_t *, acc_t *,
ulong *, ulong *, ulong *); ulong *, ulong *, ulong *);
}; };

View File

@ -41,12 +41,10 @@ bool eval_cond(ctx_t *ctx, uint cond)
#define OUTPUT(p, r) { \ #define OUTPUT(p, r) { \
if (p->type == A_REG) \ if (p->type == A_REG) \
R(p->reg) = r; \ R(p->reg) = r; \
else if (p1->type == A_IMM64) \ else if (ACC_IS_MEM(p)) \
_except(ctx, E_ACC, "Trying to output to an IMM64"); \
else { \
assert(ACC_IS_MEM(p)); \
writemem(ctx, r, p->addr, p->mlen); \ writemem(ctx, r, p->addr, p->mlen); \
} } else _except(ctx, E_ACC, "Trying to output to an IMM"); \
}
// //
// Executes an instruction // Executes an instruction

View File

@ -62,7 +62,7 @@ int main(int argc, char **argv)
main_ctx.r = arch_r; main_ctx.r = arch_r;
main_ctx.i = arch_i; main_ctx.i = arch_i;
#if 1 && !defined(NDEBUG) #if 0 && !defined(NDEBUG)
main_ctx.dumpsw = 1; main_ctx.dumpsw = 1;
#endif #endif