diff options
| author | Cliff Click <cliffc@acm.org> | 2026-09-28 13:30:22 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-09-28 13:30:22 -0700 |
| commit | 586c8f65f2d0c0e1f73aadd0aa8d850aa653bddd (patch) | |
| tree | 2f539c308452ddf5fa37826da95b17ba557e8352 /chapter24 | |
| parent | 8212a66ff27e56531e0b48807088f1c544d75756 (diff) | |
| download | Simple-586c8f65f2d0c0e1f73aadd0aa8d850aa653bddd.tar.gz Simple-586c8f65f2d0c0e1f73aadd0aa8d850aa653bddd.zip | |
Support extern C ver direct updates
FIx minor RISC encodings.
Diffstat (limited to 'chapter24')
3 files changed, 36 insertions, 4 deletions
diff --git a/chapter24/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java b/chapter24/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java index 44e73d1d..94f0da0e 100644 --- a/chapter24/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java +++ b/chapter24/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java @@ -28,9 +28,9 @@ public class TMPRISC extends ConstantNode implements MachNode, RIPRelSize { // Delta is from opcode start @Override public void patch( Encoding enc, int opStart, int opLen, int delta ) { short dst = enc.reg(this); - // AUIPC dst,#hi20_constant_pool - enc.patch4(opStart , riscv.u_type(riscv.OP_AUIPC, dst, delta>>12)); - // Load dst,[dst+#low12_constant_pool] + // Round the high part because ADDI's low 12 bits are signed. + enc.patch4(opStart , riscv.u_type(riscv.OP_AUIPC, dst, (delta+0x800)>>12)); + // ADDI dst,dst,#low12_constant_pool enc.patch4(opStart+4, riscv.i_type(riscv.OP_IMM, dst, 0, dst, delta & 0xFFF)); } diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter22Test.java index e4eb03c0..cf92f830 100644 --- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter22Test.java +++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter22Test.java @@ -13,6 +13,38 @@ import org.junit.Test; import static org.junit.Assert.*; public class Chapter22Test { + + @Test public void testRiscvRightShifts() { + // SRAI, SRLI, SRA, SRL: a0 = -32 shifted by 4. + int[] ops = {0x40455513,0x00455513,0x40b55533,0x00b55533}; + for( int i=0; i<ops.length; i++ ) { + EvalRisc5 r5 = new EvalRisc5(new byte[1<<16],1<<15); + r5.st4(0,ops[i]); + r5.regs[riscv.A0] = -32; + r5.regs[riscv.A0+1] = 4; + assertEquals(0,r5.step(1)); + assertEquals((i&1)==0 ? -2L : 0x0fff_ffff_ffff_fffeL,r5.regs[riscv.A0]); + } + } + + @Test public void testRiscvPointerRelocation() { + CodeGen code = new CheckedCodeGen("return \"x\";").driver(CodeGen.Phase.Encoding,"riscv","SystemV"); + var enc = code._encoding; + assertEquals(1,enc._bigCons.size()); + var ptr = (com.seaofnodes.simple.node.cpus.riscv.TMPRISC)enc._bigCons.keySet().iterator().next(); + int start = enc._opStart[ptr._nid]; + for( int delta : new int[]{0x7ff,0x800,0xfff,0x1000,0x1800,-1,-0x800,-0x801} ) { + ptr.patch(enc,start,enc._opLen[ptr._nid],delta); + // Place the program above zero so backward targets are valid addresses. + byte[] image = new byte[1<<16]; + System.arraycopy(enc.bits(),0,image,0x4000,enc._bits.size()); + EvalRisc5 r5 = new EvalRisc5(image,1<<15); + r5._pc = 0x4000; + assertEquals(0,r5.step(100)); + assertEquals(0x4000+start+delta,r5.regs[riscv.A0]); + } + } + @Test public void testSubZeroTypeError() { try { new CodeGen("return null-0;").parse().opto().typeCheck(); diff --git a/chapter24/src/test/java/com/seaofnodes/simple/EvalRisc5.java b/chapter24/src/test/java/com/seaofnodes/simple/EvalRisc5.java index a4cc7044..633e931e 100644 --- a/chapter24/src/test/java/com/seaofnodes/simple/EvalRisc5.java +++ b/chapter24/src/test/java/com/seaofnodes/simple/EvalRisc5.java @@ -252,7 +252,7 @@ public class EvalRisc5 { case 2 -> (rs1 < rs2) ? 1 : 0; case 3 -> (rs1 < rs2) ? 1 : 0; case 4 -> rs1 ^ rs2; - case 5 -> (ir & 0x40000000) != 0 ? (rs1 >>> (rs2 & 0x3F)) : (rs1 >> (rs2 & 0x3F)); + case 5 -> (ir & 0x40000000) != 0 ? (rs1 >> (rs2 & 0x3F)) : (rs1 >>> (rs2 & 0x3F)); case 6 -> rs1 | rs2; case 7 -> rs1 & rs2; default -> rval; |
