diff options
Diffstat (limited to 'chapter24/src/test/java/com/seaofnodes')
8 files changed, 142 insertions, 28 deletions
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/BrainFuckTest.java b/chapter24/src/test/java/com/seaofnodes/simple/BrainFuckTest.java index c1467c07..de6c5a6b 100644 --- a/chapter24/src/test/java/com/seaofnodes/simple/BrainFuckTest.java +++ b/chapter24/src/test/java/com/seaofnodes/simple/BrainFuckTest.java @@ -1,8 +1,6 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.CodeGen; -import com.seaofnodes.simple.node.cpus.arm.arm; -import com.seaofnodes.simple.node.cpus.riscv.riscv; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -18,7 +16,7 @@ public class BrainFuckTest { """ // -*- mode: java; -*- val brain_fuck = { -> - u8[] !program = new u8[106];program[0] = 43;program[1] = 43;program[2] = 43;program[3] = 43;program[4] = 43;program[5] = 43;program[6] = 43;program[7] = 43;program[8] = 91;program[9] = 62;program[10] = 43;program[11] = 43;program[12] = 43;program[13] = 43;program[14] = 91;program[15] = 62;program[16] = 43;program[17] = 43;program[18] = 62;program[19] = 43;program[20] = 43;program[21] = 43;program[22] = 62;program[23] = 43;program[24] = 43;program[25] = 43;program[26] = 62;program[27] = 43;program[28] = 60;program[29] = 60;program[30] = 60;program[31] = 60;program[32] = 45;program[33] = 93;program[34] = 62;program[35] = 43;program[36] = 62;program[37] = 43;program[38] = 62;program[39] = 45;program[40] = 62;program[41] = 62;program[42] = 43;program[43] = 91;program[44] = 60;program[45] = 93;program[46] = 60;program[47] = 45;program[48] = 93;program[49] = 62;program[50] = 62;program[51] = 46;program[52] = 62;program[53] = 45;program[54] = 45;program[55] = 45;program[56] = 46;program[57] = 43;program[58] = 43;program[59] = 43;program[60] = 43;program[61] = 43;program[62] = 43;program[63] = 43;program[64] = 46;program[65] = 46;program[66] = 43;program[67] = 43;program[68] = 43;program[69] = 46;program[70] = 62;program[71] = 62;program[72] = 46;program[73] = 60;program[74] = 45;program[75] = 46;program[76] = 60;program[77] = 46;program[78] = 43;program[79] = 43;program[80] = 43;program[81] = 46;program[82] = 45;program[83] = 45;program[84] = 45;program[85] = 45;program[86] = 45;program[87] = 45;program[88] = 46;program[89] = 45;program[90] = 45;program[91] = 45;program[92] = 45;program[93] = 45;program[94] = 45;program[95] = 45;program[96] = 45;program[97] = 46;program[98] = 62;program[99] = 62;program[100] = 43;program[101] = 46;program[102] = 62;program[103] = 43;program[104] = 43;program[105] = 46; + var !program = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."; int d = 0; u8[] !output = new u8[0]; u8[] !data = new u8[100]; @@ -68,7 +66,7 @@ val brain_fuck = { -> EvalRisc5 R5 = TestRisc5.build("brain_fuck", src, 0, 28, false); int trap = R5.step(100000); assertEquals(0,trap); - int ptr = (int)R5.regs[riscv.A0]; + int ptr = (int)R5.regs[com.seaofnodes.simple.node.cpus.riscv.riscv.A0]; assertEquals(brain_fuck.length(),R5.ld4s(ptr)); for( int i=0; i<brain_fuck.length(); i++ ) assertEquals(brain_fuck.charAt(i), R5.ld1z(ptr+4+i)); @@ -77,7 +75,7 @@ val brain_fuck = { -> int trap_arm = A5.step(100000); assertEquals(0,trap_arm); assertEquals(0,trap); - int ptr_arm = (int)A5.regs[arm.X0]; + int ptr_arm = (int)A5.regs[com.seaofnodes.simple.node.cpus.arm.arm.X0]; assertEquals(brain_fuck.length(),A5.ld4s(ptr_arm)); for( int i=0; i<brain_fuck.length(); i++ ) diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter18Test.java index 42f80d86..00b6292e 100644 --- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter18Test.java +++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter18Test.java @@ -116,7 +116,7 @@ var fcn = arg ? { int x -> x*x; } : { int x -> x+x; }; return fcn(3); """); code.parse().opto(); - assertEquals("Stop[ return #2; return (Parm_x($fun21,i64,3)*x); return (Parm_x($fun22,i64,3)<<1); ]", code._stop.toString()); + assertEquals("Stop[ return #2; return 9; return 6; ]", code._stop.toString()); assertEquals("6", Eval2.eval(code, 0)); assertEquals("9", Eval2.eval(code, 1)); } @@ -126,7 +126,7 @@ return fcn(3); public void testFcn5() { CodeGen code = new CodeGen("val fact = { int x -> x <= 1 ? 1 : x*fact(x-1); }; return fact(arg);"); code.parse().opto().typeCheck(); - assertEquals("Stop[ return #2; return Phi(Region,1,(Parm_x(fact,i64,arg,(x-1))*#2)); ]", code._stop.toString()); + assertEquals("Stop[ return #2; return Phi(Region,1,(Parm_x(fact,i64)*#2)); ]", code._stop.toString()); assertEquals( "1", Eval2.eval(code, 0)); assertEquals( "1", Eval2.eval(code, 1)); assertEquals( "2", Eval2.eval(code, 2)); @@ -142,7 +142,7 @@ struct S { int i; }; val newS = { int x -> return new S { i=x; }; }; return newS(1).i; """); - code.parse().opto().typeCheck().GCM(); + code.parse().opto().typeCheck(); assertEquals("return 1;", code._stop.toString()); assertEquals("1", Eval2.eval(code, 0)); } @@ -157,8 +157,8 @@ val f = {->1;}; val g = {->2;}; return 2; """); - code.parse().opto().typeCheck().GCM(); - assertEquals("Stop[ return 1; return 1; return 2; ]", code._stop.toString()); + code.parse().opto().typeCheck(); + assertEquals("return 1;", code._stop.toString()); assertEquals("1", Eval2.eval(code, 0)); } @@ -292,7 +292,7 @@ for(;;) { val g = { -> g(); }; -return 0; +return g(); """); try { code.parse().opto().typeCheck(); fail(); } catch( Exception e ) { assertEquals("No defined return type",e.getMessage()); } diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter19Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter19Test.java index 19d0f501..6d751946 100644 --- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter19Test.java +++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter19Test.java @@ -391,7 +391,7 @@ val fcn = arg ? { int x -> x*x; } : { int x -> x+x; }; return fcn(2)*10 + fcn(3); """); code.driver(Phase.LocalSched,"x86_64_v2", "SystemV"); - assertEquals("Stop[ return (add,#2,(muli,#2)); return (mul,Parm_x($fun21,i64),x); return (shli,Parm_x($fun22,i64)); ]", code.print()); + assertEquals("Stop[ return (add,#2,(muli,#2)); return (mul,Parm_x($fun21,[2-3]),x); return (shli,Parm_x($fun22,[2-3])); ]", code.print()); } @Test diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java index b04ba24c..02de57a2 100644 --- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java +++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter20Test.java @@ -1,12 +1,7 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.CodeGen; -import com.seaofnodes.simple.print.ASMPrinter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.*; diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java index cf6290e4..1d67949a 100644 --- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java +++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java @@ -2,12 +2,7 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.node.cpus.riscv.riscv; - import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import com.seaofnodes.simple.type.TypeInteger; import org.junit.Test; import static org.junit.Assert.*; @@ -514,7 +509,66 @@ return 0 < arg < arg+1 < 4; assertEquals(1,arm.regs[0]); } + // shows that it is parsed as + // ((0 != x) != 2) + @Test + public void testStack12() throws IOException { + String stack11 = "1"; + String src = + """ + var stack12 = { int x -> + 0 != x != 2; + }; + """; + String src2 = + """ + return 0 != arg != 2; + """; + TestC.run(src, "stacked_r_12x", null, stack11,0); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("stacked_r_12", src2, 1, 0, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(1,R5.regs[riscv.A0]); + + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("stacked_r_12", src2, 1, 0, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(1,arm.regs[0]); + } + + + // shows that it is parsed as + // ((0 == x) == 1) + @Test + public void testStack13() throws IOException { + String stack12 = "1"; + String src = + """ + var stack13 = { int x -> + 0 == x == 1; + }; + """; + String src2 = + """ + return 0 == arg == 1; + """; + TestC.run(src, "stacked_r_13x", null, stack12,0); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("stacked_r_13", src2, 1, 0, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(1,R5.regs[riscv.A0]); + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("stacked_r_13", src2, 1, 0, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(1,arm.regs[0]); + } @Test public void testFRefFields() { @@ -599,5 +653,37 @@ return s.require('['); testCPU(src,"x86_64_v2", "Win64" ,16,null); }; + @Test + public void testSCCP0() { + String src = +""" +int x = 1; +int cnt = 5; +while (cnt) { + cnt -= 1; + if (x == 0) { + x += 1; + } +} +return x; +"""; + CodeGen code = new CodeGen(src).parse().opto().typeCheck(); + assertEquals("return 1;", code._stop.toString()); + } + + @Test + public void testSCCP1() { + String src = +""" +int x = 1; +int cnt = 5; +while( cnt-- ) + if( x == 1 ) + x = 2-x; +return x; +"""; + CodeGen code = new CodeGen(src).parse().opto().typeCheck(); + assertEquals("return 1;", code._stop.toString()); + } } diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter24/src/test/java/com/seaofnodes/simple/Eval2.java index 094b5143..5994e7e1 100644 --- a/chapter24/src/test/java/com/seaofnodes/simple/Eval2.java +++ b/chapter24/src/test/java/com/seaofnodes/simple/Eval2.java @@ -308,14 +308,23 @@ public abstract class Eval2 { case TypeMem mem -> "MEM"; case TypeMemPtr tmp -> { if( tmp._obj.isAry() ) { // Constant array ptr - TypeConAry con = (TypeConAry)tmp._obj.field("[]")._t; - Object[] xs = new Object[con.len()]; - for( int i=0; i<con.len(); i++ ) - xs[i] = con.at8(i); - yield xs; + Type elem = tmp._obj.field("[]")._t; + if( elem instanceof TypeConAry con ) { + Object[] xs = new Object[con.len()]; + for( int i=0; i<con.len(); i++ ) + xs[i] = con.at8(i); + yield xs; + } else { + // Generic constant array, used as a default input to a + // function; should never execute. + yield new Object[0]; + } } else { - throw Utils.TODO(); // Constant non-array ptr + // Generic TMP (since Simple is not currently making actual + // memory constants), used as a default input to a function; + // should never execute. + yield tmp.toString(); } } default -> null; diff --git a/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_12x.c b/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_12x.c new file mode 100644 index 00000000..a4e425cb --- /dev/null +++ b/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_12x.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <stdbool.h> +#include <stdlib.h> + +__attribute__ ((CALL_CONV)) +extern int stack12(int x); + +int main() { +int result = stack12(0); + +printf("%d", result); +return 0; +}
\ No newline at end of file diff --git a/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_13x.c b/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_13x.c new file mode 100644 index 00000000..a3a51d0e --- /dev/null +++ b/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_13x.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <stdbool.h> +#include <stdlib.h> + +__attribute__ ((CALL_CONV)) +extern int stack13(int x); + +int main() { +int result = stack13(0); + +printf("%d", result); +return 0; +}
\ No newline at end of file |
