From b0dad1af25fb141bf2b20cf29392194886448832 Mon Sep 17 00:00:00 2001 From: kobalicek Date: Fri, 28 Aug 2015 17:11:48 +0200 Subject: [PATCH] Fixed #98 --- src/asmjit/x86/x86assembler.cpp | 19 +++- src/test/asmjit_test_opcode.h | 187 +++++++++++++++++++------------- 2 files changed, 127 insertions(+), 79 deletions(-) diff --git a/src/asmjit/x86/x86assembler.cpp b/src/asmjit/x86/x86assembler.cpp index 06d621f..a738e77 100644 --- a/src/asmjit/x86/x86assembler.cpp +++ b/src/asmjit/x86/x86assembler.cpp @@ -1639,23 +1639,37 @@ _Prepare: opReg = x86OpReg(o0); 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 if (static_cast(o0)->isSeg()) { ASMJIT_ASSERT(static_cast(o1)->isGpw() || static_cast(o1)->isGpd() || static_cast(o1)->isGpq() ); + + // `opReg` is the segment register. + opReg--; opCode = 0x8E; + ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); goto _EmitX86R; } - // Reg <- Sreg - if (static_cast(o1)->isSeg()) { + else if (static_cast(o1)->isSeg()) { ASMJIT_ASSERT(static_cast(o0)->isGpw() || static_cast(o0)->isGpd() || static_cast(o0)->isGpq() ); + + // `opReg` is the segment register. + opReg = static_cast(rmReg) - 1; + rmReg = x86OpReg(o0); opCode = 0x8C; + ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); goto _EmitX86R; @@ -1666,6 +1680,7 @@ _Prepare: static_cast(o0)->isGpw() || static_cast(o0)->isGpd() || static_cast(o0)->isGpq() ); + opCode = 0x8A + (o0->getSize() != 1); ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); diff --git a/src/test/asmjit_test_opcode.h b/src/test/asmjit_test_opcode.h index bff68e7..066c14a 100644 --- a/src/test/asmjit_test_opcode.h +++ b/src/test/asmjit_test_opcode.h @@ -13,7 +13,7 @@ namespace asmgen { -enum { kGenOpCodeInstCount = 2670 }; +enum { kGenOpCodeInstCount = 2690 }; // Generate all instructions asmjit can emit. 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 vmyptr_gpB = ptr(gzB, ymmB); + Label L; + // Base. a.adc(gLoA, 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, 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.lodsb(); @@ -362,87 +400,82 @@ static void opcode(asmjit::X86Assembler& a, bool useRex1 = false, bool useRex2 = a.repne_scasw(); // Label...Jcc/Jecxz/Jmp. - { - a.nop(); + a.nop(); - Label L(a); - a.bind(L); - - a.ja(L); - a.jae(L); - a.jb(L); - a.jbe(L); - a.jc(L); - a.je(L); - a.jg(L); - a.jge(L); - a.jl(L); - a.jle(L); - a.jna(L); - a.jnae(L); - a.jnb(L); - a.jnbe(L); - a.jnc(L); - a.jne(L); - a.jng(L); - a.jnge(L); - a.jnl(L); - a.jnle(L); - a.jno(L); - a.jnp(L); - a.jns(L); - a.jnz(L); - a.jo(L); - a.jp(L); - a.jpe(L); - a.jpo(L); - a.js(L); - a.jz(L); - a.jecxz(ecx, L); - a.jmp(L); - } + L = a.newLabel(); + a.bind(L); + a.ja(L); + a.jae(L); + a.jb(L); + a.jbe(L); + a.jc(L); + a.je(L); + a.jg(L); + a.jge(L); + a.jl(L); + a.jle(L); + a.jna(L); + a.jnae(L); + a.jnb(L); + a.jnbe(L); + a.jnc(L); + a.jne(L); + a.jng(L); + a.jnge(L); + a.jnl(L); + a.jnle(L); + a.jno(L); + a.jnp(L); + a.jns(L); + a.jnz(L); + a.jo(L); + a.jp(L); + a.jpe(L); + a.jpo(L); + a.js(L); + a.jz(L); + a.jecxz(ecx, L); + a.jmp(L); // Jcc/Jecxz/Jmp...Label. - { - a.nop(); + a.nop(); - Label L(a); - a.ja(L); - a.jae(L); - a.jb(L); - a.jbe(L); - a.jc(L); - a.je(L); - a.jg(L); - a.jge(L); - a.jl(L); - a.jle(L); - a.jna(L); - a.jnae(L); - a.jnb(L); - a.jnbe(L); - a.jnc(L); - a.jne(L); - a.jng(L); - a.jnge(L); - a.jnl(L); - a.jnle(L); - a.jno(L); - a.jnp(L); - a.jns(L); - a.jnz(L); - a.jo(L); - a.jp(L); - a.jpe(L); - a.jpo(L); - a.js(L); - a.jz(L); - a.jecxz(ecx, L); - a.jmp(L); - a.bind(L); - } + L = a.newLabel(); + a.ja(L); + a.jae(L); + a.jb(L); + a.jbe(L); + a.jc(L); + a.je(L); + a.jg(L); + a.jge(L); + a.jl(L); + a.jle(L); + a.jna(L); + a.jnae(L); + a.jnb(L); + a.jnbe(L); + a.jnc(L); + a.jne(L); + a.jng(L); + a.jnge(L); + a.jnl(L); + a.jnle(L); + a.jno(L); + a.jnp(L); + a.jns(L); + a.jnz(L); + a.jo(L); + a.jp(L); + a.jpe(L); + a.jpo(L); + a.js(L); + a.jz(L); + a.jecxz(ecx, L); + a.jmp(L); + a.bind(L); - // Fpu. + // FPU. a.nop(); a.f2xm1();