diff options
Diffstat (limited to 'chapter22/src/main')
124 files changed, 360 insertions, 1348 deletions
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java index 162263d9..aad19090 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/Encoding.java +++ b/chapter22/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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java index f37738bf..76e7b9b5 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java index 209f24f4..9c2f64c0 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddFARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java index a1cd8306..52cf36ea 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java +++ b/chapter22/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.*; 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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java index ad76ca4c..40812d07 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.MachConcreteNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java index 1f12ef13..82d553aa 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java index 342b7519..cce868f9 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java index a1775dde..2d50e967 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.Encoding; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java index b36a395b..5a660c90 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -34,10 +35,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)); } @@ -54,7 +55,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java index 989bd366..dd2d9e2c 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java index 87dde38c..fa0fbd81 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java index dbc86f62..ec5e8ff0 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java index 8a4f242a..dbf9c2e3 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java index 40bd8387..91bd347f 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java index 72b76444..6b86e722 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/DivFARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java index 84075edb..6fec7a77 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java +++ b/chapter22/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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java index 63c57770..6bc2fe08 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java index 3ee75608..c49875f4 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/FunARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java index 5ecc98b6..a7fa7a6a 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/I2F8ARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java index 0a07b07a..64d00d57 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java index 65ca3603..5fa68e19 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.LoadNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java index 055d6dcc..7624554e 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java index 94d3e25b..bf394172 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.Encoding; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java index a691e0fe..2d5fa52c 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java index 094cd30f..6a12e4a5 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; @@ -20,7 +21,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java index afd8723e..5e175b1e 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java +++ b/chapter22/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.*; @@ -65,8 +66,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java index 3514db9b..a0955565 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java index 89dba172..33d32bd4 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/MulFARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java index cb51eea2..0dac086b 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/NewARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -10,8 +11,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. @@ -23,7 +24,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java index 5a8d882d..5c388bab 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/NotARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -18,9 +19,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java index b5cfa8cf..ba3197c1 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java index 2a2d199a..9c7cb8cc 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java index 4597666b..a7ed5073 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/RetARM.java +++ b/chapter22/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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java index 246e482a..6809bb1c 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SetARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java index 62bb75aa..c0c60ea2 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -27,7 +28,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; } @@ -35,26 +36,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java index 0ce6197b..cf858c36 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; 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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java index 552b46df..6024df68 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java index 0d8d3c10..dd147544 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubFARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java index b882c5a4..e45bfa63 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java +++ b/chapter22/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.MachConcreteNode; @@ -19,7 +20,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java index 606b03f0..720a14c1 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TFPARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; @@ -18,10 +19,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) { @@ -38,9 +39,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java index 68e32c78..adbaa8c2 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/TMPARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; @@ -18,9 +19,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) { @@ -37,9 +38,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java index bf46a7b1..acb32ddb 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; @@ -18,7 +19,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); } @@ -32,7 +33,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java index ec86cfa5..5b635303 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorARM.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java index e2582d22..017815f3 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java +++ b/chapter22/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.node.MachConcreteNode; import com.seaofnodes.simple.node.MachNode; @@ -20,7 +21,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java index 7f175f52..15e2f0fe 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java index 37383608..fc96cbe9 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; @@ -17,7 +18,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 @@ -28,7 +29,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java index 4d2ac916..b0921fa0 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java index a85ce5d0..c3aa1276 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddIRISC.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.node.Node; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java index ba88bb48..7639ea94 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AndIRISC.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.node.Node; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java index f6dc5cf2..b5ad5f59 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java +++ b/chapter22/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.*; @@ -45,12 +46,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)); } } @@ -66,12 +67,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java index 89b2c865..ff50a67f 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -32,7 +33,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 @@ -46,7 +47,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java index dcc53cbf..55e36ebf 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java index c67d7b3d..12a798b5 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java index 4d487942..c2e93159 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java +++ b/chapter22/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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java index be699280..3dbb40d1 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java index 84f0f4c7..4ebdec15 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FunRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java index 5519fe5b..c9b20939 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java index 8847d2b7..ceea98e3 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java +++ b/chapter22/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.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java index f9b7daee..fabb3b9d 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/Int8RISC.java +++ b/chapter22/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.node.ConstantNode; import com.seaofnodes.simple.*; @@ -24,9 +25,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); } @@ -35,9 +36,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java index 70d5c18f..e4dd39dd 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/IntRISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java index b65afc79..deaa3b59 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LUI.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java index 7b0e9138..5e1845b8 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java index c9917b4f..40609f96 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java index 77f4a497..58340b32 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NegRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java index e395a811..8e3daaba 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -13,9 +14,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. @@ -31,8 +32,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java index 9cbd5025..469221f3 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NotRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.MachConcreteNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java index f6a888d9..53abcf0b 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/OrIRISC.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.node.Node; 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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java index 8a8186cd..d28311dc 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/RetRISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.Encoding; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java index 9ee19e42..fabb9f92 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.BoolNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java index 4edecc04..52b238ec 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SllIRISC.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.node.Node; 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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java index 569fa2e0..ca1bf614 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java index 1533003c..48171483 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SraIRISC.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.node.Node; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java index ed697678..985abe2c 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SrlIRISC.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.node.Node; 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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java index f07389eb..03e06f83 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java index 1e1b43c7..caf751bb 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java index 1d1f30e9..d7da5ba1 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TFPRISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; @@ -20,9 +21,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; } @@ -32,8 +33,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java index 2f7ffe0d..46b8aace 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/TMPRISC.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java index 3868990d..cc47b7ed 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java +++ b/chapter22/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.*; @@ -20,7 +21,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 @@ -33,7 +34,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java index 27098033..ebdf9fa8 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.node.Node; 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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java index 1618334f..a9327c50 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java index d54c7c31..76a2d3f7 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java index a4166bc7..b3266cb0 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java index 050451f1..c55f975c 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddIX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.Encoding; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java index f97a7cb8..d2111d07 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddMemX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java index 1a74f817..15b83bfc 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallRX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.CallNode; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java index 4696c859..3d450040 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java index 35b92170..5a0c7a37 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java index 91b6d43c..2811a640 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java index 8c558ff2..942400f4 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java index 3e4200c0..27246db5 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java index 9509a1f5..962ec44e 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java index 06f001b0..5d061ae1 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java index 3997d768..bd40bae7 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java +++ b/chapter22/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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java index e3b20003..b17ea305 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java index 07418eb0..24c2a78b 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.Encoding; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java index d3213ae4..4a17b92b 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java index 95f617e7..08c9b4c9 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java index 6d9110f2..29513d98 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java index d7acf8b8..92156c58 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -29,38 +30,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java index dce8a49a..e20fd1ec 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java index c712eb7d..c5329e1d 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -27,33 +28,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java index f0d01b3d..22a1a7ae 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java index c1edb082..3371a8ba 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java index 17006558..4a7e24d0 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java index 3cd1f795..cdc67ea8 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java index b8b83cb0..3d3798cd 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NegX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -12,10 +13,7 @@ public class NegX86 extends MachConcreteNode implements MachNode { @Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; } @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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java index 0439adfd..877ec224 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java index 2d611931..46227dd4 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NotX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java index a4a6a814..50c8e974 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java index a35d43a2..e4467bb4 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java +++ b/chapter22/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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java index 07256604..43ad6bbd 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarIX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.Encoding; @@ -23,15 +24,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java index b1be643c..50693034 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SarX86.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.Node; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java index 775ea8eb..591bf8da 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -23,26 +24,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java index 0b75b456..f31832e6 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlIX86.java +++ b/chapter22/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.node.Node; import com.seaofnodes.simple.*; @@ -24,15 +25,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java index 9f358575..08c4db25 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShlX86.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.Node; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java index 893eb23d..218542f3 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrIX86.java +++ b/chapter22/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.node.Node; import com.seaofnodes.simple.*; @@ -19,15 +20,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java index d869260f..c72f21e2 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ShrX86.java +++ b/chapter22/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.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.Node; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java index 960ea6f8..5cf668d1 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java index 22a0bd79..4796c0fe 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java +++ b/chapter22/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.SB; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java index 0a169a22..6a008551 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java index d7566f9e..8723af91 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java index c44cf2f9..027b2e01 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TMPX86.java +++ b/chapter22/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.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; @@ -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); enc.largeConstant(this,((TypeMemPtr)_con)._obj,7-4,2/*ELF encoding PC32*/); } diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java index 5db9e75e..d991e40a 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java +++ b/chapter22/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.*; import com.seaofnodes.simple.codegen.*; @@ -18,29 +19,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/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java index f9dfe8f4..5c0d4599 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java +++ b/chapter22/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), |
