commit b8a3969d419cd88e2a3485f2c8259d54cb67bedb
parent d804e36f74d2f3dcb241151bc2e3c2d385fc41e8
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sun, 20 Nov 2022 19:05:22 -0500
cc/vm/i386: fix opwidth bug
In binary expressions with the "right hand" as a 16b or 8b pointer, the
"harmonizeops" routine wouldn't go far enough with the register dereferencing
and we would end up with an operation having the wrong width.
Diffstat:
4 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/fs/app/uxn/vm.c b/fs/app/uxn/vm.c
@@ -73,15 +73,11 @@ static void poke(unsigned short addr, unsigned short val) {
}
static unsigned short peek(unsigned short addr) {
- unsigned short val;
if (bs) {
- // TODO: "return (ram[addr] << 8) | ram[addr+1];" fails on i386
- val = ram[addr] << 8;
- val |= ram[addr+1];
+ return (ram[addr] << 8) | ram[addr+1];
} else {
- val = ram[addr];
+ return ram[addr];
}
- return val;
}
static void warp(unsigned short addr) {
diff --git a/fs/cc/vm/i386.fs b/fs/cc/vm/i386.fs
@@ -117,8 +117,8 @@ struct+[ VMOp
\ 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 ;
+ 2drop vmop :>res vmop^ type to vmop type else > if
+ vmop^ :>res vmop type to vmop^ type then then ;
\ Code generation - Functions, calls, ret, pspush, pspop
diff --git a/fs/tests/cc/cc.fs b/fs/tests/cc/cc.fs
@@ -74,6 +74,7 @@ binop5 1 #eq
binop6 $1fe #eq
binop7 0 #eq
binop8 $ffffffab #eq
+binop9 $1234 #eq
structop1 44 #eq
structop2 45 #eq
structop3 42 #eq
diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c
@@ -310,6 +310,11 @@ int binop7() {
int binop8() {
return bwnot() + neg();
}
+int binop9() {
+ char array[2] = {$12, $34};
+ return array[0]<<8|array[1];
+}
+
short structop1() {
globdata.bar += 2;
return globdata.bar;