commit c515797be0ac1bb903ddb86214d3985d5bbdeac7
parent 42f38fc09b312c97c826d7706efceb4fae41263a
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Tue, 6 Dec 2022 21:26:46 -0500
comp/c/vm/i386: fix integer promotion bug in logical ops
Diffstat:
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/fs/comp/c/vm/i386.fs b/fs/comp/c/vm/i386.fs
@@ -292,7 +292,8 @@ LOGOPCNT wordtbl _tblunsigned
:w _ setz, ; :w _ setnz, ; 'w _&& 'w _||
: logop, ( opid -- )
- vmop type typeunsigned? if _tblunsigned else _tblsigned then swap wexec ;
+ harmonizeops vmop type typeunsigned?
+ if _tblunsigned else _tblsigned then swap wexec ;
: vm?:, ( condop -- )
vmop :>res \ true op in reg
diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs
@@ -105,6 +105,7 @@ opwidth4 14 #eq
opwidth5 42 #eq
opwidth6 1 #eq
$ff 1 opwidth7 $1fe #eq
+opwidth8 0 #eq
42 50 ptrari3 46 #eq
41 value myval
to' myval ptrari4 not #
diff --git a/fs/tests/comp/c/test.c b/fs/tests/comp/c/test.c
@@ -469,6 +469,14 @@ short opwidth6() {
int opwidth7(char a, int b) {
return a << b;
}
+// Under i386, integer promotion of a non-reg operand would result in a buggy
+// operation because we would read too much information from memory.
+int opwidth8() {
+ int x = 54;
+ globdata.baz[0] = 42;
+ globdata.baz[1] = 1;
+ return x < globdata.baz[0];
+}
// when subtracting 2 pointers, the result is considered a scalar for the
// remainder of the expression.
int* ptrari3(int *lo, int *hi) {