commit 2409dc0ad0c0419f4560427bbe8c65c86a5fc6b7
parent c515797be0ac1bb903ddb86214d3985d5bbdeac7
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Wed, 7 Dec 2022 19:25:37 -0500
comp/c/vm/i386: fix register misallocation in vmswitch,
Diffstat:
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/fs/comp/c/vm/i386.fs b/fs/comp/c/vm/i386.fs
@@ -305,7 +305,8 @@ LOGOPCNT wordtbl _tblunsigned
vmop^ :noop#
\ Let's force vmop into AX. After that, none of the other regs are used, so
\ we're clear to use them in our lookup algo
- vmop :isAX? not if AX regused? not _assert ax vmop :compilesz movclr, then
+ vmop :isAX? if vmop :>simple
+ else AX regused? not _assert ax vmop :compilesz movclr, then
vmop :init
di ( 'lookup ) m) mov,
cx di 0 d) mov,
diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs
@@ -119,6 +119,7 @@ funcall1 138 #eq
42 funcall2 85 #eq
41 switch1 41 #eq
42 switch1 43 #eq
+switch2 42 #eq
\ and what about inline functions?
:c int myinline() { return 42; }
diff --git a/fs/tests/comp/c/test.c b/fs/tests/comp/c/test.c
@@ -518,3 +518,12 @@ int switch1(char *x) {
}
return x;
}
+// The i386 VM used to misallocate EAX because vmop was a VM_*REGISTER=EAX
+int switch2() {
+ char c = 'X';
+ char *p = &c;
+ switch (*p) {
+ case 'X': return 42;
+ }
+ return 0;
+}