summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java10
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter20Test.java6
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java32
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/TestC.java63
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/progs/newtonFloat.c17
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.c29
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.smp5
8 files changed, 140 insertions, 23 deletions
diff --git a/.gitignore b/.gitignore
index 45ae6585..0ccb7896 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ TAGS
# Libs
*/lib/*jar
+Unicorn/
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java
index a8850630..6425fb80 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java
@@ -26,8 +26,8 @@ return 0;
public void testString() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
CodeGen code = new CodeGen(src).parse().opto().typeCheck().GCM().localSched();
- assertEquals("Stop[ return (#2+#2); return Phi(Region,1,0,0,1); return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); ]", code._stop.toString());
- assertEquals("-4898613127354160978", Eval2.eval(code, 2));
+ assertEquals("Stop[ return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); return Phi(Region,1,0,0,1); ]", code._stop.toString());
+ //assertEquals("-4898613127354160978", Eval2.eval(code, 2));
}
@Test
@@ -151,9 +151,9 @@ return arg1 * arg;
@Test
public void testToFloat() {
CodeGen code = new CodeGen("""
- int a = arg;
- return a + 2.0;
- """
+int a = arg;
+return a + 2.0;
+"""
).parse().opto().typeCheck().instSelect("x86_64_v2", "SystemV").GCM().localSched();
assertEquals("return (addf,(cvtf,arg),2.0f);", code._stop.toString());
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter20Test.java
index 69179043..004e2af3 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter20Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter20Test.java
@@ -101,9 +101,9 @@ return sqrt(arg) + sqrt(arg+2);
@Test
public void testString() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
- testCPU(src,"x86_64_v2", "SystemV", 9,null);
- testCPU(src,"riscv" , "SystemV",20,null);
- testCPU(src,"arm" , "SystemV",16,null);
+ testCPU(src,"x86_64_v2", "SystemV", 1,null);
+ testCPU(src,"riscv" , "SystemV", 5,null);
+ testCPU(src,"arm" , "SystemV", 6,null);
}
@Test
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 5f68d0e3..dd38215c 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -52,15 +52,34 @@ public class Chapter21Test {
testCPU(src,"arm" , "SystemV",19,null);
}
+ @Test public void testNewtonExport() throws Exception {
+ String result = """
+0 0.000000
+1 1.000000
+2 1.414214
+3 1.732051
+4 2.000000
+5 2.236068
+6 2.449490
+7 2.645751
+8 2.828427
+9 3.000000
+""";
+ TestC.run("newtonFloat",result);
+ }
+
@Test
public void testString() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
- testCPU(src,"x86_64_v2", "SystemV", 9,null);
- testCPU(src,"riscv" , "SystemV",18,null);
- testCPU(src,"arm" , "SystemV",17,null);
+ testCPU(src,"x86_64_v2", "SystemV", 1,null);
+ testCPU(src,"riscv" , "SystemV", 5,null);
+ testCPU(src,"arm" , "SystemV", 6,null);
}
@Test
+ public void testStringExport() throws Exception { TestC.run("stringHash"); }
+
+ @Test
public void testArray1() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/array1.smp"));
testCPU(src,"x86_64_v2", "SystemV",7,"return .[];");
@@ -76,13 +95,6 @@ public class Chapter21Test {
testCPU(src,"arm" , "SystemV",16,null);
}
- @Test
- public void testExport() throws IOException {
- String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/newtonFloat.smp"));
- CodeGen code = new CodeGen(src);
- code.parse().opto().typeCheck().instSelect( "x86_64_v2", "SystemV").GCM().localSched().regAlloc().encode().exportELF("build/objs/newton.o");
- }
-
// Read test case from disk.
// TODO: exportELF not handling external calls yet
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestC.java b/chapter21/src/test/java/com/seaofnodes/simple/TestC.java
new file mode 100644
index 00000000..121ace03
--- /dev/null
+++ b/chapter21/src/test/java/com/seaofnodes/simple/TestC.java
@@ -0,0 +1,63 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.codegen.CodeGen;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.io.InputStream;
+import java.io.IOException;
+import static org.junit.Assert.*;
+
+// Call a C driver program, which calls a Simple-generated .o, and self-checks.
+// Expects GCC from the default CLI, compiles C, compiles Simple, links and runs.
+public abstract class TestC {
+
+ public static final String OS = System.getProperty("os.name");
+ public static final String CPU = System.getProperty("os.arch");
+
+ public static final String CALL_CONVENTION = OS.startsWith("Windows") ? "Win64" : "SystemV";
+ public static final String CPU_PORT = switch( CPU ) {
+ case "amd64" -> "x86_64_v2";
+ default -> throw Utils.TODO("Map Yer CPU Port Here");
+ };
+
+ public static void run( String file ) throws Exception { run(file,""); }
+
+ public static void run( String file, String expected ) throws Exception {
+ run("src/test/java/com/seaofnodes/simple/progs",file,expected);
+ }
+
+ // Compile and run a simple program
+ public static void run( String dir, String file, String expected ) throws IOException {
+ // Files
+ String cfile = dir+"/"+file+".c" ;
+ String sfile = dir+"/"+file+".smp";
+ String sofile = "build/objs/"+file+"S.o";
+ String efile = "build/objs/"+file;
+
+ // Compile and export Simple
+ String src = Files.readString(Path.of(sfile));
+ CodeGen code = new CodeGen(src).parse().opto().typeCheck().instSelect( CPU_PORT, CALL_CONVENTION).GCM().localSched().regAlloc().encode().exportELF(sofile);
+
+ // Compile the C program
+ var params = new Ary<>(String.class);
+ //if (USE_WSL) params.add("wsl.exe");
+ params.add("gcc");
+ params.add(cfile);
+ params.add(sofile);
+ params.add("-o");
+ params.add(efile);
+ Process gcc = new ProcessBuilder(params.toArray(String[]::new)).redirectErrorStream(true).start();
+ byte error;
+ try { error = (byte)gcc.waitFor(); } catch( InterruptedException e ) { throw new IOException("interrupted"); }
+ String result = new String(gcc.getInputStream().readAllBytes());
+ assertEquals( 0, error );
+ assertTrue(result.isEmpty()); // No data in error stream
+
+ // Execute results
+ Process smp = new ProcessBuilder(efile).redirectErrorStream(true).start();
+ try { error = (byte)smp.waitFor(); } catch( InterruptedException e ) { throw new IOException("interrupted"); }
+ result = new String(smp.getInputStream().readAllBytes());
+ assertEquals( 0, error );
+ assertEquals(expected,result);
+ }
+}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/newtonFloat.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/newtonFloat.c
new file mode 100644
index 00000000..25ac7930
--- /dev/null
+++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/newtonFloat.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+extern double test_sqrt(double);
+
+int main( int argc, char** argv ) {
+ double epsilon = 1e-50;
+ for( int i=0; i<10; i++ ) {
+ double d = sqrt(i), expect = sqrt(i);
+ double delta = abs(d-expect);
+ printf("%d %f\n",i,d);
+ if( delta > 1e-50 )
+ return 1;
+ }
+ return 0;
+}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.c
new file mode 100644
index 00000000..e0704f74
--- /dev/null
+++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+typedef struct ArrayU8 {
+ unsigned int length;
+ unsigned char data[];
+} ArrayU8;
+typedef struct String {
+ ArrayU8 * cs;
+ long long _hashCode;
+} String;
+
+
+extern bool equals(String*st1, String*st2);
+
+int main() {
+ String test1 = {.cs=(ArrayU8*)"\x04\x00\x00\x00test"};
+ String test2 = {.cs=(ArrayU8*)"\x05\x00\x00\x00test1"};
+
+ if( equals(&test1, &test2) ) {
+ printf("Expected test1 and test2 unequal");
+ return 1;
+ }
+ if( !equals(&test2, &test2) ) {
+ printf("Expected test2 and test2 equal");
+ return 1;
+ }
+ return 0;
+}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.smp b/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.smp
index 455e0014..dafa7456 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.smp
+++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.smp
@@ -29,8 +29,3 @@ val _hashCodeString = { String self ->
if( !hash ) hash = 123456789;
return hash;
};
-
-String !s = new String { cs = new u8[17]; };
-s.cs[0] = 67; // C
-s.cs[1] = 108; // l
-hashCode(s)+hashCode(s);