commit 986c09be9bb1df068f9ed53cd1bee3815016019c
parent 924626e5631bfd7d24ca72823fb516fec8b117ac
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Mon, 11 Jul 2022 17:36:35 -0400
asm: add shl, and shr,
Diffstat:
2 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/fs/asm.fs b/fs/asm.fs
@@ -22,7 +22,9 @@
-1 value disp \ displacement to use
\ tgt and src are values from constants above.
\ bits 8-9 represent the appropriate mod (from modrm) for this tgt/src
-\ bit 10 is for 16bit mode. -1 means unset.
+\ bit 10 is for 16bit mode.
+\ bit 11 is an indicator that IMM is forced to 8bit
+\ -1 means unset.
: asm$ -1 to tgt -1 to src -1 to disp ;
: _err abort" argument error" ;
@@ -54,12 +56,13 @@
: [ebp] BP [r]+8b! 0 to disp ;
: [edi] DI [r]! ;
: [ebp]+ ( disp -- ) BP [r]+8b! to disp ;
-: i32 IMM $400 or to src ;
+: i32 IMM to src ;
: [i32] ( n -- ) MEM tgt-or-src! to disp ;
\ Writing the thing
: disp, disp? if disp disp32? if , else c, then then ;
-: prefix, ( -- ) exit
+: imm, ( imm -- ) src $800 and if ( forced to 8bit ) c, else , then ;
+: prefix, ( -- ) exit \ TODO: fix this
tgt is16? if $66 c, then src isimm? not swap is16? and if $67 c, then ;
: op, ( op -- ) dup 8 rshift ?dup if c, then c, ;
: inh, ( op -- ) op, asm$ ;
@@ -67,7 +70,7 @@
prefix, op, ( reg ) 3 lshift tgtid tgt mod or or ( modrm ) c,
disp? if disp c, then asm$ ;
: modrm<imm, ( imm immreg op -- ) \ immediate src, modrm tgt
- op, 3 lshift tgtid or tgt mod or ( modrm ) c, disp, , asm$ ;
+ op, 3 lshift tgtid or tgt mod or ( modrm ) c, disp, imm, asm$ ;
: modrm2, ( imm? reg op -- ) \ modrm op with 2 arguments
src mod $c0 = not if
\ surprise! it's not tgt that is the mod rm, it's src. We're in "alternate"
@@ -102,7 +105,7 @@ $e9 4 op jmp, $e8 2 op call,
0 $0f9f op setg, 0 $0f9c op setl, 0 $0f94 op setz, 0 $0f95 op setnz,
\ Two operands
-: op ( immop immreg regop -- ) doer c, c, c, does> ( imm? a -- )
+: op ( immop /immreg regop -- ) doer c, c, c, does> ( imm? a -- )
prefix,
isimm? if
dup 1+ c@ ( immreg ) swap 2 + c@ ( immreg immop ) modrm<imm, else
@@ -114,6 +117,19 @@ $81 4 $21 op and, $81 1 $09 op or, $81 6 $33 op xor,
: op ( op -- ) doer c, does> ( a -- ) c@ tgtid or c, asm$ ;
$58 op pop, $50 op push,
+\ Shifts. work with either an imm or cl src.
+: op ( immop /reg regop ) doer c, c, c, does> ( imm? a -- )
+ prefix,
+ isimm? if
+ src $800 or to src \ force imm to 8bit
+ dup 1+ c@ ( reg ) swap 2 + c@ ( reg immop ) modrm<imm,
+ else
+ src CX not = if _err then
+ dup 1+ c@ swap c@ ( reg regop ) modrm1,
+ then ;
+$c1 4 $d3 op shl, $c1 5 $d3 op shr,
+
+
\ Special
: mov,
prefix, isimm? if
@@ -121,6 +137,3 @@ $58 op pop, $50 op push,
$b8 tgtid or c, , asm$ else \ imm->modrm move
0 $c7 modrm<imm, then
else src $89 modrm2, then ;
-
-: shln, ( n -- ) \ SHL n times
- 4 $c1 modrm1, c, ;
diff --git a/fs/tests/asm.fs b/fs/tests/asm.fs
@@ -28,4 +28,15 @@ code foo3
foo3 42 #eq 42 #eq
+\ test shr/shl
+code foo4
+ eax 42 i32 mov,
+ eax 3 i32 shl,
+ cl 2 i32 mov,
+ eax cl shr,
+ ebp 4 i32 sub,
+ [ebp] eax mov,
+ ret,
+
+foo4 84 #eq
testend