summaryrefslogtreecommitdiff
path: root/chapter21/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/main/java/com')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CmpIARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java16
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SubIARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java83
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java16
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpX86.java18
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java22
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RegX86.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java4
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java1
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java18
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));
}