summaryrefslogtreecommitdiff
path: root/chapter21
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-03-27 11:55:31 -0700
committerCliff Click <cliffc@acm.org>2025-03-27 11:55:31 -0700
commitd18505d598fd7c96d152d57f6f5d1f34124defc3 (patch)
treeaba0bd49d9417295b7731bcce5df8f8ea296c079 /chapter21
parente16cf5d94bce81a27f5080be6f90da448544ee2a (diff)
downloadSimple-d18505d598fd7c96d152d57f6f5d1f34124defc3.tar.gz
Simple-d18505d598fd7c96d152d57f6f5d1f34124defc3.zip
R5 encoding bug fixes
Remove extra branch-to-next
Diffstat (limited to 'chapter21')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java22
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java5
3 files changed, 21 insertions, 10 deletions
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<CFGNode> 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;
}