summaryrefslogtreecommitdiff
path: root/chapter21/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'chapter21/src/main')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java18
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java6
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java8
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java8
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java7
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java7
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java7
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java7
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java7
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java15
13 files changed, 56 insertions, 40 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
index 7dd4d929..f09d208a 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java
@@ -18,7 +18,7 @@ public class LoadARM extends MemOpARM{
@Override public String op() { return "ld"+_sz; }
@Override public RegMask outregmap() { return arm.MEM_MASK; }
// ldr(immediate - unsigned offset) | ldr(register)
- @Override public void encoding( Encoding enc ) { arm.ldst_encode(enc,this,this); }
+ @Override public void encoding( Encoding enc ) { arm.ldst_encode(enc,0b11111000010, this,this); }
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(this)).p(",");
asm_address(code,sb);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
index 03a39f06..094348ce 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java
@@ -21,7 +21,7 @@ public class StoreARM extends MemOpARM {
}
@Override public String op() { return "st"+_sz; }
@Override public RegMask outregmap() { return null; }
- @Override public void encoding( Encoding enc ) { arm.ldst_encode(enc,this,val()); }
+ @Override public void encoding( Encoding enc ) { arm.ldst_encode(enc,0b11111000000, this,val()); }
@Override public void asm(CodeGen code, SB sb) {
asm_address(code,sb).p(",");
if( val()==null ) sb.p("#").p(_imm);
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java
index 9d8468a8..6b3faa4e 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
@@ -299,7 +299,7 @@ public class arm extends Machine {
return (opcode << 21) | (imm9 << 12) |(1 << 10) |(ptr << 5) | rt;
}
// Todo: provide op as binary here
- public static void ldst_encode( Encoding enc, MemOpARM n, Node xval ) {
+ public static void ldst_encode( Encoding enc, int opcode, MemOpARM n, Node xval ) {
short ptr = enc.reg(n.ptr());
short off = enc.reg(n.off());
short val = enc.reg(xval) ;
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 fbb57421..8e048c0a 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
@@ -330,7 +330,7 @@ public class riscv extends Machine {
case LoadNode ld -> ld(ld);
case MemMergeNode mem -> new MemMergeNode(mem);
case MulFNode mulf -> new MulFRISC(mulf);
- case MulNode mul -> mul(mul);
+ case MulNode mul -> new MulRISC(mul);
case NewNode nnn -> nnn(nnn);
case NotNode not -> new NotRISC(not);
case OrNode or -> or(or);
@@ -461,37 +461,37 @@ public class riscv extends Machine {
}
private Node or(OrNode or) {
- if( or.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti) && imm12(ti) )
+ if( or.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti))
return new OrIRISC(or, (int)ti.value());
return new OrRISC(or);
}
private Node xor(XorNode xor) {
- if( xor.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti) && imm12(ti))
+ if( xor.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti))
return new XorIRISC(xor, (int)ti.value());
return new XorRISC(xor);
}
private Node sra(SarNode sar) {
- if( sar.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti) && imm12(ti))
+ if( sar.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti))
return new SraIRISC(sar, (int)ti.value());
return new SraRISC(sar);
}
private Node srl(ShrNode shr) {
- if( shr.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti) && imm12(ti))
+ if( shr.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti))
return new SrlIRISC(shr, (int)ti.value(),true);
return new SrlRISC(shr);
}
private Node sll(ShlNode sll) {
- if( sll.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti) && imm12(ti))
+ if( sll.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti))
return new SllIRISC(sll, (int)ti.value());
return new SllRISC(sll);
}
private Node sub(SubNode sub) {
- return sub.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti) && imm12(ti)
+ return sub.in(2) instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm12(ti)
? new AddIRISC(sub, (int)(-ti.value()),true)
: new SubRISC(sub);
}
@@ -505,10 +505,6 @@ public class riscv extends Machine {
return new ProjRISC(prj);
}
- private Node mul(MulNode mul) {
- return new MulRISC(mul);
- }
-
private Node ld(LoadNode ld) {
return new LoadRISC(address(ld),off);
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java
index 9a38c990..d54c7c31 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFMemX86.java
@@ -26,9 +26,11 @@ public class AddFMemX86 extends MemOpX86 {
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);
- enc.add1(0x58);
+ enc.add1(0x0F).add1(0x58);
x86_64_v2.indirectAdr(_scale, idx, ptr, _off, dst, enc);
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java
index 839b147c..720be638 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java
@@ -17,11 +17,13 @@ public class AddFX86 extends MachConcreteNode implements MachNode {
// 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);
- enc.add1(x86_64_v2.rex(dst, src,0));
// Fopcode
enc.add1(0xF2);
- enc.add1(0x0F);
- enc.add1(0x58);
+ // 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));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java
index 31c03ccf..c2d0ff0f 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java
@@ -12,13 +12,15 @@ public class CmpFX86 extends MachConcreteNode implements MachNode {
// Encoding is appended into the byte array; size is returned
@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);
- enc.add1(x86_64_v2.rex(src1, src2, 0));
// float opcode
enc.add1(0x66);
- enc.add1(0x0F);
- enc.add1(0x2E);
+ // 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));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java
index 52988d13..cc89e808 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java
@@ -16,12 +16,13 @@ public class DivFX86 extends MachConcreteNode implements MachNode {
// 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);
- enc.add1(x86_64_v2.rex(dst, src, 0));
// Fopcode
enc.add1(0xF2);
- enc.add1(0x0F);
- enc.add1(0x5E);
+ // 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));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java
index 2d332764..9055d67f 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java
@@ -19,12 +19,13 @@ public class FltX86 extends ConstantNode implements MachNode {
// movsd xmm, [rip + 0]
// F2 0F 10 /r MOVSD xmm1, m64
short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET);
- enc.add1(x86_64_v2.rex(dst, 0, 0));
// Fopcode
enc.add1(0xF2);
- enc.add1(0x0F);
- enc.add1(0x10);
+ // rex prefix must come next (REX.W is not set)
+ 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));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java
index 22134ac4..ef821e83 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java
@@ -18,9 +18,10 @@ public class I2f8X86 extends MachConcreteNode implements MachNode {
// Fopcode
enc.add1(0xF2);
- enc.add1(x86_64_v2.rex(dst, src, 0));
- enc.add1(0x0F);
- enc.add1(0x2A);
+ // 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));
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java
index cb18e708..0af87037 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java
@@ -17,14 +17,13 @@ public class MulFX86 extends MachConcreteNode implements MachNode {
// 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);
- enc.add1(x86_64_v2.rex(dst, src, 0));
// Fopcode
enc.add1(0xF2);
- enc.add1(0x0F);
- enc.add1(0x59);
+ // rex prefix must come next (REX.W is not set)
+ x86_64_v2.rexF(dst, src, 0, false, enc);
- enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
+ enc.add1(0x0F).add1(0x59).add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
}
// General form: "mulf dst *= src"
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java
index 0c952ddc..07084932 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java
@@ -16,11 +16,12 @@ public class SubFX86 extends MachConcreteNode implements MachNode {
// 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);
- enc.add1(x86_64_v2.rex(dst, src,0));
// Fopcode
enc.add1(0xF2);
- enc.add1(0x0F);
- enc.add1(0x5C);
+ // 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));
}
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 8f29c06e..af5dbff4 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
@@ -50,6 +50,7 @@ public class x86_64_v2 extends Machine {
public static RegMask XMM0_MASK = new RegMask(XMM0);
// Encoding
+ public static int REX = 0x40;
public static int REX_W = 0x48;
public static int REX_WR = 0x4C;
public static int REX_WRB= 0x4D;
@@ -98,15 +99,25 @@ public class x86_64_v2 extends Machine {
// reg4 is X(base)
// 0 denotes no direct register
- public static int rex(int reg, int ptr, int idx) {
+ public static int rex(int reg, int ptr, int idx, boolean wide) {
// assuming 64 bit by default so: 0100 1000
- int rex = REX_W; // Default REX.W
+ int rex = wide ? REX_W : REX;
if( 8 <= reg && reg <= 15 ) rex |= 0b00000100; // REX.R
if( 8 <= ptr && ptr <= 15 ) rex |= 0b00000001; // REX.B
if( 8 <= idx && idx <= 15 ) 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
+ // don't need to use REX if 0x40
+ public static void rexF(int reg, int ptr, int idx, boolean wide, Encoding enc) {
+ int rex = rex(reg, ptr, idx, wide);
+ if (rex != 0x40) enc.add1(rex);
+ }
// 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.