diff options
Diffstat (limited to 'chapter21/src/main/java/com')
17 files changed, 136 insertions, 58 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java index 3a3e78d4..fe4ecead 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java @@ -18,7 +18,7 @@ public class AddIARM extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return arm.RMASK; } //ADD (immediate) @Override public void encoding( Encoding enc ) { - arm.imm_inst(enc,this,arm.OPI_ADD,_imm); + arm.imm_inst(enc,this, in(1), arm.OPI_ADD,_imm); } // General form: "addi rd = rs1 + imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java index e7f45843..76f5fa39 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java @@ -15,7 +15,7 @@ public class AndIARM extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } @Override public void encoding( Encoding enc ) { - arm.imm_inst_n(enc,this,arm.OPI_AND,_imm); + arm.imm_inst_n(enc,this, in(1), arm.OPI_AND,_imm); } // General form: "andi rd = rs1 & imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java index 1196add9..fe36390c 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java @@ -28,7 +28,7 @@ public class CmpIARM extends MachConcreteNode implements MachNode { @Override public boolean isClone() { return true; } @Override public Node copy() { return new CmpIARM(this); } // Encoding is appended into the byte array; size is returned - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,arm.OPI_CMP,_imm); } + @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,in(1),in(1), arm.OPI_CMP,_imm); } // General form: "cmp rs1, 1" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java index fe58a299..f6f4e472 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java @@ -15,7 +15,7 @@ public class OrIARM extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } @Override public void encoding( Encoding enc ) { - arm.imm_inst_n(enc, this, arm.OPI_OR, _imm); + arm.imm_inst_n(enc, this, in(1), arm.OPI_OR, _imm); } // General form: "ori rd = rs1 | imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java index a92f7f59..bf90703a 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java @@ -24,13 +24,15 @@ public class SplitARM extends SplitNode { throw Utils.TODO(); } int off = enc._fun.computeStackSlot(dst - arm.MAX_REG)*8; - enc.add4(arm.load_str_imm(arm.OP_STORE_IMM, off, src, dst)); + enc.add4(arm.load_str_imm(arm.OP_STORE_IMM, off, arm.RSP, src)); + return; } if(src >= arm.MAX_REG) { // Load from SP int off = enc._fun.computeStackSlot(src - arm.MAX_REG) * 8; - enc.add4(arm.load_str_imm(arm.OP_LOAD_IMM, off, src, dst)); + enc.add4(arm.load_str_imm(arm.OP_LOAD_IMM, off, arm.RSP, dst)); + return; } // pick opcode based on regs @@ -40,15 +42,15 @@ public class SplitARM extends SplitNode { } else if(dstX && srcX) { // FPR->FPR // fmov reg - enc.add4(arm.f_mov_reg(arm.OP_FMOV_REG, src,dst)); - } else if(dstX && !srcX) { + enc.add4(arm.f_mov_reg(arm.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)); - } else if(!dstX && srcX) { + enc.add4(arm.f_mov_general(arm.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, dst)); + enc.add4(arm.f_mov_general(arm.OP_FMOV, 0b01, 0, 0b110, src - arm.D_OFFSET, dst)); } } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java index 0334fa78..29ce71b6 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java @@ -18,7 +18,7 @@ public class SubIARM extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b1101000100,_imm); } + @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this, in(1), 0b1101000100,_imm); } // General form: "subi rd = rs1 - imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java index be28fb28..95e2c932 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java @@ -20,7 +20,7 @@ public class XorIARM extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return arm.RMASK; } // General form: "xori rd = rs1 ^ imm" - @Override public void encoding( Encoding enc ) { arm.imm_inst_n(enc,this,arm.OPI_XOR,_imm); } + @Override public void encoding( Encoding enc ) { arm.imm_inst_n(enc,this, in(1), arm.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/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java index 21d6aa98..f070a526 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java @@ -199,10 +199,15 @@ public class arm extends Machine { } 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; } @@ -287,17 +292,21 @@ public class arm extends Machine { // sh is encoded in opcdoe public static int imm_inst(int opcode, int imm12, int rn, int rd) { - assert opcode >=0 && imm12 >= 0 && rn >=0 && rd>=0; // Caller zeros high order bits + 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) { - return (opcode << 22) | (1 << 22) | (imm << 16) | (imms << 10) | (rn << 5) | rd; + assert 0 <= rn && rn < 32; + assert 0 <= rd && rd < 32; + return (opcode << 22) | (1 << 22) | (imm << 16) | (imms << 10) | (rn << 5) | rd; } - public static void imm_inst(Encoding enc, Node n, int opcode, int imm12) { + public static void imm_inst(Encoding enc, Node n,Node n2, int opcode, int imm12) { short self = enc.reg(n); - short reg1 = enc.reg(n.in(1)); + short reg1 = enc.reg(n2); int body = imm_inst(opcode, imm12&0xFFF, reg1, self); enc.add4(body); } @@ -308,9 +317,9 @@ public class arm extends Machine { enc.add4(body); } - public static void imm_inst_n(Encoding enc, Node n, int opcode, int imm13) { + 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(n.in(1)); + short reg1 = enc.reg(n2); int body = imm_inst_n(opcode, imm13, reg1, self); enc.add4(body); @@ -318,14 +327,16 @@ public class arm extends Machine { // 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) { + 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) { @@ -338,17 +349,23 @@ public class arm extends Machine { // 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); - enc.add4(body); + } + 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); + 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) { @@ -361,6 +378,9 @@ public class arm extends Machine { // 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) { @@ -373,11 +393,13 @@ public class arm extends Machine { // 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 dst) { - return (opcode << 21) | (src << 16) | 0b11111 << 5 | dst; + 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) { @@ -385,18 +407,21 @@ public class arm extends Machine { } // FMOV (scalar, immediate) - public static int f_mov(int opcode, int ftype, int imm8, int rd) { - return (opcode << 24) | (ftype << 21) |(imm8 << 13) | (128 << 5) | rd; - } - 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 ) { @@ -413,19 +438,20 @@ public class arm extends Machine { } // 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; } - public static int load_adr(int opcode, int offset, int base, int rt) { - return (opcode << 22) | (offset << 10) | (base << 5) | rt; - } - // [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) { + assert 0 <= ptr && ptr < 32; + assert 0 <= rt && rt < 32; return (opcode << 22) | (imm12 << 10) |(ptr << 5) | rt; } @@ -440,12 +466,16 @@ public class arm extends Machine { (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; return (opcode << 24) | (ftype << 21) | (rm << 16) | (8 << 10) | (rn << 5) | 8; } public static void f_cmp(Encoding enc, Node n) { @@ -475,11 +505,14 @@ public class arm extends Machine { } 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) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java index 16d5da3a..56da1811 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java @@ -135,6 +135,9 @@ public class riscv extends Machine { // Since riscv instructions are fixed we can just or them togehter 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) { @@ -155,11 +158,13 @@ public class riscv extends Machine { 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 @@ -174,16 +179,17 @@ public class riscv extends Machine { public static int i_type(int opcode, int rd, int func3, int rs1, int imm12) { - assert opcode >= 0 && rd >=0 && func3 >=0 && rs1 >=0 && imm12 >= 0; // Zero-extend by caller + 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 offset1, int func3, int rs1, int rs2, int offset2) { - return (offset2 << 25) | (rs2 << 20) | (rs1 << 15) | (func3 << 12) | (offset1 << 7) | opcode; - } 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 imm12 >= 0; // Masked to high zero bits by caller int imm_lo = imm12 & 0x1F; int imm_hi = imm12 >> 5; @@ -192,6 +198,8 @@ public class riscv extends Machine { // 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 diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java index 6271afcd..d274875a 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java @@ -31,7 +31,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(this); // Also src1 + 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) ); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java index b6aa5e97..f6f3474f 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java @@ -25,6 +25,7 @@ public class CmpMemX86 extends MemOpX86 { // includes modrm x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src == -1 ? 7 : src, enc); + if( src == -1 ) enc.add4(_imm); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java index 4c03e07a..06a36d99 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java @@ -1,15 +1,23 @@ package com.seaofnodes.simple.node.cpus.x86_64_v2; -import com.seaofnodes.simple.SB; +import com.seaofnodes.simple.*; import com.seaofnodes.simple.codegen.*; -import com.seaofnodes.simple.node.Node; +import com.seaofnodes.simple.node.*; -public class CmpX86 extends RegX86 { +public class CmpX86 extends MachConcreteNode implements MachNode { CmpX86( Node add ) { super(add); } @Override public String op() { return "cmp"; } - @Override int opcode() { return 0x3B; } + @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; } @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } - @Override public int twoAddress() { return 0; } + + @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)); + } @Override public void asm(CodeGen code, SB sb) { String dst = code.reg(this); if( dst!="flags" ) sb.p(dst).p(" = "); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java index 9471ccdf..b8e63780 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java @@ -5,7 +5,10 @@ import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.LoadNode; import com.seaofnodes.simple.node.Node; -import com.seaofnodes.simple.type.*; +import com.seaofnodes.simple.type.Type; +import com.seaofnodes.simple.type.TypeFloat; +import com.seaofnodes.simple.type.TypeInteger; +import com.seaofnodes.simple.type.TypeMemPtr; public class LoadX86 extends MemOpX86 { LoadX86( LoadNode ld, Node base, Node idx, int off, int scale ) { @@ -18,29 +21,34 @@ public class LoadX86 extends MemOpX86 { // Zero extension for u8, u16 and u32 but sign extension i8, i16, i32 // Use movsx and movzx + CodeGen.print_as_hex(enc); short dst = enc.reg(this ); short ptr = enc.reg(ptr()); short idx = enc.reg(idx()); if (_declaredType != TypeInteger.U32 && _declaredType != TypeFloat.F32 && _declaredType != TypeFloat.F64) { - enc.add1(x86_64_v2.rex(dst, ptr, idx)); + enc.add1(x86_64_v2.rex(dst, ptr, idx == -1 ? 0: idx)); } - if(_declaredType == TypeFloat.F32) { + if(_declaredType instanceof TypeMemPtr) { + throw Utils.TODO(); + } + + else if(_declaredType == TypeFloat.F32) { // F3 0F 10 /r MOVSS xmm1, m32 enc.add1(0xF3); enc.add1(0x0F); enc.add1(0x10); dst -= (short)x86_64_v2.XMM_OFFSET; } - if(_declaredType == TypeFloat.F64) { + else if(_declaredType == TypeFloat.F64) { // F2 0F 10 /r MOVSD xmm1, m64 enc.add1(0xF2); enc.add1(0x0F); enc.add1(0x10); dst -= (short)x86_64_v2.XMM_OFFSET; } - if(_declaredType == TypeInteger.I8) { + else if(_declaredType == TypeInteger.I8) { // sign extend: REX.W + 0F BE /r MOVSX r64, r/m8 enc.add1(0x0F); enc.add1(0xBE); @@ -59,10 +67,10 @@ public class LoadX86 extends MemOpX86 { // zero extend: REX.W + 0F B7 /r MOVZX r64, r/m16 enc.add1(0x0F); enc.add1(0xB7); - } else if(_declaredType == TypeInteger.U32 ) { + } else if(_declaredType == TypeInteger.U32) { // zero extend: 8B /r MOV r32, r/m32 enc.add1(0x8B); - } else if(_declaredType == TypeInteger.BOT || _declaredType instanceof TypeMemPtr) { + } else if(_declaredType == TypeInteger.BOT) { // REX.W + 8B /r MOV r64, r/m64 enc.add1(0x8B); } else { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java index 334791cc..0997644d 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java @@ -14,6 +14,7 @@ public abstract class RegX86 extends MachConcreteNode { // 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)); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java index a718ee51..270d2acc 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java @@ -18,7 +18,9 @@ public class SplitX86 extends SplitNode { // REX.W + 8B /r MOV r64, r/m64 short dst = enc.reg(this ); short src = enc.reg(in(1)); - + if(_nid == 69) { + CodeGen.print_as_hex(enc); + } if( dst == x86_64_v2.FLAGS ) { // mov reg, flags // push rcx diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java index 6be21c47..aa2bd9b5 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java @@ -31,6 +31,7 @@ public class StoreX86 extends MemOpX86 { short src = enc.reg(val()); int imm_op = x86_64_v2.selectOpcodeForImmStore(_imm); + if(src == -1 && _imm != 0) { if(imm_op == -1) {enc.add1(x86_64_v2.rex(src, ptr, idx));enc.add1(0xC7); } else enc.add1(imm_op); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java index f51e0c75..d0056920 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java @@ -86,12 +86,16 @@ public class x86_64_v2 extends Machine { public static int modrm(MOD mod, int reg, int m_r) { // 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; } @@ -103,6 +107,10 @@ public class x86_64_v2 extends Machine { // 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 0 <= reg && reg < 16; + assert 0 <= ptr && ptr < 16; + assert 0 <= idx && idx < 16; + int rex = wide ? REX_W : REX; if( 8 <= reg && reg <= 15 ) rex |= 0b00000100; // REX.R if( 8 <= ptr && ptr <= 15 ) rex |= 0b00000001; // REX.B @@ -153,16 +161,22 @@ public class x86_64_v2 extends Machine { : MOD.INDIRECT_disp32; // needs to pick optimal displacement mod if we want to encode base + // when we only have base = RSP then we still need displacement added so ti becomes: [RSP+RSP*1+0x0] + // RSP as index in this case is special and refers to: [base + disp8] if( mod == MOD.INDIRECT && (base == RBP || base == R13) ) mod = MOD.INDIRECT_disp8; // special encoding for [base +offset] if( index == -1 ) { // Case for mov reg, [disp] (load) - enc.add1(modrm(mod, reg == -1 ? 0 : reg, base)); + enc.add1(modrm(offset == 0 ? MOD.INDIRECT_disp8 : mod, reg == -1 ? 0 : reg, x86_64_v2.RSP)); + enc.add1(x86_64_v2.sib(scale, x86_64_v2.RSP, base)); + // special case + // still add zero it is part of SIB byte + if(offset == 0) enc.add1(offset); } else { // rsp is hard-coded here(0x04) - enc.add1(modrm(mod, reg, 0x04)); + enc.add1(modrm(mod, reg, x86_64_v2.RSP)); enc.add1(sib(scale, index, base)); } |
