commit 96ba8875683e89c5996b105a6b1eb3114fd64209
parent 59bf48d736101bdc6333b7f26d8844610a10f03e
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Fri, 7 Oct 2022 12:24:52 -0400
cc/vm/i386: code consolidation
Diffstat:
1 file changed, 24 insertions(+), 31 deletions(-)
diff --git a/fs/cc/vm/i386.fs b/fs/cc/vm/i386.fs
@@ -142,18 +142,16 @@ struct+[ VMOp
: vmpspush,
vmop :deref bp CELLSZ i) sub, bp 0 d) vmop :compile mov, vmop :init ;
-\ TODO: reduce code duplication in ops below with the help of proper does words
\ Code generation - Binary ops
-: binopprep ( -- ) \ prepare ops for the binop
- vmop :>res vmop :compile vmop^ :hasop# vmop^ :compile ;
-: vm+, binopprep add, vmop^ :init ;
-: vm-, binopprep sub, vmop^ :init ;
-: vm&, binopprep and, vmop^ :init ;
-: vm|, binopprep or, vmop^ :init ;
-: vm^, binopprep xor, vmop^ :init ;
-\ TODO: allow non-const shift right-operand
-: vm<<, binopprep vmop^ :isconst# shl, vmop^ :init ;
-: vm>>, binopprep vmop^ :isconst# shr, vmop^ :init ;
+: binop doer ' , does> ( 'w ) @
+ vmop :>res vmop :compile vmop^ :compile execute vmop^ :init ;
+binop vm+, add,
+binop vm-, sub,
+binop vm&, and,
+binop vm|, or,
+binop vm^, xor,
+binop vm<<, shl,
+binop vm>>, shr,
\ Copy the contents of vmop^ in the memory address pointed out by vmop and
\ deinit vmop^. In other words, perform a "=" binop with the right part as
@@ -169,15 +167,15 @@ struct+[ VMOp
maybederef vmop :compile vmop^ :compile mov, then
vmop^ :init ;
-: binop=prep ( -- ) \ prepare ops a binop of the "assign" loc
- maybederef vmop :compile vmop^ :hasop# vmop^ :compile ;
-: vm+=, binop=prep add, vmop^ :init ;
-: vm-=, binop=prep sub, vmop^ :init ;
-: vm&=, binop=prep and, vmop^ :init ;
-: vm|=, binop=prep or, vmop^ :init ;
-: vm^=, binop=prep xor, vmop^ :init ;
-: vm<<=, binop=prep vmop^ :isconst# shl, vmop^ :init ;
-: vm>>=, binop=prep vmop^ :isconst# shr, vmop^ :init ;
+: binop= doer ' , does> ( 'w ) @
+ maybederef vmop :compile vmop^ :hasop# vmop^ :compile execute vmop^ :init ;
+binop= vm+=, add,
+binop= vm-=, sub,
+binop= vm&=, and,
+binop= vm|=, or,
+binop= vm^=, xor,
+binop= vm<<=, shl,
+binop= vm>>=, shr,
\ mul and div are special and cannot use binopprep for two reasons: their target
\ operand is hardcoded to EAX, the other operand needs to be a register and EDX
@@ -202,17 +200,12 @@ struct+[ VMOp
\ Code generation - Unary ops
\ Unary operations are performed on the selected op, which can be either op1 or
\ op2.
-: unaryopprep vmop :>reg vmop :compile ;
-: vmneg, unaryopprep neg, ;
-: vmnot, ( ~ ) unaryopprep not, ;
-: vmboolify, unaryopprep
- vmop :compile test,
- vmop :compile 0 i) mov,
- vmop :compile setnz, ;
-: vmboolnot, unaryopprep
- vmop :compile test,
- vmop :compile 0 i) mov,
- vmop :compile setz, ;
+
+: unaryop doer ' , does> ( 'w ) @ vmop :>reg vmop :compile execute ;
+unaryop vmneg, neg,
+unaryop vmnot, not, ( ~ )
+: vmboolify, vmneg, vmop :compile 0 i) mov, vmop :compile setnz, ;
+: vmboolnot, vmneg, vmop :compile 0 i) mov, vmop :compile setz, ;
\ pre-inc/dec op1
: vm++op, vmop :compile inc, ;