summaryrefslogtreecommitdiff
path: root/chapter28a
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-25 14:20:11 -0700
committerCliff Click <cliffc@acm.org>2026-10-25 14:20:11 -0700
commit2d80a348bad4b1e3165bd955ceaff3e18a96e516 (patch)
treefdb7044da1c7d30cf295c1709d11f6381aa48759 /chapter28a
parentf258c28fb4fc98e472be2e57a2504dc1a955f2eb (diff)
downloadSimple-2d80a348bad4b1e3165bd955ceaff3e18a96e516.tar.gz
Simple-2d80a348bad4b1e3165bd955ceaff3e18a96e516.zip
Retire Evalutator
Minor rounding bug in eval2
Diffstat (limited to 'chapter28a')
-rw-r--r--chapter28a/src/test/java/com/seaofnodes/simple/Chapter19Test.java36
-rw-r--r--chapter28a/src/test/java/com/seaofnodes/simple/Eval2.java8
2 files changed, 44 insertions, 0 deletions
diff --git a/chapter28a/src/test/java/com/seaofnodes/simple/Chapter19Test.java b/chapter28a/src/test/java/com/seaofnodes/simple/Chapter19Test.java
index 6f290279..d5fe207a 100644
--- a/chapter28a/src/test/java/com/seaofnodes/simple/Chapter19Test.java
+++ b/chapter28a/src/test/java/com/seaofnodes/simple/Chapter19Test.java
@@ -11,6 +11,42 @@ import org.junit.Test;
import static org.junit.Assert.*;
public class Chapter19Test {
+ @Test public void testNarrowStores() {
+ // Return the allocation so Load forwarding cannot hide a bad Store.
+ for( String type : new String[]{"u8","i8","u16","i16","u32","i32","int","f32","flt"} ) {
+ boolean flt = type.equals("f32") || type.equals("flt");
+ String init = flt ? "flt v=arg; " : "";
+ if( type.equals("f32") ) init+="f32 w=v; ";
+ String value = type.equals("f32") ? "w" : flt ? "v" : "arg";
+ for( boolean array : new boolean[]{false,true} ) {
+ String src = array
+ ? "var a=new "+type+"[1]; a[0]="+value+"; return a;"
+ : "struct S { "+type+" x; }; var s=new S; s.x="+value+"; return s;";
+ CodeGen code = new CodeGen(init+src).driver(CodeGen.Phase.TypeCheck);
+ long[] args = flt ? new long[]{0,1,-1,16777217,-16777217}
+ : new long[]{0,1,-1,0x180,0x18000,0x180000000L,Long.MIN_VALUE,Long.MAX_VALUE};
+ for( long arg : args ) {
+ Object expected = switch( type ) {
+ case "u8" -> arg & 0xffL;
+ case "i8" -> (long)(byte)arg;
+ case "u16" -> arg & 0xffffL;
+ case "i16" -> (long)(short)arg;
+ case "u32" -> arg & 0xffffffffL;
+ case "i32" -> (long)(int)arg;
+ case "f32" -> (double)(float)arg;
+ case "flt" -> (double)arg;
+ default -> arg;
+ };
+ String msg = type+" array="+array+" arg="+arg;
+ String printed = array
+ ? (type.equals("u8") ? ""+(char)(long)(Long)expected : (type.equals("int") ? "i64" : type)+"[ "+expected+"]")
+ : "Test.S{x="+expected+"}";
+ assertEquals(msg,printed,Eval2.eval(code,arg));
+ }
+ }
+ }
+ }
+
@Test public void testPrintingFunctionLookup() {
var code = new CodeGen("return 0;").parse();
var tfp = TypeFunPtr.make1((byte)2,false,new Type[]{TypeInteger.constant(987654)},TypeInteger.constant(123456),30);
diff --git a/chapter28a/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter28a/src/test/java/com/seaofnodes/simple/Eval2.java
index 366bd7f4..901a8990 100644
--- a/chapter28a/src/test/java/com/seaofnodes/simple/Eval2.java
+++ b/chapter28a/src/test/java/com/seaofnodes/simple/Eval2.java
@@ -460,6 +460,14 @@ public abstract class Eval2 {
? offToIdx(x(st.off()),tmp._obj)
: tmp._obj.find(st._name);
Object val = val(st.val());
+ // Idealization can remove conversions already performed by the store.
+ Type type = st.declaredType();
+ if( type instanceof TypeInteger ti ) {
+ int shift = 64-(8 << st.log_size());
+ long x = (Long)val << shift;
+ val = ti._min < 0 ? x >> shift : x >>> shift;
+ } else if( type instanceof TypeFloat && st.log_size()==2 )
+ val = (double)(float)(double)(Double)val;
fs[idx] = val;
return "$mem";
}