summaryrefslogtreecommitdiff
path: root/chapter21/src/test/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/test/java/com')
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/BrainFuckTest.java2
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java47
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java79
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/MergeSortTest.java2
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java7
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java7
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;