summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chapter21/README.md12
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java52
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java6
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java22
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java31
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java12
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java5
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpFARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpMemARM.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java33
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java29
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulIARM.java43
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java3
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java10
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java27
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java120
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java10
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java3
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java18
49 files changed, 377 insertions, 149 deletions
diff --git a/chapter21/README.md b/chapter21/README.md
index 9b1e8e86..f2c74e07 100644
--- a/chapter21/README.md
+++ b/chapter21/README.md
@@ -9,4 +9,16 @@ This chapter has encodings for:
## Instruction Encodings
+## x86_64_v2
+*Source*: [^1]
+
+## ARM
+
+## RISCV
+
### Lots of Bits
+
+
+[^1]: [Intel](smt here)
+
+[^2]: ()
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
index eb6d96f9..1e778aa7 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
@@ -296,30 +296,36 @@ public class CodeGen {
return this;
}
- //public static void print_as_hex(ByteArrayOutputStream outputStream) {
- // byte[] encodedBytes = outputStream.toByteArray();
- // for (byte b : encodedBytes) {
- // System.out.print(String.format("%02X", b));
- // }
- // System.out.println();
- //}
- //
+ public static void print_as_hex(Encoding enc) {
+ for (byte b : enc._bits.toByteArray()) {
+ System.out.print(String.format("%02X", b));
+ }
+ System.out.println();
+ }
+
+ public void print_as_hex() {
+ for (byte b : _encoding._bits.toByteArray()) {
+ System.out.print(String.format("%02X", b));
+ }
+ System.out.println();
+ }
+
//// Debug purposes for now
- //public CodeGen printENCODING() {
- // ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- //
- // for(Node bb : CodeGen.CODE._cfg) {
- // for(Node n: bb.outs()) {
- // if(n instanceof MachNode) {
- // ((MachNode) n).encoding(outputStream);
- // }
- // }
- // }
- //
- // print_as_hex(outputStream);
- // // Get the raw bytes from the output stream
- // return this;
- //}
+// public CodeGen printENCODING() {
+// ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+//
+// for(Node bb : CodeGen.CODE._cfg) {
+// for(Node n: bb.outs()) {
+// if(n instanceof MachNode) {
+// ((MachNode) n).encoding(E);
+// }
+// }
+// }
+//
+// print_as_hex(outputStream);
+// // Get the raw bytes from the output stream
+// return this;
+// }
public String reg(Node n) {
if( _phase.ordinal() >= Phase.RegAlloc.ordinal() ) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java
index b95e3719..a65b9553 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java
@@ -9,7 +9,9 @@ public class AddARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "add"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,139); }
+
+ // ADD (shifted register)
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,0b10001011); }
// General form: "rd = rs1 + rs2"
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2)));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java
index 35d1eef1..6e1930ed 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java
@@ -9,10 +9,12 @@ public class AddFARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "addf"; }
@Override public RegMask regmap(int i) { return arm.DMASK; }
@Override public RegMask outregmap() { return arm.DMASK; }
- @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,10); }
+
+ //FADD (scalar)
+ @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,0b00011110); }
// Default on double precision for now(64 bits)
- // General form: "vadd.32 rd = src1 + src2
+ // General form: "addf rd = src1 + src2
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2)));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java
index b37fadee..fab40b1d 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java
@@ -16,7 +16,8 @@ public class AddIARM extends MachConcreteNode implements MachNode {
}
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,580,_imm); }
+ //ADD (immediate)
+ @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b1001000100,_imm); }
// General form: "addi rd = rs1 + imm"
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + #").p(_imm);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java
index 8e95628c..c107e87f 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java
@@ -12,7 +12,8 @@ public class AndARM extends MachConcreteNode implements MachNode {
@Override public String glabel() { return "&"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,138); }
+ // AND (shifted register)
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,0b10001010); }
// General form: #rd = rs1 & rs2
@Override public void asm(CodeGen code, SB sb){
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" & ").p(code.reg(in(2)));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java
new file mode 100644
index 00000000..ce270356
--- /dev/null
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java
@@ -0,0 +1,22 @@
+package com.seaofnodes.simple.node.cpus.arm;
+
+import com.seaofnodes.simple.*;
+import com.seaofnodes.simple.codegen.*;
+import com.seaofnodes.simple.node.*;
+
+public class AndIARM extends MachConcreteNode implements MachNode {
+ final int _imm;
+ AndIARM(Node and, int imm) {
+ super(and);
+ _inputs.pop();
+ _imm = imm;
+ }
+ @Override public String op() { return "andi"; }
+ @Override public RegMask regmap(int i) { return arm.RMASK; }
+ @Override public RegMask outregmap() { return arm.RMASK; }
+ @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b100100100,_imm); }
+ // General form: "andi rd = rs1 & imm"
+ @Override public void asm(CodeGen code, SB sb) {
+ sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" & #").p(_imm);
+ }
+} \ No newline at end of file
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java
index d91a18ab..23776896 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java
@@ -10,7 +10,7 @@ public class AsrARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "sar"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,10); }
+ @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,0b1010); }
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >> ").p(code.reg(in(2)));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java
new file mode 100644
index 00000000..e5636bc3
--- /dev/null
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java
@@ -0,0 +1,31 @@
+package com.seaofnodes.simple.node.cpus.arm;
+
+import com.seaofnodes.simple.SB;
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.codegen.Encoding;
+import com.seaofnodes.simple.codegen.RegMask;
+import com.seaofnodes.simple.node.MachConcreteNode;
+import com.seaofnodes.simple.node.MachNode;
+import com.seaofnodes.simple.node.Node;
+
+public class AsrIARM extends MachConcreteNode implements MachNode {
+ final int _imm;
+ AsrIARM(Node asr, int imm) {
+ super(asr);
+ _inputs.pop();
+ _imm = imm;
+ }
+ @Override public String op() { return "asri"; }
+ @Override public RegMask regmap(int i) { return arm.RMASK; }
+ @Override public RegMask outregmap() { return arm.RMASK; }
+ @Override public void encoding( Encoding enc ) {
+ short rd = enc.reg(this);
+ short rn = enc.reg(in(1));
+ assert _imm > 0;
+ enc.add4(arm.imm_shift(0b100100110,_imm, 0b111111, rn, rd));
+ }
+ // General form: "asri rd = rs1 >> imm"
+ @Override public void asm(CodeGen code, SB sb) {
+ sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >> #").p(_imm);
+ }
+} \ No newline at end of file
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java
index a7cbd1aa..6b87a2a5 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java
@@ -34,16 +34,8 @@ public class BranchARM extends IfNode implements MachNode{
enc.jump(this,cproj(0));
// Assuming that condition flags are already set. These flags are set
// by comparison (or sub). No need for regs because it uses flags
- arm.COND cond = switch (_bop) {
- case "==" -> arm.COND.EQ;
- case "!=" -> arm.COND.NE;
- case "<" -> arm.COND.LE;
- case "<=" -> arm.COND.LT;
- case ">=" -> arm.COND.GT;
- case ">" -> arm.COND.GE;
- default -> throw Utils.TODO();
- };
- int body = arm.b_cond(84, 0, cond);
+ // B.cond
+ int body = arm.b_cond(0b01010100, 0, arm.make_condition(_bop));
enc.add4(body);
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
index 2a815f37..1d3d4d3d 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
@@ -24,10 +24,10 @@ public class CallARM extends CallNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.callInMask(_tfp,i); }
@Override public RegMask outregmap() { return null; }
- // Encoding is appended into the byte array; size is returned
@Override public void encoding( Encoding enc ) {
enc.relo(this,_tfp); // Record relo info
- enc.add4(arm.b(37,0));
+ // BL
+ enc.add4(arm.b(0B100101,0)); // Target patched at link time
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
index 1d76b621..b5c3ecac 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
@@ -16,9 +16,10 @@ public class CallRRARM extends CallNode implements MachNode {
@Override public RegMask outregmap() { return null; }
@Override public void encoding( Encoding enc ) {
- //enc.add4(arm.b(37, 0));
// Needs a register, typically a jump-and-link-register opcode
- throw Utils.TODO();
+ // blr
+ short self = enc.reg(this);
+ enc.add4(arm.blr(0b1101011000111111000000, self));
}
@Override public void asm(CodeGen code, SB sb) {
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 f97fdeda..7b61baf7 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
@@ -9,7 +9,9 @@ public class CmpARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "cmp"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.FLAGS_MASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,235); }
+
+ // SUBS (shifted register)
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,0b11101011); }
// 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/CmpFARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpFARM.java
index f2880078..e82a2ee3 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpFARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpFARM.java
@@ -10,7 +10,8 @@ public class CmpFARM extends MachConcreteNode implements MachNode{
@Override public String op() { return "cmpf"; }
@Override public RegMask regmap(int i) { return arm.DMASK; }
@Override public RegMask outregmap() { return arm.FLAGS_MASK; }
- // Encoding is appended into the byte array; size is returned
+
+ // FCMP
@Override public void encoding( Encoding enc ) { arm.f_cmp(enc,this); }
// General form: "cmp d0, d1"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpMemARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpMemARM.java
deleted file mode 100644
index 47f68ccc..00000000
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpMemARM.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.seaofnodes.simple.node.cpus.arm;
-
-public class CmpMemARM {
-}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java
index 62ce9827..4e1f9d5d 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java
@@ -9,7 +9,8 @@ public class DivARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "div"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.madd(enc,this,1238,3); }
+ // SDIV
+ @Override public void encoding( Encoding enc ) { arm.madd(enc,this,0b10011010110,3); }
// General form: "div dst /= src"
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" / ").p(code.reg(in(2)));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java
index 8ffb14ec..9d8e064b 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java
@@ -9,7 +9,9 @@ public class DivFARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "divf"; }
@Override public RegMask regmap(int i) { return arm.DMASK; }
@Override public RegMask outregmap() { return arm.DMASK; }
- @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,6); }
+
+ // FDIV (scalar)
+ @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,0b000110); }
// General form: "VDIF = dst /= src"
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" / ").p(code.reg(in(2)));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
index be837f04..517d0831 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
@@ -20,7 +20,6 @@ public class FloatARM extends ConstantNode implements MachNode {
@Override public boolean isClone() { return true; }
@Override public FloatARM copy() { return new FloatARM(this); }
- // Encoding is appended into the byte array; size is returned
@Override public void encoding( Encoding enc ) {
short dst = (short)(enc.reg(this) - arm.D_OFFSET);
double d = ((TypeFloat)_con).value();
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java
index f1286630..f10e636a 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java
@@ -10,9 +10,10 @@ public class I2F8ARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.DMASK; }
@Override public void encoding( Encoding enc ) {
+ // SCVTF
short self = (short)(enc.reg(this )-arm.D_OFFSET);
short reg1 = enc.reg(in(1));
- int body = arm.float_cast(158, 1, reg1, self);
+ int body = arm.float_cast(0b10011110, 1, reg1, self);
enc.add4(body);
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
index d44e108e..f9b53f6b 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
@@ -17,7 +17,6 @@ public class IntARM extends ConstantNode implements MachNode {
@Override public boolean isClone() { return true; }
@Override public IntARM copy() { return new IntARM(this); }
- // Encoding is appended into the byte array; size is returned
@Override public void encoding( Encoding enc ) {
short self = enc.reg(this);
long x = ((TypeInteger)_con).value();
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
index 4fa16a74..7dd4d929 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
@@ -17,7 +17,8 @@ public class LoadARM extends MemOpARM{
}
@Override public String op() { return "ld"+_sz; }
@Override public RegMask outregmap() { return arm.MEM_MASK; }
- @Override public void encoding( Encoding enc ) { arm.ldst_encode(enc,this,1986,this); }
+ // ldr(immediate - unsigned offset) | ldr(register)
+ @Override public void encoding( Encoding enc ) { arm.ldst_encode(enc,this,this); }
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(",");
asm_address(code,sb);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java
index c97608d5..24790f9d 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java
@@ -10,7 +10,8 @@ public class LslARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "shr"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,8); }
+
+ @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,0b1000); }
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" << ").p(code.reg(in(2)));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java
new file mode 100644
index 00000000..d6633e51
--- /dev/null
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java
@@ -0,0 +1,33 @@
+package com.seaofnodes.simple.node.cpus.arm;
+
+import com.seaofnodes.simple.SB;
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.codegen.Encoding;
+import com.seaofnodes.simple.codegen.RegMask;
+import com.seaofnodes.simple.node.MachConcreteNode;
+import com.seaofnodes.simple.node.MachNode;
+import com.seaofnodes.simple.node.Node;
+
+public class LslIARM extends MachConcreteNode implements MachNode {
+ final int _imm;
+ LslIARM(Node lsl, int imm) {
+ super(lsl);
+ _inputs.pop();
+ _imm = imm;
+ }
+ @Override public String op() { return "lsli"; }
+ @Override public RegMask regmap(int i) { return arm.RMASK; }
+ @Override public RegMask outregmap() { return arm.RMASK; }
+ @Override public void encoding( Encoding enc ) {
+ short rd = enc.reg(this);
+ short rn = enc.reg(in(1));
+ assert _imm > 0;
+ // UBFM <Xd>, <Xn>, #(-<shift> MOD 64), #(63-<shift>)
+ // immr must be (-<shift> MOD 64) = 64 - shift
+ enc.add4(arm.imm_shift(0b110100110, 64 - _imm, (64 - _imm) - 1, rn, rd));
+ }
+ // General form: "lsli rd = rs1 << imm"
+ @Override public void asm(CodeGen code, SB sb) {
+ sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" << #").p(_imm);
+ }
+} \ No newline at end of file
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java
index 848f96f9..cdc0f301 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java
@@ -10,7 +10,8 @@ public class LsrARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "shr"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,9); }
+
+ @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,0b1001); }
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >>> ").p(code.reg(in(2)));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java
new file mode 100644
index 00000000..8bf2b9ce
--- /dev/null
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java
@@ -0,0 +1,29 @@
+package com.seaofnodes.simple.node.cpus.arm;
+
+
+import com.seaofnodes.simple.*;
+import com.seaofnodes.simple.codegen.*;
+import com.seaofnodes.simple.node.*;
+
+// logical right shift immediate
+public class LsrIARM extends MachConcreteNode implements MachNode {
+ final int _imm;
+ LsrIARM(Node lsr, int imm) {
+ super(lsr);
+ _inputs.pop();
+ _imm = imm;
+ }
+ @Override public String op() { return "lsri"; }
+ @Override public RegMask regmap(int i) { return arm.RMASK; }
+ @Override public RegMask outregmap() { return arm.RMASK; }
+ @Override public void encoding( Encoding enc ) {
+ short rd = enc.reg(this);
+ short rn = enc.reg(in(1));
+ assert _imm > 0;
+ enc.add4(arm.imm_shift(0b110100110,_imm, 0b111111, rn,rd));
+ }
+ // General form: "lsri rd = rs1 >>> imm"
+ @Override public void asm(CodeGen code, SB sb) {
+ sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >>> #").p(_imm);
+ }
+} \ No newline at end of file
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java
index 706922a7..5decb4de 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java
@@ -10,7 +10,8 @@ public class MulARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "mul"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.madd(enc,this,1240,31); }
+
+ @Override public void encoding( Encoding enc ) { arm.madd(enc,this,0b10011011000,31); }
// General form: "rd = rs1 * rs2"
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2)));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java
index 0e59bd96..a4862db5 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java
@@ -9,7 +9,7 @@ public class MulFARM extends MachConcreteNode implements MachNode{
@Override public String op() { return "mulf"; }
@Override public RegMask regmap(int i) { return arm.DMASK; }
@Override public RegMask outregmap() { return arm.DMASK; }
- @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,2); }
+ @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,0b10); }
// Default on double precision for now(64 bits)
// General form: "VMUL.f32 rd = src1 * src2
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulIARM.java
deleted file mode 100644
index e617ee13..00000000
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulIARM.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.seaofnodes.simple.node.cpus.arm;
-
-import com.seaofnodes.simple.*;
-import com.seaofnodes.simple.codegen.CodeGen;
-import com.seaofnodes.simple.codegen.Encoding;
-import com.seaofnodes.simple.codegen.RegMask;
-import com.seaofnodes.simple.node.*;
-import com.seaofnodes.simple.type.TypeInteger;
-
-public class MulIARM extends MachConcreteNode implements MachNode{
- final TypeInteger _ti;
- MulIARM(Node mul, TypeInteger ti) {
- super(mul);
- _inputs.pop();
- _ti = ti;
- }
-
- // Register mask allowed on input i.
- // This is the normal calling convention
- @Override public RegMask regmap(int i) {
- // assert i==1;
- return arm.RMASK; }
-
- // Register mask allowed as a result. 0 for no register.
- @Override public RegMask outregmap() { return arm.RMASK; }
-
- // Output is same register as input#1
- @Override public int twoAddress() { return 1; }
-
- // Encoding is appended into the byte array; size is returned
- @Override public void encoding( Encoding enc ) {
- throw Utils.TODO();
- }
-
- // General form
- // General form: "muli dst * #imm"
- @Override public void asm(CodeGen code, SB sb) {
- sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * #");
- _ti.print(sb);
- }
-
- @Override public String op() { return "muli"; }
-}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java
index cdac48a3..8ddf1bd6 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java
@@ -15,7 +15,8 @@ public class NewARM extends NewNode implements MachNode {
@Override public void encoding( Encoding enc ) {
enc.relo(this);
- enc.add4(arm.b(37, 0));
+ // bl
+ enc.add4(arm.b(0b100101, 0));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
index 1092c931..c492d334 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
@@ -18,9 +18,9 @@ public class NotARM extends MachConcreteNode implements MachNode{
// subtracting zero from rs will just yield rs, it sets the zero flag and then it's used in cset
short self = enc.reg(this );
short reg1 = enc.reg(in(1));
- int subs = arm.imm_inst(964, 0, reg1, self);
+ int subs = arm.imm_inst(0b1111000100, 0, reg1, self);
enc.add4(subs);
- int cset = arm.cond_set(1236, 31, arm.COND.EQ, 63, reg1);
+ int cset = arm.cond_set(0b10011010100, 31, arm.COND.EQ, 63, reg1);
enc.add4(cset);
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java
index 19631f35..860546d2 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java
@@ -11,7 +11,7 @@ public class OrARM extends MachConcreteNode implements MachNode {
@Override public String glabel() { return "|"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,170); }
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,0b10101010); }
// General form: #rd = rs1 & rs2
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" | ").p(code.reg(in(2)));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java
index 3f72f026..bb28acdb 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java
@@ -14,7 +14,7 @@ public class OrIARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "ori"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0xC8,_imm); }
+ @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b101100100,_imm); }
// General form: "ori rd = rs1 | imm"
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" | #").p(_imm);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java
index 9066925e..2a702247 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java
@@ -15,7 +15,8 @@ public class RetARM extends ReturnNode implements MachNode {
}
@Override public RegMask regmap(int i) { return arm.retMask(_fun.sig(),i); }
@Override public RegMask outregmap() { return null; }
- @Override public void encoding( Encoding enc ) { enc.add4(arm.ret(3512256)); }
+ // RET
+ @Override public void encoding( Encoding enc ) { enc.add4(arm.ret(0b1101011001011111000000)); }
@Override public void asm(CodeGen code, SB sb) {
// Post code-gen, just print the "ret"
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java
index 0f958e38..5c187239 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java
@@ -21,8 +21,8 @@ public class SetARM extends MachConcreteNode implements MachNode {
// Encoding is appended into the byte array; size is returned
@Override public void encoding( Encoding enc ) {
- //arm.cond_set(???);
- Utils.TODO();
+ int body = arm.cset(0b1001101010011111, arm.make_condition(_bop), 0b0111111, enc.reg(this));
+ enc.add4(body);
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java
index defb4f92..f3ef7f7b 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java
@@ -9,11 +9,10 @@ public class SplitARM extends SplitNode {
@Override public RegMask regmap(int i) { return arm.SPLIT_MASK; }
@Override public RegMask outregmap() { return arm.SPLIT_MASK; }
- // Encoding is appended into the byte array; size is returned
@Override public void encoding( Encoding enc ) {
short self = enc.reg(this );
short reg1 = enc.reg(in(1));
- int body = arm.r_reg(170, 0, reg1, 0, 31, self);
+ int body = arm.r_reg(0b10101010, 0, reg1, 0, 31, self);
enc.add4(body);
}
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
index ae7e88d9..03a39f06 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
@@ -21,7 +21,7 @@ public class StoreARM extends MemOpARM {
}
@Override public String op() { return "st"+_sz; }
@Override public RegMask outregmap() { return null; }
- @Override public void encoding( Encoding enc ) { arm.ldst_encode(enc,this,1984,val()); }
+ @Override public void encoding( Encoding enc ) { arm.ldst_encode(enc,this,val()); }
@Override public void asm(CodeGen code, SB sb) {
asm_address(code,sb).p(",");
if( val()==null ) sb.p("#").p(_imm);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java
index df85199c..072bbf46 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java
@@ -9,7 +9,8 @@ public class SubARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "sub"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,203); }
+
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,0b11001011); }
// General form: "sub # rd = rs1 - rs2"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java
index b5aacc52..903c7947 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java
@@ -9,7 +9,7 @@ public class SubFARM extends MachConcreteNode implements MachNode {
@Override public String op() { return "subf"; }
@Override public RegMask regmap(int i) { return arm.DMASK; }
@Override public RegMask outregmap() { return arm.DMASK; }
- @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,14); }
+ @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,0b1110); }
// Default on double precision for now(64 bits)
// General form: "vsub.f32 rd = src1 + src2
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java
index bda6681e..0334fa78 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java
@@ -17,8 +17,8 @@ public class SubIARM extends MachConcreteNode implements MachNode {
@Override public String op() { return _imm == -1 ? "dec" : "subi"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- // Encoding is appended into the byte array; size is returned
- @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,836,_imm); }
+
+ @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b1101000100,_imm); }
// General form: "subi rd = rs1 - imm"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
index 36125048..eb06a4e0 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
@@ -16,11 +16,11 @@ public class TFPARM extends ConstantNode implements MachNode {
@Override public void encoding( Encoding enc ) {
enc.relo(this,(TypeFunPtr)_con);
short self = enc.reg(this);
- // Limit of 16bit address for function constants???
- int body = arm.load_adr(1986,0,0,self);
- enc.add4(body);
- // Surely need to split into 2 ops?
- throw Utils.TODO();
+ // adrp x0, 0
+ int adrp = arm.adrp(1,0, 0b10000, 0,self);
+ // add x0, x0, 0
+ arm.imm_inst(enc,this,0b1001000100,0);
+ enc.add4(adrp);
}
@Override public void asm(CodeGen code, SB sb) {
String reg = code.reg(this);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java
index 8c4f65f9..9fdf0619 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java
@@ -10,7 +10,7 @@ public class XorARM extends MachConcreteNode implements MachNode{
@Override public String glabel() { return "^"; }
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.RMASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,202); }
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,0b11001010); }
// General form: "rd = x1 ^ x2"
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ^ ").p(code.reg(in(2)));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java
new file mode 100644
index 00000000..4814a7cc
--- /dev/null
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java
@@ -0,0 +1,27 @@
+package com.seaofnodes.simple.node.cpus.arm;
+
+import com.seaofnodes.simple.node.MachConcreteNode;
+import com.seaofnodes.simple.node.MachNode;
+
+import com.seaofnodes.simple.*;
+import com.seaofnodes.simple.codegen.*;
+import com.seaofnodes.simple.node.*;
+
+public class XorIARM extends MachConcreteNode implements MachNode {
+ final int _imm;
+ XorIARM(Node xor, int imm) {
+ super(xor);
+ _inputs.pop();
+ _imm = imm;
+ }
+
+ @Override public String op() { return "xori"; }
+ @Override public RegMask regmap(int i) { return arm.RMASK; }
+ @Override public RegMask outregmap() { return arm.RMASK; }
+
+ // General form: "xori rd = rs1 ^ imm"
+ @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b110100100,_imm); }
+ @Override public void asm(CodeGen code, SB sb) {
+ sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ^ #").p(_imm);
+ }
+}
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 add609fc..04569476 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
@@ -116,6 +116,10 @@ public class arm extends Machine {
SXTX,
}
+ static public int cset(int opcode, COND cond, int rn, int rd) {
+ return (opcode << 16) | (cond.ordinal() << 12) | (rn << 5) | rd;
+ }
+
public enum STORE_LOAD_OPTION {
UXTW, // base+ u32 index [<< logsize]
UXTX, // base+ u64 index [<< logsize]
@@ -169,16 +173,42 @@ public class arm extends Machine {
// Some combination of shifted bit-masks.
private static int imm12Logical(TypeInteger ti) {
if( !ti.isConstant() ) return -1;
- // TODO: THE REAL THING
- // INVARIANT: always a positive thing
- return -1;
+ if( !ti.isConstant() ) return -1;
+ long val = ti.value();
+ if (val == 0 || val == -1) return -1; // Special cases are not allowed
+ int immr = 0;
+ // Rotate until we have 0[...]1
+ while (val < 0 || (val & 1)==0) {
+ val = (val >>> 63) | (val << 1);
+ immr++;
+ }
+ int size = 32;
+ long pattern = val;
+ // Is upper half of pattern the same as the lower?
+ while ((pattern & ((1L<<size)-1)) == (pattern >> size)) {
+ // Then only take one half
+ pattern >>= size;
+ size >>= 1;
+ }
+ size <<= 1;
+ int imms = Long.bitCount(pattern);
+ // Pattern should now be zeros followed by ones 0000011111
+ if (pattern != (1L<<imms)-1) return -1;
+ imms--;
+ if (size == 64) return 0x1000 | immr << 6 | imms;
+ return (32-size)<<1 | immr << 6 | imms;
}
// sh is encoded in opcdoe
public static int imm_inst(int opcode, int imm12, int rn, int rd) {
assert opcode >=0 && imm12 >= 0 && rn >=0 && rd>=0; // Caller zeros high order bits
- return (opcode << 22) | (imm12 << 10) | (rn << 5) | rd;
+ return (opcode << 23) | (imm12 << 10) | (rn << 5) | rd;
+ }
+
+ public static int imm_shift(int opcode, int imm, int imms, int rn, int rd) {
+ return (opcode << 23) | (1 << 22) | (imm << 16) | (imms << 10) | (rn << 5) | rd;
}
+
public static void imm_inst(Encoding enc, Node n, int opcode, int imm12) {
short self = enc.reg(n);
short reg1 = enc.reg(n.in(1));
@@ -206,7 +236,7 @@ public class arm extends Machine {
short self = enc.reg(n);
short reg1 = enc.reg(n.in(1));
short reg2 = enc.reg(n.in(2));
- int body = shift_reg(1238, reg2, op2, reg1, self);
+ int body = shift_reg(0b10011010110, reg2, op2, reg1, self);
enc.add4(body);
}
@@ -243,12 +273,20 @@ public class arm extends Machine {
short self = (short)(enc.reg(n) -D_OFFSET);
short reg1 = (short)(enc.reg(n.in(1))-D_OFFSET);
short reg2 = (short)(enc.reg(n.in(2))-D_OFFSET);
- int body = f_scalar(30, 1, reg2, op, reg1, self);
+ int body = f_scalar(0b00011110, 1, reg2, op, reg1, self);
enc.add4(body);
}
+ public static int load_pc(int opcode, int offset, int rt) {
+ return (opcode << 24) | (offset << 5) | rt;
+ }
+ // int l
+ public static int adrp(int op, int imlo,int opcode, int imhi, int rd) {
+ return (op << 31) | (imlo << 29) |(opcode << 24) | (imhi << 5) | rd;
+ }
+
public static int load_adr(int opcode, int offset, int base, int rt) {
- return (opcode << 21) | (offset << 12) | (3 << 10) | (base << 5) | rt;
+ return (opcode << 22) | (offset << 10) | (base << 5) | rt;
}
// [Rptr+Roff]
@@ -259,13 +297,14 @@ public class arm extends Machine {
public static int load_str_imm(int opcode, int imm9, int ptr, int rt) {
return (opcode << 21) | (imm9 << 12) |(1 << 10) |(ptr << 5) | rt;
}
- public static void ldst_encode( Encoding enc, MemOpARM n, int op, Node xval ) {
+ // Todo: provide op as binary here
+ public static void ldst_encode( Encoding enc, MemOpARM n, Node xval ) {
short ptr = enc.reg(n.ptr());
short off = enc.reg(n.off());
short val = enc.reg(xval) ;
int body = n.off() == null
- ? load_str_imm(op, off, ptr, val)
- : indr_adr(op+1, off, arm.STORE_LOAD_OPTION.SXTX, 0, ptr, val);
+ ? load_str_imm(0b1111100101, off, ptr, val)
+ : indr_adr(0b11111000011, off, arm.STORE_LOAD_OPTION.SXTX, 0, ptr, val);
enc.add4(body);
}
@@ -291,10 +330,21 @@ public class arm extends Machine {
public static void f_cmp(Encoding enc, Node n) {
short reg1 = (short)(enc.reg(n.in(1))-arm.D_OFFSET);
short reg2 = (short)(enc.reg(n.in(2))-arm.D_OFFSET);
- int body = f_cmp(30, 3, reg1, reg2);
+ int body = f_cmp(0b00011110, 3, reg1, reg2);
enc.add4(body);
}
+ public static COND make_condition(String bop) {
+ return switch (bop) {
+ case "==" -> arm.COND.EQ;
+ case "!=" -> arm.COND.NE;
+ case "<" -> arm.COND.LE;
+ case "<=" -> arm.COND.LT;
+ case ">=" -> arm.COND.GT;
+ case ">" -> arm.COND.GE;
+ default -> throw Utils.TODO();
+ };
+ }
// Todo: maybe missing zero here after label << 5
public static int b_cond(int opcode, int label, COND cond) {
return (opcode << 24) | (label << 5) | cond.ordinal();
@@ -304,6 +354,10 @@ public class arm extends Machine {
return (opcode << 21) | (rm << 16) | (cond.ordinal() << 12) | (rn << 5) | rd;
}
+ // Branch with Link to Register calls a subroutine at an address in a register, setting register X30 to PC+4.
+ public static int blr(int opcode, int rd) {
+ return opcode << 10 | rd << 5;
+ }
public static int b(int opcode, int imm26) {
return (opcode << 26) | imm26;
}
@@ -389,7 +443,7 @@ public class arm extends Machine {
return switch( n ) {
case AddFNode addf -> new AddFARM(addf);
case AddNode add -> add(add);
- case AndNode and -> new AndARM(and);
+ case AndNode and -> and(and);
case BoolNode bool -> cmp(bool);
case CallNode call -> call(call);
case CastNode cast -> new CastNode(cast);
@@ -412,16 +466,16 @@ public class arm extends Machine {
case ProjNode prj -> new ProjARM(prj);
case ReadOnlyNode read -> new ReadOnlyNode(read);
case ReturnNode ret -> new RetARM(ret,ret.fun());
- case SarNode sar -> new AsrARM(sar);
- case ShlNode shl -> new LslARM(shl);
- case ShrNode shr -> new LsrARM(shr);
+ case SarNode sar -> asr(sar);
+ case ShlNode shl -> lsl(shl);
+ case ShrNode shr -> lsr(shr);
case StartNode start -> new StartNode(start);
case StopNode stop -> new StopNode(stop);
case StoreNode st -> st(st);
case SubFNode subf -> new SubFARM(subf);
case SubNode sub -> sub(sub);
case ToFloatNode tfn-> new I2F8ARM(tfn);
- case XorNode xor -> new XorARM(xor);
+ case XorNode xor -> xor(xor);
case LoopNode loop -> new LoopNode(loop);
case RegionNode region-> new RegionNode(region);
@@ -431,7 +485,7 @@ public class arm extends Machine {
private Node cmp(BoolNode bool){
Node cmp = _cmp(bool);
- return new SetARM(cmp, bool.op());
+ return new SetARM(cmp, invert(bool.op()));
}
private Node _cmp(BoolNode bool) {
if( bool instanceof BoolNode.EQF ||
@@ -494,6 +548,38 @@ public class arm extends Machine {
: new OrARM(or);
}
+ private Node xor(XorNode xor) {
+ int imm12;
+ return xor.in(2) instanceof ConstantNode off && off._con instanceof TypeInteger ti && (imm12 = imm12Logical(ti)) != -1
+ ? new XorIARM(xor, imm12)
+ : new XorARM(xor);
+ }
+
+ private Node and(AndNode and) {
+ int imm12;
+ return and.in(2) instanceof ConstantNode off && off._con instanceof TypeInteger ti && (imm12 = imm12Logical(ti)) != -1
+ ? new AndIARM(and, imm12)
+ : new AndARM(and);
+ }
+
+ private Node asr(SarNode asr) {
+ return asr.in(2) instanceof ConstantNode off && off._con instanceof TypeInteger ti && ti.value() >= 0 && ti.value() < 63
+ ? new AsrIARM(asr, (int)ti.value())
+ : new AsrARM(asr);
+ }
+
+ private Node lsl(ShlNode lsl) {
+ return lsl.in(2) instanceof ConstantNode off && off._con instanceof TypeInteger ti && ti.value() >= 0 && ti.value() < 63
+ ? new LslIARM(lsl, (int)ti.value())
+ : new LslARM(lsl);
+ }
+
+ private Node lsr(ShrNode lsr) {
+ return lsr.in(2) instanceof ConstantNode off && off._con instanceof TypeInteger ti && ti.value() >= 0 && ti.value() < 63
+ ? new LsrIARM(lsr, (int)ti.value())
+ : new LsrARM(lsr);
+ }
+
private static int off;
private static Node idx;
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
index d209ad5f..0adfe716 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
@@ -15,7 +15,6 @@ public class CallRRISC extends CallNode implements MachNode {
}
@Override public RegMask outregmap() { return null; }
- // Encoding is appended into the byte array; size is returned
@Override public void encoding( Encoding enc ) {
short rpc = enc.reg(this);
short src = enc.reg(in(_inputs._len-1));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java
index 7ce82ec7..2d253ff3 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java
@@ -14,12 +14,12 @@ public class FltRISC extends ConstantNode implements MachNode{
@Override public RegMask outregmap() { return riscv.FMASK; }
@Override public boolean isClone() { return true; }
@Override public FltRISC copy() { return new FltRISC(this); }
- // Encoding is appended into the byte array; size is returned
+
@Override public void encoding( Encoding enc ) {
enc.largeConstant(this,_con);
short dst = (short)(enc.reg(this) - riscv.F_OFFSET);
// AUIPC dst,#hi20_constant_pool
- enc.add4(riscv.u_type(0x17, dst, 0));
+ enc.add4(riscv.u_type(0b0010111, dst, 0));
// Load dst,[dst+#low12_constant_pool]
enc.add4(riscv.i_type(0x07, dst, 0x03, dst, 0));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java
index 4e73aeab..5374eae8 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java
@@ -37,7 +37,6 @@ abstract public class ImmRISC extends MachConcreteNode implements MachNode {
abstract int opcode();
abstract int func3();
- // Encoding is appended into the byte array; size is returned
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(this );
short src = enc.reg(in(1));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
index ac2eac39..d2bdcb8a 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
@@ -17,10 +17,12 @@ public class TFPRISC extends ConstantNode implements MachNode {
enc.relo(this,(TypeFunPtr)_con);
short dst = enc.reg(this);
TypeFunPtr tfp = (TypeFunPtr)_con;
- //int body = riscv.i_type(riscv.I_TYPE, dst, 0, riscv.ZERO, (int)(ti.value() & 0xFFF));
- //enc.add4(body);
- // Surely need to split into 2 ops?
- throw Utils.TODO();
+ // auipc t0,0
+ int auipc = riscv.u_type(0b0010111, dst, 0);
+ // addi t1,t0 + #0
+ int addi = riscv.i_type(0b0010011, dst, 0, dst, 0);
+ enc.add4(auipc);
+ enc.add4(addi);
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
index 4eac27a8..b9d4fa8d 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
@@ -16,7 +16,8 @@ public class CallRX86 extends CallNode implements MachNode {
}
@Override public RegMask outregmap() { return null; }
@Override public void encoding( Encoding enc ) {
- // 0xFF/2
+ // FF /2 CALL r/m64
+ // calls the function in the register
short src = enc.reg(fptr());
enc.add1(0xFF);
enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT,2,src));
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index e2a79b8f..f3075a68 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -62,4 +62,22 @@ return sqrt(farg) + sqrt(farg+2.0);
testCPU(src,"riscv" , "SystemV",17,null);
testCPU(src,"arm" , "SystemV",18,null);
}
+
+ @Test
+ public void testArray1() {
+ String src =
+ """
+ int[] !ary = new int[arg];
+ // Fill [0,1,2,3,4,...]
+ for( int i=0; i<ary#; i++ )
+ ary[i] = i;
+ // Fill [0,1,3,6,10,...]
+ for( int i=0; i<ary#-1; i++ )
+ ary[i+1] += ary[i];
+ return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6
+ """;
+ testCPU(src,"x86_64_v2", "SystemV",3,"return .[];");
+ testCPU(src,"riscv" , "SystemV",1,"return (add,.[],(mul,.[],1000));");
+ testCPU(src,"arm" , "SystemV",1,"return (add,.[],(muli,.[]));");
+ }
}