diff options
Diffstat (limited to 'chapter21/src/main')
3 files changed, 31 insertions, 11 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java index 8cc4621d..dbc86f62 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java @@ -11,7 +11,7 @@ public class CmpARM extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return arm.FLAGS_MASK; } // SUBS (shifted register) - @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_CMP); } + @Override public void encoding( Encoding enc ) { arm.r_reg_subs(enc,this,arm.OP_CMP); } // General form: "cmp rs1, rs2" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java index c0193323..8a4f242a 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java @@ -28,7 +28,7 @@ public class CmpIARM extends MachConcreteNode implements MachNode { @Override public boolean isClone() { return true; } @Override public Node copy() { return new CmpIARM(this); } - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,in(1),in(1), arm.OPI_CMP,_imm); } + @Override public void encoding( Encoding enc ) { arm.imm_inst_subs(enc,in(1),in(1), arm.OPI_CMP,_imm); } // General form: "cmp rs1, 1" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java index ca3d096b..1d9d2efe 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java @@ -273,7 +273,7 @@ public class arm extends Machine { return (32-size)<<1 | immr << 6 | imms; } - // sh is encoded in opcdoe + // sh is encoded in opcode public static int imm_inst(int opcode, int imm12, int rn, int rd) { assert 0 <= rn && rn < 32; assert 0 <= rd && rd < 32; @@ -294,6 +294,13 @@ public class arm extends Machine { enc.add4(body); } + public static void imm_inst_subs(Encoding enc, Node n,Node n2, int opcode, int imm12) { + short reg1 = enc.reg(n2); + // 31 = 11111 + int body = imm_inst(opcode, imm12&0xFFF, reg1, 31); + enc.add4(body); + } + // for cases where rs1 and dst are the same, eg add x0, x0, 1 public static void imm_inst(Encoding enc, int opcode, int imm12, int self) { int body = imm_inst(opcode, imm12&0xFFF, self, self); @@ -335,7 +342,7 @@ public class arm extends Machine { assert 0 <= rm && rm < 32; assert 0 <= rn && rn < 32; assert 0 <= rd && rd < 32; - return (opcode << 24) | (shift << 21) | (rm << 16) | (imm6 << 10) << (rn << 5) | rd; + return (opcode << 24) | (shift << 21) | (rm << 16) | (imm6 << 10) | (rn << 5) | rd; } public static void r_reg(Encoding enc, Node n, int opcode) { short self = enc.reg(n); @@ -343,6 +350,14 @@ public class arm extends Machine { short reg2 = enc.reg(n.in(2)); int body = r_reg(opcode, 0, reg2, 0, reg1, self >= 32 ? reg1: self); enc.add4(body); + } + + public static void r_reg_subs(Encoding enc, Node n, int opcode) { + short reg1 = enc.reg(n.in(1)); + short reg2 = enc.reg(n.in(2)); + // 31 = 11111 + int body = r_reg(opcode, 0, reg2, 0, reg1, 31); + enc.add4(body); } public static int shift_reg(int opcode, int rm, int op2, int rn, int rd) { @@ -459,7 +474,8 @@ public class arm extends Machine { public static int f_cmp(int opcode, int ftype, int rm, int rn) { assert 0 <= rn && rn < 32; assert 0 <= rm && rm < 32; - return (opcode << 24) | (ftype << 21) | (rm << 16) | (8 << 10) | (rn << 5) | 8; + // Todo: |8 is not needed + return (opcode << 24) | (ftype << 21) | (rm << 16) | (8 << 10) | (rn << 5); } public static void f_cmp(Encoding enc, Node n) { short reg1 = (short)(enc.reg(n.in(1))-D_OFFSET); @@ -472,19 +488,21 @@ public class arm extends Machine { return switch (bop) { case "==" -> COND.EQ; case "!=" -> COND.NE; - case "<" -> COND.LE; - case "<=" -> COND.LT; - case ">=" -> COND.GT; - case ">" -> COND.GE; + case "<" -> COND.LT; + case "<=" -> COND.LE; + case ">=" -> COND.GE; + case ">" -> COND.GT; default -> throw Utils.TODO(); }; } - // Todo: maybe missing zero here after delta << 5 + public static int b_cond(int opcode, int delta, COND cond) { // 24-5 == 19bits offset range assert -(1<<19) <= delta && delta < (1<<19); + assert (delta&3)==0; + delta>>=2; delta &= (1L<<19)-1; // Zero extend - return (opcode << 24) | (delta << 5) | cond.ordinal(); + return (opcode << 24) | ((delta)<< 5) | cond.ordinal(); } public static int cond_set(int opcode, int rm, COND cond, int rn, int rd) { @@ -500,6 +518,8 @@ public class arm extends Machine { } public static int b(int opcode, int delta) { assert -(1<<26) <= delta && delta < (1<<26); + assert (delta&3)==0; + delta>>=2; delta &= (1L<<26)-1; // Zero extend return (opcode << 26) | delta; } |
