duskos

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

commit 8f6bdeded1bb580d98408d823d39da293f4fdd31
parent 30d0c77ad9412022cdee7bca84978eeb4eeab47f
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Thu, 13 Oct 2022 20:45:24 -0400

cc/vm/i386: fix opwidth bug

Diffstat:
Mfs/cc/vm/i386.fs | 15++++++++++++---
Mfs/tests/cc/cc.fs | 1+
Mfs/tests/cc/test.c | 6++++++
3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/fs/cc/vm/i386.fs b/fs/cc/vm/i386.fs @@ -80,7 +80,10 @@ struct+[ VMOp VM_*STACKFRAME of = V1 :>reg endof VM_*ARGSFRAME of = V1 :>reg endof VM_*REGISTER of = - V1 arg r! V1 arg r! 0 d) movclr, VM_REGISTER V1 to loc endof + V1 type typesize 4 < if + V1 :typesz! dx V1 arg r! 0 d) movclr, V1 arg r! dx mov, else + V1 arg r! V1 arg r! 0 d) mov, then + VM_REGISTER V1 to loc endof endcase rdrop ; \ Before doing an operation on two operands, we verify that they are @@ -104,6 +107,12 @@ struct+[ VMOp \ Verify that we're in "neutral" position with regards to registers : neutral# reglvl if abort" unbalanced reg allot/free" then ; +\ If one op is larger than the other, copy the smaller one to a register and +\ copy the type of the larger op to the smaller. +: harmonizeops vmop type typesize vmop^ type typesize 2dup < if + 2drop vmop :>reg vmop^ type to vmop type else > if + vmop^ :>reg vmop type to vmop^ type then then ; + \ Code generation - Functions, calls, ret, pspush, pspop \ generate function prelude code by allocating "locsz" bytes on RS. @@ -148,7 +157,7 @@ struct+[ VMOp \ Code generation - Binary ops : binop doer ' , does> ( 'w ) @ - vmop :>res vmop :compileDest vmop^ :compile execute vmop^ :init ; + vmop :>res harmonizeops vmop :compile vmop^ :compile execute vmop^ :init ; binop vm+, add, binop vm-, sub, binop vm&, and, @@ -218,7 +227,7 @@ unaryop vmnot, not, ( ~ ) : vm+n, ( n -- ) vmop :loclo VM_CONSTANT = if to+ vmop arg - else vmop :compileDest i) add, then ; + else vmop :>res vmop :compile i) add, then ; \ post-inc/dec op1 \ It's a bit complicated here. Before we inc/dec, we need a copy of the current diff --git a/fs/tests/cc/cc.fs b/fs/tests/cc/cc.fs @@ -70,6 +70,7 @@ globdata 4 + 16b @ 42 #eq '2' binop2 44 #eq binop3 $605 #eq binop5 1 #eq +binop6 $1fe #eq structop1 44 #eq structop2 45 #eq opwidth1 42 #eq diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c @@ -291,6 +291,12 @@ int binop5() { int x = 2; return x && 1; } +// the i386 VM performed this add in 8b mode, not carrying the $100. +unsigned int binop6() { + unsigned int x = $ff; + unsigned char y = $ff; + return x + y; +} short structop1() { globdata.bar += 2; return globdata.bar;