diff options
Diffstat (limited to 'chapter21/src/test/java/com')
6 files changed, 126 insertions, 18 deletions
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java b/chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java index 1d03a946..391bba67 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java @@ -15,7 +15,7 @@ public class BrainFuckTest { String brain_fuck = "Hello World!\n"; TestC.run("brain_fuck", brain_fuck, 40); - EvalRisc5 R5 = TestRisc5.build("brain_fuck", 0, 44); + EvalRisc5 R5 = TestRisc5.build("brain_fuck", 0, 44, false); int trap = R5.step(100000); assertEquals(0,trap); int ptr = (int)R5.regs[riscv.A0]; diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java index 74c0d42d..291d4a55 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java @@ -88,7 +88,7 @@ public class Chapter21Test { """; TestC.run("newtonFloat",result,34); - EvalRisc5 R5 = TestRisc5.build("newtonFloat", 0, 10); + EvalRisc5 R5 = TestRisc5.build("newtonFloat", 0, 10, false); R5.fregs[riscv.FA0 - riscv.F_OFFSET] = 3.0; int trap_r5 = R5.step(1000); assertEquals(0,trap_r5); @@ -96,13 +96,31 @@ public class Chapter21Test { assertEquals(1.732051,R5.fregs[riscv.FA0 - riscv.F_OFFSET], 0.00001); // arm - EvalArm64 A5 = TestArm64.build("newtonFloat", 0, 10); + EvalArm64 A5 = TestArm64.build("newtonFloat", 0, 10, false); A5.fregs[arm.D0 - arm.D_OFFSET] = 3.0; int trap_arm = A5.step(1000); assertEquals(0,trap_arm); assertEquals(1.732051, A5.fregs[arm.D0 - arm.D_OFFSET], 0.00001); } + @Test + public void testFibPrint() 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().loopTree().instSelect("arm", "SystemV").GCM().localSched().regAlloc().encode().print_as_hex(); + System.out.print(code.asm()); + } + + @Test + public void testFibPrintRiscv() 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().loopTree().instSelect("riscv", "SystemV").GCM().localSched().regAlloc().encode().print_as_hex(); + System.out.print(code.asm()); + } + @Test public void testSieve() throws IOException { // The primes int[] primes = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, }; @@ -114,9 +132,9 @@ public class Chapter21Test { // Compile, link against native C; expect the above string of primes to be printed out by C TestC.run("sieve",sprimes, 257); - // Evaluate on RISC5 emulator; expect return of a array of primes in + // Evaluate on RISC5 emulator; expect return of an array of primes in // the simulated heap. - EvalRisc5 R5 = TestRisc5.build("sieve", 100, 160); + EvalRisc5 R5 = TestRisc5.build("sieve", 100, 160, false); int trap = R5.step(10000); assertEquals(0,trap); // Return register A0 holds sieve(100) @@ -125,20 +143,31 @@ public class Chapter21Test { assertEquals(primes.length, R5.ld4s(ary)); for( int i=0; i<primes.length; i++ ) assertEquals(primes[i], R5.ld4s(ary + 4 + i*4)); + // Evaluate on ARM5 emulator; expect return of an array of primes in the simualted heap. + + EvalArm64 A5 = TestArm64.build("sieve", 100, 160, false); + int trap_arm = A5.step(10000); + assertEquals(0, trap_arm); + int ary_arm = (int)A5.regs[arm.X0]; + // Memory layout starting at ary(length,pad, prime1, primt2, prime3, prime4) + assertEquals(primes.length, A5.ld4s(ary_arm)); + for(int i = 0; i<primes.length; i++) + assertEquals(primes[i], A5.ld4s(ary_arm + 4 + i * 4)); + } @Test public void testFibExport() throws IOException { String fib = "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]"; TestC.run("fib", fib, 24); - EvalRisc5 R5 = TestRisc5.build("fib", 9, 16); + EvalRisc5 R5 = TestRisc5.build("fib", 9, 16, false); int trap = R5.step(100); assertEquals(0,trap); // Return register A0 holds fib(8)==55 assertEquals(55,R5.regs[riscv.A0]); // arm - EvalArm64 A5 = TestArm64.build("fib", 9, 16); + EvalArm64 A5 = TestArm64.build("fib", 9, 16, false); int trap_arm = A5.step(100); assertEquals(0,trap_arm); // Return register X0 holds fib(8)==55 @@ -158,7 +187,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, 0); + EvalRisc5 R5 = TestRisc5.build("person", ps, 0, false); R5.regs[riscv.A1] = 1; // Index 1 R5.st4(ps,3); // Length R5.st8(ps+1*8,p0); @@ -183,7 +212,7 @@ public class Chapter21Test { TestC.CALL_CONVENTION.equals("Win64") ? 42 : 15); - EvalRisc5 R5 = TestRisc5.build("no_stack_arg_count", 0, 0); + EvalRisc5 R5 = TestRisc5.build("no_stack_arg_count", 0, 0, false); // Todo: handle stack(imaginary stack in emulator) // pass in float arguments @@ -213,7 +242,7 @@ public class Chapter21Test { assertEquals(22.8, result, 0.00001); // arm - EvalArm64 A5 = TestArm64.build("no_stack_arg_count", 0, 0); + EvalArm64 A5 = TestArm64.build("no_stack_arg_count", 0, 0, false); A5.fregs[arm.D0 - arm.D_OFFSET] = 1.1; A5.fregs[arm.D1 - arm.D_OFFSET] = 1.1; diff --git a/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java b/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java index 4d0082b9..4a4cf25c 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple; +import com.seaofnodes.simple.codegen.Encoding; import com.seaofnodes.simple.node.cpus.arm.arm; public class EvalArm64 { @@ -63,6 +64,7 @@ public class EvalArm64 { for(int icount = 0; icount < maxops; icount++) { int ir = 0; rval = 0; + frval = 0; cycle++; if( pc >= _buf.length ) { @@ -95,6 +97,27 @@ public class EvalArm64 { rdid = -1; continue ; } + case 0x25: { + // bl (just calloc) + rval = pc + 4; + regs[arm.X30] = rval; + if(pc + 4 == 0) { + regs[rdid] = rval; + break outer; + } + int imm26 = (ir & 0x03FFFFFF); + int imm = (imm26 << 6) >> 6; + pc = pc + (imm << 2) ; + + if (pc == Encoding.SENTINAL_CALLOC) { + long size = regs[arm.X0]*regs[arm.X1]; + regs[arm.X0] = _heap; + _heap += (int)size; + // unwind pc + pc = (int)rval - 4; + } + continue; + } } // for the opcode we just match for bits[31:24]; switch(opcode1) { @@ -104,6 +127,42 @@ public class EvalArm64 { rval = (ir >> 5) & 0x7FFF; break; } + case 0x5c: { + // ldr + is_f = true; + // address = delta + int address = ir << 8 >> 13; + address *= 4; + if(address >= _buf.length-3) trap = (5 + 1); + frval = ld8f(pc + address); + break; + } + + case 0xF9: { + // str + // rn + int base = ir >> 5 & 0x1F; + int imm = (ir >> 10) & 0xFFF; + rval = regs[base] + imm; + switch(ir <<8 >> 30) { + case 0x0: { + // store + _buf[(int)rval] = (byte)regs[rdid]; + if(rdid == 30) { + System.out.print("Here"); + } + rdid = -1; + break; + } + case 0x1: { + // load + rval = _buf[(int)rval]; + break; + } + default: trap = (2+1); + } + break; + } case 0x54: { // b.cond int imm19 = ir << 8 >> 13; @@ -211,6 +270,12 @@ public class EvalArm64 { rval = regs[rn] + immediate; break; } + case 0xD3: { + // lsl + int immr = ir << 10 >> 26; + rval = 64 - immr; + break; + } case 0xAA: { // MOV(register) int rm = (ir >> 16) & 0x1F; @@ -242,8 +307,20 @@ public class EvalArm64 { case 16: frval = fregs[rs1]; break; // fmov case 10:frval = fregs[rs1] + fregs[rs2]; break; // fadd - case 6: frval = fregs[rs1] / fregs[rs2]; break; // fdiv + case 6: if (fregs[rs2] == 0) frval = 0; else frval = fregs[rs1] / fregs[rs2]; break; // fdiv + case 8: { + // fcmp + double lhs = fregs[rs1]; + double rhs = fregs[rs2]; + Z = (lhs == rhs); + N = (lhs < rhs); + C = lhs >= rhs; + V = Double.isNaN(lhs) || Double.isNaN(rhs); + rdid = -1; + + break; + } case 2: frval = fregs[rs1] * fregs[rs2]; break; // fmul case 14: frval = fregs[rs1] - fregs[rs2]; break; // fsub default: trap = (2+1); diff --git a/chapter21/src/test/java/com/seaofnodes/simple/MergeSortTest.java b/chapter21/src/test/java/com/seaofnodes/simple/MergeSortTest.java index 5624ee1b..a72c7c3a 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/MergeSortTest.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/MergeSortTest.java @@ -20,7 +20,7 @@ public class MergeSortTest { TestC.run("sort", sprimes, 40); - EvalRisc5 R5 = TestRisc5.build("sort", 0, 36); + EvalRisc5 R5 = TestRisc5.build("sort", 0, 36, false); // Allocate an array of primes, filled in reverse order int ps = R5._heap; R5._heap += (primes.length+1)*8; // 25 primes, and length diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java b/chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java index 874beca8..739f5b1e 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java @@ -13,15 +13,16 @@ import static org.junit.Assert.assertEquals; // Runs 32-bit ARM code in an emulator public class TestArm64 { - public static EvalArm64 build(String file, int arg, int spills) throws IOException { - return build("src/test/java/com/seaofnodes/simple/progs",file, arg, spills); + public static EvalArm64 build(String file, int arg, int spills, boolean print) throws IOException { + return build("src/test/java/com/seaofnodes/simple/progs",file, arg, spills, print); } // Compile and run a simple program - public static EvalArm64 build(String dir, String file, int arg, int spills) throws IOException { + public static EvalArm64 build(String dir, String file, int arg, int spills, boolean print) throws IOException { // Compile and export Simple String src = Files.readString(Path.of(dir+"/"+file+".smp")); CodeGen code = new CodeGen(src).driver("arm", "SystemV",null); + if(print) {code.print_as_hex(); System.out.print(code.asm());} // Allocation quality not degraded int delta = spills>>3; diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java b/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java index c1d76b79..485a0df7 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java @@ -10,15 +10,16 @@ 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, int spills ) throws IOException { - return build("src/test/java/com/seaofnodes/simple/progs",file, arg, spills); + public static EvalRisc5 build( String file, int arg, int spills, boolean print) throws IOException { + return build("src/test/java/com/seaofnodes/simple/progs",file, arg, spills, print); } // Compile and run a simple program - public static EvalRisc5 build( String dir, String file, int arg, int spills ) throws IOException { + public static EvalRisc5 build( String dir, String file, int arg, int spills, boolean print) throws IOException { // Compile and export Simple String src = Files.readString(Path.of(dir+"/"+file+".smp")); CodeGen code = new CodeGen(src).driver("riscv", "SystemV",null); + if(print) {code.print_as_hex(); System.out.print(code.asm());} // Allocation quality not degraded int delta = spills>>3; |
