diff options
| author | Cliff Click <cliffc@acm.org> | 2025-04-15 19:41:55 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-04-15 19:41:55 -0700 |
| commit | 2a3b2d4d4bc6099ab9fead00cfaa3f0a8e6aeb9f (patch) | |
| tree | 6a94bfc5734ba84497083d233281a569ffe0c67f /chapter21/src/test/java/com | |
| parent | 2fb0ec312d76f22534331023c86e68b7a62b98e6 (diff) | |
| download | Simple-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')
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) |
