This commit is contained in:
kobalicek
2015-08-28 17:11:48 +02:00
parent 938691c736
commit b0dad1af25
2 changed files with 127 additions and 79 deletions

View File

@@ -1639,23 +1639,37 @@ _Prepare:
opReg = x86OpReg(o0); opReg = x86OpReg(o0);
rmReg = x86OpReg(o1); rmReg = x86OpReg(o1);
// Asmjit uses segment registers indexed from 1 to 6, leaving zero as
// "no segment register used". We have to fix this (decrement the index
// of the register) when emitting MOV instructions which move to/from
// a segment register. The segment register is always `opReg`, because
// the MOV instruction uses RM or MR encoding.
// Sreg <- Reg // Sreg <- Reg
if (static_cast<const X86Reg*>(o0)->isSeg()) { if (static_cast<const X86Reg*>(o0)->isSeg()) {
ASMJIT_ASSERT(static_cast<const X86Reg*>(o1)->isGpw() || ASMJIT_ASSERT(static_cast<const X86Reg*>(o1)->isGpw() ||
static_cast<const X86Reg*>(o1)->isGpd() || static_cast<const X86Reg*>(o1)->isGpd() ||
static_cast<const X86Reg*>(o1)->isGpq() ); static_cast<const X86Reg*>(o1)->isGpq() );
// `opReg` is the segment register.
opReg--;
opCode = 0x8E; opCode = 0x8E;
ADD_66H_P_BY_SIZE(o1->getSize()); ADD_66H_P_BY_SIZE(o1->getSize());
ADD_REX_W_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize());
goto _EmitX86R; goto _EmitX86R;
} }
// Reg <- Sreg // Reg <- Sreg
if (static_cast<const X86Reg*>(o1)->isSeg()) { else if (static_cast<const X86Reg*>(o1)->isSeg()) {
ASMJIT_ASSERT(static_cast<const X86Reg*>(o0)->isGpw() || ASMJIT_ASSERT(static_cast<const X86Reg*>(o0)->isGpw() ||
static_cast<const X86Reg*>(o0)->isGpd() || static_cast<const X86Reg*>(o0)->isGpd() ||
static_cast<const X86Reg*>(o0)->isGpq() ); static_cast<const X86Reg*>(o0)->isGpq() );
// `opReg` is the segment register.
opReg = static_cast<uint32_t>(rmReg) - 1;
rmReg = x86OpReg(o0);
opCode = 0x8C; opCode = 0x8C;
ADD_66H_P_BY_SIZE(o0->getSize()); ADD_66H_P_BY_SIZE(o0->getSize());
ADD_REX_W_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize());
goto _EmitX86R; goto _EmitX86R;
@@ -1666,6 +1680,7 @@ _Prepare:
static_cast<const X86Reg*>(o0)->isGpw() || static_cast<const X86Reg*>(o0)->isGpw() ||
static_cast<const X86Reg*>(o0)->isGpd() || static_cast<const X86Reg*>(o0)->isGpd() ||
static_cast<const X86Reg*>(o0)->isGpq() ); static_cast<const X86Reg*>(o0)->isGpq() );
opCode = 0x8A + (o0->getSize() != 1); opCode = 0x8A + (o0->getSize() != 1);
ADD_66H_P_BY_SIZE(o0->getSize()); ADD_66H_P_BY_SIZE(o0->getSize());
ADD_REX_W_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize());

View File

@@ -13,7 +13,7 @@
namespace asmgen { namespace asmgen {
enum { kGenOpCodeInstCount = 2670 }; enum { kGenOpCodeInstCount = 2690 };
// Generate all instructions asmjit can emit. // Generate all instructions asmjit can emit.
static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 = false) { static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 = false) {
@@ -71,6 +71,8 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
X86Mem vmxptr_gpB = ptr(gzB, xmmB); X86Mem vmxptr_gpB = ptr(gzB, xmmB);
X86Mem vmyptr_gpB = ptr(gzB, ymmB); X86Mem vmyptr_gpB = ptr(gzB, ymmB);
Label L;
// Base. // Base.
a.adc(gLoA, 1); a.adc(gLoA, 1);
a.adc(gLoB, 1); a.adc(gLoB, 1);
@@ -318,6 +320,42 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
a.xor_(intptr_gpA, 1); a.xor_(intptr_gpA, 1);
a.xor_(intptr_gpA, gzB); a.xor_(intptr_gpA, gzB);
// Segment registers.
a.nop();
if (a.getArch() == kArchX86) {
a.mov(es, ax);
a.mov(es, bx);
a.mov(ax, es);
a.mov(bx, es);
a.mov(cs, ax);
a.mov(cs, bx);
a.mov(ax, cs);
a.mov(bx, cs);
a.mov(ss, ax);
a.mov(ss, bx);
a.mov(ax, ss);
a.mov(bx, ss);
a.mov(ds, ax);
a.mov(ds, bx);
a.mov(ax, ds);
a.mov(bx, ds);
}
a.mov(fs, ax);
a.mov(fs, bx);
a.mov(ax, fs);
a.mov(bx, fs);
a.mov(gs, ax);
a.mov(gs, bx);
a.mov(ax, gs);
a.mov(bx, gs);
// Instructions using REP prefix.
a.nop(); a.nop();
a.lodsb(); a.lodsb();
@@ -362,12 +400,10 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
a.repne_scasw(); a.repne_scasw();
// Label...Jcc/Jecxz/Jmp. // Label...Jcc/Jecxz/Jmp.
{
a.nop(); a.nop();
Label L(a); L = a.newLabel();
a.bind(L); a.bind(L);
a.ja(L); a.ja(L);
a.jae(L); a.jae(L);
a.jb(L); a.jb(L);
@@ -400,13 +436,11 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
a.jz(L); a.jz(L);
a.jecxz(ecx, L); a.jecxz(ecx, L);
a.jmp(L); a.jmp(L);
}
// Jcc/Jecxz/Jmp...Label. // Jcc/Jecxz/Jmp...Label.
{
a.nop(); a.nop();
Label L(a); L = a.newLabel();
a.ja(L); a.ja(L);
a.jae(L); a.jae(L);
a.jb(L); a.jb(L);
@@ -440,9 +474,8 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 =
a.jecxz(ecx, L); a.jecxz(ecx, L);
a.jmp(L); a.jmp(L);
a.bind(L); a.bind(L);
}
// Fpu. // FPU.
a.nop(); a.nop();
a.f2xm1(); a.f2xm1();