summaryrefslogtreecommitdiff
path: root/chapter23/src/test/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'chapter23/src/test/java/com')
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java4
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java125
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java11
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/TestC.java22
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/progs/and1.smp10
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/progs/and2.smp16
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/progs/and3.smp14
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/progs/or1.smp12
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/progs/or2.smp23
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/progs/ptrand.smp10
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;