diff options
| author | Cliff Click <cliffc@acm.org> | 2025-04-16 14:17:17 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-04-16 14:17:17 -0700 |
| commit | bd0f7963b117d3760cd0206ddfa54573c3e9b149 (patch) | |
| tree | b83cad268c8db7fbba16647313d601dbb39209e1 | |
| parent | d3bc904d9d44bd9ad1e1b6e72c5f9c1a8c428f0b (diff) | |
| download | Simple-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).
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); |
