mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 12:34:35 +03:00
Fixed #98
This commit is contained in:
@@ -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());
|
||||||
|
|||||||
@@ -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,87 +400,82 @@ 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);
|
a.jbe(L);
|
||||||
a.jbe(L);
|
a.jc(L);
|
||||||
a.jc(L);
|
a.je(L);
|
||||||
a.je(L);
|
a.jg(L);
|
||||||
a.jg(L);
|
a.jge(L);
|
||||||
a.jge(L);
|
a.jl(L);
|
||||||
a.jl(L);
|
a.jle(L);
|
||||||
a.jle(L);
|
a.jna(L);
|
||||||
a.jna(L);
|
a.jnae(L);
|
||||||
a.jnae(L);
|
a.jnb(L);
|
||||||
a.jnb(L);
|
a.jnbe(L);
|
||||||
a.jnbe(L);
|
a.jnc(L);
|
||||||
a.jnc(L);
|
a.jne(L);
|
||||||
a.jne(L);
|
a.jng(L);
|
||||||
a.jng(L);
|
a.jnge(L);
|
||||||
a.jnge(L);
|
a.jnl(L);
|
||||||
a.jnl(L);
|
a.jnle(L);
|
||||||
a.jnle(L);
|
a.jno(L);
|
||||||
a.jno(L);
|
a.jnp(L);
|
||||||
a.jnp(L);
|
a.jns(L);
|
||||||
a.jns(L);
|
a.jnz(L);
|
||||||
a.jnz(L);
|
a.jo(L);
|
||||||
a.jo(L);
|
a.jp(L);
|
||||||
a.jp(L);
|
a.jpe(L);
|
||||||
a.jpe(L);
|
a.jpo(L);
|
||||||
a.jpo(L);
|
a.js(L);
|
||||||
a.js(L);
|
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);
|
||||||
a.jbe(L);
|
a.jbe(L);
|
||||||
a.jc(L);
|
a.jc(L);
|
||||||
a.je(L);
|
a.je(L);
|
||||||
a.jg(L);
|
a.jg(L);
|
||||||
a.jge(L);
|
a.jge(L);
|
||||||
a.jl(L);
|
a.jl(L);
|
||||||
a.jle(L);
|
a.jle(L);
|
||||||
a.jna(L);
|
a.jna(L);
|
||||||
a.jnae(L);
|
a.jnae(L);
|
||||||
a.jnb(L);
|
a.jnb(L);
|
||||||
a.jnbe(L);
|
a.jnbe(L);
|
||||||
a.jnc(L);
|
a.jnc(L);
|
||||||
a.jne(L);
|
a.jne(L);
|
||||||
a.jng(L);
|
a.jng(L);
|
||||||
a.jnge(L);
|
a.jnge(L);
|
||||||
a.jnl(L);
|
a.jnl(L);
|
||||||
a.jnle(L);
|
a.jnle(L);
|
||||||
a.jno(L);
|
a.jno(L);
|
||||||
a.jnp(L);
|
a.jnp(L);
|
||||||
a.jns(L);
|
a.jns(L);
|
||||||
a.jnz(L);
|
a.jnz(L);
|
||||||
a.jo(L);
|
a.jo(L);
|
||||||
a.jp(L);
|
a.jp(L);
|
||||||
a.jpe(L);
|
a.jpe(L);
|
||||||
a.jpo(L);
|
a.jpo(L);
|
||||||
a.js(L);
|
a.js(L);
|
||||||
a.jz(L);
|
a.jz(L);
|
||||||
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();
|
||||||
|
|||||||
Reference in New Issue
Block a user