summaryrefslogtreecommitdiff
path: root/chapter19
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-28 13:39:05 -0700
committerCliff Click <cliffc@acm.org>2026-10-28 13:39:05 -0700
commit86ce5bc5d5018dcb62054d214b23f7a59b9c0d7d (patch)
tree7b564b142c32924db354edfd8553d34cb66fff3e /chapter19
parente481e3d215882faa82b19f29cfde5746d4e51863 (diff)
downloadSimple-86ce5bc5d5018dcb62054d214b23f7a59b9c0d7d.tar.gz
Simple-86ce5bc5d5018dcb62054d214b23f7a59b9c0d7d.zip
Fix bugs x86 storing only 32bits of a large constant
Missed field narrowing in a few cases
Diffstat (limited to 'chapter19')
-rw-r--r--chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java2
-rw-r--r--chapter19/src/test/java/com/seaofnodes/simple/X86StoreTest.java34
2 files changed, 35 insertions, 1 deletions
diff --git a/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
index e7e0b874..1b14bcf1 100644
--- a/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
+++ b/chapter19/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
@@ -430,7 +430,7 @@ public class x86_64_v2 extends Machine {
}
private int imm( Node xval ) {
assert val==null && imm==0;
- if( xval instanceof ConstantNode con && con._con instanceof TypeInteger ti ) {
+ if( xval instanceof ConstantNode con && con._con instanceof TypeInteger ti && ti.isConstant() && (int)ti.value()==ti.value() ) {
val = null;
imm = (int)ti.value();
assert imm == ti.value(); // In 32-bit range
diff --git a/chapter19/src/test/java/com/seaofnodes/simple/X86StoreTest.java b/chapter19/src/test/java/com/seaofnodes/simple/X86StoreTest.java
new file mode 100644
index 00000000..c32a69c3
--- /dev/null
+++ b/chapter19/src/test/java/com/seaofnodes/simple/X86StoreTest.java
@@ -0,0 +1,34 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.node.cpus.x86_64_v2.StoreX86;
+import com.seaofnodes.simple.type.TypeInteger;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class X86StoreTest {
+ @Test public void testConstantStores() {
+ check("u8",255,false);
+ check("u16",65535,false);
+ check("u32",Integer.MAX_VALUE,false);
+ check("u32",2147483648L,true);
+ check("u32",4294967295L,true);
+ check("int",Integer.MIN_VALUE,false);
+ check("int",Integer.MAX_VALUE,false);
+ for( long value : new long[]{2147483648L,4294967295L,-2147483649L,
+ 0x123456789abcdefL,Long.MIN_VALUE,Long.MAX_VALUE} )
+ check("int",value,true);
+ }
+
+ private static void check(String type, long value, boolean register) {
+ // Returning the object keeps the Store; returning its field could fold.
+ String literal = value==Long.MIN_VALUE ? "(-9223372036854775807-1)" : Long.toString(value);
+ String src = "struct S { "+type+" x="+literal+"; }; return new S;";
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.InstructionSelection,"x86_64_v2","SystemV");
+ StoreX86 store = code._stop.walk(n -> n instanceof StoreX86 st && st._name.equals("x") ? st : null);
+ assertNotNull(src,store);
+ if( register ) {
+ assertNotNull(src,store.in(4));
+ assertEquals(src,value,((TypeInteger)store.in(4)._type).value());
+ } else assertNull(src,store.in(4));
+ }
+}