more opcodes (branches, MOV)

This commit is contained in:
Jeremy Penner 2023-09-01 19:10:52 -04:00
parent 73ffd53c68
commit bea5d1b0e4

62
asm.jrt
View file

@ -6,6 +6,8 @@ var target
var op-encode
var lastop
var is-byteptr : byteptr 1 is-byteptr ! ;
var current-oparg
var opargs-remaining
array oparg1 3 cells allot
@ -35,7 +37,8 @@ array oparg2 3 cells allot
( ie. inc [bx] vs inc byte [bx]?? )
( or do we just say incb? )
: bytearg? ( -- f ) oparg-breg? swap-args oparg-breg? or swap-args ;
: byteop? ( -- f )
oparg-breg? swap-args oparg-breg? or swap-args is-byteptr @ or ;
: byteval? ( v -- f ) 0xff00 & dup 0xff00 = swap 0 = or ;
: operror ( err -- ) lastop @ wordname type s" : " type type cr ;
@ -79,6 +82,7 @@ array oparg2 3 cells allot
0x25 reg es 0x27 reg ss 0x2d reg cs 0x2f reg ds
: start-op ( does-ptr argcount -- )
0 is-byteptr !
opargs-remaining @ if s" not enough arguments" operror then
opargs-remaining ! cell - lastop ! arg1 ;
: prefix create , does> @ >t ;
@ -118,16 +122,16 @@ array oparg2 3 cells allot
( convention: words ending in * mean "will return if matched" )
: disp>t oparg-val @ memarg>dispsize
dup 1 = if drop >t else 2 = if w>t else drop then then ;
: imm?>t oparg-imm? if oparg-val @ dup byteval? if >t else w>t then then ;
: imm?>t oparg-imm? if oparg-val @ byteop? if >t else w>t then then ;
: >wreg+op* ( base -- )
oparg-wreg? if oparg-val @ | >t rdrop else drop then ;
: >segreg+op* ( off -- )
oparg-segreg? if oparg-val @ 0x0f & 1 << + >t rdrop else drop then ;
: >mem* ( reg op -- )
oparg-mem? if
>t memarg>mod+rm modrm>t disp>t swap-args imm?>t rdrop
else 2drop then ;
: >mem ( reg op -- ) >t memarg>mod+rm modrm>t disp>t swap-args imm?>t ;
: >mem* oparg-mem? byteop? not and if >mem rdrop else 2drop then ;
: >bmem* oparg-mem? byteop? and if >mem rdrop else 2drop then ;
: >regreg ( reg op -- ) >t regarg>mod+rm modrm>t ;
: >byte-regreg* ( reg op -- ) oparg-breg? if >regreg rdrop else 2drop then ;
: >regreg* ( reg op -- ) oparg-wreg? if >regreg rdrop else 2drop then ;
@ -158,9 +162,47 @@ array oparg2 3 cells allot
1 0xfe >byte-regreg*
1 0xff >regreg*
0 0xff >mem*
1 0xfe >bmem*
invalid-args ;
1 :op decb
1 0xfe >byte-regreg*
1 0xfe >mem*
invalid-args ;
1 :op int
oparg-imm? if oparg-val @ dup 3 = if drop 0xcc t> else 0xcd t> t> then
else invalid-args then ;
: diffaddr ( addr opsize -- diff ) target @ + - ;
: >short-jmp* ( op -- ) oparg-type @ 3 = if oparg-base @ -1 = if
oparg-val @ 2 diffaddr dup byteval? if swap >t >t rdrop return else drop
then then then drop ;
1 :op jo 0x70 >short-jmp* invalid-args ;
1 :op jno 0x71 >short-jmp* invalid-args ;
1 :op jb 0x72 >short-jmp* invalid-args ;
1 :op jnb 0x73 >short-jmp* invalid-args ;
1 :op jz 0x74 >short-jmp* invalid-args ;
1 :op jnz 0x75 >short-jmp* invalid-args ;
1 :op jbe 0x76 >short-jmp* invalid-args ;
1 :op ja 0x77 >short-jmp* invalid-args ;
1 :op js 0x78 >short-jmp* invalid-args ;
1 :op jns 0x79 >short-jmp* invalid-args ;
1 :op jpe 0x7a >short-jmp* invalid-args ;
1 :op jpo 0x7b >short-jmp* invalid-args ;
1 :op jl 0x7c >short-jmp* invalid-args ;
1 :op jge 0x7d >short-jmp* invalid-args ;
1 :op jle 0x7e >short-jmp* invalid-args ;
1 :op jg 0x7f >short-jmp* invalid-args ;
1 :op loopnz 0xe0 >short-jmp* invalid-args ;
1 :op loopz 0xe1 >short-jmp* invalid-args ;
1 :op loop 0xe2 >short-jmp* invalid-args ;
1 :op jcxz 0xe3 >short-jmp* invalid-args ;
2 :op xchg
arg2 oparg-reg? oparg-val @ 0x00 = arg1 oparg-wreg? and
if 0x90 >wreg+op* then
invalid-args ;
2 :op mov
arg2 oparg-imm? arg1 if
oparg-wreg? if oparg-val @ 0xb8 | >t arg2 oparg-val @ w>t return then
oparg-breg? if oparg-val @ 0x0f & 0xb0 | >t arg2 oparg-val @ >t return then
0 0xc6 >bmem*
0 0xc7 >mem*
then
invalid-args ;