summaryrefslogtreecommitdiff
path: root/chapter23/src
diff options
context:
space:
mode:
Diffstat (limited to 'chapter23/src')
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java7
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java35
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java7
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java13
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java406
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java11
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java17
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java130
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java15
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java13
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java14
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java7
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java12
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java10
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java48
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java8
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java14
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java12
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java8
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java17
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java7
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java14
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java10
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java40
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java30
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java21
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java36
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java16
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java12
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java11
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java6
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java8
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java23
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java9
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java10
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java11
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java7
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java19
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java11
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java7
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java11
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java7
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java69
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java52
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java12
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java20
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java23
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java91
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/BrainFuckTest.java4
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/Chapter21Test.java4
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java4
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java4
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java766
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/EvalRisc5.java368
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java4
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/MergeSortTest.java2
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/TestArm64.java2
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/TestRisc5.java2
134 files changed, 386 insertions, 2482 deletions
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
index 6a16d56b..5099c02a 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/codegen/Encoding.java
@@ -19,7 +19,7 @@ import java.util.*;
* There are also a bunch of generic utilities for managing bits and bytes
* common in all encodings.
*/
-public class Encoding {
+public class Encoding implements com.seaofnodes.isa.CodeSink {
// Top-level program graph structure
public final CodeGen _code;
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java
index 1c865254..76e47ca2 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,7 +12,7 @@ public class AddARM extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return arm.WMASK; }
// ADD (shifted register)
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_ADD); }
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,Arm64.OP_ADD); }
// 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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java
index eb75c1a0..67a10b48 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,7 +12,7 @@ public class AddFARM extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return arm.DMASK; }
//FADD (scalar)
- @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,arm.OPF_OP_ADD);}
+ @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,Arm64.OPF_OP_ADD);}
// Default on double precision for now(64 bits)
// General form: "addf rd = src1 + src2
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java
index 93c9e8c3..4c635d07 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.util.SB;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
@@ -18,7 +19,7 @@ public class AddIARM extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return arm.WMASK; }
//ADD (immediate)
@Override public void encoding( Encoding enc ) {
- arm.imm_inst(enc,this, in(1), arm.OPI_ADD,_imm);
+ arm.imm_inst(enc,this, in(1), Arm64.OPI_ADD,_imm);
}
// General form: "addi rd = rs1 + imm"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java
index 77115d54..1a0365ad 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.MachConcreteNode;
import com.seaofnodes.simple.node.MachNode;
@@ -13,7 +14,7 @@ public class AndARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.WMASK; }
// AND (shifted register)
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_AND); }
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,Arm64.OP_AND); }
// 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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java
index 5b739cd3..6292e98e 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -15,10 +16,10 @@ public class AndIARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.WMASK; }
@Override public void encoding( Encoding enc ) {
- arm.imm_inst_n(enc,this, in(1), arm.OPI_AND,_imm);
+ arm.imm_inst_n(enc,this, in(1), Arm64.OPI_AND,_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(arm.decodeImm12(_imm));
+ sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" & #").p(Arm64.decodeImm12(_imm));
}
} \ No newline at end of file
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java
index b83fb3cb..77f14d4c 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -10,7 +11,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.DMASK; }
- @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,arm.OP_ASR); }
+ @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,Arm64.OP_ASR); }
@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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java
index 38373e67..7cb42eec 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.codegen.Encoding;
import com.seaofnodes.simple.codegen.RegMask;
@@ -22,7 +23,7 @@ public class AsrIARM extends MachConcreteNode implements MachNode {
short rd = enc.reg(this);
short rn = enc.reg(in(1));
assert _imm > 0;
- enc.add4(arm.imm_shift(arm.OPI_ASR,_imm, 0b111111, rn, rd));
+ enc.add4(Arm64.imm_shift(Arm64.OPI_ASR,_imm, 0b111111, rn, rd));
}
// General form: "asri rd = rs1 >> imm"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java
index b9ede544..127f17ff 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -35,10 +36,10 @@ public class BranchARM extends IfNode implements MachNode, RIPRelSize {
// by comparison (or sub). No need for regs because it uses flags
if( in(1)!=null ) {
// B.cond
- enc.add4( arm.b_cond(arm.OP_BRANCH, 0, arm.make_condition(_bop)) );
+ enc.add4( Arm64.b_cond(Arm64.OP_BRANCH, 0, Arm64.make_condition(_bop)) );
} else {
if( _bop=="!=" ) return; // Inverted, no code
- enc.add4(arm.b(arm.OP_UJMP, 0));
+ enc.add4(Arm64.b(Arm64.OP_UJMP, 0));
}
enc.jump(this,cproj(0));
}
@@ -55,7 +56,7 @@ public class BranchARM extends IfNode implements MachNode, RIPRelSize {
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
assert !( in(1)==null && _bop=="!=" ); // Inverted never-node, no code no patch
if( opLen==4 ) {
- enc.patch4(opStart,arm.b_cond(arm.OP_BRANCH, delta, arm.make_condition(_bop)));
+ enc.patch4(opStart,Arm64.b_cond(Arm64.OP_BRANCH, delta, Arm64.make_condition(_bop)));
} else {
throw Utils.TODO();
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
index 427cf2e2..e1717cb3 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeFunPtr;
@@ -30,7 +31,7 @@ public class CallARM extends CallNode implements MachNode, RIPRelSize {
if( fun==null ) enc.external(this,_name);
else enc.relo(this);
// BL
- enc.add4(arm.b(arm.OP_CALL,0)); // Target patched at link time
+ enc.add4(Arm64.b(Arm64.OP_CALL,0)); // Target patched at link time
}
// Delta is from opcode start, but X86 measures from the end of the 5-byte encoding
@@ -38,7 +39,7 @@ public class CallARM extends CallNode implements MachNode, RIPRelSize {
// Delta is from opcode start
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
- enc.patch4(opStart,arm.b(arm.OP_CALL,delta));
+ enc.patch4(opStart,Arm64.b(Arm64.OP_CALL,delta));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
index c84aa9e5..1949ae46 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -19,7 +20,7 @@ public class CallRRARM extends CallNode implements MachNode {
// Needs a register, typically a jump-and-link-register opcode
// blr
short self = enc.reg(this);
- enc.add4(arm.blr(arm.OP_CALLRARM, self));
+ enc.add4(Arm64.blr(Arm64.OP_CALLRARM, self));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java
index 794ff0c9..1bd9c372 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,7 +12,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_subs(enc,this,arm.OP_CMP); }
+ @Override public void encoding( Encoding enc ) { arm.r_reg_subs(enc,this,Arm64.OP_CMP); }
// General form: "cmp rs1, rs2"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java
index f84a1649..cd4dd9cf 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -28,7 +29,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_subs(enc,in(1),in(1), arm.OPI_CMP,_imm); }
+ @Override public void encoding( Encoding enc ) { arm.imm_inst_subs(enc,in(1),in(1), Arm64.OPI_CMP,_imm); }
// General form: "cmp rs1, 1"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java
index de254eeb..e94b6491 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -10,7 +11,7 @@ public class DivARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.WMASK; }
// SDIV
- @Override public void encoding( Encoding enc ) { arm.madd(enc,this,arm.OP_DIV,3); }
+ @Override public void encoding( Encoding enc ) { arm.madd(enc,this,Arm64.OP_DIV,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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java
index 813bebe4..68ad6047 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,7 +12,7 @@ public class DivFARM extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return arm.DMASK; }
// FDIV (scalar)
- @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,arm.OPF_DIV); }
+ @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,Arm64.OPF_DIV); }
// 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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java
index 26a237d0..814a82c2 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeInteger;
@@ -22,7 +23,7 @@ public class ExtendARM extends MachConcreteNode {
@Override public void encoding(Encoding enc) {
short dst = enc.reg(this), src = enc.reg(in(1));
// SBFM/UBFM aliases: sign/zero extend the low byte, short or int.
- enc.add4(arm.imm_shift(_signed ? arm.OPI_ASR : arm.OPI_LSR,0,_bits-1,src,dst));
+ enc.add4(Arm64.imm_shift(_signed ? Arm64.OPI_ASR : Arm64.OPI_LSR,0,_bits-1,src,dst));
}
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1)));
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
index b47b65ad..dc21e075 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -20,7 +21,7 @@ public class FloatARM extends ConstantNode implements MachNode, RIPRelSize {
@Override public void encoding( Encoding enc ) {
enc.largeConstant(this,_con,0,-1/*TODO: ARM-style ELF patching*/);
short dst = (short)(enc.reg(this) - arm.D_OFFSET);
- enc.add4(arm.load_pc(arm.OPF_ARM, 0, dst));
+ enc.add4(Arm64.load_pc(Arm64.OPF_ARM, 0, dst));
}
// Delta is from opcode start.
@@ -29,7 +30,7 @@ public class FloatARM extends ConstantNode implements MachNode, RIPRelSize {
// Delta is from opcode start
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
short dst = (short)(enc.reg(this) - arm.D_OFFSET);
- enc.patch4(opStart, arm.load_pc(arm.OPF_ARM, delta, dst));
+ enc.patch4(opStart, Arm64.load_pc(Arm64.OPF_ARM, delta, dst));
}
// Human-readable form appended to the SB. Things like the encoding,
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java
index b9e85202..17cafcde 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.FunNode;
import com.seaofnodes.simple.node.MachNode;
@@ -16,6 +17,6 @@ public class FunARM extends FunNode implements MachNode {
int sz = _frameAdjust;
if( sz == 0 ) return; // Skip if no frame adjust
if( sz >= 1L<<12 ) throw Utils.TODO();
- enc.add4(arm.imm_inst(arm.OPI_SUB, sz, arm.RSP, arm.RSP));
+ enc.add4(Arm64.imm_inst(Arm64.OPI_SUB, sz, arm.RSP, arm.RSP));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java
index f1fa162f..b1c30afc 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -13,7 +14,7 @@ public class I2F8ARM extends MachConcreteNode implements MachNode {
// SCVTF
short self = (short)(enc.reg(this )-arm.D_OFFSET);
short reg1 = enc.reg(in(1));
- int body = arm.float_cast(arm.OP_FLOAT_C, 1, reg1, self);
+ int body = Arm64.float_cast(Arm64.OP_FLOAT_C, 1, reg1, self);
enc.add4(body);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
index ee74b95e..7a9e74c6 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -21,39 +22,7 @@ public class IntARM extends ConstantNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short self = enc.reg(this);
long x = _con==Type.NIL ? 0 : ((TypeInteger)_con).value();
- int nb0 = 0;
- int nb1 = 0;
- // Count number of 0000 and FFFF blocks
- for (int i=0; i<64; i+=16) {
- int block = (int)(x >> i) & 0xFFFF;
- if (block == 0) nb0++;
- if (block == 0xFFFF) nb1++;
- }
- int pattern;
- int op;
- if(nb0 >= nb1) {
- // More 0 blocks then F blocks, use movz
- pattern = 0;
- op = arm.OP_MOVZ;
- } else {
- // More F blocks then 0 blocks, use movn
- pattern = 0xFFFF;
- op = arm.OP_MOVN;
- }
- int invert = pattern;
- for (int i=0; i<4; i++) {
- int block = (int)x & 0xFFFF;
- x >>= 16;
- if (block != pattern) {
- enc.add4(arm.mov(op, i, block ^ invert, self));
- op = arm.OP_MOVK;
- invert = 0;
- }
- }
- if (op != arm.OP_MOVK) {
- // All blocks are the same, special case
- enc.add4(arm.mov(op, 0, 0, self));
- }
+ Arm64.constant(enc,self,x);
}
// Human-readable form appended to the SB. Things like the encoding,
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
index 8967d654..f3bbbbeb 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.LoadNode;
import com.seaofnodes.simple.node.Node;
@@ -18,9 +19,9 @@ public class LoadARM extends MemOpARM {
@Override public String op() { return "ld"+_sz; }
@Override public RegMask outregmap() { return size() >= 4 ? arm.MEM_MASK : arm.RMASK; }
- private static final int[] OP_LOADS = new int[]{ arm.OP_LOAD_IMM_8, arm.OP_LOAD_IMM_16, arm.OP_LOAD_IMM_32, arm.OP_LOAD_IMM_64, };
+ private static final int[] OP_LOADS = new int[]{ Arm64.OP_LOAD_IMM_8, Arm64.OP_LOAD_IMM_16, Arm64.OP_LOAD_IMM_32, Arm64.OP_LOAD_IMM_64, };
- private static final int[] OP_LOAD_RS = new int[]{ arm.OP_LOAD_R_8 , arm.OP_LOAD_R_16 , arm.OP_LOAD_R_32 , arm.OP_LOAD_R_64, };
+ private static final int[] OP_LOAD_RS = new int[]{ Arm64.OP_LOAD_R_8 , Arm64.OP_LOAD_R_16 , Arm64.OP_LOAD_R_32 , Arm64.OP_LOAD_R_64, };
// ldr(immediate - unsigned offset) | ldr(register)
@Override public void encoding( Encoding enc ) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java
index 80ce493f..954cfac2 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,7 +12,7 @@ public class LslARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.WMASK; }
- @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,arm.OP_LSL); }
+ @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,Arm64.OP_LSL); }
@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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java
index 7fe16cbe..b32153ab 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.codegen.Encoding;
import com.seaofnodes.simple.codegen.RegMask;
@@ -24,7 +25,7 @@ public class LslIARM extends MachConcreteNode implements MachNode {
assert _imm > 0;
// UBFM <Xd>, <Xn>, #(-<shift> MOD 64), #(63-<shift>)
// immr must be (-<shift> MOD 64) = 64 - shift
- enc.add4(arm.imm_shift(arm.OPI_LSL, 64 - _imm, (64 - _imm) - 1, rn, rd));
+ enc.add4(Arm64.imm_shift(Arm64.OPI_LSL, 64 - _imm, (64 - _imm) - 1, rn, rd));
}
// General form: "lsli rd = rs1 << imm"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java
index fc005e04..91be34e3 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,7 +12,7 @@ public class LsrARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.WMASK; }
- @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,arm.OP_LSR); }
+ @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,Arm64.OP_LSR); }
@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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java
index 78844b0a..243ce968 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -19,7 +20,7 @@ public class LsrIARM extends MachConcreteNode implements MachNode {
short rd = enc.reg(this);
short rn = enc.reg(in(1));
assert _imm > 0;
- enc.add4(arm.imm_shift(arm.OPI_LSR,_imm, 0b111111, rn,rd));
+ enc.add4(Arm64.imm_shift(Arm64.OPI_LSR,_imm, 0b111111, rn,rd));
}
// General form: "lsri rd = rs1 >>> imm"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java
index 9257f25b..dfbe5e06 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.print.ExprPrinter;
import com.seaofnodes.simple.codegen.*;
@@ -64,8 +65,8 @@ public abstract class MemOpARM extends MemOpNode implements MachNode {
val -= arm.D0;
}
int body = off() == null
- ? arm.load_str_imm(opcode_imm, _off, ptr, val, size)
- : arm.indr_adr(opcode_reg, off, arm.STORE_LOAD_OPTION.SXTX, 0, ptr, val);
+ ? Arm64.load_str_imm(opcode_imm, _off, ptr, val, size)
+ : Arm64.indr_adr(opcode_reg, off, Arm64.STORE_LOAD_OPTION.SXTX, 0, ptr, val);
enc.add4(body);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java
index a23ec75b..f598cefb 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,7 +12,7 @@ public class MulARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.WMASK; }
- @Override public void encoding( Encoding enc ) { arm.madd(enc,this,arm.OP_MUL,31); }
+ @Override public void encoding( Encoding enc ) { arm.madd(enc,this,Arm64.OP_MUL,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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java
index 73ebbf00..a4f81fd4 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -9,7 +10,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,arm.OPF_MUL); }
+ @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,Arm64.OPF_MUL); }
// 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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java
index c1aad15f..7110df62 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,8 +12,8 @@ public class NewARM extends NewNode implements MachNode, RIPRelSize {
@Override public void encoding( Encoding enc ) {
// BL(branch with link)
enc.external(this,"calloc").
- add4(arm.mov(arm.OP_MOVZ, 0, 1, 0)). // movz x0,#1
- add4(arm.b(arm.OP_CALL, 0));
+ add4(Arm64.mov(Arm64.OP_MOVZ, 0, 1, 0)). // movz x0,#1
+ add4(Arm64.b(Arm64.OP_CALL, 0));
}
// Patch is for running "new" in a JIT.
@@ -24,7 +25,7 @@ public class NewARM extends NewNode implements MachNode, RIPRelSize {
@Override public void patch(Encoding enc, int opStart, int opLen, int delta ) {
// Negative patches are JIT emulator targets.
if( opStart+delta < 0 ) {
- enc.patch4(opStart+4, arm.b_calloc(arm.OP_CALL, delta-4));
+ enc.patch4(opStart+4, Arm64.b_calloc(Arm64.OP_CALL, delta-4));
} else {
throw Utils.TODO();
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
index 027a8128..8cf72aaf 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.node.MachConcreteNode;
@@ -17,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(arm.OP_SUBS, 0, reg1, self);
+ int subs = Arm64.imm_inst(Arm64.OP_SUBS, 0, reg1, self);
enc.add4(subs);
- int cset = arm.cond_set(arm.OP_CSET, 31, arm.COND.EQ, 63, reg1);
+ int cset = Arm64.cond_set(Arm64.OP_CSET, 31, Arm64.COND.EQ, 63, reg1);
enc.add4(cset);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java
index e8245749..5b7264ec 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,7 +12,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.WMASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_OR); }
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,Arm64.OP_OR); }
// 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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java
index a48caa51..86d07bee 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -15,7 +16,7 @@ public class OrIARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.WMASK; }
@Override public void encoding( Encoding enc ) {
- arm.imm_inst_n(enc, this, in(1), arm.OPI_OR, _imm);
+ arm.imm_inst_n(enc, this, in(1), Arm64.OPI_OR, _imm);
}
// General form: "ori rd = rs1 | imm"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java
index 4597666b..a7ed5073 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.*;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
@@ -9,7 +10,7 @@ public class RetARM extends ReturnNode implements MachNode {
@Override public void encoding( Encoding enc ) {
int frameAdjust = ((FunARM)fun())._frameAdjust;
if( frameAdjust > 0 )
- enc.add4(arm.imm_inst(arm.OPI_ADD, frameAdjust, arm.RSP, arm.RSP));
- enc.add4(arm.ret(arm.OP_RET));
+ enc.add4(Arm64.imm_inst(Arm64.OPI_ADD, frameAdjust, arm.RSP, arm.RSP));
+ enc.add4(Arm64.ret(Arm64.OP_RET));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java
index 01b46b8d..1cda4787 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -20,7 +21,7 @@ public class SetARM extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return arm.WMASK; }
@Override public void encoding( Encoding enc ) {
- int body = arm.cset(arm.OP_CSET,0b11111, arm.make_condition(_bop), 0b011111, enc.reg(this));
+ int body = Arm64.cset(Arm64.OP_CSET,0b11111, Arm64.make_condition(_bop), 0b011111, enc.reg(this));
enc.add4(body);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java
index 5af45892..f93f0f24 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.FunNode;
import com.seaofnodes.simple.node.Node;
@@ -26,7 +27,7 @@ public class SplitARM extends SplitNode {
}
int off = enc._fun.computeStackOffset(enc._code,dst);
if( srcX ) src -= arm.D_OFFSET;
- enc.add4(arm.load_str_imm(arm.OP_STORE_IMM_64, off, arm.RSP, src, 8));
+ enc.add4(Arm64.load_str_imm(Arm64.OP_STORE_IMM_64, off, arm.RSP, src, 8));
return;
}
@@ -34,26 +35,26 @@ public class SplitARM extends SplitNode {
// Load from SP
int off = enc._fun.computeStackOffset(enc._code,src);
if( dstX ) dst -= arm.D_OFFSET;
- enc.add4(arm.load_str_imm(arm.OP_LOAD_IMM_64, off, arm.RSP, dst, 8));
+ enc.add4(Arm64.load_str_imm(Arm64.OP_LOAD_IMM_64, off, arm.RSP, dst, 8));
return;
}
// pick opcode based on regs
if(!dstX && !srcX) {
// GPR->GPR
- enc.add4(arm.mov_reg(arm.OP_MOV, src, dst));
+ enc.add4(Arm64.mov_reg(Arm64.OP_MOV, src, dst));
} else if(dstX && srcX) {
// FPR->FPR
// fmov reg
- enc.add4(arm.f_mov_reg(arm.OP_FMOV_REG, src - arm.D_OFFSET,dst - arm.D_OFFSET));
+ enc.add4(Arm64.f_mov_reg(Arm64.OP_FMOV_REG, src - arm.D_OFFSET,dst - arm.D_OFFSET));
} else if(!srcX && dstX) {
// GPR->FPR
// FMOV(general) 64 bits to DOUBLE-PRECISION
- enc.add4(arm.f_mov_general(arm.OP_FMOV, 0b01, 0, 0b111, src, dst - arm.D_OFFSET));
+ enc.add4(Arm64.f_mov_general(Arm64.OP_FMOV, 0b01, 0, 0b111, src, dst - arm.D_OFFSET));
} else if( srcX && !dstX) {
//FPF->GPR
// FMOV(general) DOUBLE-PRECISION to 64 bits
- enc.add4(arm.f_mov_general(arm.OP_FMOV, 0b01, 0, 0b110, src - arm.D_OFFSET, dst));
+ enc.add4(Arm64.f_mov_general(Arm64.OP_FMOV, 0b01, 0, 0b110, src - arm.D_OFFSET, dst));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
index 4fd8ac79..2cc54f76 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.node.StoreNode;
@@ -22,9 +23,9 @@ public class StoreARM extends MemOpARM {
@Override public String op() { return "st"+_sz; }
@Override public RegMask outregmap() { return null; }
- private static final int[] OP_STORES = new int[]{ arm.OP_STORE_IMM_8, arm.OP_STORE_IMM_16, arm.OP_STORE_IMM_32, arm.OP_STORE_IMM_64, };
+ private static final int[] OP_STORES = new int[]{ Arm64.OP_STORE_IMM_8, Arm64.OP_STORE_IMM_16, Arm64.OP_STORE_IMM_32, Arm64.OP_STORE_IMM_64, };
- private static final int[] OP_STORE_RS = new int[]{ arm.OP_STORE_R_8, arm.OP_STORE_R_16, arm.OP_STORE_R_32, arm.OP_STORE_R_64, };
+ private static final int[] OP_STORE_RS = new int[]{ Arm64.OP_STORE_R_8, Arm64.OP_STORE_R_16, Arm64.OP_STORE_R_32, Arm64.OP_STORE_R_64, };
@Override public void encoding( Encoding enc ) {
ldst_encode(enc, OP_STORES[Integer.numberOfTrailingZeros(size())], OP_STORE_RS[_declaredType.log_size()], val(), size());
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java
index e3b95e50..fd5cd4de 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -10,7 +11,7 @@ public class SubARM extends MachConcreteNode implements MachNode {
@Override public RegMask regmap(int i) { return arm.RMASK; }
@Override public RegMask outregmap() { return arm.WMASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_SUB); }
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,Arm64.OP_SUB); }
// General form: "sub # rd = rs1 - rs2"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java
index a252e542..1a751434 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -9,7 +10,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,arm.OPF_SUB); }
+ @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,Arm64.OPF_SUB); }
// 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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java
index b50107c9..b2c0b2ed 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.node.MachConcreteNode;
@@ -18,7 +19,7 @@ public class SubIARM extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return arm.WMASK; }
@Override public void encoding( Encoding enc ) {
- arm.imm_inst(enc,this, in(1), arm.OPI_SUB,_imm);
+ arm.imm_inst(enc,this, in(1), Arm64.OPI_SUB,_imm);
}
// General form: "subi rd = rs1 - imm"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
index 29d490ef..98a56089 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -19,10 +20,10 @@ public class TFPARM extends ConstantNode implements MachNode, RIPRelSize {
enc.relo(this);
short self = enc.reg(this);
// adrp x0, 0
- int adrp = arm.adrp(1,0, arm.OP_ADRP, 0,self);
+ int adrp = Arm64.adrp(1,0, Arm64.OP_ADRP, 0,self);
// add x0, x0, 0
enc.add4(adrp);
- arm.imm_inst(enc,arm.OPI_ADD,0, 0);
+ arm.imm_inst(enc,Arm64.OPI_ADD,0, 0);
}
@Override public byte encSize(int delta) {
@@ -39,9 +40,9 @@ public class TFPARM extends ConstantNode implements MachNode, RIPRelSize {
delta = target-base;
int adrp_delta = delta >> 12;
// patch upper 20 bits via adrp
- enc.patch4(opStart, arm.adrp(1, adrp_delta & 0b11, 0b10000, adrp_delta >> 2, rpc));
+ enc.patch4(opStart, Arm64.adrp(1, adrp_delta & 0b11, 0b10000, adrp_delta >> 2, rpc));
// low 12 bits via add
- enc.patch4(opStart+4, arm.imm_inst_l(arm.OPI_ADD, delta & 0xfff, rpc));
+ enc.patch4(opStart+4, Arm64.imm_inst_l(Arm64.OPI_ADD, delta & 0xfff, rpc));
} else {
// should not happen as one instruction is 4 byte, and TFP arm encodes 2.
throw Utils.TODO();
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java
index cdcaa433..d1cafa96 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -19,9 +20,9 @@ public class TMPARM extends ConstantNode implements MachNode, RIPRelSize {
enc.largeConstant(this,((TypeMemPtr)_con)._obj,0,-1);
short dst = enc.reg(this);
// adrp x0, 0
- enc.add4(arm.adrp(1,0, arm.OP_ADRP, 0,dst));
+ enc.add4(Arm64.adrp(1,0, Arm64.OP_ADRP, 0,dst));
// add x0, x0, 0
- arm.imm_inst(enc,arm.OPI_ADD,0, dst);
+ arm.imm_inst(enc,Arm64.OPI_ADD,0, dst);
}
@Override public byte encSize(int delta) {
@@ -38,9 +39,9 @@ public class TMPARM extends ConstantNode implements MachNode, RIPRelSize {
delta = target-base;
int adrp_delta = delta >> 12;
// patch upper 20 bits via adrp
- enc.patch4(opStart, arm.adrp(1, adrp_delta & 0b11, 0b10000, adrp_delta >> 2, dst));
+ enc.patch4(opStart, Arm64.adrp(1, adrp_delta & 0b11, 0b10000, adrp_delta >> 2, dst));
// low 12 bits via add
- enc.patch4(opStart+4, arm.imm_inst_l(arm.OPI_ADD, delta & 0xfff, dst));
+ enc.patch4(opStart+4, Arm64.imm_inst_l(Arm64.OPI_ADD, delta & 0xfff, dst));
} else {
throw Utils.TODO();
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java
index ce4f523c..aecd02bb 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
@@ -19,7 +20,7 @@ public class UJmpARM extends CFGNode implements MachNode, RIPRelSize {
@Override public Node idealize() { throw Utils.TODO(); }
@Override public void encoding( Encoding enc ) {
enc.jump(this,uctrl());
- int body = arm.b(arm.OP_UJMP, 0);
+ int body = Arm64.b(Arm64.OP_UJMP, 0);
enc.add4(body);
}
@@ -33,7 +34,7 @@ public class UJmpARM extends CFGNode implements MachNode, RIPRelSize {
// Delta is from opcode start
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
if( opLen==4 ) {
- enc.patch4(opStart,arm.b(arm.OP_UJMP, delta));
+ enc.patch4(opStart,Arm64.b(Arm64.OP_UJMP, delta));
} else {
throw Utils.TODO();
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java
index 52bda021..d56397a3 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -10,7 +11,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.WMASK; }
- @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_XOR); }
+ @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,Arm64.OP_XOR); }
// 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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java
index 23b29644..12143ccd 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.node.MachConcreteNode;
@@ -19,7 +20,7 @@ public class XorIARM extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return arm.WMASK; }
// General form: "xori rd = rs1 ^ imm"
- @Override public void encoding( Encoding enc ) { arm.imm_inst_n(enc,this, in(1), arm.OPI_XOR,_imm); }
+ @Override public void encoding( Encoding enc ) { arm.imm_inst_n(enc,this, in(1), Arm64.OPI_XOR,_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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
index c39c5f74..e7119608 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
@@ -1,5 +1,7 @@
package com.seaofnodes.simple.node.cpus.arm;
+import com.seaofnodes.isa.Arm64;
+import static com.seaofnodes.isa.Arm64.*;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.*;
@@ -81,102 +83,6 @@ public class arm extends Machine {
static final RegMask D6_MASK = new RegMask(D6);
static final RegMask D7_MASK = new RegMask(D7);
- // major opcode: OP
- public static int OP_ADD = 0b10_001_011;
- public static int OPF_ADD = 0b00_011_110;
- public static int OPF_OP_ADD = 0b00_101_0;
- public static int OPI_ADD = 0b10_010_00100;
-
- public static int OPI_SUB = 0b11_010_00100;
- public static int OP_UJMP = 0b000101;
-
- public static int OP_ADRP = 0b10000;
-
- public static int OP_ASR = 0b1010;
- public static int OPI_ASR = 0b10_0100_1101;
-
- public static int OP_LSL = 0b1000;
- public static int OPI_LSL =0b1101001101;
-
- public static int OP_LSR = 0b1001;
- public static int OPI_LSR = 0b1101001101;
-
- public static int OP_BRANCH = 0b01_0101_00;
- public static int OP_CALL = 0b10_010_1;
-
- public static int OP_CALLRARM = 0b1101011000111111000000;
-
- public static int OP_SUBS = 0b1111000100;
- public static int OP_CSET = 0b10011010100;
- public static int OP_CMP = 0b11101011;
- public static int OPI_CMP = 0b1111000100;
-
- public static int OP_DIV = 0b10011010110;
- public static int OPF_DIV = 0b000110;
-
- public static int OP_MUL = 0b10011011000;
- public static int OPF_MUL = 0b10;
-
- public static int OPF_ARM = 0b01011100;
-
- public static int OP_FLOAT_C = 0b10011110;
-
- public static int OP_XOR = 0b11001010;
- public static int OPI_XOR = 0b110100100;
-
- public static int OP_AND = 0b10_0010_10;
- public static int OPI_AND = 0b10_0100_100;
-
- public static int OP_OR = 0b10101010;
- public static int OPI_OR = 0b101100100;
-
- public static int OP_SUB = 0b11001011;
- public static int OPF_SUB = 0b1110;
-
- public static int OP_MOVK = 0b111100101;
- public static int OP_MOVN = 0b100100101;
- public static int OP_MOVZ = 0b110100101;
-
- public static int OP_RET = 0b1101011001011111000000;
- // Store/load opcodes
- public static int OP_LOAD_R_64 = 0b11111000011;
- public static int OP_LOAD_R_32 = 0b10111000011;
- public static int OP_LOAD_R_16 = 0b01111000010;
- public static int OP_LOAD_R_8 = 0b00111000011;
-
- public static int OP_LOAD_IMM_64 = 0b1111100101;
- public static int OP_LOAD_IMM_32 = 0b1011100101;
- public static int OP_LOAD_IMM_16 = 0b0111100101;
- public static int OP_LOAD_IMM_8 = 0b0011100101;
-
- // load
- public static int OPF_LOAD_R_64 = 0b11111100011;
- public static int OPF_LOAD_R_32 = 0b10111100011;
-
- public static int OPF_LOAD_IMM_64 = 0b1111110101;
- public static int OPF_LOAD_IMM_32 = 0b1011110101;
-
- public static int OP_STORE_R_64 = 0b11111000001;
- public static int OP_STORE_R_32 = 0b10111000001;
- public static int OP_STORE_R_16 = 0b01111000001;
- public static int OP_STORE_R_8 = 0b00111000001;
-
- public static int OP_STORE_IMM_64 = 0b1111100100;
- public static int OP_STORE_IMM_32 = 0b1011100100;
- public static int OP_STORE_IMM_16 = 0b0111100100;
- public static int OP_STORE_IMM_8 = 0b0011100100;
-
- public static int OPF_STORE_R_64 = 0b11111100001;
- public static int OPF_STORE_R_32 = 0b10111100001;
-
- public static int OPF_STORE_IMM_32 = 0b1011110100;
- public static int OPF_STORE_IMM_64 = 0b1111110100;
-
-
- public static int OP_FMOV = 0b10011110;
- public static int OP_FMOV_REG = 0b00011110;
- // https://docsmirror.github.io/A64/2023-06/mov_orr_log_shift.html
- public static int OP_MOV = 0b10101010000;
// Calling convention; returns a machine-specific register
// for incoming argument idx.
// index 0 for control, 1 for memory, real args start at index 2
@@ -202,54 +108,6 @@ public class arm extends Machine {
};
// ARM ENCODING
- public enum OPTION {
- UXTB,
- UXTH,
- UXTX,
- SXTB,
- SXTH,
- SXTW,
- SXTX,
- }
-
- static public int cset(int opcode, int rm, COND cond, int rn, int rd) {
- assert 0 <= rm && rm < 32;
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- return (opcode << 21) | (rm << 15) | (cond.ordinal() << 12) | (rn << 5) | rd;
- }
-
- static public int cset(int opcode, COND cond, int rn, int rd) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- return (opcode << 16) | (cond.ordinal() << 12) | (rn << 5) | rd;
- }
-
- public enum STORE_LOAD_OPTION {
- UXTW, // base+ u32 index [<< logsize]
- UXTX, // base+ u64 index [<< logsize]
- SXTW, // base+ s32 index [<< logsize]
- SXTX, // base+ s64 index [<< logsize]
- }
-
- public enum COND {
- EQ,
- NE,
- CS,
- CC,
- MI,
- PL,
- VS,
- VC,
- HI,
- LS,
- GE,
- LT,
- GT,
- LE,
- AL,
- NV
- }
// True if signed 9-bit immediate
private static boolean imm9(TypeInteger ti) {
@@ -262,55 +120,10 @@ public class arm extends Machine {
return ti.isConstant() && ((ti.value()<<52)>>52) == ti.value();
}
-
// Can we encode this in ARM's 12-bit LOGICAL immediate form?
// Some combination of shifted bit-masks.
private static int imm12Logical(TypeInteger ti) {
- if( !ti.isConstant() ) 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
-
- // Rotate until:
- // The number is negative (MSB is 1)
- // Or the LSB is not 1
- while (val < 0 || (val & 1)==0) {
- // circular rotation
- val = (val >>> 63) | (val << 1);
- immr++;
- }
- // Start by assuming that val might be made of two 32-bit chunks that repeat.
- 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 opcode
- public static int imm_inst(int opcode, int imm12, int rn, int rd) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- assert opcode >=0 && imm12 >= 0; // Caller zeros high order bits
- return (opcode << 22) | (imm12 << 10) | (rn << 5) | rd;
- }
-
- public static int imm_shift(int opcode, int imm, int imms, int rn, int rd) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- return (opcode << 22) | (1 << 22) | (imm << 16) | (imms << 10) | (rn << 5) | rd;
+ return ti.isConstant() ? Arm64.logicalImmediate(ti.value()) : -1;
}
public static void imm_inst(Encoding enc, Node n,Node n2, int opcode, int imm12) {
@@ -322,64 +135,46 @@ public class arm extends Machine {
opcode ^= OPI_ADD ^ OPI_SUB;
imm12 = -imm12;
}
- int body = imm_inst(opcode, imm12&0xFFF, reg1, self);
+ int body = Arm64.imm_inst(opcode, imm12&0xFFF, reg1, self);
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);
+ int body = Arm64.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);
+ int body = Arm64.imm_inst(opcode, imm12&0xFFF, self, self);
enc.add4(body);
}
public static void imm_inst_n(Encoding enc, Node n, Node n2, int opcode, int imm13) {
short self = enc.reg(n);
short reg1 = enc.reg(n2);
- int body = imm_inst_n(opcode, imm13, reg1, self);
+ int body = Arm64.imm_inst_n(opcode, imm13, reg1, self);
enc.add4(body);
}
- // nth bit comes from immediate and not opcode
- public static int imm_inst_n(int opcode, int imm13, int rn, int rd) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- assert 0 <= imm13 && imm13 <= 0x1FFF;
- return (opcode << 23) | (imm13 << 10) | (rn << 5) | rd;
- }
-
- public static int imm_inst_l(int opcode, int imm12, int self) {
- int body = imm_inst(opcode, imm12&0xFFF, self, self);
- return body;
- }
-
// for cases where rs1 and dst are the same, eg add x0, x0, 1
public static int imm_inst_l(Encoding enc, Node n, int opcode, int imm12) {
short self = enc.reg(n);
short reg1 = enc.reg(n.in(1));
- int body = imm_inst(opcode, imm12&0xFFF, reg1, self);
+ int body = Arm64.imm_inst(opcode, imm12&0xFFF, reg1, self);
return body;
}
// for normal add, reg1, reg2 cases (reg-to-reg)
// using shifted-reg form
- public static int r_reg(int opcode, int shift, int rm, int imm6, int rn, int rd) {
- 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;
- }
+
public static void r_reg(Encoding enc, Node n, int opcode) {
short self = enc.reg(n);
short reg1 = enc.reg(n.in(1));
short reg2 = enc.reg(n.in(2));
- int body = r_reg(opcode, 0, reg2, 0, reg1, self >= 32 ? reg1: self);
+ int body = Arm64.r_reg(opcode, 0, reg2, 0, reg1, self >= 32 ? reg1: self);
enc.add4(body);
}
@@ -387,187 +182,43 @@ public class arm extends Machine {
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);
+ int body = Arm64.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) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rm && rm < 32;
- assert 0 <= rd && rd < 32;
- return (opcode << 21) | (rm << 16) | (op2 << 10) | (rn << 5) | rd;
- }
public static void shift_reg(Encoding enc, Node n, int op2) {
short self = enc.reg(n);
short reg1 = enc.reg(n.in(1));
short reg2 = enc.reg(n.in(2));
- int body = shift_reg(0b10011010110, reg2, op2, reg1, self);
+ int body = Arm64.shift_reg(0b10011010110, reg2, op2, reg1, self);
enc.add4(body);
}
// MUL can be considered an alias for MADD with the third operand Ra being set to 0
- public static int madd(int opcode, int rm, int ra, int rn, int rd) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- assert 0 <= rm && rm < 32;
- return (opcode << 21) | (rm << 16) | (ra << 10) | (rn << 5) | rd;
- }
+
public static void madd(Encoding enc, Node n, int opcode, int ra) {
short self = enc.reg(n);
short reg1 = enc.reg(n.in(1));
short reg2 = enc.reg(n.in(2));
- int body = madd(opcode, reg2, ra, reg1, self);
+ int body = Arm64.madd(opcode, reg2, ra, reg1, self);
enc.add4(body);
}
- // encodes movk, movn, and movz
- public static int mov(int opcode, int shift, int imm16, int rd) {
- assert 0 <= rd && rd < 32;
- return (opcode << 23) | (shift << 21) | (imm16 << 5) | rd;
- }
-
- public static int mov_reg(int opcode, int src, int rd) {
- assert 0 <= rd && rd < 32;
- return (opcode << 21) | (src << 16) | 0b11111 << 5 | rd;
- }
-
- public static int ret(int opcode) {
- return (opcode << 10) | (X30 << 5);
- }
-
- // FMOV (scalar, immediate)
- public static int f_scalar(int opcode, int ftype, int rm, int op, int rn, int rd) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- assert 0 <= rm && rm < 32;
- return (opcode << 24) | (ftype << 22) | (1 << 21) | (rm << 16) | (op << 10) | (rn << 5) | rd;
- }
-
- public static int f_mov_reg(int opcode, int rn, int rd) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- return (opcode << 24) | (0b01100000010000 << 10) | (rn << 5) | rd;
- }
- public static int f_mov_general(int opcode, int ftype, int rmode, int opcode1, int rn, int rd) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rd && rd < 32;
- return (opcode << 24) |(ftype << 22) | (1 << 21) | (rmode << 19) | (opcode1 << 16) | (rn << 5) | rd;
- }
public static void f_scalar(Encoding enc, Node n, int op ) {
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(0b00011110, 1, reg2, op, reg1, self);
+ int body = Arm64.f_scalar(0b00011110, 1, reg2, op, reg1, self);
enc.add4(body);
}
- // share same encoding with LDR (literal, SIMD&FP) flavour
- public static int load_pc(int opcode, int offset, int rt) {
- offset>>=2;
- return (opcode << 24) | (offset << 5) | rt;
- }
- // int l
- public static int adrp(int op, int imlo,int opcode, int imhi, int rd) {
- assert 0 <= rd && rd < 32;
- return (op << 31) | (imlo << 29) |(opcode << 24) | (imhi << 5) | rd;
- }
-
- // [Rptr+Roff]
- public static int indr_adr(int opcode, int off, STORE_LOAD_OPTION option, int s, int ptr, int rt) {
- assert 0 <= ptr && ptr < 32;
- assert 0 <= rt && rt < 32;
- return (opcode << 21) | (off << 16) | (option.ordinal() << 13) | (s << 12) | (2 << 10) | (ptr << 5) | rt;
- }
- // [Rptr+imm9]
- public static int load_str_imm(int opcode, int imm12, int ptr, int rt, int size) {
- assert 0 <= ptr && ptr < 32;
- assert 0 <= rt && rt < 32;
-
- if(size == 8) imm12 = imm12 >> 3;
- if(size == 4) imm12 = imm12 >> 2;
- if(size == 2) imm12 = imm12 >> 1;
- // size == 1 imm12 = imm12
- return (opcode << 22) | ((imm12) << 10) | (ptr << 5) | rt;
- }
-
- // encoding for vcvt, size is encoded in operand
- // <Qd>, <Qm>
- // F32.S32
- //encoded as op = 0b00, size = 0b10.
- // VCVT<c>.<Td>.<Tm> <Dd>, <Dm>
- // opcode is broken down into 4 pieces
- public static int f_convert(int opcode_1, int opcode_2, int opcode_3, int opcode_4, int vd, int vm) {
- return (opcode_1 << 28) | (opcode_2 << 24) | (opcode_3 << 20) | (opcode_4 << 16) |
- (vd << 12) | (0x01100010 << 4) | vm;
- }
- public static int float_cast(int opcode, int ftype, int rn, int rd) {
- assert 0 <= rd && rd < 32;
- assert 0 <= rn && rn < 32;
- return (opcode << 24) | (ftype << 22) | (2176 << 10) | (rn << 5) | rd;
- }
-
-
- // ftype = 3
- public static int f_cmp(int opcode, int ftype, int rm, int rn) {
- assert 0 <= rn && rn < 32;
- assert 0 <= rm && rm < 32;
- // 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);
short reg2 = (short)(enc.reg(n.in(2))-D_OFFSET);
- int body = f_cmp(0b00011110, 3, reg1, reg2);
+ int body = Arm64.f_cmp(0b00011110, 3, reg1, reg2);
enc.add4(body);
}
- public static COND make_condition(String bop) {
- return switch (bop) {
- case "==" -> COND.EQ;
- case "!=" -> COND.NE;
- case "<" -> COND.LT;
- case "<=" -> COND.LE;
- case ">=" -> COND.GE;
- case ">" -> COND.GT;
- default -> throw Utils.TODO();
- };
- }
-
- 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();
- }
-
- public static int cond_set(int opcode, int rm, COND cond, int rn, int rd) {
- assert 0 <= rd && rd < 32;
- assert 0 <= rn && rn < 32;
- 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) {
- assert 0 <= rd && rd < 32;
- return opcode << 10 | rd << 5;
- }
- 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;
- }
- // no aligned assert(assert (delta&3)==0;)
- public static int b_calloc(int opcode, int delta) {
- assert -(1<<26) <= delta && delta < (1<<26);
- delta>>=2;
- delta &= (1L<<26)-1; // Zero extend
- return (opcode << 26) | delta;
- }
-
@Override public RegMask callArgMask(TypeFunPtr tfp, int idx, int maxArgSlot ) { return callInMask(tfp,idx,maxArgSlot); }
static RegMask callInMask(TypeFunPtr tfp, int idx, int maxArgSlot ) {
if( idx==0 ) return CodeGen.CODE._rpcMask;
@@ -591,29 +242,6 @@ public class arm extends Machine {
throw Utils.TODO(); // Pass on stack slot
}
- public static long decodeImm12(int imm12) {
- int immr = (imm12 >> 6) & 0x3F;
- int imms = imm12 & 0x3F;
- int size;
- if ((imm12 & 0x1000) != 0) {
- size = 64;
- } else {
- size = 31-(imms >> 1);
- size |= size >> 1;
- size |= size >> 2;
- size |= size >> 4;
- size++;
- imms &= ~((32-size) << 1);
- }
- long val = (2L << imms)-1;
- while (size < 64) {
- val |= val << size;
- size <<= 1;
- }
- val = (val >>> immr) | val << (64-immr);
- return val;
- }
-
// Return the max stack slot used by this signature, or 0
@Override public short maxArgSlot( TypeFunPtr tfp ) {
int icnt=0, fcnt=0; // Count of ints, floats
@@ -793,7 +421,6 @@ public class arm extends Machine {
: new LsrARM(lsr);
}
-
private static int off;
private static Node idx;
private Node st(StoreNode st) {
@@ -819,7 +446,6 @@ public class arm extends Machine {
return mop;
}
-
private Node prj(ProjNode prj) {
TypeInteger ret = cReturn(prj);
return ret==null ? new ProjARM(prj) : new ExtendARM(prj,ret);
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java
index 2cd00845..14581111 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -18,7 +19,7 @@ public class AUIPC extends ConstantNode implements MachNode, RIPRelSize {
@Override public void encoding( Encoding enc ) {
enc.relo(this);
short dst = enc.reg(this);
- enc.add4(riscv.u_type(riscv.OP_AUIPC, dst, 0));
+ enc.add4(RiscV.u_type(RiscV.OP_AUIPC, dst, 0));
}
// Delta is from opcode start, but X86 measures from the end of the 5-byte encoding
@@ -29,7 +30,7 @@ public class AUIPC extends ConstantNode implements MachNode, RIPRelSize {
//short rpc = enc.reg(this);
//// High half is where the TFP constant used to be, the last input
//short auipc = enc.reg(in(_inputs._len-1));
- //enc.patch4(opStart,riscv.i_type(0x67, rpc, 0, auipc, delta));
+ //enc.patch4(opStart,RiscV.i_type(0x67, rpc, 0, auipc, delta));
throw Utils.TODO();
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java
index 8636df9f..d87e49b9 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -10,7 +11,7 @@ public class AddFRISC extends MachConcreteNode implements MachNode {
@Override public String op() { return "addf"; }
@Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; }
@Override public RegMask outregmap() { return riscv.FMASK; }
- @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,1); }
+ @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,RiscV.RM.RNE,1); }
@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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java
index 511b0583..8012b61e 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
@@ -8,7 +9,7 @@ public class AddIRISC extends ImmRISC {
public AddIRISC( Node add, int imm12, boolean pop ) { super(add,imm12,pop); }
@Override public String op() { return "addi"; }
@Override public String glabel() { return "+"; }
- @Override int opcode() { return riscv.OP_IMM; }
+ @Override int opcode() { return RiscV.OP_IMM; }
@Override int func3() {return 0;}
@Override public AddIRISC copy() {
// Clone the AddI, using the same inputs-only code used during inst select.
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java
index 842c8bdc..9fd65e7d 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
@@ -7,6 +8,6 @@ public class AndIRISC extends ImmRISC {
public AndIRISC( Node and, int imm) { super(and,imm); }
@Override public String op() { return "andi"; }
@Override public String glabel() { return "&"; }
- @Override int opcode() { return riscv.OP_IMM; }
+ @Override int opcode() { return RiscV.OP_IMM; }
@Override int func3() {return 7;}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java
index b8664679..a9d03da5 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.print.ExprPrinter;
import com.seaofnodes.simple.codegen.*;
@@ -46,12 +47,12 @@ public class BranchRISC extends IfNode implements MachNode, RIPRelSize {
if( in(1)==null && _bop=="!=" ) return; // Inverted never-node, no code
enc.jump(this,cproj(0));
if( in(1)==null ) // Never node
- enc.add4(riscv.j_type(riscv.OP_JAL, 0, 0));
+ enc.add4(RiscV.j_type(RiscV.OP_JAL, 0, 0));
else {
// 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(riscv.OP_BRANCH, riscv.jumpop(_bop), src1, src2, 0));
+ enc.add4(RiscV.b_type(RiscV.OP_BRANCH, RiscV.jumpop(_bop), src1, src2, 0));
}
}
@@ -67,12 +68,12 @@ public class BranchRISC extends IfNode implements MachNode, RIPRelSize {
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
assert !( in(1)==null && _bop=="!=" ); // Inverted never-node, no code no patch
if( in(1)==null ) { // Never node
- enc.patch4(opStart,riscv.j_type(riscv.OP_JAL, 0, delta));
+ enc.patch4(opStart,RiscV.j_type(RiscV.OP_JAL, 0, delta));
} else {
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(riscv.OP_BRANCH, 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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
index bd5dabe5..f0ad8e88 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeFunPtr;
@@ -33,7 +34,7 @@ public class CallRISC extends CallNode implements MachNode, RIPRelSize {
if( fun==null ) enc.external(this,_name);
else enc.relo(this);
short rpc = enc.reg(this);
- enc.add4(riscv.j_type(riscv.OP_JAL, rpc, 0));
+ enc.add4(RiscV.j_type(RiscV.OP_JAL, rpc, 0));
}
// Delta is from opcode start
@@ -47,7 +48,7 @@ public class CallRISC extends CallNode implements MachNode, RIPRelSize {
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
short rpc = enc.reg(this);
if( opLen==4 ) {
- enc.patch4(opStart,riscv.j_type(riscv.OP_JAL, rpc, delta));
+ enc.patch4(opStart,RiscV.j_type(RiscV.OP_JAL, rpc, delta));
} else {
throw Utils.TODO();
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
index 298789e8..5eee596d 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -18,7 +19,7 @@ public class CallRRISC extends CallNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short rpc = enc.reg(this);
short src = enc.reg(in(_inputs._len-1));
- int body = riscv.i_type(riscv.OP_JALR, rpc, 0, src, 0);
+ int body = RiscV.i_type(RiscV.OP_JALR, rpc, 0, src, 0);
enc.add4(body);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java
index 68ed6f6c..8eb4fb3b 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -10,7 +11,7 @@ public class DivFRISC extends MachConcreteNode implements MachNode{
@Override public String op() { return "divf"; }
@Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; }
@Override public RegMask outregmap() { return riscv.FMASK; }
- @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RUP,13); }
+ @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,RiscV.RM.RUP,13); }
// Default on double precision for now(64 bits)
// General form: "fdiv.d rd = src1 / src2
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java
index 22ac2a69..5bd3ec1c 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeInteger;
@@ -22,8 +23,8 @@ public class ExtendRISC extends MachConcreteNode {
@Override public void encoding(Encoding enc) {
short dst = enc.reg(this), src = enc.reg(in(1));
int shift = 64-_bits;
- enc.add4(riscv.i_type(riscv.OP_IMM,dst,1,src,shift));
- enc.add4(riscv.i_type(riscv.OP_IMM,dst,5,dst,shift | (_signed ? 0x400 : 0)));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM,dst,1,src,shift));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM,dst,5,dst,shift | (_signed ? 0x400 : 0)));
}
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1)));
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java
index 81726200..51ddc9db 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -20,9 +21,9 @@ public class FltRISC extends ConstantNode implements MachNode, RIPRelSize {
short dst = (short)(enc.reg(this) - riscv.F_OFFSET);
short tmp = (short)riscv.T6;
// AUIPC dst,#hi20_constant_pool
- enc.add4(riscv.u_type(riscv.OP_AUIPC, tmp, 0));
+ enc.add4(RiscV.u_type(RiscV.OP_AUIPC, tmp, 0));
// Load dst,[dst+#low12_constant_pool]
- enc.add4(riscv.i_type(riscv.OP_LOADFP, dst, 0b11, tmp, 0));
+ enc.add4(RiscV.i_type(RiscV.OP_LOADFP, dst, 0b11, tmp, 0));
}
@Override public RegMask killmap() { return new RegMask(riscv.T6); }
@@ -34,9 +35,9 @@ public class FltRISC extends ConstantNode implements MachNode, RIPRelSize {
short dst = (short)(enc.reg(this) - riscv.F_OFFSET);
short tmp = (short)riscv.T6;
// AUIPC dst,#hi20_constant_pool
- enc.patch4(opStart , riscv.u_type(riscv.OP_AUIPC, tmp, delta>>12));
+ enc.patch4(opStart , RiscV.u_type(RiscV.OP_AUIPC, tmp, delta>>12));
// Load dst,[dst+#low12_constant_pool]
- enc.patch4(opStart+4, riscv.i_type(riscv.OP_LOADFP, dst, 0b11, tmp, delta & 0xFFF));
+ enc.patch4(opStart+4, RiscV.i_type(RiscV.OP_LOADFP, dst, 0b11, tmp, delta & 0xFFF));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java
index 6fce6244..d3d64b06 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.FunNode;
import com.seaofnodes.simple.node.MachNode;
@@ -17,6 +18,6 @@ public class FunRISC extends FunNode implements MachNode {
int sz = _frameAdjust;
if( sz == 0 ) return; // Skip if no frame adjust
if( sz >= 1L<<12 ) throw Utils.TODO();
- enc.add4(riscv.i_type(riscv.OP_IMM, riscv.RSP, 0, riscv.RSP, -sz & 0xFFF));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM, riscv.RSP, 0, riscv.RSP, -sz & 0xFFF));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java
index db0547fe..1b53ab0f 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -14,7 +15,7 @@ public class I2F8RISC extends MachConcreteNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short dst = (short)(enc.reg(this )-riscv.F_OFFSET);
short src1 = enc.reg(in(1));
- int body = riscv.r_type(riscv.OP_FP,dst,riscv.RM.RNE.ordinal(),src1,0,0x69);
+ int body = RiscV.r_type(RiscV.OP_FP,dst,RiscV.RM.RNE.ordinal(),src1,0,0x69);
enc.add4(body);
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java
index b4c87872..ee247c3e 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.print.ExprPrinter;
import com.seaofnodes.simple.codegen.*;
@@ -41,7 +42,7 @@ abstract public class ImmRISC extends MachConcreteNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(this );
short src = enc.reg(in(1));
- enc.add4(riscv.i_type(opcode(), dst, func3(), src, _imm12 & 0xFFF));
+ enc.add4(RiscV.i_type(opcode(), dst, func3(), src, _imm12 & 0xFFF));
}
// General form: "addi rd = rs1 + imm"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java
index edd1850f..23ac8481 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -23,9 +24,9 @@ public class Int8RISC extends ConstantNode implements MachNode, RIPRelSize {
short tmp = (short)riscv.T6;
enc.largeConstant(this,_con, 0, -1);
// AUIPC dst,#hi20_constant_pool
- enc.add4(riscv.u_type(riscv.OP_AUIPC, tmp, 0));
+ enc.add4(RiscV.u_type(RiscV.OP_AUIPC, tmp, 0));
// Load dst,[dst+#low12_constant_pool]
- enc.add4(riscv.i_type(riscv.OP_LOAD, dst, 0b11, tmp, 0));
+ enc.add4(RiscV.i_type(RiscV.OP_LOAD, dst, 0b11, tmp, 0));
}
@Override public RegMask killmap() { return new RegMask(riscv.T6); }
@@ -34,9 +35,9 @@ public class Int8RISC extends ConstantNode implements MachNode, RIPRelSize {
short dst = enc.reg(this);
short tmp = (short)riscv.T6;
// AUIPC dst,#hi20_constant_pool
- enc.patch4(opStart , riscv.u_type(riscv.OP_AUIPC, tmp, delta>>12));
+ enc.patch4(opStart , RiscV.u_type(RiscV.OP_AUIPC, tmp, delta>>12));
// Load dst,[dst+#low12_constant_pool]
- enc.patch4(opStart+4, riscv.i_type(riscv.OP_LOAD, dst, 0b11, tmp, delta & 0xFFF));
+ enc.patch4(opStart+4, RiscV.i_type(RiscV.OP_LOAD, dst, 0b11, tmp, delta & 0xFFF));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java
index f8af913a..9088abbd 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -21,7 +22,7 @@ public class IntRISC extends ConstantNode implements MachNode {
int val = _con==Type.NIL ? 0 : (int)(((TypeInteger)_con).value() & 0xFFF);
// Explicit truncation of larger immediates; this will sign-extend on
// load and this is handled during instruction selection.
- enc.add4(riscv.i_type(riscv.OP_IMM, dst, 0, riscv.ZERO, val));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM, dst, 0, riscv.ZERO, val));
}
@Override public void asm(CodeGen code, SB sb) {
String reg = code.reg(this);
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java
index 7333f2b7..aedd8b47 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -21,7 +22,7 @@ public class LUI extends ConstantNode implements MachNode {
long x = ((TypeInteger)_con).value();
int imm20 = (int)(x>>12) & 0xFFFFF;
short dst = enc.reg(this);
- int lui = riscv.u_type(riscv.OP_LUI, dst, imm20);
+ int lui = RiscV.u_type(RiscV.OP_LUI, dst, imm20);
enc.add4(lui);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java
index 7e08a01d..2e3dfd8d 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -17,9 +18,9 @@ public class LoadRISC extends MemOpRISC {
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(this );
short ptr = enc.reg(ptr());
- int op = dst >= riscv.F_OFFSET ? riscv.OP_LOADFP : riscv.OP_LOAD;
+ int op = dst >= riscv.F_OFFSET ? RiscV.OP_LOADFP : RiscV.OP_LOAD;
if( dst >= riscv.F_OFFSET ) dst -= riscv.F_OFFSET;
- enc.add4(riscv.i_type(op, dst, func3(), ptr, _off));
+ enc.add4(RiscV.i_type(op, dst, func3(), ptr, _off));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java
index 5cc40079..dacec2b5 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -10,7 +11,7 @@ public class MulFRISC extends MachConcreteNode implements MachNode {
@Override public String op() { return "mulf"; }
@Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; }
@Override public RegMask outregmap() { return riscv.FMASK; }
- @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,9); }
+ @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,RiscV.RM.RNE,9); }
@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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java
index d8183d09..3070c56c 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -12,7 +13,7 @@ public class NegRISC extends MachConcreteNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(this );
short src = enc.reg(in(1));
- riscv.r_type(riscv.OP,dst,0,0,src,0x20);
+ RiscV.r_type(RiscV.OP,dst,0,0,src,0x20);
}
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = -").p(code.reg(in(1)));
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java
index 6c03bda6..965a3c7c 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.print.ASMPrinter;
@@ -14,9 +15,9 @@ public class NewRISC extends NewNode implements MachNode, RIPRelSize {
enc.external(this,"calloc");
// A1 is a caller-save, allowed to crush building external address
// auipc
- enc.add4(riscv.i_type(riscv.OP_IMM , _arg2Reg , 0, riscv.ZERO, 1));
- enc.add4(riscv.u_type(riscv.OP_AUIPC, riscv.A2 , 0));
- enc.add4(riscv.i_type(riscv.OP_JALR , riscv.RPC, 0, riscv.A2, 0));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM , _arg2Reg , 0, riscv.ZERO, 1));
+ enc.add4(RiscV.u_type(RiscV.OP_AUIPC, riscv.A2 , 0));
+ enc.add4(RiscV.i_type(RiscV.OP_JALR , riscv.RPC, 0, riscv.A2, 0));
}
// Patch is for running "new" in a JIT.
@@ -32,8 +33,8 @@ public class NewRISC extends NewNode implements MachNode, RIPRelSize {
int imm20 = delta>>12;
if( ((delta>>11)&1)==1 ) imm20++; // Correct accidental sign extension
int imm12 = delta&0xFFF;
- enc.patch4(opStart+4,riscv.u_type(riscv.OP_AUIPC, riscv.A2 , imm20));
- enc.patch4(opStart+8,riscv.i_type(riscv.OP_JALR , riscv.RPC, 0, riscv.A2, imm12));
+ enc.patch4(opStart+4,RiscV.u_type(RiscV.OP_AUIPC, riscv.A2 , imm20));
+ enc.patch4(opStart+8,RiscV.i_type(RiscV.OP_JALR , riscv.RPC, 0, riscv.A2, imm12));
} else
throw Utils.TODO();
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java
index 1369ee76..dbe9ceb0 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.MachConcreteNode;
import com.seaofnodes.simple.node.MachNode;
@@ -14,7 +15,7 @@ public class NotRISC extends MachConcreteNode implements MachNode {
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(this );
short src = enc.reg(in(1));
- enc.add4(riscv.i_type(riscv.OP_IMM, dst, 2, src, 1));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM, dst, 2, src, 1));
}
@Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)); }
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java
index 963b9d50..937595a3 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java
@@ -1,11 +1,12 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
public class OrIRISC extends ImmRISC {
public OrIRISC( Node and, int imm) { super(and,imm); }
- @Override int opcode() { return riscv.OP_IMM; }
+ @Override int opcode() { return RiscV.OP_IMM; }
@Override int func3() { return 6; }
@Override public String glabel() { return "|"; }
@Override public String op() { return "ori"; }
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java
index 7e4631d3..33143c6b 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.codegen.Encoding;
import com.seaofnodes.simple.codegen.RegMask;
@@ -14,8 +15,8 @@ public class RetRISC extends ReturnNode implements MachNode {
int sz = fun()._frameAdjust;
if( sz >= 1L<<12 ) throw Utils.TODO();
if( sz != 0 )
- enc.add4(riscv.i_type(riscv.OP_IMM, riscv.RSP, 0, riscv.RSP, sz & 0xFFF));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM, riscv.RSP, 0, riscv.RSP, sz & 0xFFF));
short rpc = enc.reg(rpc());
- enc.add4(riscv.i_type(riscv.OP_JALR, riscv.ZERO, 0, rpc, 0));
+ enc.add4(RiscV.i_type(RiscV.OP_JALR, riscv.ZERO, 0, rpc, 0));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java
index 3424cd01..d037dd5c 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.BoolNode;
import com.seaofnodes.simple.node.MachConcreteNode;
@@ -23,7 +24,7 @@ public class SetFRISC extends MachConcreteNode implements MachNode {
short dst = enc.reg(this );
short src1 = (short)(enc.reg(in(1))-riscv.F_OFFSET);
short src2 = (short)(enc.reg(in(2))-riscv.F_OFFSET);
- int body = riscv.r_type(riscv.OP_FP,dst,riscv.fsetop(_bop),src1,src2,0b1010001/*FCMP*/);
+ int body = RiscV.r_type(RiscV.OP_FP,dst,RiscV.fsetop(_bop),src1,src2,0b1010001/*FCMP*/);
enc.add4(body);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java
index 12c0ddec..1425caa2 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java
@@ -1,11 +1,12 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
public class SllIRISC extends ImmRISC {
public SllIRISC( Node and, int imm) { super(and,imm); }
- @Override int opcode() { return riscv.OP_IMM; }
+ @Override int opcode() { return RiscV.OP_IMM; }
@Override int func3() { return 1; }
@Override public String glabel() { return "<<"; }
@Override public String op() { return "slli"; }
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java
index 6082cbbf..8a16f6b7 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.FunNode;
import com.seaofnodes.simple.node.Node;
@@ -25,36 +26,36 @@ public class SplitRISC extends SplitNode {
throw Utils.TODO(); // Very rare stack-stack move
}
int off = enc._fun.computeStackOffset(enc._code,dst);
- int op = srcX ? riscv.OP_STOREFP : riscv.OP_STORE;
+ int op = srcX ? RiscV.OP_STOREFP : RiscV.OP_STORE;
if( srcX ) src -= riscv.F_OFFSET;
- enc.add4(riscv.s_type(op, 0b011, riscv.RSP, src, off));
+ enc.add4(RiscV.s_type(op, 0b011, riscv.RSP, src, off));
return;
}
if( src >= riscv.MAX_REG ) {
// Load from SP
int off = enc._fun.computeStackOffset(enc._code,src);
- int op = dstX ? riscv.OP_LOADFP : riscv.OP_LOAD;
+ int op = dstX ? RiscV.OP_LOADFP : RiscV.OP_LOAD;
if( dstX ) dst -= riscv.F_OFFSET;
- enc.add4(riscv.i_type(op, dst, 0b011, riscv.RSP, off));
+ enc.add4(RiscV.i_type(op, dst, 0b011, riscv.RSP, off));
return;
}
// pick opcode based on regs
if( !dstX && !srcX ) {
// GPR->GPR
- enc.add4(riscv.r_type(riscv.OP,dst,0,src,riscv.ZERO,0));
+ enc.add4(RiscV.r_type(RiscV.OP,dst,0,src,riscv.ZERO,0));
} else if( dstX && srcX ) {
// FPR->FPR
src -= riscv.F_OFFSET;
dst -= riscv.F_OFFSET;
- enc.add4(riscv.r_type(riscv.OP_FP, dst, 0b000, src, src, 0b0010101)); // dst = FMIN(src,src)
+ enc.add4(RiscV.r_type(RiscV.OP_FP, dst, 0b000, src, src, 0b0010101)); // dst = FMIN(src,src)
} else if(!srcX && dstX) {
//GPR->FPR
// fmv.d.x
- enc.add4(riscv.r_type(riscv.OP_FP, dst - riscv.F_OFFSET, 0, src, 0, 0b1111001));
+ enc.add4(RiscV.r_type(RiscV.OP_FP, dst - riscv.F_OFFSET, 0, src, 0, 0b1111001));
} else if(srcX && !dstX) {
//FPR->GPR
//fmv.x.d
- enc.add4(riscv.r_type(riscv.OP_FP, dst, 0, src - riscv.F_OFFSET, 0, 0b1110001));
+ enc.add4(RiscV.r_type(RiscV.OP_FP, dst, 0, src - riscv.F_OFFSET, 0, 0b1110001));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java
index fcfa0774..b316b303 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
@@ -7,7 +8,7 @@ public class SraIRISC extends ImmRISC {
public SraIRISC( Node and, int imm) {
super(and,imm | (0x20 << 5));
}
- @Override int opcode() { return riscv.OP_IMM; }
+ @Override int opcode() { return RiscV.OP_IMM; }
@Override int func3() { return 5;}
@Override public String glabel() { return ">>"; }
@Override public String op() { return "srai"; }
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java
index 2f73e139..d0ea6b18 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java
@@ -1,11 +1,12 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
public class SrlIRISC extends ImmRISC {
public SrlIRISC( Node and, int imm, boolean pop) { super(and,imm,pop); }
- @Override int opcode() { return riscv.OP_IMM; }
+ @Override int opcode() { return RiscV.OP_IMM; }
@Override int func3() { return 5; }
@Override public String glabel() { return ">>>"; }
@Override public String op() { return "srli"; }
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java
index df83ce1c..48cb7c78 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.codegen.RegMask;
import com.seaofnodes.simple.node.*;
@@ -36,9 +37,9 @@ public class StoreRISC extends MemOpRISC {
@Override public void encoding( Encoding enc ) {
short val = enc.reg(val());
short ptr = enc.reg(ptr());
- int op = val >= riscv.F_OFFSET ? riscv.OP_STOREFP : riscv.OP_STORE;
+ int op = val >= riscv.F_OFFSET ? RiscV.OP_STOREFP : RiscV.OP_STORE;
if( val >= riscv.F_OFFSET ) val -= riscv.F_OFFSET;
- enc.add4(riscv.s_type(op, func3()&7, ptr, val == -1 ? riscv.ZERO : val, _off));
+ enc.add4(RiscV.s_type(op, func3()&7, ptr, val == -1 ? riscv.ZERO : val, _off));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java
index da3e92f4..044820cf 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -10,7 +11,7 @@ public class SubFRISC extends MachConcreteNode implements MachNode {
@Override public String op() { return "subf"; }
@Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; }
@Override public RegMask outregmap() { return riscv.FMASK; }
- @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,5); }
+ @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,RiscV.RM.RNE,5); }
@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/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
index db140304..e57f6e09 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -21,9 +22,9 @@ public class TFPRISC extends ConstantNode implements MachNode, RIPRelSize {
short dst = enc.reg(this);
TypeFunPtr tfp = (TypeFunPtr)_con;
// auipc t0,0
- enc.add4(riscv.u_type(riscv.OP_AUIPC, dst, 0));
+ enc.add4(RiscV.u_type(RiscV.OP_AUIPC, dst, 0));
// addi t1,t0 + #0
- enc.add4(riscv.i_type(riscv.OP_IMM, dst, 0, dst, 0));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM, dst, 0, dst, 0));
}
@Override public byte encSize(int delta) { return 8; }
@@ -33,8 +34,8 @@ public class TFPRISC extends ConstantNode implements MachNode, RIPRelSize {
short rpc = enc.reg(this);
if( opLen==8 ) {
// ADDI sign-extends its low 12 bits, so round the AUIPC high part.
- enc.patch4(opStart ,riscv.u_type(riscv.OP_AUIPC, rpc, (delta+0x800)>>12));
- enc.patch4(opStart+4,riscv.i_type(riscv.OP_IMM, rpc, 0, rpc, delta & 0xFFF));
+ enc.patch4(opStart ,RiscV.u_type(RiscV.OP_AUIPC, rpc, (delta+0x800)>>12));
+ enc.patch4(opStart+4,RiscV.i_type(RiscV.OP_IMM, rpc, 0, rpc, delta & 0xFFF));
} else {
// should not happen as one instruction is 4 byte, and TFP arm encodes 2.
throw Utils.TODO();
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java
index 94f0da0e..7bc2db7e 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.ConstantNode;
import com.seaofnodes.simple.node.MachNode;
@@ -18,9 +19,9 @@ public class TMPRISC extends ConstantNode implements MachNode, RIPRelSize {
enc.largeConstant(this,((TypeMemPtr)_con)._obj,0,-1);
short dst = enc.reg(this);
// AUIPC dst,#hi20_constant_pool
- enc.add4(riscv.u_type(riscv.OP_AUIPC, dst, 0));
+ enc.add4(RiscV.u_type(RiscV.OP_AUIPC, dst, 0));
// addi dst,[dst+#low12_constant_pool]
- enc.add4(riscv.i_type(riscv.OP_IMM, dst, 0, dst, 0));
+ enc.add4(RiscV.i_type(RiscV.OP_IMM, dst, 0, dst, 0));
}
@Override public byte encSize(int delta) { return 8; }
@@ -29,9 +30,9 @@ public class TMPRISC extends ConstantNode implements MachNode, RIPRelSize {
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
short dst = enc.reg(this);
// Round the high part because ADDI's low 12 bits are signed.
- enc.patch4(opStart , riscv.u_type(riscv.OP_AUIPC, dst, (delta+0x800)>>12));
+ enc.patch4(opStart , RiscV.u_type(RiscV.OP_AUIPC, dst, (delta+0x800)>>12));
// ADDI dst,dst,#low12_constant_pool
- enc.patch4(opStart+4, riscv.i_type(riscv.OP_IMM, dst, 0, dst, delta & 0xFFF));
+ enc.patch4(opStart+4, RiscV.i_type(RiscV.OP_IMM, dst, 0, dst, delta & 0xFFF));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java
index 160895df..448d9ec3 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.print.ExprPrinter;
import com.seaofnodes.simple.codegen.*;
@@ -21,7 +22,7 @@ public class UJmpRISC extends CFGNode implements MachNode, RIPRelSize {
// Short form +/-4K: beq r0,r0,imm12
// Long form: auipc rX,imm20/32; jal r0,[rX+imm12/32]
enc.jump(this,uctrl());
- enc.add4(riscv.j_type(riscv.OP_JAL, 0, 0));
+ enc.add4(RiscV.j_type(RiscV.OP_JAL, 0, 0));
}
// Delta is from opcode start
@@ -34,7 +35,7 @@ public class UJmpRISC extends CFGNode implements MachNode, RIPRelSize {
// Delta is from opcode start
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
if( opLen==4 ) {
- enc.patch4(opStart,riscv.j_type(riscv.OP_JAL, 0, delta));
+ enc.patch4(opStart,RiscV.j_type(RiscV.OP_JAL, 0, delta));
} else {
throw Utils.TODO();
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java
index 19ea6bc7..f4323cae 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java
@@ -1,12 +1,13 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
public class XorIRISC extends ImmRISC {
public XorIRISC( Node and, int imm) { super(and,imm); }
public XorIRISC( Node and, int imm, boolean pop) { super(and,imm,pop); }
- @Override int opcode() { return riscv.OP_IMM; }
+ @Override int opcode() { return RiscV.OP_IMM; }
@Override int func3() { return 4; }
@Override public String glabel() { return "^"; }
@Override public String op() { return "xori"; }
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
index 88ec9ebd..6be0376a 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java
@@ -1,5 +1,7 @@
package com.seaofnodes.simple.node.cpus.riscv;
+import com.seaofnodes.isa.RiscV;
+import static com.seaofnodes.isa.RiscV.*;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.*;
@@ -68,7 +70,6 @@ public class riscv extends Machine {
static final RegMask SPLIT_MASK = new RegMask( WR_BITS | FP_BITS, -1L );
-
// Arguments masks
public static RegMask A0_MASK = new RegMask(A0);
public static RegMask A1_MASK = new RegMask(A1);
@@ -114,40 +115,13 @@ public class riscv extends Machine {
FA7_MASK
};
- // major opcode: OP
- public static int OP_LOAD = 0b00_000_11;
- public static int OP_LOADFP = 0b00_001_11;
- public static int OP_CUSTOM0 = 0b00_010_11;
- public static int OP_IMM = 0b00_100_11;
- public static int OP_AUIPC = 0b00_101_11;
-
- public static int OP_STORE = 0b01_000_11;
- public static int OP_STOREFP = 0b01_001_11;
- public static int OP_CUSTOM1 = 0b01_010_11;
- public static int OP = 0b01_100_11;
- public static int OP_LUI = 0b01_101_11;
-
- public static int OP_CUSTOM2 = 0b10_010_11;
- public static int OP_FP = 0b10_100_11;
-
- public static int OP_BRANCH = 0b11_000_11;
- public static int OP_JALR = 0b11_001_11;
- public static int OP_RESERVED= 0b11_010_11;
- public static int OP_JAL = 0b11_011_11;
-
-
// Since riscv instructions are fixed we can just or them together
- public static int r_type(int opcode, int rd, int func3, int rs1, int rs2, int func7) {
- assert 0 <= rs1 && rs1 < 32;
- assert 0 <= rs2 && rs2 < 32;
- assert 0 <= rd && rd < 32;
- return (func7 << 25) | (rs2 << 20) | (rs1 << 15) | (func3 << 12) | (rd << 7) | opcode;
- }
+
public static void r_type(Encoding enc, Node n, int func3, int func7) {
short dst = enc.reg(n);
short src1 = enc.reg(n.in(1));
short src2 = enc.reg(n.in(2));
- int body = r_type(OP,dst,func3,src1,src2,func7);
+ int body = RiscV.r_type(OP,dst,func3,src1,src2,func7);
enc.add4(body);
}
@@ -155,103 +129,10 @@ public class riscv extends Machine {
short dst = (short)(enc.reg(n )-F_OFFSET);
short src1 = (short)(enc.reg(n.in(1))-F_OFFSET);
short src2 = (short)(enc.reg(n.in(2))-F_OFFSET);
- int body = r_type(OP_FP,dst,func3.ordinal(),src1,src2,func7);
+ int body = RiscV.r_type(OP_FP,dst,func3.ordinal(),src1,src2,func7);
enc.add4(body);
}
-
- public static int u_type(int opcode, int rd, int imm20) {
- assert 0 <= rd && rd < 32;
- return (imm20 << 12) | (rd << 7) | opcode;
- }
-
- public static int j_type(int opcode, int rd, int delta) {
- assert -(1L<<20) <= delta && delta < (1L<<20);
- assert 0 <= rd && rd < 32;
- // Messy branch offset encoding
- // 31 30-21 20 19-12 11-7 6-0
- // 20 10- 1 11 19-12 rpc JAL
- assert (delta&1)==0; // Low bit is always zero, not encoded
- int imm10_01 = (delta>> 1) & 0x3FF;
- int imm11 = (delta>>11) & 1;
- int imm12_19 = (delta>>12) & 0xFF;
- int imm20 = (delta>>19) & 1;
- int bits = imm20<<19 | imm10_01 << 9 | imm11 << 8 | imm12_19;
- return bits << 12 | rd << 7 | opcode;
- }
-
-
- public static int i_type(int opcode, int rd, int func3, int rs1, int imm12) {
- assert 0 <= rd && rd < 32;
- assert 0 <= rs1 && rs1 < 32;
- assert opcode >= 0 && func3 >=0 && imm12 >= 0; // Zero-extend by caller
- return (imm12 << 20) | (rs1 << 15) | (func3 << 12) | (rd << 7) | opcode;
- }
-
- // S-type instructions(store)
- public static int s_type(int opcode, int func3, int rs1, int rs2, int imm12) {
- assert 0 <= rs1 && rs1 < 32;
- assert 0 <= rs2 && rs2 < 32;
- assert 0 <= func3;
-
- assert imm12 >= 0; // Masked to high zero bits by caller
- int imm_lo = imm12 & 0x1F;
- int imm_hi = imm12 >> 5;
- return (imm_hi << 25) | (rs2 << 20) | (rs1 << 15) | (func3 << 12) | (imm_lo << 7) | opcode;
- }
-
- // BRANCH
- public static int b_type(int opcode, int func3, short rs1, short rs2, int delta) {
- assert 0 <= rs1 && rs1 < 32;
- assert 0 <= rs2 && rs2 < 32;
- assert -4*1024 <= delta && delta < 4*1024;
- assert (delta&1)==0; // Low bit is always zero, not encoded
- // Messy branch offset encoding
- // 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) &0x3F;
- int imm11 = (delta>>11) & 1;
- int imm12 = (delta>>12) & 1;
- int imm5 = imm4_1<<1 | imm11;
- int imm7 = imm12<<6 | imm10_5;
- return (imm7 << 25 ) | (rs2 << 20) | (rs1 << 15) | (func3 << 12) | (imm5 << 7) | opcode;
- }
-
- public enum RM {
- RNE, // Round to Nearest, ties to Even
- RTZ, // Round towards Zero
- RDN, // Round Down
- RUP, // Round Up
- DIRECT, // Round to Nearest, ties to Max Magnitude
- RESERVED1, // Reserved for futue use
- RESERVED2, // Reserved for future use
- DYN, // In instruction’s rm field, selects dynamic rounding mode; In Rounding Mode register, reserved
- }
-
- // Since opcode is the same just return back func3
- static public int jumpop(String op) {
- return switch(op) {
- case "==" -> 0x0;
- case "!=" -> 0x1;
- case "<" -> 0x4;
- case ">=" -> 0x5;
- case "u<" -> 0x6;
- case "u<=" -> 0x7;
- default -> throw Utils.TODO();
- };
- }
-
- // Since opcode is the same just return back func3
- static public int fsetop(String op) {
- return switch(op) {
- case "<" -> 1;
- case "<=" -> 0;
- case "==" -> 2;
- default -> throw Utils.TODO();
- };
- }
-
@Override public RegMask callArgMask( TypeFunPtr tfp, int idx, int maxArgSlot ) { return callInMask(tfp,idx,maxArgSlot); }
static RegMask callInMask( TypeFunPtr tfp, int idx, int maxArgSlot ) {
if( idx==0 ) return RPC_MASK;
@@ -301,7 +182,6 @@ public class riscv extends Machine {
}
@Override public int rpc() { return RPC; }
-
// Return a MachNode unconditional branch
@Override public CFGNode jump() { return new UJmpRISC(); }
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java
index 2513de37..974f690f 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -20,19 +21,7 @@ public class AddFMemX86 extends MemOpX86 {
@Override public RegMask outregmap() { return x86_64_v2.XMASK; }
@Override public int twoAddress() { return 4; }
@Override public void encoding( Encoding enc ) {
- // addsd xmm0, DWORD PTR [rdi+0xc]
- short dst = enc.reg(this );
- short ptr = enc.reg(ptr());
- short idx = enc.reg(idx());
- // F opcode
- enc.add1(0xF2);
- // rex prefix must come next (REX.W is not set)
- x86_64_v2.rexF(dst, ptr, idx, false, enc);
-
- // FP ADD
- enc.add1(0x0F).add1(0x58);
-
- x86_64_v2.indirectAdr(_scale, idx, ptr, _off, dst, enc);
+ X86.memory(enc,0xF2,0x0F58,false,enc.reg(this)-x86_64_v2.XMM_OFFSET,enc.reg(ptr()),enc.reg(idx()),_off,_scale);
}
// General form: "add dst = src + [base + idx<<2 + 12]"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java
index 02e0c7ea..c7d0cf9c 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -13,17 +14,7 @@ public class AddFX86 extends MachConcreteNode implements MachNode {
@Override public boolean commutes() { return true; }
@Override public void encoding( Encoding enc ) {
- // F2 0F 58 /r ADDSD xmm1, xmm2/m64
- short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET);
- short src = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET);
- // Fopcode
- enc.add1(0xF2);
- // rex prefix must come next (REX.W is not set)
- x86_64_v2.rexF(dst, src, 0, false, enc);
-
- enc.add1(0x0F).add1(0x58);
-
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.sse(enc,0xF2,0x0F58,false,enc.reg(this)-x86_64_v2.XMM_OFFSET,enc.reg(in(2))-x86_64_v2.XMM_OFFSET);
}
// General form: "addf dst += src"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java
index 0ba390c6..0e652a93 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.Encoding;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.SB;
@@ -16,9 +17,7 @@ public class AddIX86 extends ImmX86 {
@Override public final void encoding( Encoding enc ) {
if( _imm== 1 || _imm== -1 ) {
short dst = enc.reg(this); // Also src1
- enc.add1( x86_64_v2.rex(0,dst,0));
- enc.add1(0xFF);
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, _imm==1 ? 0 : 1, dst) );
+ X86.unary(enc,0xFF,_imm==1 ? 0 : 1,dst);
} else super.encoding(enc);
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java
index 3ee721e3..ed65b0a8 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -12,18 +13,7 @@ public class AddMemX86 extends MemOpX86 {
@Override public RegMask outregmap() { return x86_64_v2.WMASK; }
@Override public int twoAddress() { return 4; }
@Override public void encoding( Encoding enc ) {
- // add something to register from memory
- // add eax,DWORD PTR [rdi+0xc]
- // REX.W + 03 /r ADD r64, r/m64
- short dst = enc.reg(this );
- short ptr = enc.reg(ptr());
- short idx = enc.reg(idx());
-
- enc.add1(x86_64_v2.rex(dst, ptr, idx));
- // opcode
- enc.add1(0x03);
-
- x86_64_v2.indirectAdr(_scale, idx, ptr, _off, dst, enc);
+ X86.memory(enc,0,0x03,true,enc.reg(this),enc.reg(ptr()),enc.reg(idx()),_off,_scale);
}
// General form: "add dst += [base + idx<<2 + 12]"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
index 460f568b..f97163eb 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.CallNode;
import com.seaofnodes.simple.node.MachNode;
@@ -16,11 +17,7 @@ public class CallRX86 extends CallNode implements MachNode {
}
@Override public RegMask outregmap() { return null; }
@Override public void encoding( Encoding enc ) {
- // 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));
+ X86.callRegister(enc,enc.reg(fptr()));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java
index d74e3833..d1a43b83 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeFunPtr;
@@ -28,7 +29,7 @@ public class CallX86 extends CallNode implements MachNode, RIPRelSize {
FunNode fun = CodeGen.CODE.link(_tfp);
if( fun==null ) enc.external(this,_name);
else enc.relo(this);
- enc.add1(0xe8).add4(0);
+ X86.call(enc);
}
// Delta is from opcode start, but X86 measures from the end of the 5-byte encoding
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java
index 5b97ef63..5ef7a476 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,16 +12,7 @@ public class CmpFX86 extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; }
@Override public void encoding( Encoding enc ) {
- // UCOMISD
- short src1 = (short)(enc.reg(in(1)) - x86_64_v2.XMM_OFFSET);
- short src2 = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET);
- // float opcode
- enc.add1(0x66);
- // rex prefix must come next (REX.W is not set)
- x86_64_v2.rexF(src1, src2, 0, false, enc);
-
- enc.add1(0x0F).add1(0x2E);
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, src1, src2));
+ X86.sse(enc,0x66,0x0F2E,false,enc.reg(in(1))-x86_64_v2.XMM_OFFSET,enc.reg(in(2))-x86_64_v2.XMM_OFFSET);
}
// General form: "cmp src1,src2"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java
index 8b8318eb..151f8ca8 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -26,14 +27,7 @@ public class CmpIX86 extends MachConcreteNode implements MachNode {
@Override public Node copy() { return new CmpIX86(this); }
@Override public final void encoding( Encoding enc ) {
- short dst = enc.reg(in(1)); // Also src1
- enc.add1(x86_64_v2.rex(0, dst, 0));
- // opcode; 0x81 or 0x83; 0x69 or 0x6B
- enc.add1( 0x81 + (x86_64_v2.imm8(_imm) ? 2 : 0) );
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 7, dst) );
- // immediate(4 bytes) 32 bits or (1 byte)8 bits
- if( x86_64_v2.imm8(_imm) ) enc.add1(_imm);
- else enc.add4(_imm);
+ X86.imm(enc,0x81,7,enc.reg(in(1)),_imm);
}
@Override public void asm(CodeGen code, SB sb) {
String dst = code.reg(this);
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java
index 278bf0e6..7b7d98d5 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.Type;
@@ -16,51 +17,16 @@ public class CmpMemX86 extends MemOpX86 {
@Override public String op() { return ((val()==null && _imm==0) ? "test" : "cmp") + _sz; }
@Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; }
@Override public void encoding( Encoding enc ) {
- // REX.W + 81 /7 id CMP r/m64, imm32 | REX.W + 39 /r CMP r/m64,r64
- // CMP [mem], imm32
-
- short ptr = enc.reg(ptr());
- short idx = enc.reg(idx());
- short src = enc.reg(val());
-
- if(src == -1) {
+ short ptr=enc.reg(ptr()), idx=enc.reg(idx()), src=enc.reg(val());
+ if( src==-1 ) {
assert !_swap;
- int log = _declaredType.log_size();
- x86_64_v2.rexF(-1, ptr, idx, log==3, enc);
- switch(log) {
- case 0: enc.add1(0x80); break;
- case 1: enc.add1(0x66).add1(0x81); break;
- case 2: enc.add1(0x81); break;
- case 3: enc.add1(0x81); break;
- }
- x86_64_v2.indirectAdr(_scale, idx, ptr, _off, 7, enc);
- switch(log) {
- case 0: enc.add1(_imm); break;
- case 1: enc.add2(_imm); break;
- case 2: enc.add4(_imm); break;
- case 3: enc.add4(_imm); break;
- }
- } else {
- encVal(enc, _declaredType, ptr, idx, src, _off, _scale, _swap);
- }
+ X86.cmpImm(enc,_declaredType.log_size(),_imm,ptr,idx,_off,_scale);
+ } else encVal(enc,_declaredType,ptr,idx,src,_off,_scale,_swap);
}
static void encVal(Encoding enc, Type decl, short ptr, short idx, short src, int off, int scale, boolean _swap) {
- if(decl instanceof TypeFloat) {
- src -= (short)x86_64_v2.XMM_OFFSET;
- enc.add1(decl==TypeFloat.F32 ? 0xF3 : 0xF2).add1(0x0F).add1(0xC2);
- } else {
- int log = decl.log_size();
- x86_64_v2.rexF(src, ptr, idx, log == 3, enc);
- int swap = _swap ? 2 : 0;
- switch(log) {
- case 0: enc.add1(0x38+swap); break;
- case 1: enc.add1(0x66).add1(0x39+swap); break;
- case 2: enc.add1(0x39+swap); break;
- case 3: enc.add1(0x39+swap); break;
- }
- }
- x86_64_v2.indirectAdr(scale, idx, ptr, off, src, enc);
+ assert !(decl instanceof TypeFloat); // Selected separately as CmpFX86.
+ X86.cmpMem(enc,decl.log_size(),src,ptr,idx,off,scale,_swap);
}
// General form: "cmp dst = src, [base + idx<<2 + 12]"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java
index e7305cdf..7faea17b 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -17,12 +18,7 @@ public class CmpX86 extends MachConcreteNode implements MachNode {
@Override public boolean isClone() { return true; }
@Override public void encoding( Encoding enc ) {
- short dst = enc.reg(in(1));
- short src = enc.reg(in(2));
-
- enc.add1(x86_64_v2.rex(dst, src, 0));
- enc.add1(0x3B);
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.reg(enc,0x3B,enc.reg(in(1)),enc.reg(in(2)));
}
@Override public void asm(CodeGen code, SB sb) {
String dst = code.reg(this);
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java
index 3427aea5..7bbb5102 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -12,18 +13,7 @@ public class DivFX86 extends MachConcreteNode implements MachNode {
@Override public int twoAddress() { return 1; }
@Override public void encoding( Encoding enc ) {
- // F2 0F 5E /r DIVSD xmm1, xmm2/m64
- short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET);
- short src = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET);
-
- // Fopcode
- enc.add1(0xF2);
- // rex prefix must come next (REX.W is not set)
- x86_64_v2.rexF(dst, src, 0, false, enc);
-
- enc.add1(0x0F).add1(0x5E);
-
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.sse(enc,0xF2,0x0F5E,false,enc.reg(this)-x86_64_v2.XMM_OFFSET,enc.reg(in(2))-x86_64_v2.XMM_OFFSET);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java
index b5904a7f..9f375a80 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -14,16 +15,7 @@ public class DivX86 extends MachConcreteNode implements MachNode {
@Override public RegMask killmap() { return x86_64_v2.RDX_MASK; }
@Override public void encoding( Encoding enc ) {
- // REX.W + F7 /7 IDIV r/m64
- short src = enc.reg(in(2));
- // sign extend rax before 128/64 bits division
- // sign extend rax to rdx:rax
- enc.add1(x86_64_v2.REX_W);
- enc.add1(0x99);
- enc.add1(x86_64_v2.rex(0, src, 0));
- // divide
- enc.add1(0xF7); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0x07, src));
+ X86.divide(enc,enc.reg(in(2)));
}
// General form: "div dst /= src"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java
index e905e2e3..1a6ae123 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeInteger;
@@ -20,12 +21,7 @@ public class ExtendX86 extends MachConcreteNode {
@Override public RegMask regmap(int i) { return x86_64_v2.RMASK; }
@Override public RegMask outregmap() { return x86_64_v2.WMASK; }
@Override public void encoding(Encoding enc) {
- short dst = enc.reg(this), src = enc.reg(in(1));
- // MOVSX/MOVZX for bytes and shorts; MOVSXD/MOV r32 for ints.
- enc.add1(x86_64_v2.rex(dst,src,0,_signed || _bits<32));
- if( _bits==32 ) enc.add1(_signed ? 0x63 : 0x8b);
- else enc.add1(0x0f).add1((_signed ? 0xbe : 0xb6) + (_bits==16 ? 1 : 0));
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT,dst,src));
+ X86.extend(enc,_bits,_signed,enc.reg(this),enc.reg(in(1)));
}
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" = ").p(code.reg(in(1)));
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java
index 9bcbac8f..da9bdce7 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -14,20 +15,8 @@ public class FltX86 extends ConstantNode implements MachNode, RIPRelSize{
@Override public Node copy() { return new FltX86(this); }
@Override public void encoding( Encoding enc ) {
- // Load the constant into a FPR
- // movsd xmm, [rip + 0]
- // F2 0F 10 /r MOVSD xmm1, m64
- _encSize = 1/*Fop*/+0/*REX*/+2/*op*/+1/*MODRM*/+4/*offset*/;
- short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET);
- // Fopcode
- enc.add1(0xF2);
- // rex prefix must come next (REX.W is not set)
- _encSize += x86_64_v2.rexF(dst, 0, 0, false, enc);
- enc.add1(0x0F).add1(0x10);
- // hard-code rip here
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT, dst, 0x05));
- enc.add4(0);
- enc.largeConstant(this,_con,_encSize-4,2/*ELF encoding PC32*/);
+ _encSize=X86.rip(enc,0xF2,0x0F10,false,enc.reg(this)-x86_64_v2.XMM_OFFSET);
+ enc.largeConstant(this,_con,_encSize-4,2/*ELF PC32*/);
}
// Delta is from opcode start
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java
index cbd5fdbf..c7a20e4d 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.codegen.Encoding;
import com.seaofnodes.simple.node.FunNode;
@@ -24,11 +25,7 @@ public class FunX86 extends FunNode implements MachNode {
@Override public void encoding( Encoding enc ) {
int sz = _frameAdjust;
if( sz == 0 ) return; // Skip if no frame adjust
- // opcode: 0x83, addi rsp with immediate 8
- enc.add1( x86_64_v2.REX_W ).add1( x86_64_v2.imm8(sz) ? 0x83 : 0x81 );
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0b101, x86_64_v2.RSP) );
- if( x86_64_v2.imm8(sz) ) enc.add1(sz);
- else enc.add4(sz);
+ X86.imm(enc,0x81,5,x86_64_v2.RSP,sz);
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java
index 9f3d7905..ee357901 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -11,18 +12,7 @@ public class I2f8X86 extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return x86_64_v2.XMASK; }
@Override public void encoding( Encoding enc ) {
- // F2 0F 2A /r CVTSI2SD xmm1, r32/m32
- short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET);
- short src = enc.reg(in(1));
-
- // Fopcode
- enc.add1(0xF2);
- // rex prefix must come next (REX.W is not set)
- x86_64_v2.rexF(dst, src, 0, true, enc);
-
- enc.add1(0x0F).add1(0x2A);
-
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.sse(enc,0xF2,0x0F2A,true,enc.reg(this)-x86_64_v2.XMM_OFFSET,enc.reg(in(1)));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java
index 5e406911..5a4ff4b2 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeInteger;
@@ -21,14 +22,7 @@ public abstract class ImmX86 extends MachConcreteNode implements MachNode {
abstract int mod();
@Override public void encoding( Encoding enc ) {
- short dst = enc.reg(this); // Also src1
- enc.add1(x86_64_v2.rex(0, dst, 0));
- // opcode; 0x81 or 0x83; 0x69 or 0x6B
- enc.add1( opcode() + (x86_64_v2.imm8(_imm) ? 2 : 0) );
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, mod(), dst) );
- // immediate(4 bytes) 32 bits or (1 byte)8 bits
- if( x86_64_v2.imm8(_imm) ) enc.add1(_imm);
- else enc.add4(_imm);
+ X86.imm(enc,opcode(),mod(),enc.reg(this),_imm);
}
// General form: "addi dst += #imm"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java
index 3f2f696c..656b1543 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.Type;
@@ -22,44 +23,7 @@ public class IntX86 extends ConstantNode implements MachNode {
}
@Override public void encoding( Encoding enc ) {
- short dst = enc.reg(this);
- // Short form for zero
- if( _con==Type.NIL || _con==TypeInteger.ZERO ) {
- // XOR dst,dst. Can skip REX is dst is low 8, makes this a 32b
- // xor, which will also zero the high bits.
- if( dst >= 8 ) enc.add1(x86_64_v2.rex(dst, dst, 0));
- enc.add1(0x33); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, dst));
- return;
- }
-
- // Simply move the constant into a GPR
- // Conditional encoding based on 64 or 32 bits
- //REX.W + C7 /0 id MOV r/m64, imm32
-
- long imm = ((TypeInteger)_con).value();
- if (Integer.MIN_VALUE <= imm && imm < 0) {
- // We need sign extension, so use imm32 into 64 bit register
- // REX.W + C7 /0 id MOV r/m64, imm32
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1(0xC7); // 32 bits encoding
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0x00, dst));
- enc.add4((int)imm);
- } else if (0 <= imm && imm <= 0xFFFFFFFFL) {
- // We want zero extension into 64 bit register
- // so move 32 bit into 32 bit register which zeros
- // the upper bits in the 64 bit register.
- // B8+ rd id MOV r32, imm32
- if (dst >= 8) enc.add1(0x41);
- enc.add1(0xB8 + (dst & 0x07));
- enc.add4((int)imm);
- } else {
- // Just write the full 64 bit constant
- // REX.W + B8+ rd io MOV r64, imm64
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1(0xB8 + (dst & 0x07));
- enc.add8(imm); // 64 bits encoding
- }
+ X86.constant(enc,enc.reg(this),_con==Type.NIL ? 0 : ((TypeInteger)_con).value());
}
// Human-readable form appended to the SB. Things like the encoding,
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java
index de27aa5c..10cee059 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -30,38 +31,21 @@ public class JmpX86 extends IfNode implements MachNode, RIPRelSize {
@Override public void negate() { _bop = negate(_bop); }
@Override public void encoding( Encoding enc ) {
- if( in(1)!=null ) {
- int op = x86_64_v2.jumpop(_bop);
- enc.add1(op-16).add1(0); // Short form jump
- } else {
- if( _bop=="!=" ) return; // Inverted, no code
- enc.add1(0xEB).add1(0); // Never-node
- }
+ if( in(1)==null && _bop=="!=" ) return;
+ X86.branch(enc,in(1)==null ? -1 : x86_64_v2.jumpop(_bop)&15);
enc.jump(this,cproj(0));
}
// Delta is from opcode start, but X86 measures from the end of the 2-byte encoding
@Override public byte encSize(int delta) {
- if( in(1)==null && _bop=="!=" ) return 0; // Inverted never-node, no code
- return (byte)(x86_64_v2.imm8(delta-2) ? 2 : 6);
+ if( in(1)==null && _bop=="!=" ) return 0;
+ return X86.branchSize(delta,in(1)!=null);
}
// Delta is from opcode start
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
- assert !( in(1)==null && _bop=="!=" ); // Inverted never-node, no code no patch
- byte[] bits = enc.bits();
- if( opLen==2 ) {
- assert in(1)==null || bits[opStart] == x86_64_v2.jumpop(_bop)-16;
- delta -= 2; // Offset from opcode END
- assert (byte)delta==delta;
- bits[opStart+1] = (byte)delta;
- } else {
- assert in(1)==null || bits[opStart] == x86_64_v2.jumpop(_bop)-16;
- delta -= 6; // Offset from opcode END
- bits[opStart] = 0x0F;
- bits[opStart+1] = (byte)(in(1)==null ? 0xE9 : x86_64_v2.jumpop(_bop));
- enc.patch4(opStart+2,delta);
- }
+ assert !(in(1)==null && _bop=="!=");
+ X86.patchBranch(enc.bits(),opStart,opLen,delta,in(1)==null ? -1 : x86_64_v2.jumpop(_bop)&15);
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java
index 2cd6018f..4b00e4dd 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -23,25 +24,7 @@ public class LeaX86 extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return x86_64_v2.WMASK; }
@Override public void encoding( Encoding enc ) {
- // REX.W + 8D /r LEA r64,m
- short dst = enc.reg(this);
- short ptr = enc.reg(in(1));
- short idx = enc.reg(in(2));
- // ptr is null
- // just do: [(index * s) + disp32]
- if( ptr == -1 ) {
- enc.add1(x86_64_v2.rex(dst, 0, idx));
- enc.add1(0x8D); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT, dst, 0x04));
- enc.add1(x86_64_v2.sib(_scale, idx, x86_64_v2.RBP));
- enc.add4(_offset);
- return;
- }
-
- enc.add1(x86_64_v2.rex(dst, ptr, idx));
- enc.add1(0x8D); // opcode
- // rsp is hard-coded here(0x04)
- x86_64_v2.indirectAdr(_scale, idx, ptr, _offset, dst, enc);
+ X86.lea(enc,enc.reg(this),enc.reg(in(1)),enc.reg(in(2)),_offset,_scale);
}
// General form: "lea dst = base + 4*idx + 12"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java
index d0fb0081..d4f1413e 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.LoadNode;
import com.seaofnodes.simple.node.Node;
@@ -24,33 +25,14 @@ public class LoadX86 extends MemOpX86 {
}
static void enc( Encoding enc, Type decl, short dst, short ptr, short idx, int off, int scale ) {
- // Allocation may put a full-width integer in an XMM register (or a
- // floating value in a GPR). Move its bits using the selected register bank.
- if( dst>=x86_64_v2.XMM_OFFSET && decl.log_size()==3 ) decl=TypeFloat.F64;
- else if( dst<x86_64_v2.XMM_OFFSET && decl instanceof TypeFloat )
- decl = decl==TypeFloat.F32 ? TypeInteger.U32 : TypeInteger.BOT;
- if( decl == TypeFloat.F32) enc.add1(0xF3);
- if( decl == TypeFloat.F64) enc.add1(0xF2);
-
- if( decl.isa(TypeFloat.F64) )
- dst -= (short)x86_64_v2.XMM_OFFSET;
-
- x86_64_v2.rexF(dst, ptr, idx, decl != TypeInteger.U32 && decl != TypeFloat.F32 && decl != TypeFloat.F64, enc);
-
- if( false ) ;
- else if( decl == TypeFloat.F32 ) enc.add1(0x0F).add1(0x10); // F3 0F 10 /r MOVSS xmm1, m32
- else if( decl == TypeFloat.F64 ) enc.add1(0x0F).add1(0x10); // F2 0F 10 /r MOVSD xmm1, m64
- else if( decl.isa(TypeInteger.I8)) enc.add1(0x0F).add1(0xBE); // sign extend: REX.W + 0F BE /r MOVSX r64, r/m8
- else if( decl == TypeInteger.I16 ) enc.add1(0x0F).add1(0xBF); // sign extend: REX.W + 0F BF /r MOVSX r64, r/m16
- else if( decl == TypeInteger.I32 ) enc.add1(0x63); // sign extend: REX.W + 63 /r MOVSXD r64, r/m32
- else if( decl == TypeInteger.U8 ) enc.add1(0x0F).add1(0xB6); // zero extend: REX.W + 0F B6 /r MOVZX r64, r/m8
- else if( decl == TypeInteger.U16 ) enc.add1(0x0F).add1(0xB7); // zero extend: REX.W + 0F B7 /r MOVZX r64, r/m16
- // Covers U32, I64/BOT, TMP
- else if( decl.log_size()>=2 ) enc.add1(0x8B); // zero extend: 8B /r MOV r32, r/m32
- else throw Utils.TODO();
-
- // includes modrm internally
- x86_64_v2.indirectAdr(scale, idx, ptr, off, dst, enc);
+ // The chapter chooses the register bank and extension from its own type facts.
+ boolean xmm=dst>=x86_64_v2.XMM_OFFSET;
+ if( xmm && decl.log_size()==3 ) decl=TypeFloat.F64;
+ else if( !xmm && decl instanceof TypeFloat )
+ decl=decl==TypeFloat.F32 ? TypeInteger.U32 : TypeInteger.BOT;
+ boolean signed=decl.isa(TypeInteger.I8) || decl==TypeInteger.I16 || decl==TypeInteger.I32;
+ X86.load(enc,decl.log_size(),signed,xmm,
+ xmm ? dst-x86_64_v2.XMM_OFFSET : dst,ptr,idx,off,scale);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java
index bd56d022..2e18a058 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -15,20 +16,7 @@ public class MemAddX86 extends MemOpX86 {
@Override public RegMask outregmap() { return null; }
@Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; }
@Override public void encoding( Encoding enc ) {
- // add something to memory
- // REX.W + 01 /r | REX.W + 81 /0 id
- // ADD [mem], imm32/reg
- short ptr = enc.reg(ptr());
- short idx = enc.reg(idx());
- short src = enc.reg(val());
-
- enc.add1(x86_64_v2.rex(src, ptr, idx));
- // opcode
- enc.add1( src == -1 ? (_imm==1 ? 0xFF : 0x81): 0x01);
-
- // includes modrm
- x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src == -1 ? 0 : src, enc);
- if( src == -1 && _imm!=1 ) enc.add4(_imm);
+ X86.addMem(enc,enc.reg(val()),_imm,enc.reg(ptr()),enc.reg(idx()),_off,_scale);
}
// General form: "add [base + idx<<2 + 12] += src"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java
index 7932c893..74616db7 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -13,16 +14,7 @@ public class MulFX86 extends MachConcreteNode implements MachNode {
@Override public boolean commutes() { return true; }
@Override public void encoding( Encoding enc ) {
- // F2 0F 59 /r MULSD xmm1,xmm2/m64
- short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET);
- short src = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET);
-
- // Fopcode
- enc.add1(0xF2);
- // rex prefix must come next (REX.W is not set)
- x86_64_v2.rexF(dst, src, 0, false, enc);
-
- enc.add1(0x0F).add1(0x59).add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.sse(enc,0xF2,0x0F59,false,enc.reg(this)-x86_64_v2.XMM_OFFSET,enc.reg(in(2))-x86_64_v2.XMM_OFFSET);
}
// General form: "mulf dst *= src"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java
index 1e9e708f..5dcb253d 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -17,15 +18,7 @@ public class MulIX86 extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return x86_64_v2.WMASK; }
// Rare 3-address form
@Override public final void encoding( Encoding enc ) {
- short dst = enc.reg(this ); // Also src1
- short src = enc.reg(in(1));
- enc.add1(x86_64_v2.rex(dst, src, 0));
- // opcode; 0x69 or 0x6B
- enc.add1( 0x69 + (x86_64_v2.imm8(_imm) ? 2 : 0) );
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src) );
- // immediate(4 bytes) 32 bits or (1 byte)8 bits
- if( x86_64_v2.imm8(_imm) ) enc.add1(_imm);
- else enc.add4(_imm);
+ X86.imul(enc,enc.reg(this),enc.reg(in(1)),_imm);
}
// General form: "addi dst += #imm"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java
index 4d2a11ed..6f3fcdeb 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -13,13 +14,7 @@ public class MulX86 extends MachConcreteNode implements MachNode {
@Override public boolean commutes() { return true; }
@Override public void encoding( Encoding enc ) {
- // REX.W + 0F AF /r IMUL r64, r/m64
- short dst = enc.reg(this ); // src1
- short src = enc.reg(in(2)); // src2
- enc.add1(x86_64_v2.rex(dst, src, 0));
- enc.add1(0x0F); // opcode
- enc.add1(0xAF); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.reg(enc,0x0FAF,enc.reg(this),enc.reg(in(2)));
}
// General form: "mul dst *= src"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java
index 0c2baced..86610f6d 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -13,10 +14,7 @@ public class NegX86 extends MachConcreteNode implements MachNode {
@Override public int twoAddress() { return 1; }
@Override public void encoding( Encoding enc ) {
- short dst = enc.reg(this );
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1(0xF7); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 3, dst));
+ X86.unary(enc,0xF7,3,enc.reg(this));
}
@Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)); }
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java
index fc896dce..1cfc1c42 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeFunPtr;
@@ -10,11 +11,8 @@ public class NewX86 extends NewNode implements MachNode {
NewX86( NewNode nnn ) { super(nnn); }
@Override public void encoding( Encoding enc ) {
enc.external(this,"calloc");
- // ldi rcx,#1 // number of elements to calloc
- enc.add1(0xB8 + _arg2Reg).add4(1);
- // E8 cd CALL rel32;
- enc.add1(0xE8);
- enc.add4(0); // offset
+ X86.constant(enc,_arg2Reg,1);
+ X86.call(enc);
}
// General form: "alloc #bytes PC"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java
index 7db80299..1e4e7c26 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -12,25 +13,9 @@ public class NotX86 extends MachConcreteNode implements MachNode {
@Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; }
@Override public void encoding( Encoding enc ) {
- assert !(in(1) instanceof NotNode); // Cleared out by peeps
- assert !(in(1) instanceof BoolNode); // Cleared out by peeps
- short dst = enc.reg(this );
- short src = enc.reg(in(1));
-
- // test rdi,rdi
- enc.add1(x86_64_v2.rex(src, src, 0));
- enc.add1(0x85);
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, src, src));
-
- // setz dstb; then zero-extend the low byte into the full register.
- if( dst >= 4 ) enc.add1(x86_64_v2.rex(0, dst, 0, false));
- enc.add1(0x0F);
- enc.add1(0x94);
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0, dst));
- if( dst >= 4 ) enc.add1(x86_64_v2.rex(dst, dst, 0, false));
- enc.add1(0x0F);
- enc.add1(0xB6);
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, dst));
+ assert !(in(1) instanceof NotNode); // Cleared out by peeps
+ assert !(in(1) instanceof BoolNode);
+ X86.not(enc,enc.reg(this),enc.reg(in(1)));
}
@Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)); }
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java
index 5a475efe..06755143 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -12,13 +13,7 @@ public abstract class RegX86 extends MachConcreteNode {
@Override public int twoAddress() { return 1; }
abstract int opcode();
@Override public void encoding( Encoding enc ) {
- // REX.W + 01 /r
- short dst = enc.reg(in(1)); // src1
- short src = enc.reg(in(2)); // src2
-
- enc.add1(x86_64_v2.rex(dst, src, 0));
- enc.add1(opcode()); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.reg(enc,opcode(),enc.reg(in(1)),enc.reg(in(2)));
}
// General form: "add dst += src"
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java
index a35d43a2..e4467bb4 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.*;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
@@ -8,12 +9,7 @@ public class RetX86 extends ReturnNode implements MachNode {
RetX86( ReturnNode ret, FunNode fun ) { super(ret, fun); fun.setRet(this); }
@Override public void encoding( Encoding enc ) {
int sz = fun()._frameAdjust;
- if( sz != 0 ) {
- enc.add1( x86_64_v2.REX_W ).add1( x86_64_v2.imm8(sz) ? 0x83 : 0x81 );
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0b000, x86_64_v2.RSP) );
- if( x86_64_v2.imm8(sz) ) enc.add1(sz);
- else enc.add4(sz);
- }
- enc.add1(0xC3);
+ if( sz!=0 ) X86.imm(enc,0x81,0,x86_64_v2.RSP,sz);
+ X86.ret(enc);
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java
index 95e0c336..cf6275dc 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.codegen.Encoding;
import com.seaofnodes.simple.codegen.RegMask;
@@ -22,15 +23,7 @@ public class SarIX86 extends MachConcreteNode implements MachNode {
@Override public int twoAddress() { return 1; }
@Override public void encoding(Encoding enc) {
- short dst = enc.reg(this); // Also src1
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1( opcode());
-
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, mod(), dst) );
-
- // immediate(4 bytes) 32 bits or (1 byte)8 bits
- if( x86_64_v2.imm8(_imm) ) enc.add1(_imm);
- else enc.add4(_imm);
+ X86.shift(enc,mod(),enc.reg(this),_imm);
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java
index 4cc8b558..92493712 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
@@ -15,10 +16,6 @@ public class SarX86 extends RegX86 {
}
@Override int opcode() { return 0xD3; }
@Override public void encoding( Encoding enc ) {
- short dst = enc.reg(this ); // src1
- short src = enc.reg(in(2)); // src2
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1(opcode()); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 7, dst));
+ X86.unary(enc,opcode(),7,enc.reg(this));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
index 0eff2afe..533d5652 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -24,26 +25,14 @@ public class SetX86 extends MachConcreteNode implements MachNode {
@Override public RegMask outregmap() { return x86_64_v2.WMASK; }
@Override public void encoding( Encoding enc ) {
- // REX + 0F 94
- short dst = enc.reg(this );
-
- // Optional rex, for dst
- if( dst >= 4 ) enc.add1(x86_64_v2.rex(0, dst, 0, false));
- enc.add1(0x0F); // opcode
- enc.add1(switch (_bop) {
+ int op=switch (_bop) {
case "==" -> 0x94; // SETE
case "<" -> _unsigned ? 0x92 : 0x9C; // SETB /SETL
case "<=" -> _unsigned ? 0x96 : 0x9E; // SETBE/SETLE
case ">=" -> _unsigned ? 0x93 : 0x9D; // SETAE/SETGE
default -> throw Utils.TODO();
- });
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0, dst));
-
- // low 8 bites are set, now zero extend for next instruction
- if( dst >= 4 ) enc.add1(x86_64_v2.rex(dst, dst, 0, false));
- enc.add1(0x0F); // opcode
- enc.add1(0xB6); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, dst));
+ };
+ X86.set(enc,op&15,enc.reg(this));
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java
index f7b2f28a..1e62243e 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.node.Node;
@@ -23,15 +24,7 @@ public class ShlIX86 extends MachConcreteNode implements MachNode {
@Override public String op() { return "shli"; }
@Override public String glabel() { return "<<"; }
@Override public void encoding(Encoding enc) {
- short dst = enc.reg(this); // Also src1
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1( opcode());
-
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, mod(), dst) );
-
- // immediate(4 bytes) 32 bits or (1 byte)8 bits
- if( x86_64_v2.imm8(_imm) ) enc.add1(_imm);
- else enc.add4(_imm);
+ X86.shift(enc,mod(),enc.reg(this),_imm);
}
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" ").p(glabel()).p("= #").p(_imm);
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java
index 5fee72d9..768d97e7 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
@@ -15,10 +16,6 @@ public class ShlX86 extends RegX86 {
}
@Override int opcode() { return 0xD3; }
@Override public final void encoding( Encoding enc ) {
- short dst = enc.reg(this ); // src1
- short src = enc.reg(in(2)); // src2
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1(opcode()); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 4, dst));
+ X86.unary(enc,opcode(),4,enc.reg(this));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java
index 7e0378b1..8a0d1b58 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.node.Node;
@@ -18,15 +19,7 @@ public class ShrIX86 extends MachConcreteNode implements MachNode {
@Override public int twoAddress() { return 1; }
@Override public void encoding(Encoding enc) {
- short dst = enc.reg(this); // Also src1
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1( opcode());
-
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, mod(), dst) );
-
- // immediate(4 bytes) 32 bits or (1 byte)8 bits
- if( x86_64_v2.imm8(_imm) ) enc.add1(_imm);
- else enc.add4(_imm);
+ X86.shift(enc,mod(),enc.reg(this),_imm);
}
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(" ").p(glabel()).p("= #").p(_imm);
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java
index 67dcf055..1ba20fee 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.Node;
import com.seaofnodes.simple.util.Utils;
@@ -15,10 +16,6 @@ public class ShrX86 extends RegX86 {
}
@Override int opcode() { return 0xD3; }
@Override public final void encoding( Encoding enc ) {
- short dst = enc.reg(this ); // src1
- short src = enc.reg(in(2)); // src2
- enc.add1(x86_64_v2.rex(0, dst, 0));
- enc.add1(opcode()); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 5, dst));
+ X86.unary(enc,opcode(),5,enc.reg(this));
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java
index 4a14240a..e8281975 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.FunNode;
import com.seaofnodes.simple.node.Node;
@@ -19,44 +20,17 @@ public class SplitX86 extends SplitNode {
// Need to handle 8 cases: . reg->reg, reg->xmm, reg->flags, xmm->reg, xmm->xmm, xmm->flags, flags->reg, flags->xmm,
// flags->flags.
@Override public void encoding( Encoding enc ) {
- // REX.W + 8B /r MOV r64, r/m64
- short dst = enc.reg(this );
- short src = enc.reg(in(1));
- if( dst == x86_64_v2.FLAGS ) {
- // mov reg, flags
- // push rcx
- // popf (Pop the top of the stack into the FLAGS register)
- // 50+rd PUSH r64
- x86_64_v2.rexF(0,src,0,false,enc);
- enc.add1(0x50 + src);
- // popf
- enc.add1(0x9D);
- return;
- }
- if( src == x86_64_v2.FLAGS ) {
- // mov flags, reg
- // pushf; pop reg
- enc.add1(0x9C);
- // 58+ rd POP r64
- x86_64_v2.rexF(0,dst,0,false, enc);
- enc.add1(0x58 + dst);
- return;
- }
-
- // Flag for being either XMM or stack
- boolean dstX = dst >= x86_64_v2.XMM_OFFSET;
- boolean srcX = src >= x86_64_v2.XMM_OFFSET;
-
+ short dst=enc.reg(this), src=enc.reg(in(1));
+ if( dst==x86_64_v2.FLAGS ) { X86.flags(enc,src,true); return; }
+ if( src==x86_64_v2.FLAGS ) { X86.flags(enc,dst,false); return; }
+ boolean dstX=dst>=x86_64_v2.XMM_OFFSET, srcX=src>=x86_64_v2.XMM_OFFSET;
// Stack spills
if( dst >= x86_64_v2.MAX_REG ) {
int off = enc._fun.computeStackOffset(enc._code,dst);
if( src >= x86_64_v2.MAX_REG ) {
// Rare stack-stack move. push [RSP+soff]; pop [RSP+doff]
int soff = enc._fun.computeStackOffset(enc._code,src);
- enc.add1(0xFF);
- x86_64_v2.indirectAdr(0, (short)-1/*index*/, (short)x86_64_v2.RSP, soff, 6, enc);
- enc.add1(0x8F);
- x86_64_v2.indirectAdr(0, (short)-1/*index*/, (short)x86_64_v2.RSP, off, 0, enc);
+ X86.stackCopy(enc,soff,off);
return;
}
StoreX86.encVal(enc, srcX ? TypeFloat.F64 : TypeInteger.BOT, (short)x86_64_v2.RSP, (short)-1/*index*/, src, off, 0);
@@ -68,35 +42,8 @@ public class SplitX86 extends SplitNode {
return;
}
- // reg-reg move. Adjust numbering for GPR vs FPR reg set
- if( dstX ) dst -= (short) x86_64_v2.XMM_OFFSET;
- if( srcX ) src -= (short) x86_64_v2.XMM_OFFSET;
-
- // 0x66 if moving between register classes
- if( dstX ^ srcX ) enc.add1(0x66);
- if( !dstX && srcX )
- { short tmp=src; src=dst; dst=tmp; }
- enc.add1(x86_64_v2.rex(dst, src, 0));
-
- // pick opcode based on regs
- if( !dstX && !srcX ) {
- // reg->reg (MOV r64, r/m64)
- enc.add1(0x8B);
- } else if( dstX && srcX ) {
- // xmm->xmm (NP 0F 28 /r MOVAPS xmm1, xmm2/m128)
- enc.add1(0x0F);
- enc.add1(0x28);
- } else if( dstX && !srcX ) {
- // reg->xmm (66 REX.W 0F 6E /r MOVQ xmm, r/m64)
- enc.add1(0x0F);
- enc.add1(0x6E);
- } else if( !dstX && srcX ) {
- // xmm->reg(66 0F 7E /r MOVQ r/m64, xmm)
- enc.add1(0x0F);
- enc.add1(0x7E);
- }
-
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.move(enc,dstX,srcX,dstX ? dst-x86_64_v2.XMM_OFFSET : dst,
+ srcX ? src-x86_64_v2.XMM_OFFSET : src);
}
// General form: "mov dst = src"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java
index b7b6c5d3..c83dfd44 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.print.ExprPrinter;
import com.seaofnodes.simple.codegen.*;
@@ -25,55 +26,16 @@ public class StoreX86 extends MemOpX86 {
// Register mask allowed as a result. 0 for no register.
@Override public RegMask outregmap() { return null; }
@Override public void encoding( Encoding enc ) {
- // REX.W + C7 /0 id MOV r/m64, imm32 |
- // REX.W + 89 /r MOV r/m64, r64
- short ptr = enc.reg(ptr());
- short idx = enc.reg(idx());
- short src = enc.reg(val());
-
- if( src == -1 ) {
- int log = _declaredType.log_size();
- x86_64_v2.rexF(-1, ptr, idx, log==3, enc);
- switch( log ) {
- case 0: enc .add1(0xC6); break;
- case 1: enc.add1(0x66).add1(0xC7); break;
- case 2: enc .add1(0xC7); break;
- case 3: enc .add1(0xC7); break;
- }
- x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src, enc);
- switch( log ) {
- case 0: enc.add1(_imm); break;
- case 1: enc.add2(_imm); break;
- case 2: enc.add4(_imm); break;
- case 3: enc.add4(_imm); break; // Limit of a 4 byte immediate
- }
- } else {
- encVal(enc,_declaredType,ptr,idx,src,_off,_scale);
- }
+ short ptr=enc.reg(ptr()), idx=enc.reg(idx()), src=enc.reg(val());
+ if( src==-1 ) X86.storeImm(enc,_declaredType.log_size(),_imm,ptr,idx,_off,_scale);
+ else encVal(enc,_declaredType,ptr,idx,src,_off,_scale);
}
// Non-immediate encoding
static void encVal( Encoding enc, Type decl, short ptr, short idx, short src, int off, int scale ) {
- int log = decl.log_size();
- // Float reg being stored
- if( src >= x86_64_v2.XMM_OFFSET ) {
- src -= (short)x86_64_v2.XMM_OFFSET;
- assert log == 2 || log == 3;
- enc.add1( log==2 ? 0xF3 : 0xF2 );
- x86_64_v2.rexF(src,ptr,idx,false,enc);
- enc.add1(0x0F).add1(0x11);
- } else {
- // byte stores from sil, dil, bpl, spl need a rex
- if( log == 0 && src >= x86_64_v2.RSP ) enc.add1(x86_64_v2.rex(src,ptr,idx,false));
- else x86_64_v2.rexF(src,ptr,idx,log==3,enc);
- switch( log ) {
- case 0: enc .add1(0x88); break;
- case 1: enc.add1(0x66).add1(0x89); break;
- case 2: enc .add1(0x89); break;
- case 3: enc .add1(0x89); break;
- }
- }
- x86_64_v2.indirectAdr(scale, idx, ptr, off, src, enc);
+ boolean xmm=src>=x86_64_v2.XMM_OFFSET;
+ X86.store(enc,decl.log_size(),xmm,
+ xmm ? src-x86_64_v2.XMM_OFFSET : src,ptr,idx,off,scale);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java
index b6530a87..29f0033a 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.util.SB;
@@ -12,16 +13,7 @@ public class SubFX86 extends MachConcreteNode implements MachNode {
@Override public int twoAddress() { return 1; }
@Override public void encoding( Encoding enc ) {
- // F2 0F 5C /r SUBSD xmm1, xmm2/m64
- short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET);
- short src = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET);
- // Fopcode
- enc.add1(0xF2);
- // rex prefix must come next (REX.W is not set)
- x86_64_v2.rexF(dst, src, 0, false, enc);
-
- enc.add1(0x0F).add1(0x5C);
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ X86.sse(enc,0xF2,0x0F5C,false,enc.reg(this)-x86_64_v2.XMM_OFFSET,enc.reg(in(2))-x86_64_v2.XMM_OFFSET);
}
// General form: "subf dst -= src"
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
index 359b6d83..fff2fb04 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.node.cpus.riscv.riscv;
@@ -23,24 +24,9 @@ public class TFPX86 extends ConstantNode implements MachNode, RIPRelSize {
}
@Override public void encoding( Encoding enc ) {
- short dst = enc.reg(this);
- // Short form for zero
- if( _con==Type.NIL ) {
- // XOR dst,dst. Can skip REX is dst is low 8, makes this a 32b
- // xor, which will also zero the high bits.
- if( dst >= 8 ) enc.add1(x86_64_v2.rex(dst, dst, 0));
- enc.add1(0x33); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, dst));
- return;
- }
-
- // lea to load function pointer address
- // lea rax, [rip+disp32]
+ if( _con==Type.NIL ) { X86.constant(enc,enc.reg(this),0); return; }
enc.relo(this);
- enc.add1(x86_64_v2.rex(dst, 0, 0));
- enc.add1(0x8D); // opcode
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT, dst, 0b101));
- enc.add4(0);
+ X86.rip(enc,0,0x8D,true,enc.reg(this));
}
@Override public byte encSize(int delta) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java
index c23f6c5f..c78ac6de 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.TypeMemPtr;
@@ -15,8 +16,8 @@ public class TMPX86 extends ConstantNode implements MachNode, RIPRelSize{
@Override public void encoding( Encoding enc ) {
short dst = enc.reg(this);
- x86_64_v2.rexF(dst, 0, 0, true, enc);
- enc.add1(0x8D).add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT, dst, 0b101)).add4(0);
+ X86.rexF(dst, 0, 0, true, enc);
+ enc.add1(0x8D).add1(X86.modrm(X86.MOD.INDIRECT, dst, 0b101)).add4(0);
int opLen = 1/*rexF*/+1/*opcode 0x8D*/+1/*modrm*/+4/*pc rel offset*/;
// Base of constant array
TypeMemPtr tmp = (TypeMemPtr)_con;
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java
index 6f538d27..591a51c3 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java
@@ -1,5 +1,6 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
+import com.seaofnodes.isa.X86;
import com.seaofnodes.simple.codegen.*;
import com.seaofnodes.simple.node.*;
@@ -19,29 +20,17 @@ public class UJmpX86 extends CFGNode implements MachNode, RIPRelSize {
@Override public Node idealize() { throw Utils.TODO(); }
@Override public void encoding( Encoding enc ) {
enc.jump(this,uctrl());
- // Short-form jump
- enc.add1(0xEB).add1(0);
- //// E9 cd JMP rel32
- //enc.add1(0xE9).add4(0);
+ X86.branch(enc,-1);
}
// Delta is from opcode start, but X86 measures from the end of the 2-byte encoding
- @Override public byte encSize(int delta) { return (byte)(x86_64_v2.imm8(delta-2) ? 2 : 5); }
+ @Override public byte encSize(int delta) {
+ return X86.branchSize(delta,false);
+ }
// Delta is from opcode start
@Override public void patch( Encoding enc, int opStart, int opLen, int delta ) {
- byte[] bits = enc.bits();
- if( opLen==2 ) {
- assert bits[opStart] == (byte)0xEB;
- delta -= 2; // Offset from opcode END
- assert (byte)delta==delta;
- bits[opStart+1] = (byte)delta;
- } else {
- assert bits[opStart] == (byte)0xEB;
- bits[opStart] = (byte)0xE9; // Long form
- delta -= 5; // Offset from opcode END
- enc.patch4(opStart+1,delta);
- }
+ X86.patchBranch(enc.bits(),opStart,opLen,delta,-1);
}
@Override public void asm(CodeGen code, SB sb) {
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
index cf9288b8..4beef793 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
@@ -69,13 +69,6 @@ public class x86_64_v2 extends Machine {
public static int REX_WRB= 0x4D;
public static int REX_WB = 0x49;
- public enum MOD {
- INDIRECT, // [mem]
- INDIRECT_disp8, // [mem + 0x12]
- INDIRECT_disp32, // [mem + 0x12345678]
- DIRECT, // mem
- };
-
// opcode included here
// 0F 84 cd JE rel32
// 0F 85 cd JNE rel32
@@ -95,90 +88,6 @@ public class x86_64_v2 extends Machine {
};
}
- public static int modrm(MOD mod, int reg, int m_r) {
- if( reg == -1 ) reg=0; // Missing reg in this flavor
- // combine all the bits
- assert 0 <= reg && reg < 16;
- assert 0 <= m_r && m_r < 16;
- return (mod.ordinal() << 6) | ((reg & 0x07) << 3) | m_r & 0x07;
- }
-
- // 00 000 000
- // same bit-layout as modrm
- public static int sib(int scale, int index, int base) {
- assert 0 <= base && base < 16;
- assert 0 <= index && index < 16;
- return (scale << 6) | ((index & 0x07) << 3) | base & 0x07;
- }
-
- // reg1 is reg(R)
- // reg2 is r/mem(B)
- // reg3 is X(index)
- // reg4 is X(base)
-
- // 0 denotes no direct register
- public static int rex(int reg, int ptr, int idx, boolean wide) {
- // assuming 64 bit by default so: 0100 1000
- assert -1 <= reg && reg < 16;
- assert -1 <= ptr && ptr < 16;
- assert -1 <= idx && idx < 16;
-
- int rex = wide ? REX_W : REX;
- if( 8 <= reg ) rex |= 0b00000100; // REX.R
- if( 8 <= ptr ) rex |= 0b00000001; // REX.B
- if( 8 <= idx ) rex |= 0b00000010; // REX.X
- return rex;
- }
-
- public static int rex(int reg, int ptr, int idx) {
- return rex(reg, ptr, idx, true);
- }
-
- // rex for floats. Return size (0 or 1)
- // don't need to use REX if 0x40.
- public static byte rexF(int reg, int ptr, int idx, boolean wide, Encoding enc) {
- int rex = rex(reg, ptr, idx, wide);
- if (rex == REX) return 0;
- enc.add1(rex);
- return 1;
- }
- // Function used for encoding indirect memory addresses
- // Does not always generate SIB byte e.g index == -1.
- // -1 denotes empty value, not set - note 0 is different from -1 as it can represent rax.
- // Looks for best mod locally
- public static void indirectAdr( int scale, short index, short base, int offset, int reg, Encoding enc ) {
- // Assume indirect
- assert 0 <= base && base < 16;
- assert -1 <= index && index < 16 && index != RSP;
-
- MOD mod = MOD.INDIRECT;
- // is 1 byte enough or need more?
- if( offset != 0 )
- mod = imm8(offset)
- ? MOD.INDIRECT_disp8
- : MOD.INDIRECT_disp32;
-
- if( mod == MOD.INDIRECT && (base == RBP || base == R13) ) {
- mod = MOD.INDIRECT_disp8;
- } else if( index == -1 && (base == RSP || base == R12) ) {
- index = RSP;
- }
-
- if( index == -1 ) {
- enc.add1(modrm(mod, reg, base));
- } else {
- enc.add1(modrm(mod, reg, x86_64_v2.RSP));
- enc.add1(sib(scale, index, base));
- }
-
- if( mod == MOD.INDIRECT_disp8 ) {
- enc.add1(offset);
- } else if( mod == MOD.INDIRECT_disp32 ) {
- enc.add4(offset);
- }
- }
-
-
// Limit of float args passed in registers
static RegMask[] XMMS8 = new RegMask[]{
new RegMask(XMM0), new RegMask(XMM1), new RegMask(XMM2), new RegMask(XMM3),
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/BrainFuckTest.java b/chapter23/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
index bf809d2a..9f626805 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
@@ -1,5 +1,9 @@
package com.seaofnodes.simple;
+import com.seaofnodes.isa.eval.EvalRisc5;
+
+import com.seaofnodes.isa.eval.EvalArm64;
+
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.node.cpus.arm.arm;
import com.seaofnodes.simple.node.cpus.riscv.riscv;
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter23/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 14f9fdb8..9aa18821 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -1,5 +1,9 @@
package com.seaofnodes.simple;
+import com.seaofnodes.isa.eval.EvalRisc5;
+
+import com.seaofnodes.isa.eval.EvalArm64;
+
import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.node.cpus.arm.arm;
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java
index def21258..46457b40 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/Chapter22Test.java
@@ -1,5 +1,9 @@
package com.seaofnodes.simple;
+import com.seaofnodes.isa.eval.EvalRisc5;
+
+import com.seaofnodes.isa.eval.EvalArm64;
+
import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen;
import com.seaofnodes.simple.codegen.CodeGen;
import java.io.IOException;
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java b/chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java
index 41f0df6e..10d27ac8 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/Chapter23Test.java
@@ -1,5 +1,9 @@
package com.seaofnodes.simple;
+import com.seaofnodes.isa.eval.EvalRisc5;
+
+import com.seaofnodes.isa.eval.EvalArm64;
+
import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.*;
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java b/chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java
deleted file mode 100644
index e0cbdcff..00000000
--- a/chapter23/src/test/java/com/seaofnodes/simple/EvalArm64.java
+++ /dev/null
@@ -1,766 +0,0 @@
-package com.seaofnodes.simple;
-
-import com.seaofnodes.simple.codegen.Encoding;
-import com.seaofnodes.simple.node.cpus.arm.arm;
-import com.seaofnodes.simple.util.Utils;
-import java.io.ByteArrayOutputStream;
-
-public class EvalArm64 {
- // Memory image, always 0-based
- public final byte[] _buf;
-
- // GPRs
- final long[] regs;
- // FRs
- final double[] fregs;
-
- int _pc;
-
- // Start of free memory for allocation
- int _heap;
-
- // Standard out and err streams
- ByteArrayOutputStream _stdout, _stderr;
-
- // Cycle counters
- int _cycle;
-
- // flags
- boolean N = false;
- boolean Z = false;
- boolean C = false;
- boolean V = false;
-
- EvalArm64(byte[] buf, int stackSize) {
- _buf = buf;
- regs = new long[32];
- fregs = new double[32];
- // Stack grows down, heap grows up
- regs[arm.RSP] = _heap = stackSize;
- _pc = 0;
- }
-
- // Little endian
- public int ld1s(int x) { return _buf[x ] ; }
- public int ld1z(int x) { return _buf[x ]&0xFF; }
- public int ld2s(int x) { return ld1z(x) | ld1s(x+1)<< 8; }
- public int ld2z(int x) { return ld1z(x) | ld1z(x+1)<< 8; }
- public int ld4s(int x) { return ld2z(x) | ld2s(x+2)<<16; }
- public long ld8 (int x) { return (long)ld4s(x)&0xFFFFFFFFL | ((long)ld4s(x+4))<<32; }
-
-
- public float ld4f(int x) { return Float.intBitsToFloat(ld4s(x)); }
- public double ld8f(int x) { return Double.longBitsToDouble(ld8(x)); }
-
- public void st1(int x, int val) { _buf[x] = (byte)val; }
- public void st2(int x, int val) { st1(x,val); st1(x+1,val>> 8); }
- public void st4(int x, int val) { st2(x,val); st2(x+2,val>>16); }
- public void st8(int x, long val) { st4(x,(int)val); st4(x+4,(int)(val>>32)); }
-
- public int step(int maxops) {
- int trap = 0;
- long rval = 0;
- double frval = 0;
- int pc = _pc;
- int cycle = _cycle;
- boolean is_f = false;
- outer:
- for(int icount = 0; icount < maxops; icount++) {
- int ir = 0;
- rval = 0;
- frval = 0;
- cycle++;
- if( pc >= _buf.length ) {
- trap = 1 + 1; // Handle access violation on instruction read.
- break;
- }
-
- if( (pc & 3)!=0 ) {
- trap = 1; // Handle PC-misaligned access
- break;
- }
-
- // Load instruction from image buffer at PC
- ir = ld4s( pc );
-
- int rdid = ir & 0x1f;
- // [31:24]
- int opcode1 = (ir >> 24) & 0xFF;
-
- // for the opcode we just match for bits[31:24];
- switch( opcode1 ) {
- case 0x14, 0x15, 0x16, 0x17: { //b
- int imm26 = ir << 6 >> 6;
- pc = pc + (imm26 * 4) - 4;
- rdid = -1;
- break;
- }
- case 0x1E: { // floats
- is_f = true;
- int rs1 = (ir >> 5) & 0x1F;
- int rs2 = (ir >> 16) & 0x1F;
-
- int op = (ir >> 10) & 0x3F;
- switch(op) {
- case 16: frval = fregs[rs1]; break; // fmov
- case 10:frval = fregs[rs1] + fregs[rs2]; break; // fadd
-
- case 6: if (fregs[rs2] == 0) frval = 0; else frval = fregs[rs1] / fregs[rs2]; break; // fdiv
- case 8: {
- // fcmp
- double lhs = fregs[rs1];
- double rhs = fregs[rs2];
-
- Z = (lhs == rhs);
- N = (lhs < rhs);
- C = lhs >= rhs;
- V = Double.isNaN(lhs) || Double.isNaN(rhs);
- rdid = -1;
-
- break;
- }
- case 2: frval = fregs[rs1] * fregs[rs2]; break; // fmul
- case 14: frval = fregs[rs1] - fregs[rs2]; break; // fsub
- default: trap = (2+1);
- }
- break;
- }
-
- case 0x38: {
- // STRB/LDRB(register)
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- // full opcode
- opcode1 = (ir >> 21) & 0x7FF;
- switch( ir >> 21 & 0x7 ) {
- case 0x1 -> { // store
- if( opcode1 == arm.OP_STORE_R_8 ) st1((int)regs[rn] + (int)regs[rm], (int)regs[rdid]);
- else trap = (2+1);
- rdid = -1;
- }
- case 0x3 -> { // load
- if( opcode1 == arm.OP_LOAD_R_8 ) rval = ld1s((int)regs[rn] + (int)regs[rm]);
- else trap = (2+1);
- }
- default -> trap = (2+1);
- }
- break;
- }
- case 0x39: {
- // STRB/LDRB(immediate)
- // str/ldr(immediate)
- // rn
- int base = ir >> 5 & 0x1F;
- int imm = (ir >> 10) & 0xFFF;
- rval = regs[base] + imm;
- int opc = (ir >> 22) & 0x3;
- // full opcode
- opcode1 = (ir >> 22) & 0x3FF;
-
- switch(opc) {
- case 0x0: {
- // store
- if(opcode1 == arm.OP_STORE_IMM_8) {
- st1((int)rval, (int)regs[rdid]);
- } else trap = (2+1);
- rdid = -1;
-
- break;
- }
- case 0x1: {
- // LDR (immediate)
- if(opcode1 == arm.OP_LOAD_IMM_8) {
- rval = ld1s((int)rval);
- } else trap = (2+1);
- rdid = -1;
- break;
- }
- default: trap = (2+1);
- }
- break;
- }
- case 0x54: {
- // b.cond
- int imm19 = ir << 8 >> 13;
- imm19 = pc + (imm19 * 4) - 4;
- rdid = -1;
-
- switch(ir & 0xF) {
- case 0x0: if(Z) pc = imm19; break; // eq
- case 0x1: if(!Z) pc = imm19; break; // ne
- case 0x2: if(C) pc = imm19; break; // cs
- case 0x3: if(!C) pc = imm19; break;
- case 0x4: if(N) pc = imm19; break; // mi
- case 0x5: if(!N) pc = imm19; break; // pl
- case 0x6: if(V) pc = imm19; break; // vs
- case 0x7: if(!V) pc = imm19; break; // vc
- case 0x8: if(C && !Z) pc = imm19; break; // hi
- case 0x9: if(!C || Z) pc = imm19; break; // ls
- case 0xA: if(N == V) pc = imm19; break; // ge
- case 0xB: if(N != V) pc = imm19; break; // lt
- case 0xC: if(!Z && N == V) pc = imm19; break; // gt
- case 0xD: if(Z || N != V) pc = imm19; break; // le
- case 0xE: pc = imm19; break; // always executed(al)
- default: trap = (2+1);
- }
- break;
- }
-
- case 0x5c: {
- // ldr
- is_f = true;
- // address = delta
- int address = ir << 8 >> 13;
- address *= 4;
- if(address >= _buf.length-3) trap = (5 + 1);
- frval = ld8f(pc + address);
- break;
- }
-
- case 0x78: {
- // STRH/LDRH(register)
- int opc = ir >> 21 & 0x7;
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- // full opcode
- opcode1 = (ir >> 21) & 0x7FF;
- switch(opc) {
- case 0x1: {
- // store
- if(opcode1 == arm.OP_STORE_R_16) {
- st1((int)regs[rn] + (int)regs[rm], (int)regs[rdid]);
- }else {
- trap = (2+1);
- }
- rdid = -1;
- break;
- }
- case 0x3: {
- // load
- if(opcode1 == arm.OP_LOAD_R_16) {
- rval = ld1s((int)regs[rn] + (int)regs[rm]);
- } else {
- trap = (2+1);
- }
- break;
- }
- default: trap = (2+1);
- }
- break;
- }
-
- case 0x79: {
- // STRH/LDRH(immediate)
- int base = ir >> 5 & 0x1F;
- int imm = (ir >> 10) & 0xFFF;
- imm *= 2;
- rval = regs[base] + imm;
- int opc = (ir >> 22) & 0x3;
- // full opcode
- opcode1 = (ir >> 22) & 0x3FF;
-
- switch(opc) {
- case 0x0: {
- // store
- if(opcode1 == arm.OP_STORE_IMM_16) {
- st2((int)rval, (int)regs[rdid]);
- } else trap = (2+1);
- rdid = -1;
-
- break;
- }
- case 0x1: {
- // LDR (immediate)
- if(opcode1 == arm.OP_LOAD_IMM_16) {
- rval = ld2s((int)rval);
- } else trap = (2+1);
- rdid = -1;
- break;
- }
- default: trap = (2+1);
- }
- break;
- }
-
- case 0x8A: { // AND
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- rval = regs[rn] & regs[rm];
- break;
- }
-
- case 0x8B, 0xCB: {
- // add/sub(register), unshifted form emitted by Simple
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- long lhs = regs[rn];
- long rhs = regs[rm];
- rval = opcode1==0x8B ? lhs + rhs : lhs - rhs;
- break;
- }
-
- case 0x90: { // adrp
- int immhi = ( (ir& ~0x1F) << 8 ) >> 8;
- int immlo = (ir>>29)& 3;
- int imm = ((immhi<<2) | immlo) << 12;
- rval = (pc & ~0xFFF) + imm;
- break;
- }
-
- case 0x91, 0xD1: { // ADD/SUB (immediate), unsigned imm12, optional LSL #12
- int rn = (ir >> 5) & 0x1F;
- long immediate = (ir >>> 10) & 0xFFF;
- if( (ir & (1<<22))!=0 ) immediate <<= 12;
- rval = opcode1==0x91 ? regs[rn] + immediate : regs[rn] - immediate;
- break;
- }
- case 0x92: { // and(immediate)
- int imm12 = (ir >> 10) & 0x1FFF;
- long immediate = arm.decodeImm12(imm12);
- int rn = (ir >> 5) & 0x1F;
- rval = regs[rn] & immediate;
- break;
- }
- case 0x93, 0xD3: { // SBFM/UBFM: shifts and signed/unsigned extracts
- int immr = (ir >>> 16) & 63;
- int imms = (ir >>> 10) & 63;
- int rn = (ir >>> 5) & 31;
- boolean signed = (ir & 0x40000000)==0;
- long value = regs[rn] << (63-imms);
- value = signed ? value >> (63-imms) : value >>> (63-imms);
- rval = immr > imms ? value << (64-immr)
- : signed ? value >> immr : value >>> immr;
- break;
- }
-
- case 0x94, 0x95, 0x96, 0x97: { // bl
- rdid = -1; // BL writes only X30, not a displacement-selected register.
- rval = pc + 4;
- regs[arm.X30] = rval;
- int imm26 = (ir & 0x03FFFFFF);
- int imm = (imm26 << 6) >> 6;
- pc = pc + (imm << 2) ;
- if( pc == Encoding.SENTINEL_CALLOC ) {
- assert (_heap&7) == 0; // 8-byte aligned
- long size = regs[arm.X0]*regs[arm.X1];
- size = (size+7) & -8; // 8-byte aligned
- regs[arm.X0] = _heap;
- _heap += (int)size;
- pc = (int)rval;
- rdid = -1;
- }
- if( pc == Encoding.SENTINEL_WRITE ) {
- ByteArrayOutputStream baos = switch((int)regs[0]) {
- case 1 -> _stdout==null ? (_stdout = new ByteArrayOutputStream()) : _stdout;
- case 2 -> _stderr==null ? (_stderr = new ByteArrayOutputStream()) : _stderr;
- default -> throw new IllegalArgumentException();
- };
- baos.write(_buf,(int)regs[1],(int)regs[2]);
- regs[0] = regs[2];
- pc = (int)rval;
- rdid = -1;
- }
- pc -= 4;
- break;
- }
-
- case 0x9A: {
- // conditional select(csel)
- int rm = (ir >> 16) & 0x1F;
- switch((ir >> 12) & 0xF) {
- case 0x0: if(Z) rval = regs[rm]; break; // eq
- case 0x1: if(!Z) rval = regs[rm]; break; // ne
- case 0x2: if(C) rval = regs[rm]; break; // cs
- case 0x3: if(!C) rval = regs[rm]; break;
- case 0x4: if(N) rval = regs[rm]; break; // mi
- case 0x5: if(!N) rval = regs[rm]; break; // pl
- case 0x6: if(V) rval = regs[rm]; break; // vs
- case 0x7: if(!V) rval = regs[rm]; break; // vc
- case 0x8: if(C && !Z) rval = regs[rm]; break; // hi
- case 0x9: if(!C || Z) rval = regs[rm]; break; // ls
- case 0xA: if(N == V) rval = regs[rm]; break; // ge
- case 0xB: if(N != V) rval = regs[rm]; break; // lt
- case 0xC: if(!Z && N == V) rval = regs[rm]; break; // gt
- case 0xD: if(Z || N != V) rval = regs[rm]; break; // le
- case 0xE: rval = regs[rm]; break; // always executed(al)
- default: rval = regs[(ir >> 5) & 0x1F];
- }
- break;
- }
- case 0x9B: { // mul
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- rval = regs[rn] * regs[rm];
- break;
- }
- case 0x9E: {
- // scvtf
- is_f = true;
- int rs1 = (ir >> 5) & 0x1F;
- frval = (double)regs[rs1];
- break;
- }
-
- case 0xAA: {
- // MOV(register)
- int rm = (ir >> 16) & 0x1F;
- rval = regs[rm];
- break;
- }
-
- case 0xB8: {
- // LDR/STR (register + index) 32 bits
- int opc = ir >> 21 & 0x7;
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- // full opcode
- opcode1 = (ir >> 21) & 0x7FF;
- switch(opc) {
- case 0x1: {
- if(opcode1 == arm.OP_STORE_R_32) {
- st4((int)regs[rn] + (int)regs[rm], (int)regs[rdid]);
- }else {
- trap = (2+1);
- }
- // store(expected to store the length here)
-
- rdid = -1;
- break;
- }
- case 0x3: {
- // load
- if( opcode1 == arm.OP_LOAD_R_32) {
- rval = ld4s((int) (regs[rn] + regs[rm]));
- } else {
- trap = (2+1);
- }
- break;
- }
- default: trap = (2+1);
- }
-
- break;
- }
-
- case 0xB9: {
- // str/ldr(immediate) 32 bits
- int base = ir >> 5 & 0x1F;
- int imm = (ir >> 10) & 0xFFF;
- imm *= 4;
-
- rval = regs[base] + imm;
- int opc = (ir >> 22) & 0x3;
-
- opcode1 = (ir >> 22) & 0x3FF;
- switch(opc) {
- case 0x0: {
- // store
- if(opcode1 == arm.OP_STORE_IMM_32) {
- st4((int)rval, (int)regs[rdid]);
- } else trap = (2+1);
-
- rdid = -1;
- break;
- }
- case 0x1: {
- // LDR (immediate)
- if(opcode1 == arm.OP_LOAD_IMM_32) {
- rval = ld4s((int) rval);
- } else trap = (2+1);
- break;
- }
- default: trap = (2+1);
- }
- break;
- }
-
- case 0xBC: {
- // LDR/STR (register + index) float 32 bits
- int opc = ir >> 21 & 0x7;
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- is_f = true;
- // full opcode
- opcode1 = (ir >> 21) & 0x7FF;
- switch(opc) {
- case 0x1: {
- if(opcode1 == arm.OPF_STORE_R_32) {
- st4((int)regs[rn] + (int)regs[rm], Float.floatToRawIntBits((float)fregs[rdid]));
- }else {
- trap = (2+1);
- }
- // store(expected to store the length here)
-
- rdid = -1;
- break;
- }
- case 0x3: {
- // load
- if(opcode1 == arm.OPF_LOAD_R_32) {
- frval = ld4f((int) (regs[rn] + regs[rm]));
- } else {
- trap = (2+1);
- }
- break;
- }
- default: trap = (2+1);
- }
-
- break;
- }
-
- case 0xBD: {
- // LDR/STR(immediate) 32 bits floats
- int base = ir >> 5 & 0x1F;
- int imm = (ir >> 10) & 0xFFF;
-
- imm *= 4;
- is_f = true;
- rval = regs[base] + imm;
- int opc = (ir >> 22) & 0x3;
- // full opcode
- opcode1 = (ir >> 22) & 0x3FF;
- switch(opc) {
- case 0x0: {
- // store
- if(opcode1 == arm.OPF_STORE_IMM_32) {
- st4((int)rval, Float.floatToRawIntBits((float)fregs[rdid]));
- } else trap = (2+1);
-
- rdid = -1;
- break;
- }
- case 0x1: {
- // LDR (immediate)
- if(opcode1 == arm.OPF_LOAD_IMM_32) {
- frval = ld4f((int)rval);
- } else trap = (2+1);
- break;
- }
- default: trap = (2+1);
- }
- break;
- }
-
- case 0xD2: // MOVZ
- case 0xF2: { // MOVK preserves the other halfwords
- // movz
- // get immediate
- int shift = ((ir >> 21) & 3)*16;
- rval = ((ir >> 5) & 0xFFFFL) << shift;
- if( opcode1==0xF2 ) rval |= regs[rdid] & ~(0xFFFFL << shift);
- break;
- }
-
- case 0xEB: {
- // subs(shifted register)
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- long lhs = regs[rn];
- long rhs = regs[rm];
- rval = lhs - rhs;
-
- // set flags as a side effect
- Z = (rval == 0);
- N = (rval < 0);
- C = lhs >= rhs;
-
- boolean sign_lhs = (lhs >>> 63) != 0;
- boolean sign_rhs = (rhs >>> 63) != 0;
- boolean sign_res = (rval >>> 63) != 0;
- V = (sign_lhs != sign_rhs) && (sign_res != sign_lhs);
- rdid = -1;
- break;
- }
-
- case 0xD6: {
- int op = ir & 0xFFFFFC1F;
- int rn = (ir >>> 5) & 31;
- int target = (int)regs[rn]; // Read before BLR overwrites X30.
- rdid = -1;
- if( op==0xD63F0000 ) regs[arm.X30] = pc+4; // BLR
- else if( op!=0xD65F0000 ) { trap = 3; break; } // RET
- pc = target;
- if( op==0xD65F0000 && pc==0 ) break outer;
- pc -= 4;
- break;
- }
-
- case 0xF1: {
- // subs(immediate)
- int rn = (ir >> 5) & 0x1F;
- int immediate = ir << 10 >> 20;
- long lhs = regs[rn];
-
- rval = lhs - immediate;
-
- // set flags as a side effect
- Z = (rval == 0);
- N = (rval < 0);
- C = lhs >= immediate;
-
- boolean sign_lhs = (lhs >>> 63) != 0;
- boolean sign_rhs = (immediate >>> 63) != 0;
- boolean sign_res = (rval >>> 63) != 0;
- V = (sign_lhs != sign_rhs) && (sign_res != sign_lhs);
- rdid = -1;
- break;
- }
- case 0xF8: {
- // LDR/STR (register + index) 64 bits
- int opc = ir >> 21 & 0x7;
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- // full opcode
- opcode1 = (ir >> 21) & 0x7FF;
- switch(opc) {
- case 0x1: {
- if(opcode1 == arm.OP_STORE_R_64) {
- st8((int)regs[rn] + (int)regs[rm], regs[rdid]);
- }else {
- trap = (2+1);
- }
- // store(expected to store the length here)
-
- rdid = -1;
- break;
- }
- case 0x3: {
- // load
- if(opcode1 == arm.OP_LOAD_R_64) {
- rval = ld8((int) (regs[rn] + regs[rm]));
- } else {
- trap = (2+1);
- }
- break;
- }
- default: trap = (2+1);
- }
-
- break;
- }
- case 0xF9: {
- // str/ldr(immediate) 64 bits
- int base = ir >> 5 & 0x1F;
- int imm = (ir >> 10) & 0xFFF;
-
- imm *= 8;
-
- rval = regs[base] + imm;
- int opc = (ir >> 22) & 0x3;
- // full opcode
- opcode1 = (ir >> 22) & 0x3FF;
- switch(opc) {
- case 0x0: {
- // store
- if(opcode1 == arm.OP_STORE_IMM_64) {
- st8((int)rval, regs[rdid]);
- } else trap = (2+1);
-
- rdid = -1;
- break;
- }
- case 0x1: {
- // LDR (immediate)
- if(opcode1 == arm.OP_LOAD_IMM_64) {
- rval = ld8((int)rval);
- } else trap = (2+1);
- break;
- }
- default: trap = (2+1);
- }
- break;
- }
-
- case 0xFC: {
- // LDR/STR (register + index) float 64 bits
- int opc = ir >> 21 & 0x7;
- int rn = (ir >> 5) & 0x1F;
- int rm = (ir >> 16) & 0x1F;
- is_f = true;
- // full opcode
- opcode1 = (ir >> 21) & 0x7FF;
- switch(opc) {
- case 0x1: {
- if(opcode1 == arm.OPF_STORE_R_64) {
- st8((int)regs[rn] + (int)regs[rm], Double.doubleToRawLongBits(fregs[rdid]));
- }else {
- trap = (2+1);
- }
- // store(expected to store the length here)
-
- rdid = -1;
- break;
- }
- case 0x3: {
- // load
- if(opcode1 == arm.OPF_LOAD_R_64) {
- frval = ld8f((int) (regs[rn] + regs[rm]));
- } else {
- trap = (2+1);
- }
- break;
- }
- default: trap = (2+1);
- }
-
- break;
- }
- case 0xFD: {
- // LDR/STR(immediate) 64 bits floats
- int base = ir >> 5 & 0x1F;
- int imm = (ir >> 10) & 0xFFF;
-
- imm *= 8;
- is_f = true;
- rval = regs[base] + imm;
- int opc = (ir >> 22) & 0x3;
- // full opcode
- opcode1 = (ir >> 22) & 0x3FF;
- switch(opc) {
- case 0x0: {
- // store
- if(opcode1 == arm.OPF_STORE_IMM_64) {
- st8((int)rval, Double.doubleToRawLongBits(fregs[rdid]));
- } else trap = (2+1);
-
- rdid = -1;
- break;
- }
- case 0x1: {
- // LDR (immediate)
- if(opcode1 == arm.OPF_LOAD_IMM_64) {
- frval = ld8f((int)rval);
- } else trap = (2+1);
- break;
- }
- default: trap = (2+1);
- }
- break;
- }
-
- default: trap = (2+1);
- }
-
- if(trap != 0) {
- _pc = pc;
- break;
- }
- if(rdid != -1) {
- if(is_f) {fregs[rdid] = frval; is_f = false;}
- else regs[rdid] = rval;
- }
-
- pc += 4;
- }
- // Handle traps and interrupts.
- if(trap != 0) {
- return trap;
- }
- _cycle = cycle;
- _pc = pc;
- return 0;
- }
-
-
-}
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/EvalRisc5.java b/chapter23/src/test/java/com/seaofnodes/simple/EvalRisc5.java
deleted file mode 100644
index 633e931e..00000000
--- a/chapter23/src/test/java/com/seaofnodes/simple/EvalRisc5.java
+++ /dev/null
@@ -1,368 +0,0 @@
- package com.seaofnodes.simple;
-
-/** Simple RISC5 CPU Emulator
- *
- * Original works credit Charles Lohr.
- * This is a complete rewrite in Java.
- *
- * Load code into memory and go!
- */
-
-import com.seaofnodes.simple.codegen.Encoding;
-import com.seaofnodes.simple.node.cpus.riscv.riscv;
-import com.seaofnodes.simple.util.Utils;
-import java.io.ByteArrayOutputStream;
-import java.util.Arrays;
-
-public class EvalRisc5 {
-
- // Memory image, always 0-based
- public final byte[] _buf;
-
- // GPRs
- final long[] regs;
- // FRs
- final double[] fregs;
- // PC
- int _pc;
-
- // Start of free memory for allocation
- int _heap;
-
- // Standard out and err streams
- ByteArrayOutputStream _stdout, _stderr;
-
- // Cycle counters
- int _cycle;
-
- EvalRisc5( byte[] buf, int stackSize ) {
- _buf = buf;
- regs = new long[32];
- fregs = new double[32];
- // Stack grows down, heap grows up
- regs[riscv.RSP] = _heap = stackSize;
- _pc = 0;
- }
-
- // Little endian
- public int ld1s(int x) { return _buf[x ] ; }
- public int ld1z(int x) { return _buf[x ]&0xFF; }
- public int ld2s(int x) { return ld1z(x) | ld1s(x+1)<< 8; }
- public int ld2z(int x) { return ld1z(x) | ld1z(x+1)<< 8; }
- public int ld4s(int x) { return ld2z(x) | ld2s(x+2)<<16; }
- public long ld8 (int x) { return (long)ld4s(x)&0xFFFFFFFFL | ((long)ld4s(x+4))<<32; }
-
- public float ld4f(int x) { return Float.intBitsToFloat(ld4s(x)); }
- public double ld8f(int x) { return Double.longBitsToDouble(ld8(x)); }
-
-
- public void st1(int x, int val) { _buf[x] = (byte)val; }
- public void st2(int x, int val) { st1(x,val); st1(x+1,val>> 8); }
- public void st4(int x, int val) {st2(x,val); st2(x+2,val>>16); }
- public void st8(int x, long val) { st4(x,(int)val); st4(x+4,(int)(val>>32)); }
-
- // Note: only a few bits are used. (Machine = 3, User = 0)
- // Bits 0..1 = privilege.
- // Bit 2 = WFI (Wait for interrupt)
- // Bit 3+ = Load/Store reservation LSBs.
- int _extraflags;
-
- public int step( int maxops ) {
- int trap = 0;
- long rval = 0;
- double frval = 0;
- int pc = _pc;
- int cycle = _cycle;
- boolean is_f = false;
- outer:
- for( int icount = 0; icount < maxops; icount++ ) {
- int ir = 0;
- rval = 0;
- cycle++;
-
- if( pc >= _buf.length ) {
- trap = 1 + 1; // Handle access violation on instruction read.
- break;
- }
- if( (pc & 3)!=0 ) {
- trap = 1; // Handle PC-misaligned access
- break;
- }
- // Load instruction from image buffer at PC
- ir = ld4s( pc );
- int rdid = (ir >> 7) & 0x1f;
-
- switch( ir & 0x7f ) {
- case 0x37: // LUI (0b0110111)
- rval = ( ir & 0xfffff000 );
- break;
- case 0x17: // AUIPC (0b0010111)
- rval = pc + ( ir & 0xfffff000 );
- break;
- case 0x6F: { // JAL (0b1101111)
- int reladdy = ((ir & 0x80000000)>>11) | ((ir & 0x7fe00000)>>20) | ((ir & 0x00100000)>>9) | ((ir&0x000ff000));
- if( (reladdy & 0x00100000)!=0 ) reladdy |= 0xffe00000; // Sign extension.
- rval = pc + 4;
- pc = pc + reladdy - 4;
- if( pc+4 == Encoding.SENTINEL_WRITE ) {
- ByteArrayOutputStream baos = switch((int)regs[10]) {
- case 1 -> _stdout==null ? (_stdout = new ByteArrayOutputStream()) : _stdout;
- case 2 -> _stderr==null ? (_stderr = new ByteArrayOutputStream()) : _stderr;
- default -> throw new IllegalArgumentException();
- };
- baos.write(_buf,(int)regs[11],(int)regs[12]);
- regs[10] = regs[12];
- rdid = 0;
- pc = (int)(rval - 4); // Unwind PC, as-if returned from write
- }
- break;
- }
- case 0x67: { // JALR (0b1100111)
- int imm_se = ir >> 20; // Sign extend 12 bits
- rval = pc + 4;
- pc = ((int)regs[ (ir >> 15) & 0x1f ] + imm_se) & ~1;
- // Return from top-level ; exit sim
- if( pc==0 ) {
- if( rdid!=0 ) regs[rdid] = rval; // Write PC into register before exit
- break outer;
- }
- // Inline CALLOC effect
- if( pc == Encoding.SENTINEL_CALLOC ) {
- assert (_heap&7) == 0; // 8-byte aligned
- int size = (int)(regs[10]*regs[11]);
- size = (size+7) & -8; // 8-byte aligned
- regs[10] = _heap; // Return next free address
- _heap += size;
- pc = (int)(rval - 4); // Unwind PC, as-if returned from calloc
- } else
- pc -= 4;
- break;
- }
- case 0x63: { // Branch (0b1100011)
- int immm4 = ((ir & 0xf00)>>7) | ((ir & 0x7e000000)>>20) | ((ir & 0x80) << 4) | ((ir >> 31)<<12);
- if( (immm4 & 0x1000)!=0 ) immm4 |= 0xffffe000;
- long rs1 = regs[(ir >> 15) & 0x1f];
- long rs2 = regs[(ir >> 20) & 0x1f];
- immm4 = pc + immm4 - 4;
- rdid = 0;
- if( switch( (ir >> 12) & 0x7 ) {
- case 0 -> rs1 == rs2;
- case 1 -> rs1 != rs2;
- case 4 -> rs1 < rs2;
- case 5 -> rs1 >= rs2;
- case 6 -> Long.compareUnsigned(rs1,rs2) < 0; //BLTU
- case 7 -> Long.compareUnsigned(rs1,rs2) >= 0; //BGEU
- default -> { trap = (2+1); yield false; }
- } ) pc = immm4;
- break;
- }
- case 0x03: { // Load (0b0000011)
- int rs1 = (int)regs[(ir >> 15) & 0x1f]; // Address chop to 32b
- int imm = ir >> 20;
- int imm_se = imm | (( (imm & 0x800)!=0 ) ? 0xfffff000 : 0 );
- int rsval = rs1 + imm_se;
-
- if( rsval >= _buf.length-3 ) {
- trap = (5+1);
- rval = rsval;
- } else {
- switch( ( ir >> 12 ) & 0x7 ) {
- //LB, LH, LW, LBU, LHU
- case 0: rval = ld1s( rsval ); break;
- case 1: rval = ld2s( rsval ); break;
- case 2: rval = ld4s( rsval ); break;
- case 3: rval = ld8 ( rsval ); break;
- case 4: rval = ld1z( rsval ); break;
- case 5: rval = ld2z( rsval ); break;
- case 6: rval = ld4s( rsval ); break;
- default: trap = (2+1);
- }
- }
- break;
- }
- // floats
- case 0x7: {
- is_f = true;
- int rs1 = (int)regs[(ir >> 15) & 0x1f]; // Address chop to 32b
- int imm = ir >> 20;
- int imm_se = imm | (( (imm & 0x800)!=0 ) ? 0xfffff000 : 0 );
- int rsval = rs1 + imm_se;
-
- if( rsval >= _buf.length-3 ) {
- trap = (5+1);
- rval = rsval;
- } else {
- switch( ( ir >> 12 ) & 0x7 ) {
- case 2: frval = ld4f( rsval ); break;
- case 3: frval = ld8f( rsval ); break;
- default: trap = (2+1);
- }
- }
- break;
- }
-
- case 0x23: { // Store 0b0100011
- int rs1 = (int)regs[(ir >> 15) & 0x1f]; // Address chop to 32b
- long rs2 = regs[(ir >> 20) & 0x1f];
- int addy = ( ( ir >> 7 ) & 0x1f ) | ( ( ir & 0xfe000000 ) >> 20 );
- if( (addy & 0x800)!=0 ) addy |= 0xfffff000;
- addy += rs1;
- rdid = 0;
- if( addy >= _buf.length-3 ) {
- trap = (7+1); // Store access fault.
- rval = addy;
- } else {
- switch( ( ir >> 12 ) & 0x7 ) { //SB, SH, SW
- case 0: st1( addy, (int)rs2 ); break;
- case 1: st2( addy, (int)rs2 ); break;
- case 2: st4( addy, (int)rs2 ); break;
- case 3: st8( addy, rs2 ); break;
- default: trap = (2+1);
- }
- }
- break;
- }
- case 0x13: // Op-immediate 0b0010011
- case 0x33: { // Op 0b0110011
- int imm = ir >> 20;
- imm = imm | (( (imm & 0x800)!=0 ) ? 0xfffff000 : 0);
- long rs1 = regs[(ir >> 15) & 0x1f];
- boolean is_reg = (ir & 0x20)!=0;
- long rs2 = is_reg ? regs[imm & 0x1f] : imm;
-
- // Insert the detection here
- int rs1id = (ir >> 15) & 0x1f;
- int funct3 = (ir >> 12) & 0x7;
-
- if( is_reg && ( ir & 0x02000000 )!=0 ) {
- switch( (ir>>12)&7 ) { //0x02000000 = RV32M
- case 0: rval = rs1 * rs2; break; // MUL
- case 1: rval = (int)((long)((int)rs1) * (long)((int)rs2)) >> 32; break; // MULH
- case 2: rval = (int)((long)((int)rs1) * (long)rs2) >> 32; break; // MULHSU
- case 3: rval = (int)((long)rs1 * (long)rs2) >> 32; break; // MULHU
- case 4: if( rs2 == 0 ) rval = -1; else rval = ((int)rs1 == Integer.MIN_VALUE && (int)rs2 == -1) ? rs1 : ((int)rs1 / (int)rs2); break; // DIV
- case 5: if( rs2 == 0 ) rval = 0xffffffff; else rval = rs1 / rs2; break; // DIVU
- case 6: if( rs2 == 0 ) rval = rs1; else rval = ((int)rs1 == Integer.MIN_VALUE && (int)rs2 == -1) ? 0 : ((int)((int)rs1 % (int)rs2)); break; // REM
- case 7: if( rs2 == 0 ) rval = rs1; else rval = rs1 % rs2; break; // REMU
- }
- } else {
- rval = switch( (ir >> 12) & 7 ) { // These could be either op-immediate or op commands. Be careful.
- case 0 -> (is_reg && (ir & 0x40000000) != 0) ? (rs1 - rs2) : (rs1 + rs2);
- case 1 -> rs1 << (rs2 & 0x3F);
- case 2 -> (rs1 < rs2) ? 1 : 0;
- case 3 -> (rs1 < rs2) ? 1 : 0;
- case 4 -> rs1 ^ rs2;
- case 5 -> (ir & 0x40000000) != 0 ? (rs1 >> (rs2 & 0x3F)) : (rs1 >>> (rs2 & 0x3F));
- case 6 -> rs1 | rs2;
- case 7 -> rs1 & rs2;
- default -> rval;
- };
- }
- break;
- }
- case 0x0f: // 0b0001111
- rdid = 0; // fencetype = (ir >> 12) & 0b111; We ignore fences in this impl.
- break;
- case 0x73: // Zifencei+Zicsr (0b1110011)
- trap = (2+1); // Note micrrop 0b100 == undefined.
- break;
-
- case 0x2f: { // RV32A (0b00101111)
- long rs1 = regs[(ir >> 15) & 0x1f];
- long rs2 = regs[(ir >> 20) & 0x1f];
- int irmid = ( ir>>27 ) & 0x1f;
-
- // We don't implement load/store from UART or CLNT with RV32A here.
- if( rs1 >= _buf.length-3 ) {
- trap = (7+1); //Store/AMO access fault
- rval = rs1;
- } else {
- rval = ld4s( (int)rs1 );
-
- // Referenced a little bit of https://github.com/franzflasch/riscv_em/blob/master/src/core/core.c
- boolean dowrite = true;
- switch( irmid ) {
- case 2: //LR.W (0b00010)
- dowrite = false;
- _extraflags = (_extraflags & 0x07) | (int)(rs1<<3);
- break;
- case 3: { //SC.W (0b00011) (Make sure we have a slot, and, it's valid)
- boolean xflag = _extraflags >> 3 != ( rs1 & 0x1fffffff );
- rval = xflag ? 1 : 0; // Validate that our reservation slot is OK.
- dowrite = !xflag; // Only write if slot is valid.
- break;
- }
- case 0: rs2 += rval; break; // AMOADD.W (0b00000)
- case 1: break; // AMOSWAP.W (0b00001)
- case 4: rs2 ^= rval; break; // AMOXOR.W (0b00100)
- case 8: rs2 |= rval; break; // AMOOR.W (0b01000)
- case 12: rs2 &= rval; break; // AMOAND.W (0b01100)
- case 16: rs2 = Math.min( rs2, rval ); break; //AMOMIN.W (0b10000)
- case 20: rs2 = Math.max( rs2, rval ); break; //AMOMAX.W (0b10100)
- case 24: rs2 = Math.min( rs2, rval ); break; //AMOMINU.W (0b11000)
- case 28: rs2 = Math.max( rs2, rval ); break; //AMOMAXU.W (0b11100)
- default: trap = (2+1); dowrite = false; break; //Not supported.
- }
- if( dowrite ) st4( (int)rs1, (int)rs2 );
- }
- break;
- }
-
- case 0x53: {
- is_f = true;
- int rs1 = (ir >> 15) & 0x1F;
- int rs2 = (ir >> 20) & 0x1F;
- double lhs = fregs[rs1];
- double rhs = fregs[rs2];
- int func5 = (ir >> 27) & 0x1F;
- int func2 = (ir >> 25) & 0x3;
- if( func2 != 1 ) throw Utils.TODO(); // 1==double
- switch( func5 ) {
- case 0: frval = lhs + rhs; break; // fadd.d
- case 1: frval = lhs - rhs; break; // fsub.d
- case 2: frval = lhs * rhs; break; // fmul.d
- case 3: frval = lhs / rhs; break; // fdiv.d
- case 5: frval = Math.min(lhs,rhs); break; // fmin.d, also used for move
- case 20:
- is_f = false; // Output into a GPR
- rval = switch( (ir >> 12) & 7 ) {
- case 0 -> lhs <= rhs ? 1 : 0;
- case 1 -> lhs == rhs ? 1 : 0;
- case 2 -> lhs < rhs ? 1 : 0;
- default -> throw Utils.TODO();
- };
- break;
- case 26: frval = (double)regs[rs1]; break; // fcvt.w.d
- default:
- trap = (2+1); // Fault: Invalid opcode.
- throw Utils.TODO();
- }
- break;
- }
-
- default: trap = (2+1); // Fault: Invalid opcode.
- }
-
- // If there was a trap, do NOT allow register writeback.
- if( trap!=0 ) {
- _pc = pc;
- break;
- }
-
- if( rdid!=0 || is_f) {
- if(is_f) {fregs[rdid] = frval; is_f = false;} // Write back register.
- else regs[rdid] = rval; // Write back register.
- }
-
- pc += 4;
- }
-
- // Handle traps and interrupts.
- if( trap!=0 )
- return trap;
-
- _cycle = cycle;
- _pc = pc;
- return 0;
- }
-}
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java b/chapter23/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
index 0f09b7f0..11881194 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
@@ -1,5 +1,9 @@
package com.seaofnodes.simple;
+import com.seaofnodes.isa.eval.EvalRisc5;
+
+import com.seaofnodes.isa.eval.EvalArm64;
+
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.codegen.RegAllocTestSupport;
import com.seaofnodes.simple.node.*;
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/MergeSortTest.java b/chapter23/src/test/java/com/seaofnodes/simple/MergeSortTest.java
index d1fbd7df..39cacd98 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/MergeSortTest.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/MergeSortTest.java
@@ -1,5 +1,7 @@
package com.seaofnodes.simple;
+import com.seaofnodes.isa.eval.EvalRisc5;
+
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.util.SB;
import com.seaofnodes.simple.node.cpus.riscv.riscv;
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/TestArm64.java b/chapter23/src/test/java/com/seaofnodes/simple/TestArm64.java
index edce92f3..a22063eb 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/TestArm64.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/TestArm64.java
@@ -1,5 +1,7 @@
package com.seaofnodes.simple;
+import com.seaofnodes.isa.eval.EvalArm64;
+
import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen;
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/TestRisc5.java b/chapter23/src/test/java/com/seaofnodes/simple/TestRisc5.java
index adb256eb..ace2a7ea 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/TestRisc5.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/TestRisc5.java
@@ -1,5 +1,7 @@
package com.seaofnodes.simple;
+import com.seaofnodes.isa.eval.EvalRisc5;
+
import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.node.FunNode;