duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit f864277bceaddc0154fcd09902cf8d7034242e18
parent 30eb221dc5d83a0d0c2cd806169c1345c157d17c
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sat, 17 Sep 2022 07:55:01 -0400

cc/vm/forth: remove usage of selop1/selop2

I'm trying to disentangle the ops selection system, with the help of my new
"vmop^" structbind and the structification of words related to ops.

The idea is that the VM part will never change op selection and will never care
whether currently selected op is op1 or op2. The only contract with the user is
that the "destination" op needs to be selected before calling the op.

Diffstat:
Mfs/cc/gen.fs | 2+-
Mfs/cc/vm/commonlo.fs | 3++-
Mfs/cc/vm/forth.fs | 34+++++++++++++++-------------------
Mfs/tests/cc/vm.fs | 14+++++++-------
4 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs @@ -250,7 +250,7 @@ ASTIDCNT wordtbl gentbl ( node -- ) selop2 gennode op1<>op2 then else \ nothing special needed, regular resolution selop1 gennode selop2 gennode then - bopgentblpost r> Op opid wexec + selop1 bopgentblpost r> Op opid wexec r> ( selectedop ) if op1<>op2 else selop1 then ; \ TODO: this doesn't work with lvalues yet :w ( List ) diff --git a/fs/cc/vm/commonlo.fs b/fs/cc/vm/commonlo.fs @@ -40,6 +40,7 @@ struct[ VMOp \ Is op a pointer? : :pointer? loc $10 and bool ; : :noop# loc VM_NONE = _assert ; + : :hasop# loc VM_NONE <> _assert ; : :keep ( self -- arg loc ) dup arg swap loc ; : :push ( self -- arg loc ) dup >r :keep VM_NONE to r> loc ; : :pop ( arg loc self -- ) dup >r :noop# r@ to loc r> to arg ; @@ -62,7 +63,7 @@ vmop :self to vmop^ other \ Managing operands -: hasop# vmop loc VM_NONE = not _assert ; +: hasop# vmop :hasop# ; : isconst? vmop loc VM_CONSTANT = ; : isconst# isconst? _assert ; : noop# vmop :noop# ; diff --git a/fs/cc/vm/forth.fs b/fs/cc/vm/forth.fs @@ -96,8 +96,8 @@ struct+[ VMOp \ result there. : vmret, argsz >r \ V1=argsz - selop2 noop# \ returning with a second operand? something's wrong - selop1 vmop loc if + vmop^ :noop# \ returning with a second operand? something's wrong + vmop loc if vmop :compile PS- vmop :forgetTOS argsz ?dup if p', compile ! -4 to+ V1 then then r> ( argsz ) ?dup if p+, then @@ -151,17 +151,13 @@ unop vm--op, 1- postop vmop++, 1+ postop vmop--, 1- -\ Just after having compiled an op, if the "other op" is TOS, we need to compile -\ a "swap" to "unbury" it. We do it here. -: swapifTOS vmop :TOS? if compile swap then ; - \ 2 fields: signed op, unsigned op : binop doer ' , ' , does> ( 'w ) - selop1 vmop type typeunsigned? if CELLSZ + then @ ( w ) + vmop type typeunsigned? if CELLSZ + then @ ( w ) vmop :compile \ op1 is TOS - selop2 hasop# swapifTOS - vmop :compile vmop :forgetTOS - ( w ) execute, PS- selop1 ; \ result in op1 as VM_TOS + vmop^ :hasop# vmop^ :TOS? if compile swap then + vmop^ :compile vmop^ :forgetTOS + ( w ) execute, PS- ; \ result in op1 as VM_TOS binop vmadd, + + binop vmsub, - - @@ -180,11 +176,11 @@ binop vm||, or and \ a binop= is like a unop in the sense that it operates directly on op1, but \ with the participation of op2. : binop= doer ' , does> @ ( w ) - >r selop1 vmop :keep r> ( ... w ) + >r vmop :keep r> ( ... w ) vmop :compile \ op1 is TOS - selop2 hasop# vmop :compile \ op2 is TOS + vmop^ :hasop# vmop^ :compile \ op2 is TOS ( w ) execute, PS- \ result on TOS - selop1 vmop :forgetTOS + vmop :forgetTOS vmop :pop &op>op vmop :compile vmop :forgetTOS vmop^ :forgetTOS compile ! PS- PS- ; @@ -195,15 +191,15 @@ binop= vm>>=, rshift \ op2. In other words, perform a AST_ASSIGN with the right part as op2 \ and the left part as op1. : _movarray, \ special case, we have a {1, 2, 3} assign - selop1 vmop loc VM_STACKFRAME = _assert vmop :compile \ dst on PS - vmop :forgetTOS selop2 vmop arg @+ ( a len ) >r begin ( a ) + vmop loc VM_STACKFRAME = _assert vmop :compile \ dst on PS + vmop :forgetTOS vmop^ arg @+ ( a len ) >r begin ( a ) @+ litn compile swap compile !+ next compile drop PS- ( a ) drop - vmop :init ; + vmop^ :init ; : vmmov, - selop2 hasop# vmop loc VM_CONSTARRAY = if _movarray, else - vmop :compile \ op2 is TOS - selop1 swapifTOS &op>op vmop :compile + vmop^ :hasop# vmop^ loc VM_CONSTARRAY = if _movarray, else + vmop^ :compile \ op2 is TOS + vmop :TOS? if compile swap then &op>op vmop :compile vmop :forgetTOS vmop^ :forgetTOS compile ! PS- PS- then ; \ Jumping diff --git a/fs/tests/cc/vm.fs b/fs/tests/cc/vm.fs @@ -8,9 +8,9 @@ code test1 0 0 vmprelude, selop1 2 const>op selop2 3 const>op - vmmul, + selop1 vmmul, selop2 1 const>op - vmadd, + selop1 vmadd, vmret, test1 7 #eq @@ -20,11 +20,11 @@ code test2 0 0 vmprelude, selop1 3 const>op selop2 1 const>op - vmsub, + selop1 vmsub, selop1 vmop :push selop1 2 const>op selop2 3 const>op - vmmul, + selop1 vmmul, selop2 vmop :pop vmadd, vmret, @@ -36,7 +36,7 @@ code test3 8 0 vmprelude, selop1 4 ps+>op selop2 0 ps+>op - vmsub, + selop1 vmsub, vmret, 54 12 test3 42 #eq @@ -57,7 +57,7 @@ code test4 \ return foo + bar selop1 4 sf+>op selop2 0 sf+>op - vmadd, + selop1 vmadd, vmret, test4 47 #eq @@ -157,7 +157,7 @@ code test10 \ returns 42 if arg >= 10, 54 otherwise 4 0 vmprelude, selop1 0 ps+>op selop2 10 const>op - vm<, + selop1 vm<, vmjnz[, selop1 42 const>op vmret,