diff options
Diffstat (limited to 'chapter25/src/test/java/com')
6 files changed, 71 insertions, 4 deletions
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java index a71cc167..f1ff2e14 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java @@ -124,8 +124,8 @@ struct N { !N? !next; int i; }; n.i = 3.14; return n.i; """); - try { code.parse().opto().typeCheck(); fail(); } - catch( Exception e ) { assertEquals("Type 3.14 is not of declared type i64",e.getMessage()); } + code.parse().opto().typeCheck(); + assertEquals("3",Eval2.eval(code,0)); } @Test diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java index 20274581..80f70ff8 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java @@ -5,6 +5,25 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; public class Chapter14FloatTest { + @Test public void testNumericAssignments() { + String[][] tests = { + {"int rounded=17.3/2.5; return rounded;", "6", "6"}, + {"int rounded=arg/2.5; return rounded;", "6", "-6"}, + {"int rounded=0; rounded=arg/2.5; return rounded;", "6", "-6"}, + {"i8 rounded=arg*16.0; return rounded;", "16", "-16"}, + {"int rounded=1e100; return rounded;", "9223372036854775807", "9223372036854775807"}, + {"int rounded=-1e100; return rounded;", "-9223372036854775808", "-9223372036854775808"}, + {"int rounded=1e300*1e300-1e300*1e300; return rounded;", "0", "0"}, + {"f32 rounded=arg+16777216.0; return rounded;", "1.6777232E7", "1.6777199E7"} + }; + for( String[] test : tests ) { + var code = new CodeGen(test[0]).parse().opto().typeCheck(); + assertEquals(test[0],test[1],Eval2.eval(code,17)); + assertEquals(test[0],test[2],Eval2.eval(code,-17)); + } + } + + @Test public void testSubZeroFloat() { var code = new CodeGen("flt x = arg; return 0-x;").parse().opto().typeCheck(); // Compare strings so +0.0 and -0.0 remain distinct. diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java index ab1a59e1..62d0b261 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java @@ -123,8 +123,8 @@ return s.x; @Test public void testInt10() { CodeGen code = new CodeGen("flt x = 1.5; x++; int i = x; return i;"); - try { code.parse().opto().typeCheck(); fail(); } - catch( Exception e ) { assertEquals("Type 2.5f is not of declared type i64",e.getMessage()); } + code.parse().opto().typeCheck(); + assertEquals("2",Eval2.eval(code,0)); } diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java index 4d610a42..ba71d1dd 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java @@ -15,6 +15,27 @@ import static org.junit.Assert.*; public class Chapter21Test { + @Test public void testFloatToInteger() throws IOException { + String src = "val float_to_int={ flt x -> int i=x; return i; };"+ + "val float_to_u8={ flt x -> u8 i=x; return i; };"; + TestC.runC(src,"floatToInteger","",-1); + for( double x : new double[]{0.0,-0.0,6.92,-6.92,255.75,-257.75, + 0x1p63,Math.nextDown(0x1p63),-0x1p63,Math.nextDown(-0x1p63), + Double.POSITIVE_INFINITY,Double.NEGATIVE_INFINITY,Double.NaN} ) { + for( String name : new String[]{"float_to_int","float_to_u8"} ) { + long expected = name.equals("float_to_u8") ? ((long)x)&255 : (long)x; + EvalRisc5 r = TestRisc5.build(src,name,0,-1,false); + r.fregs[riscv.FA0-riscv.F_OFFSET]=x; + assertEquals(0,r.step(1000)); + assertEquals(name+"("+x+")",expected,r.regs[riscv.A0]); + EvalArm64 a = TestArm64.build(name,src,0,-1,false); + a.fregs[arm.D0-arm.D_OFFSET]=x; + assertEquals(0,a.step(1000)); + assertEquals(name+"("+x+")",expected,a.regs[arm.X0]); + } + } + } + @Test public void testReadBeforeConditionalStore() { var code = new CodeGen(""" struct S { int x; }; !S !a=new S; !S !b=new S; diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java index 5716c1b8..21e677ce 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java @@ -307,6 +307,8 @@ public abstract class Eval2 { case SubNode sub -> sub.mode()==1 ? (Object)(x(sub.in(1)) - x(sub.in(2))) : (Object)(d(sub.in(1)) - d(sub.in(2))); + case RoundF32Node rnd -> (double)(float)d(rnd.in(1)); + case ToIntegerNode cvt -> (long)d(cvt.in(1)); case ToFloatNode toflt-> (double)x(toflt.in(1)); case XorNode xor -> x(xor.in(1)) ^ x(xor.in(2)); default -> throw Utils.TODO(); diff --git a/chapter25/src/test/java/com/seaofnodes/simple/progs/floatToInteger.c b/chapter25/src/test/java/com/seaofnodes/simple/progs/floatToInteger.c new file mode 100644 index 00000000..cf9390d8 --- /dev/null +++ b/chapter25/src/test/java/com/seaofnodes/simple/progs/floatToInteger.c @@ -0,0 +1,25 @@ +#include <stdint.h> +#include <math.h> +#include <stdio.h> + +extern int64_t float_to_int(double); +extern int64_t float_to_u8(double); + +int main(void) { + double values[] = {0.0,-0.0,6.92,-6.92,0.99,-0.99,255.75,-257.75, + 0x1p63,0x1.fffffffffffffp62,-0x1p63,-0x1.0000000000001p63, + INFINITY,-INFINITY,NAN,-NAN}; + for( unsigned i=0; i<sizeof(values)/sizeof(values[0]); i++ ) { + double x=values[i]; + int64_t expected=isnan(x) ? 0 : x>=0x1p63 ? INT64_MAX + : x<=-0x1p63 ? INT64_MIN : (int64_t)x; + int64_t actual=float_to_int(x), narrow=float_to_u8(x); + if( actual!=expected || narrow!=(expected&255) ) { + fprintf(stderr,"conversion of %g: got %lld / %lld, expected %lld / %lld\n", + x,(long long)actual,(long long)narrow, + (long long)expected,(long long)(expected&255)); + return 1; + } + } + return 0; +} |
