diff options
Diffstat (limited to 'chapter23/src/test/java/com/seaofnodes')
10 files changed, 238 insertions, 9 deletions
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java index 394ba336..13322d3d 100644 --- a/chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java +++ b/chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java @@ -180,7 +180,7 @@ return cc.cz; @Test public void testHelloWorld() throws IOException { String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/helloWorld.smp")); - TestC.run(src,TestC.CALL_CONVENTION,null,null,"build/objs/helloWorld","","Hello, World!",0); + TestC.run(src,TestC.CALL_CONVENTION,null, null,null,"build/objs/helloWorld","","Hello, World!",0); // Evaluate on RISC5 emulator EvalRisc5 R5 = TestRisc5.build("helloWorld", 0, 2, false); @@ -221,7 +221,7 @@ return sum(is); @Test @Ignore public void testEcho() throws IOException { String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/echo.smp")); - TestC.run(src,TestC.CALL_CONVENTION,null,null,"build/objs/echo","","",0); + TestC.run(src,TestC.CALL_CONVENTION,null, null,null,"build/objs/echo","","",0); // Evaluate on RISC5 emulator EvalRisc5 R5 = TestRisc5.build("echo", 0, 2, false); diff --git a/chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java b/chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java index 20a506fb..12e089fc 100644 --- a/chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java +++ b/chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java @@ -1,6 +1,7 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.CodeGen; +import com.seaofnodes.simple.node.cpus.riscv.riscv; import com.seaofnodes.simple.type.TypeInteger; import java.io.IOException; import java.nio.file.Files; @@ -32,6 +33,130 @@ public class Chapter23Test { } @Test + public void testOr() throws IOException { + TestC.runS("or1","Or",0); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("or1", 0, 2, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(0,R5.regs[riscv.A0]); + assertEquals("Or",R5._stdout.toString()); + + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("or1", 0, 2, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(0,arm.regs[0]); + assertEquals("Or",arm._stdout.toString()); + } + + @Test + public void testAnd() throws IOException { + TestC.runS("and1","And",0); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("and1", 0, 2, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(0,R5.regs[riscv.A0]); + assertEquals("And",R5._stdout.toString()); + + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("and1", 0, 2, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(0,arm.regs[0]); + assertEquals("And",arm._stdout.toString()); + } + + @Test + public void testAndPtr() throws IOException { + String src = +""" +struct S { S? fld; }; +val ptr = arg == 1 ? null : new S{fld = arg==1 ? null : new S{fld = null;};}; +return ptr && ptr.fld ? "true" : "false"; + """; + CodeGen code = new CodeGen(src).parse().opto().typeCheck(); + assertEquals("[97-117][ 116,114,117,101]", Eval2.eval(code, 0)); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("ptrand", 1, 8, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(0,R5.regs[riscv.A0]); + assertEquals("false",R5._stdout.toString()); + + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("ptrand", 1, 8, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(0,arm.regs[0]); + assertEquals("false",arm._stdout.toString()); + } + + // conditional side effect + @Test + public void testCondSideEffAnd() throws IOException { + TestC.runS("and2","Effected",0); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("and2", 0, 2, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(0,R5.regs[riscv.A0]); + assertEquals("Effected",R5._stdout.toString()); + + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("and2", 0, 2, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(0,arm.regs[0]); + assertEquals("Effected",arm._stdout.toString()); + } + + + @Test + public void testCondSideEffOr() throws IOException { + TestC.runS("or2","Effected",0); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("or2", 0, 2, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(0,R5.regs[riscv.A0]); + assertEquals("Effected",R5._stdout.toString()); + + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("or2", 0, 2, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(0,arm.regs[0]); + assertEquals("Effected",arm._stdout.toString()); + } + + // test it with function calls + @Test + public void testFuncCall() throws IOException { + TestC.runS("and3","Or",0); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("and3", 0, 2, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(0,R5.regs[riscv.A0]); + assertEquals("Or",R5._stdout.toString()); + + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("and3", 0, 2, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(0,arm.regs[0]); + assertEquals("Or",arm._stdout.toString()); + } + + @Test public void testFRefFields() { String src = """ diff --git a/chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java b/chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java index ec97eab0..c719b8e8 100644 --- a/chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java +++ b/chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java @@ -573,11 +573,16 @@ public class EvalArm64 { break; } case 0xD6: { + if( (ir & 0xFFFF) != 0 ) throw Utils.TODO(); + if( ((ir>>16) & 0xFF) != 0x5F ) throw Utils.TODO(); // 0x3F is register call rdid = -1; + int rn = ir << 22 >> 27; + assert rn == 0; + pc = (int)regs[30]; // Return to zero breaks simulation - if(regs[30] == 0) - break outer; - throw Utils.TODO(); + if( pc==0 ) break outer; + pc -= 4; // Undo post-increment + break; } case 0xF1: { diff --git a/chapter23/src/test/java/com/seaofnodes/simple/TestC.java b/chapter23/src/test/java/com/seaofnodes/simple/TestC.java index 9df3dc68..dbe9f02f 100644 --- a/chapter23/src/test/java/com/seaofnodes/simple/TestC.java +++ b/chapter23/src/test/java/com/seaofnodes/simple/TestC.java @@ -1,6 +1,7 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.CodeGen; +import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.util.Ary; import com.seaofnodes.simple.util.Utils; import java.io.IOException; @@ -29,7 +30,7 @@ public abstract class TestC { } // Compile and run a simple program - public static void run( String dir, String file, String expected, int spills ) throws IOException { + public static void run( String dir, String file, TypeInteger arg, String expected, int spills, boolean standalone) throws IOException { // Files String cfile = dir+"/"+file+".c" ; String sfile = dir+"/"+file+".smp"; @@ -37,15 +38,28 @@ public abstract class TestC { // Compile and export Simple String src = Files.readString(Path.of(sfile)); - run(src,CALL_CONVENTION,"",cfile,efile,"S",expected,spills); + run(src,CALL_CONVENTION,arg, "",standalone? null: cfile,efile,"S",expected,spills); + } + public static void run(String dir, String file, String expected, int spills ) throws IOException { + run(dir, file,null, expected, spills, false); + } + + public static void runS(String file, String expected, int spills ) throws IOException { + run("src/test/java/com/seaofnodes/simple/progs", file, null, expected, spills, true); } - public static void run( String src, String simple_conv, String c_conv, String cfile, String efile, String xtn, String expected, int spills ) throws IOException { + public static void runS(String file, TypeInteger arg, String expected, int spills ) throws IOException { + run("src/test/java/com/seaofnodes/simple/progs", file, arg, expected, spills, true); + } + + + public static void run( String src, String simple_conv, TypeInteger arg, String c_conv, String cfile, String efile, String xtn, String expected, int spills ) throws IOException { String bin = efile+xtn; String obj = bin+".o"; String exe = OS.startsWith("Windows") ? bin+".exe" : bin; // Compile simple, emit ELF - CodeGen code = new CodeGen(src).driver( CPU_PORT, simple_conv, obj); + CodeGen code = new CodeGen(src, arg).driver( CPU_PORT, simple_conv, obj); + String result = gcc(obj, c_conv, cfile, false, exe ); assertEquals(expected,result); diff --git a/chapter23/src/test/java/com/seaofnodes/simple/progs/and1.smp b/chapter23/src/test/java/com/seaofnodes/simple/progs/and1.smp new file mode 100644 index 00000000..ef4c904f --- /dev/null +++ b/chapter23/src/test/java/com/seaofnodes/simple/progs/and1.smp @@ -0,0 +1,10 @@ +// -*- mode: java; -*- +int a = 1; +int b = 1; + +if(a && b) { + sys.io.p("And"); +} else { + sys.io.p("Or"); +} +return 0; diff --git a/chapter23/src/test/java/com/seaofnodes/simple/progs/and2.smp b/chapter23/src/test/java/com/seaofnodes/simple/progs/and2.smp new file mode 100644 index 00000000..2a463c94 --- /dev/null +++ b/chapter23/src/test/java/com/seaofnodes/simple/progs/and2.smp @@ -0,0 +1,16 @@ +// -*- mode: java; -*- +int a = 1; +int b = 1; + +int x=1; +int y=1; +int z=0; + +int g = x++ && y++ && z++; + +if(x == 2 && y == 2 && z == 1 && g == 0) { + sys.io.p("Effected"); +} else { + sys.io.p("Not effected"); +} +return 0; diff --git a/chapter23/src/test/java/com/seaofnodes/simple/progs/and3.smp b/chapter23/src/test/java/com/seaofnodes/simple/progs/and3.smp new file mode 100644 index 00000000..aadbdfed --- /dev/null +++ b/chapter23/src/test/java/com/seaofnodes/simple/progs/and3.smp @@ -0,0 +1,14 @@ +// -*- mode: java; -*- +int a = 1; +int b = 1; + +var sq = { int x -> + x*x; +}; + +if(a && sq(0)) { + sys.io.p("And"); +} else { + sys.io.p("Or"); +} +return 0; diff --git a/chapter23/src/test/java/com/seaofnodes/simple/progs/or1.smp b/chapter23/src/test/java/com/seaofnodes/simple/progs/or1.smp new file mode 100644 index 00000000..f5f526c3 --- /dev/null +++ b/chapter23/src/test/java/com/seaofnodes/simple/progs/or1.smp @@ -0,0 +1,12 @@ +// -*- mode: java; -*- +int a = 1; +int b = 0; + +if(a++ || b++ ) { + if(b == 0 && a == 2) { + sys.io.p("Or"); + } +} else{ + sys.io.p("And"); +} +return 0; diff --git a/chapter23/src/test/java/com/seaofnodes/simple/progs/or2.smp b/chapter23/src/test/java/com/seaofnodes/simple/progs/or2.smp new file mode 100644 index 00000000..ac688b5a --- /dev/null +++ b/chapter23/src/test/java/com/seaofnodes/simple/progs/or2.smp @@ -0,0 +1,23 @@ +// -*- mode: java; -*- +int a = 1; +int b = 1; + +int x = -1; +int y=1; +int z= -1; + +int g = x++ || y++ || z++; + +int switch = 0; +if(x == 4 || y == 4 || z == 4) { + switch = -1; +} else { + switch = 1; +} +int cd = 1; +if((x == 0 && y == 1 && z==-1) && switch && g) { + sys.io.p("Effected"); +} else { + sys.io.p("Not effected"); +} +return 0; diff --git a/chapter23/src/test/java/com/seaofnodes/simple/progs/ptrand.smp b/chapter23/src/test/java/com/seaofnodes/simple/progs/ptrand.smp new file mode 100644 index 00000000..9d7bce88 --- /dev/null +++ b/chapter23/src/test/java/com/seaofnodes/simple/progs/ptrand.smp @@ -0,0 +1,10 @@ +struct S { S? fld; }; + +val ptr = arg == 1 ? null : new S{fld = arg==1 ? null : new S{fld = null;};}; +if( ptr && ptr.fld ) { + sys.io.p("true"); +} else { + sys.io.p("false"); +} + +return 0; |
