diff options
Diffstat (limited to 'chapter21/src/main/java')
5 files changed, 45 insertions, 36 deletions
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 71085971..c857c0b1 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 @@ -23,29 +23,33 @@ public class LoadX86 extends MemOpX86 { short dst = enc.reg(this ); short ptr = enc.reg(ptr()); short idx = enc.reg(idx()); + enc(enc, _declaredType, dst, ptr, idx, _off, _scale); + } - if( _declaredType != TypeInteger.U32 && _declaredType != TypeFloat.F32 && _declaredType != TypeFloat.F64 ) + static void enc( Encoding enc, Type decl, short dst, short ptr, short idx, int off, int scale ) { + if( decl != TypeInteger.U32 && decl != TypeFloat.F32 && decl != TypeFloat.F64 ) enc.add1(x86_64_v2.rex(dst, ptr, idx)); - if( _declaredType.isa(TypeFloat.F64) ) + if( decl.isa(TypeFloat.F64) ) dst -= (short)x86_64_v2.XMM_OFFSET; if( false ) ; - else if( _declaredType == TypeFloat.F32 ) enc.add1(0xF3).add1(0x0F).add1(0x10); // F3 0F 10 /r MOVSS xmm1, m32 - else if( _declaredType == TypeFloat.F64 ) enc.add1(0xF2).add1(0x0F).add1(0x10); // F2 0F 10 /r MOVSD xmm1, m64 - else if( _declaredType == TypeInteger.I8 ) enc.add1(0x0F).add1(0xBE); // sign extend: REX.W + 0F BE /r MOVSX r64, r/m8 - else if( _declaredType == TypeInteger.I16) enc.add1(0x0F).add1(0xBF); // sign extend: REX.W + 0F BF /r MOVSX r64, r/m16 - else if( _declaredType == TypeInteger.I32) enc.add1(0x63); // sign extend: REX.W + 63 /r MOVSXD r64, r/m32 - else if( _declaredType == TypeInteger.U8 ) enc.add1(0x0F).add1(0xB6); // zero extend: REX.W + 0F B6 /r MOVZX r64, r/m8 - else if( _declaredType == TypeInteger.U16) enc.add1(0x0F).add1(0xB7); // zero extend: REX.W + 0F B7 /r MOVZX r64, r/m16 + else if( decl == TypeFloat.F32 ) enc.add1(0xF3).add1(0x0F).add1(0x10); // F3 0F 10 /r MOVSS xmm1, m32 + else if( decl == TypeFloat.F64 ) enc.add1(0xF2).add1(0x0F).add1(0x10); // F2 0F 10 /r MOVSD xmm1, m64 + else if( decl == 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( _declaredType.log_size()>=2 ) enc.add1(0x8B); // zero extend: 8B /r MOV r32, r/m32 + 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); + x86_64_v2.indirectAdr(scale, idx, ptr, off, dst, enc); } + // General form: "ldN dst,[base + idx<<2 + 12]" @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(","); 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 adf1e1a6..f474b431 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 @@ -5,6 +5,9 @@ import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.node.SplitNode; +import com.seaofnodes.simple.type.Type; +import com.seaofnodes.simple.type.TypeFloat; +import com.seaofnodes.simple.type.TypeInteger; public class SplitX86 extends SplitNode { SplitX86( String kind, byte round ) { super(kind,round, new Node[2]); } @@ -23,6 +26,7 @@ public class SplitX86 extends SplitNode { // push rcx // popf (Pop the top of the stack into the FLAGS register) // 50+rd PUSH r64 + if( src >= 8 ) x86_64_v2.rex(0,src,0,true); enc.add1(0x50 + src); // popf enc.add1(0x9D); @@ -33,6 +37,7 @@ public class SplitX86 extends SplitNode { // pushf; pop reg enc.add1(0x9C); // 58+ rd POP r64 + if( dst >= 8 ) x86_64_v2.rex(0,dst,0,true); enc.add1(0x58 + dst); return; } @@ -45,20 +50,13 @@ public class SplitX86 extends SplitNode { if( dst >= x86_64_v2.MAX_REG ) { if( src >= x86_64_v2.MAX_REG ) throw Utils.TODO(); // Very rare stack-stack move - // TODO: Missing FP 0x66 prefix - if( srcX ) { src -= (short)x86_64_v2.XMM_OFFSET; enc.add1(0x66); } int off = enc._fun.computeStackSlot(dst - x86_64_v2.MAX_REG)*8; - enc.add1(x86_64_v2.rex(src, x86_64_v2.RSP, -1)); - enc.add1( 0x89 ); - x86_64_v2.indirectAdr(0, (short)-1, (short)x86_64_v2.RSP, off, src, enc); + StoreX86.encVal(enc, srcX ? TypeFloat.F64 : TypeInteger.BOT, (short)x86_64_v2.RSP, (short)-1/*index*/, src, off, 0); return; } if( src >= x86_64_v2.MAX_REG ) { - if( dstX ) { dst -= (short)x86_64_v2.XMM_OFFSET; enc.add1(0x66); } int off = enc._fun.computeStackSlot(src - x86_64_v2.MAX_REG)*8; - enc.add1(x86_64_v2.rex(dst, x86_64_v2.RSP, -1)); - enc.add1( 0x8B ); - x86_64_v2.indirectAdr(0, (short)-1, (short)x86_64_v2.RSP, off, dst, enc); + LoadX86.enc(enc, dstX ? TypeFloat.F64 : TypeInteger.BOT, dst, (short)x86_64_v2.RSP, (short)-1, off, 0); return; } 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 52e4660d..6886a363 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 @@ -5,8 +5,8 @@ import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.node.StoreNode; +import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFloat; - import java.util.BitSet; public class StoreX86 extends MemOpX86 { @@ -30,31 +30,38 @@ public class StoreX86 extends MemOpX86 { short idx = enc.reg(idx()); short src = enc.reg(val()); - if( src == -1 && _imm != 0 ) { + if( src == -1 ) { // return opcode for optimised immediate store if( x86_64_v2.imm8(_imm) ) enc.add1(0xC6); else if( x86_64_v2.imm32(_imm) ) enc.add1(0xC7); else enc.add1(x86_64_v2.rex(-1, ptr, idx)).add1(0xC7); - } else { - if(_declaredType == TypeFloat.F32) {src -= (short)x86_64_v2.XMM_OFFSET; enc.add1(0xF3); enc.add1(0x0F); enc.add1(0x11);} - else if(_declaredType == TypeFloat.F64) {src -= (short)x86_64_v2.XMM_OFFSET; enc.add1(0xF2); enc.add1(0x0F); enc.add1(0x11);} - else if(_declaredType.log_size() == 0) enc.add1(0x88); - else if(_declaredType.log_size() == 1) enc.add1(0x89); - else if(_declaredType.log_size() == 2) enc.add1(0x89); - else if(_declaredType.log_size() == 3) {enc.add1(x86_64_v2.rex(src, ptr, idx)); enc.add1(0x89);} - } - - x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src, enc); - if( src == -1 ) { + x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src, enc); switch (x86_64_v2.imm_size(_imm)) { - case 8: enc.add1(_imm); break; + case 8: enc.add1(_imm); break; case 16: enc.add2(_imm); break; case 32: enc.add4(_imm); break; case 64: enc.add8(_imm); break; } + } 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 ) { + if( decl instanceof TypeFloat ) { + src -= (short)x86_64_v2.XMM_OFFSET; + enc.add1( decl==TypeFloat.F32 ? 0xF3 : 0xF2 ).add1(0x0F).add1(0x11); } + else if( decl.log_size() == 0 ) enc.add1(0x88); + else if( decl.log_size() == 1 ) enc.add1(0x89); + else if( decl.log_size() == 2 ) enc.add1(0x89); + else if( decl.log_size() == 3 ) enc.add1(x86_64_v2.rex(src, ptr, idx)).add1(0x89); + + x86_64_v2.indirectAdr(scale, idx, ptr, off, src, enc); } + // General form: "stN [base + idx<<2 + 12],val" @Override public void asm(CodeGen code, SB sb) { asm_address(code,sb).p(","); 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 69cb59aa..d475a260 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 @@ -165,7 +165,7 @@ public class x86_64_v2 extends Machine { if( index == -1 ) { // Case for mov reg, [disp] (load) enc.add1(modrm(offset == 0 ? MOD.INDIRECT_disp8 : mod, reg, x86_64_v2.RSP)); - enc.add1(x86_64_v2.sib(scale, x86_64_v2.RSP, base)); + enc.add1(sib(scale, x86_64_v2.RSP, base)); // special case // still add zero it is part of SIB byte if(offset == 0) enc.add1(offset); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/type/Type.java b/chapter21/src/main/java/com/seaofnodes/simple/type/Type.java index 7dc091aa..6df4e7ab 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/type/Type.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/type/Type.java @@ -218,7 +218,7 @@ public class Type { // Sizes are expected to be between 1 and 64 bits. // Size 0 means this either takes no space (such as a known-zero field) // or isn't a scalar to be stored in memory. - public int log_size() { throw Utils.TODO(); } + public int log_size() { return 3; } // ---------------------------------------------------------- // Useful in the debugger, which calls toString everywhere. |
