diff options
Diffstat (limited to 'chapter21/src/main')
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. |
