summaryrefslogtreecommitdiff
path: root/chapter21/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/main')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java38
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;
}