summaryrefslogtreecommitdiff
path: root/chapter21/src/test/java/com/seaofnodes
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-15 19:41:55 -0700
committerCliff Click <cliffc@acm.org>2025-04-15 19:41:55 -0700
commit2a3b2d4d4bc6099ab9fead00cfaa3f0a8e6aeb9f (patch)
tree6a94bfc5734ba84497083d233281a569ffe0c67f /chapter21/src/test/java/com/seaofnodes
parent2fb0ec312d76f22534331023c86e68b7a62b98e6 (diff)
downloadSimple-2a3b2d4d4bc6099ab9fead00cfaa3f0a8e6aeb9f.tar.gz
Simple-2a3b2d4d4bc6099ab9fead00cfaa3f0a8e6aeb9f.zip
R5 fcmp, flt load from pool
exportELF(null) now patches the cpool entries as well as globals. Repeated cpool entries folded. Fixed FltRISC, FCMP encoding.
Diffstat (limited to 'chapter21/src/test/java/com/seaofnodes')
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java9
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java113
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java2
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java2
4 files changed, 56 insertions, 70 deletions
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index faf21b4f..cf088835 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -101,13 +101,14 @@ public class Chapter21Test {
8 2.828427
9 3.000000
""";
- TestC.run("newtonFloat",result);
+ //TestC.run("newtonFloat",result);
+
EvalRisc5 R5 = TestRisc5.build("newtonFloat", 0);
- R5.fregs[riscv.FA0 - riscv.F_OFFSET] = 4.0;
- int trap = R5.step(100);
+ 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(2.0,R5.fregs[riscv.FA0 - riscv.F_OFFSET], 0.00001);
+ assertEquals(1.732051,R5.fregs[riscv.FA0 - riscv.F_OFFSET], 0.00001);
}
@Test public void testSieve() throws IOException {
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java b/chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java
index 50e52095..e48dd34c 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/EvalRisc5.java
@@ -47,6 +47,10 @@ import java.util.Arrays;
public int ld4s(int x) { return ld2z(x) | ld2s(x+2)<<16; }
public long ld8 (int x) { return (long)ld4s(x)&0xFFFFFFFFL | ((long)ld4s(x+4))<<32; }
+ public float ld4f(int x) { return Float.intBitsToFloat(ld4s(x)); }
+ public double ld8f(int x) { return Double.longBitsToDouble(ld8(x)); }
+
+
public void st1(int x, int val) { _buf[x] = (byte)val; }
public void st2(int x, int val) { st1(x,val); st1(x+1,val>> 8); }
public void st4(int x, int val) { st2(x,val); st2(x+2,val>>16); }
@@ -85,17 +89,6 @@ import java.util.Arrays;
int rdid = (ir >> 7) & 0x1f;
switch( ir & 0x7f ) {
- // floats
- case 0x7: {
- is_f = true;
- // does not handle rsp case
-
- long rs1 = (ir >> 15) & 0x1f;
- // Todo: look for stack case
- if (rs1 == 2) break;
- frval = ir & 0x7FF000;
- break;
- }
case 0x37: // LUI (0b0110111)
rval = ( ir & 0xfffff000 );
break;
@@ -174,6 +167,27 @@ import java.util.Arrays;
}
break;
}
+ // floats
+ case 0x7: {
+ is_f = true;
+ int rs1 = (int)regs[(ir >> 15) & 0x1f]; // Address chop to 32b
+ int imm = ir >> 20;
+ int imm_se = imm | (( (imm & 0x800)!=0 ) ? 0xfffff000 : 0 );
+ int rsval = rs1 + imm_se;
+
+ if( rsval >= _buf.length-3 ) {
+ trap = (5+1);
+ rval = rsval;
+ } else {
+ switch( ( ir >> 12 ) & 0x7 ) {
+ case 2: frval = ld4f( rsval ); break;
+ case 3: frval = ld8f( rsval ); break;
+ default: trap = (2+1);
+ }
+ }
+ break;
+ }
+
case 0x23: { // Store 0b0100011
int rs1 = (int)regs[(ir >> 15) & 0x1f]; // Address chop to 32b
long rs2 = regs[(ir >> 20) & 0x1f];
@@ -279,66 +293,37 @@ import java.util.Arrays;
}
case 0x53: {
- // differentiate between fcvt.d.w and fadd.d
is_f = true;
- int rs1;
- int rs1_int;
- int rs2;
- int func5 = (ir >> 27) & 0x1F;;
+ int rs1 = (ir >> 15) & 0x1F;
+ int rs2 = (ir >> 20) & 0x1F;
+ double lhs = fregs[rs1];
+ double rhs = fregs[rs2];
+ int func5 = (ir >> 27) & 0x1F;
int func2 = (ir >> 25) & 0x3;
-// if(func5 == 0 && func2 == 1) {
-// }
- if(func5 == 0) {
- // fadd.d
- rs1 = (ir >> 15) & 0x1F;
- rs2 = (ir >> 20) & 0x1F;
- double lhs = fregs[rs1];
- double rhs = fregs[rs2];
- frval = lhs + rhs;
+ if( func2 != 1 ) throw Utils.TODO(); // 1==double
+ switch( func5 ) {
+ case 0: frval = lhs + rhs; break; // fadd.d
+ case 1: frval = lhs - rhs; break; // fsub.d
+ case 2: frval = lhs * rhs; break; // fmul.d
+ case 3: frval = lhs / rhs; break; // fdiv.d
+ case 5: frval = Math.min(lhs,rhs); break; // fmin.d, also used for move
+ case 20:
+ is_f = false; // Output into a GPR
+ rval = switch( (ir >> 12) & 7 ) {
+ case 0 -> lhs <= rhs ? 1 : 0;
+ case 1 -> lhs == rhs ? 1 : 0;
+ case 2 -> lhs < rhs ? 1 : 0;
+ default -> throw Utils.TODO();
+ };
break;
- } else if(func5 == 26) {
- //fcvt.d.w
- rs1_int = (ir >> 15) & 0x1F;
- long value = regs[rs1_int];
- frval = (double)value;
- break;
- } else if (func5 == 5) {
- // fmin.d
- rs1 = (ir >> 15) & 0x1F;
- rs2 = (ir >> 20) & 0x1F;
- // just pick one as they are the same
- frval = fregs[rs1];
- break;
- } else if(func5 == 3) {
- // fdiv.d
- rs1 = (ir >> 15) & 0x1F;
- rs2 = (ir >> 20) & 0x1F;
- double lhs = fregs[rs1];
- double rhs = fregs[rs2];
- frval = lhs / rhs;
- break;
- } else if(func5 == 2) {
- // fmul.d
- rs1 = (ir >> 15) & 0x1F;
- rs2 = (ir >> 20) & 0x1F;
- double lhs = fregs[rs1];
- double rhs = fregs[rs2];
- frval = lhs * rhs;
- break;
-
- } else if(func5 == 1) {
- // fsub.d
- rs1 = (ir >> 15) & 0x1F;
- rs2 = (ir >> 20) & 0x1F;
- double lhs = fregs[rs1];
- double rhs = fregs[rs2];
- frval = lhs - rhs;
- break;
- } else {
+ case 26: frval = (double)regs[rs1]; break; // fcvt.w.d
+ default:
trap = (2+1); // Fault: Invalid opcode.
throw Utils.TODO();
}
+ break;
}
+
default: trap = (2+1); // Fault: Invalid opcode.
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java b/chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java
index 96aa5b74..1325f1e1 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/TestArm64.java
@@ -19,7 +19,7 @@ public class TestArm64 {
public static EvalArm64 build(String dir, String file, int arg) throws IOException {
// Compile and export Simple
String src = Files.readString(Path.of(dir+"/"+file+".smp"));
- CodeGen code = new CodeGen(src).driver(CodeGen.Phase.RegAlloc,"arm", "SystemV").encode(true);
+ CodeGen code = new CodeGen(src).driver("arm", "SystemV",null);
// Image
byte[] image = new byte[1<<20]; // A megabyte (1024*1024 bytes)
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java b/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
index 8b9b8884..a72dbd1d 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/TestRisc5.java
@@ -18,7 +18,7 @@ public abstract class TestRisc5 {
public static EvalRisc5 build( String dir, String file, int arg ) throws IOException {
// Compile and export Simple
String src = Files.readString(Path.of(dir+"/"+file+".smp"));
- CodeGen code = new CodeGen(src).driver(CodeGen.Phase.RegAlloc,"riscv", "SystemV").encode(true);
+ CodeGen code = new CodeGen(src).driver("riscv", "SystemV",null);
// Image
byte[] image = new byte[1<<20]; // A megabyte (1024*1024 bytes)