From d18505d598fd7c96d152d57f6f5d1f34124defc3 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Thu, 27 Mar 2025 11:55:31 -0700 Subject: R5 encoding bug fixes Remove extra branch-to-next --- .../com/seaofnodes/simple/codegen/Encoding.java | 22 ++++++++++++++++------ .../simple/node/cpus/riscv/BranchRISC.java | 4 ++-- .../seaofnodes/simple/node/cpus/riscv/riscv.java | 5 +++-- 3 files changed, 21 insertions(+), 10 deletions(-) (limited to 'chapter21') diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java index 756735ad..f2a2449e 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java @@ -183,13 +183,17 @@ public class Encoding { if( bb.nOuts()==0 ) return; // StopNode if( !(bb instanceof IfNode iff) ) { CFGNode next = bb instanceof ReturnNode ? (CFGNode)bb.out(bb.nOuts()-1) : bb.uctrl(); - // If the *next* BB has already been visited, we require an - // unconditional backwards jump here + // If the *next* BB has already been visited, we may need an + // unconditional jump here if( visit.get(next._nid) && !(next instanceof StopNode) ) { - CFGNode jmp = _code._mach.jump(); - jmp.setDefX(0,bb); - next.setDef(next._inputs.find(bb),jmp); - rpo.add(jmp); + // If all the blocks, in RPO order, to our target + // are empty, we will fall in and not need a jump. + if( next instanceof LoopNode || !isEmptyBackwardsScan(rpo,next) ) { + CFGNode jmp = _code._mach.jump(); + jmp.setDefX(0,bb); + next.setDef(next._inputs.find(bb),jmp); + rpo.add(jmp); + } } _rpo_cfg(next,visit,rpo); } else { @@ -232,6 +236,12 @@ public class Encoding { rpo.add(bb); } + private static boolean isEmptyBackwardsScan(Ary rpo, CFGNode next) { + for( int i=rpo._len-1; rpo.at(i)!=next; i-- ) + if( rpo.at(i).nOuts()!=1 ) + return false; + return true; + } // Write encoding bits in order into a big byte array. // Record opcode start and length. diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java index a0a4b6aa..ef1792eb 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java @@ -43,7 +43,7 @@ public class BranchRISC extends IfNode implements MachNode, RIPRelSize { // Todo: relocs (for offset - immf) short src1 = enc.reg(in(1)); short src2 = in(2)==null ? (short)riscv.ZERO : enc.reg(in(2)); - enc.add4(riscv.b_type(0x63, riscv.jumpop(_bop), src1, src2, 0)); + enc.add4(riscv.b_type(riscv.OP_BRANCH, riscv.jumpop(_bop), src1, src2, 0)); } // Delta is from opcode start @@ -58,7 +58,7 @@ public class BranchRISC extends IfNode implements MachNode, RIPRelSize { short src1 = enc.reg(in(1)); short src2 = in(2)==null ? (short)riscv.ZERO : enc.reg(in(2)); if( opLen==4 ) { - enc.patch4(opStart,riscv.b_type(0x63, riscv.jumpop(_bop), src1, src2, delta)); + enc.patch4(opStart,riscv.b_type(riscv.OP_BRANCH, riscv.jumpop(_bop), src1, src2, delta)); } else { throw Utils.TODO(); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java index 03569709..0d382c6d 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java @@ -106,6 +106,7 @@ public class riscv extends Machine { public static int OP = 0b01_100_11; public static int OP_FP = 0b10_100_11; public static int OP_CUSTOM0 = 0b00_010_11; + public static int OP_BRANCH = 0b11_000_11; //I_type opcode: 0010 0011 public static int I_TYPE = 0x13; @@ -178,11 +179,11 @@ public class riscv extends Machine { // 31 30 29 28 27 26 25 24-20 19-15 14-12 11 10 9 8 7 6-0 // 12 10 9 8 7 6 5 SRC2 SRC1 FUNC3 4 3 2 1 11 OP int imm4_1 = (delta>> 1) & 0xF; - int imm10_5= (delta>> 5) &0x2F; + int imm10_5= (delta>> 5) &0x3F; int imm11 = (delta>>11) & 1; int imm12 = (delta>>12) & 1; int imm5 = imm4_1<<1 | imm11; - int imm7 = imm12<<7 | imm10_5; + int imm7 = imm12<<6 | imm10_5; return (imm7 << 25 ) | (rs2 << 20) | (rs1 << 15) | (func3 << 12) | (imm5 << 7) | opcode; } -- cgit v1.2.3