summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-16 14:17:17 -0700
committerCliff Click <cliffc@acm.org>2025-04-16 14:17:17 -0700
commitbd0f7963b117d3760cd0206ddfa54573c3e9b149 (patch)
treeb83cad268c8db7fbba16647313d601dbb39209e1
parentd3bc904d9d44bd9ad1e1b6e72c5f9c1a8c428f0b (diff)
downloadSimple-bd0f7963b117d3760cd0206ddfa54573c3e9b149.tar.gz
Simple-bd0f7963b117d3760cd0206ddfa54573c3e9b149.zip
Remove redundant BrainFuck test
Move all flavors into BrainFuck,java. Check x86 by linking with C & running. Check risc5 by running in EvalRisc5. Check arm by encoding, but no sim (yet).
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java74
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java62
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/TestC.java20
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java16
4 files changed, 65 insertions, 107 deletions
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java b/chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
index 991a2f66..1d03a946 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
@@ -1,70 +1,32 @@
package com.seaofnodes.simple;
import com.seaofnodes.simple.codegen.CodeGen;
-import java.nio.charset.StandardCharsets;
+import com.seaofnodes.simple.node.cpus.riscv.riscv;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class BrainFuckTest {
- @Test
- public void testBrainfuck() {
- var program = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.".getBytes(StandardCharsets.UTF_8);
- var encoded = new StringBuilder("u8[] !program = new u8[").append(program.length).append("];");
- for (int i = 0; i < program.length; i++) {
- int value = program[i] & 0xFF;
- encoded.append("program[").append(i).append("] = ").append(value).append(";");
- }
+ @Test public void testBrainFuck() throws IOException {
+ String brain_fuck = "Hello World!\n";
+ TestC.run("brain_fuck", brain_fuck, 40);
- String src = encoded + """
+ EvalRisc5 R5 = TestRisc5.build("brain_fuck", 0, 44);
+ int trap = R5.step(100000);
+ assertEquals(0,trap);
+ int ptr = (int)R5.regs[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));
-int d = 0;
-u8[] !output = new u8[0];
-u8[] !data = new u8[100];
+ // TODO: replace with ARM Eval
+ String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/brain_fuck.smp"));
+ Chapter21Test.testCPU(src,"arm", "SystemV",26,null);
-for( int pc = 0; pc < program#; pc++ ) {
- var command = program[pc];
- if (command == 62) {
- d++;
- } else if (command == 60) {
- d--;
- } else if (command == 43) {
- data[d]++;
- } else if (command == 45) {
- data[d]--;
- } else if (command == 46) {
- // Output a byte; increase the output array size
- var old = output;
- output = new u8[output# + 1];
- for( int i = 0; i < old#; i++ )
- output[i] = old[i];
- output[old#] = data[d]; // Add the extra byte on the end
- } else if (command == 44) {
- data[d] = 42;
- } else if (command == 91) {
- if (data[d] == 0) {
- for( int d = 1; d > 0; ) {
- command = program[++pc];
- if (command == 91) d++;
- if (command == 93) d--;
- }
- }
- } else if (command == 93) {
- if (data[d]) {
- for( int d = 1; d > 0; ) {
- command = program[--pc];
- if (command == 93) d++;
- if (command == 91) d--;
- }
- }
- }
-}
-return output;
-""";
- Chapter21Test.testCPU(src,"x86_64_v2", "SystemV",40,null);
- Chapter21Test.testCPU(src,"riscv" , "SystemV",44,null);
- Chapter21Test.testCPU(src,"arm" , "SystemV",26,null);
- //assertEquals("Hello World!\n", Eval2.eval(code, 0, 10000));
}
+
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 2e071531..d1db1609 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -53,23 +53,6 @@ public class Chapter21Test {
}
@Test
- public void testFib() throws IOException {
- String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/fib.smp"));
- testCPU(src,"x86_64_v2", "SystemV",24,null);
- testCPU(src,"riscv" , "SystemV",16,null);
- testCPU(src,"arm" , "SystemV",16,null);
- }
-
- @Test
- public void testNewtonFloat() throws IOException {
- String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/newtonFloat.smp"))
- + "flt farg = arg; return test_sqrt(farg) + test_sqrt(farg+2.0);";
- testCPU(src,"x86_64_v2", "Win64" ,39,null);
- testCPU(src,"riscv" , "SystemV",18,null);
- testCPU(src,"arm" , "SystemV",19,null);
- }
-
- @Test
public void testAntiDeps1() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/antiDep1.smp"));
testCPU(src,"x86_64_v2", "SystemV", 7,"return mov(mov(S));");
@@ -85,7 +68,9 @@ public class Chapter21Test {
testCPU(src,"arm" , "SystemV", 6,null);
}
- @Test public void testStringExport() throws IOException { TestC.run("stringHash"); }
+ @Test public void testStringExport() throws IOException {
+ TestC.run("stringHash", 9);
+ }
@Test public void testNewtonExport() throws IOException {
String result = """
@@ -100,14 +85,19 @@ public class Chapter21Test {
8 2.828427
9 3.000000
""";
- //TestC.run("newtonFloat",result);
+ TestC.run("newtonFloat",result,34);
- EvalRisc5 R5 = TestRisc5.build("newtonFloat", 0);
+ EvalRisc5 R5 = TestRisc5.build("newtonFloat", 0, 10);
R5.fregs[riscv.FA0 - riscv.F_OFFSET] = 3.0;
int trap = R5.step(1000);
assertEquals(0,trap);
// Return register A0 holds fib(8)==55
assertEquals(1.732051,R5.fregs[riscv.FA0 - riscv.F_OFFSET], 0.00001);
+
+ // TODO: Run on ARM eval
+ String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/newtonFloat.smp"))
+ + "flt farg = arg; return test_sqrt(farg) + test_sqrt(farg+2.0);";
+ testCPU(src,"arm", "SystemV",19,null);
}
@Test public void testSieve() throws IOException {
@@ -119,11 +109,11 @@ public class Chapter21Test {
String sprimes = sb.p("]").toString();
// Compile, link against native C; expect the above string of primes to be printed out by C
- TestC.run("sieve",sprimes);
+ TestC.run("sieve",sprimes, 257);
// Evaluate on RISC5 emulator; expect return of a array of primes in
// the simulated heap.
- EvalRisc5 R5 = TestRisc5.build("sieve", 100);
+ EvalRisc5 R5 = TestRisc5.build("sieve", 100, 160);
int trap = R5.step(10000);
assertEquals(0,trap);
// Return register A0 holds sieve(100)
@@ -136,31 +126,22 @@ public class Chapter21Test {
@Test public void testFibExport() throws IOException {
String fib = "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]";
- TestC.run("fib", fib);
+ TestC.run("fib", fib, 24);
- EvalRisc5 R5 = TestRisc5.build("fib", 9);
+ EvalRisc5 R5 = TestRisc5.build("fib", 9, 16);
int trap = R5.step(100);
assertEquals(0,trap);
// Return register A0 holds fib(8)==55
assertEquals(55,R5.regs[riscv.A0]);
- }
- @Test public void testBrainFuck() throws IOException {
- String brain_fuck = "Hello World!\n";
- TestC.run("brain_fuck", brain_fuck);
-
- EvalRisc5 R5 = TestRisc5.build("brain_fuck", 0);
- int trap = R5.step(100000);
- assertEquals(0,trap);
- int ptr = (int)R5.regs[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));
+ // TODO: run on arm eval
+ String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/fib.smp"));
+ testCPU(src,"arm" , "SystemV",16,null);
}
@Test public void testPerson() throws IOException {
String person = "6\n";
- TestC.run("person", person);
+ TestC.run("person", person, 0);
// Memory layout starting at PS:
int ps = 1<<16; // Person array pointer
@@ -171,7 +152,7 @@ public class Chapter21Test {
int p1 = ps+4*8+1*8;
// P2 = { age } // sizeof=8
int p2 = ps+4*8+2*8;
- EvalRisc5 R5 = TestRisc5.build("person", ps);
+ EvalRisc5 R5 = TestRisc5.build("person", ps, 0);
R5.regs[riscv.A1] = 1; // Index 1
R5.st4(ps,3); // Length
R5.st8(ps+1*8,p0);
@@ -189,9 +170,10 @@ public class Chapter21Test {
}
@Test public void testArgCount() throws IOException {
String arg_count = "191.000000\n";
- TestC.run("arg_count", arg_count);
+ TestC.run("arg_count", arg_count, 42);
+
- EvalRisc5 R5 = TestRisc5.build("no_stack_arg_count", 0);
+ EvalRisc5 R5 = TestRisc5.build("no_stack_arg_count", 0, 0);
// Todo: handle stack(imaginary stack in emulator)
// pass in float arguments
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestC.java b/chapter21/src/test/java/com/seaofnodes/simple/TestC.java
index 8398c673..81742cab 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/TestC.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/TestC.java
@@ -20,14 +20,14 @@ public abstract class TestC {
default -> throw Utils.TODO("Map Yer CPU Port Here");
};
- public static void run( String file ) throws IOException { run(file,""); }
+ public static void run( String file, int spills ) throws IOException { run(file,"",spills); }
- public static void run( String file, String expected ) throws IOException {
- run("src/test/java/com/seaofnodes/simple/progs",file,expected);
+ public static void run( String file, String expected, int spills ) throws IOException {
+ run("src/test/java/com/seaofnodes/simple/progs",file,expected,spills);
}
// Compile and run a simple program
- public static void run( String dir, String file, String expected ) throws IOException {
+ public static void run( String dir, String file, String expected, int spills ) throws IOException {
// Files
String cfile = dir+"/"+file+".c" ;
String sfile = dir+"/"+file+".smp";
@@ -35,14 +35,15 @@ public abstract class TestC {
// Compile and export Simple
String src = Files.readString(Path.of(sfile));
- _run(src,CALL_CONVENTION,"",cfile,efile,"S",expected);
+ _run(src,CALL_CONVENTION,"",cfile,efile,"S",expected,spills);
}
- static void _run( String src, String simple_conv, String c_conv, String cfile, String efile, String xtn, String expected ) throws IOException {
+ static void _run( String src, String simple_conv, String c_conv, String cfile, String efile, String xtn, String expected, int spills ) throws IOException {
String bin = efile+xtn;
String obj = bin+".o";
// Compile simple, emit ELF
CodeGen code = new CodeGen(src).driver( CPU_PORT, simple_conv, obj);
+
// Compile the C program
var params = new String[] {
//if (USE_WSL) "wsl.exe";
@@ -77,5 +78,12 @@ public abstract class TestC {
}
assertEquals( 0, error );
assertEquals(expected,result.replace("\r",""));
+
+ // Allocation quality not degraded
+ int delta = spills>>3;
+ if( delta==0 ) delta = 1;
+ if( spills != -1 )
+ assertEquals("Expect spills:",spills,code._regAlloc._spillScaled,delta);
+
}
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java b/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
index a72dbd1d..c1d76b79 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
@@ -2,24 +2,30 @@ package com.seaofnodes.simple;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.node.cpus.riscv.riscv;
-import junit.framework.Assert;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.io.IOException;
+import static org.junit.Assert.*;
// Runs 32-bit R5 code in an emulator
public abstract class TestRisc5 {
- public static EvalRisc5 build( String file, int arg ) throws IOException {
- return build("src/test/java/com/seaofnodes/simple/progs",file, arg);
+ public static EvalRisc5 build( String file, int arg, int spills ) throws IOException {
+ return build("src/test/java/com/seaofnodes/simple/progs",file, arg, spills);
}
// Compile and run a simple program
- public static EvalRisc5 build( String dir, String file, int arg ) throws IOException {
+ public static EvalRisc5 build( String dir, String file, int arg, int spills ) throws IOException {
// Compile and export Simple
String src = Files.readString(Path.of(dir+"/"+file+".smp"));
CodeGen code = new CodeGen(src).driver("riscv", "SystemV",null);
+ // Allocation quality not degraded
+ int delta = spills>>3;
+ if( delta==0 ) delta = 1;
+ if( spills != -1 )
+ assertEquals("Expect spills:",spills,code._regAlloc._spillScaled,delta);
+
// Image
byte[] image = new byte[1<<20]; // A megabyte (1024*1024 bytes)
EvalRisc5 R5 = new EvalRisc5(image, 1<<16);