Externals: update Bochs to newer version
Should resolve the disassembler not handling all the opcodes Dolphin generates.
This commit is contained in:
parent
001c9a18fa
commit
290643ad25
|
@ -50,14 +50,18 @@
|
||||||
<ClInclude Include="dis_tables.h" />
|
<ClInclude Include="dis_tables.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="dis_decode.cpp" />
|
<ClCompile Include="dis_decode.cc" />
|
||||||
<ClCompile Include="dis_groups.cpp" />
|
<ClCompile Include="dis_groups.cc" />
|
||||||
<ClCompile Include="resolve.cpp" />
|
<ClCompile Include="resolve.cc" />
|
||||||
<ClCompile Include="syntax.cpp" />
|
<ClCompile Include="syntax.cc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="dis_tables.inl" />
|
<None Include="opcodes.inc" />
|
||||||
<None Include="opcodes.inl" />
|
<None Include="dis_tables.inc" />
|
||||||
|
<None Include="dis_tables_avx.inc" />
|
||||||
|
<None Include="dis_tables_sse.inc" />
|
||||||
|
<None Include="dis_tables_x87.inc" />
|
||||||
|
<None Include="dis_tables_xop.inc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
set(SRCS dis_decode.cpp
|
set(SRCS dis_decode.cc
|
||||||
dis_groups.cpp
|
dis_groups.cc
|
||||||
resolve.cpp
|
resolve.cc
|
||||||
syntax.cpp)
|
syntax.cc)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(SRCS ${SRCS} stdafx.cpp)
|
set(SRCS ${SRCS} stdafx.cpp)
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Copyright (C) 2001 The Bochs Project
|
||||||
|
#
|
||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2 of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This library is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
|
||||||
|
@SUFFIX_LINE@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
top_builddir = ..
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
|
||||||
|
SHELL = @SHELL@
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXFLAGS = @CXXFLAGS@ @GUI_CXXFLAGS@
|
||||||
|
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
|
||||||
|
|
||||||
|
# ===========================================================
|
||||||
|
# end of configurable options
|
||||||
|
# ===========================================================
|
||||||
|
|
||||||
|
|
||||||
|
BX_OBJS = \
|
||||||
|
dis_decode.o \
|
||||||
|
dis_groups.o \
|
||||||
|
resolve.o \
|
||||||
|
syntax.o
|
||||||
|
|
||||||
|
BX_INCLUDES = disasm.h
|
||||||
|
|
||||||
|
BX_INCDIRS = -I.. -I$(srcdir)/.. -I../@INSTRUMENT_DIR@ -I$(srcdir)/../@INSTRUMENT_DIR@
|
||||||
|
|
||||||
|
all: libdisasm.a
|
||||||
|
|
||||||
|
.@CPP_SUFFIX@.o:
|
||||||
|
$(CXX) @DASH@c $(BX_INCDIRS) $(CXXFLAGS) @CXXFP@$< @OFP@$@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
libdisasm.a: $(BX_OBJS)
|
||||||
|
@RMCOMMAND@ libdisasm.a
|
||||||
|
@MAKELIB@ $(BX_OBJS)
|
||||||
|
$(RANLIB) libdisasm.a
|
||||||
|
|
||||||
|
$(BX_OBJS): $(BX_INCLUDES)
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@RMCOMMAND@ *.o
|
||||||
|
@RMCOMMAND@ *.a
|
||||||
|
|
||||||
|
dist-clean: clean
|
||||||
|
@RMCOMMAND@ Makefile
|
||||||
|
|
||||||
|
###########################################
|
||||||
|
# dependencies generated by
|
||||||
|
# gcc -MM -I.. -I../instrument/stubs *.cc | sed 's/\.cc/.@CPP_SUFFIX@/g'
|
||||||
|
###########################################
|
||||||
|
dis_decode.o: dis_decode.@CPP_SUFFIX@ disasm.h ../config.h dis_tables.h opcodes.inc \
|
||||||
|
dis_tables.inc dis_tables_x87.inc dis_tables_sse.inc dis_tables_avx.inc dis_tables_xop.inc
|
||||||
|
dis_groups.o: dis_groups.@CPP_SUFFIX@ disasm.h ../config.h
|
||||||
|
resolve.o: resolve.@CPP_SUFFIX@ disasm.h ../config.h
|
||||||
|
syntax.o: syntax.@CPP_SUFFIX@ disasm.h ../config.h
|
|
@ -38,4 +38,8 @@ typedef Bit64u bx_address;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define BX_CONST64(x) (x##LL)
|
||||||
|
#define GET32L(val64) ((Bit32u)(((Bit64u)(val64)) & 0xFFFFFFFF))
|
||||||
|
#define GET32H(val64) ((Bit32u)(((Bit64u)(val64)) >> 32))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,557 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// $Id: dis_decode.cc 11873 2013-10-10 21:00:26Z sshwarts $
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005-2012 Stanislav Shwartsman
|
||||||
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "disasm.h"
|
||||||
|
#include "dis_tables.h"
|
||||||
|
|
||||||
|
#define OPCODE(entry) ((BxDisasmOpcodeInfo_t*) entry->OpcodeInfo)
|
||||||
|
#define OPCODE_TABLE(entry) ((BxDisasmOpcodeTable_t*) entry->OpcodeInfo)
|
||||||
|
|
||||||
|
static const unsigned char instruction_has_modrm[512] = {
|
||||||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||||||
|
/* ------------------------------- */
|
||||||
|
/* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
|
||||||
|
/* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
|
||||||
|
/* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
|
||||||
|
/* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
|
||||||
|
/* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
/* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
/* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
|
||||||
|
/* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
/* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||||
|
/* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
/* A0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
/* B0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
/* C0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
|
||||||
|
/* D0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
|
||||||
|
/* E0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
/* F0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,
|
||||||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||||||
|
/* ------------------------------- */
|
||||||
|
1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0F 00 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 10 */
|
||||||
|
1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 0F 20 */
|
||||||
|
0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 0F 30 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 40 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 50 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 60 */
|
||||||
|
1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 0F 70 */
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0F 80 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 90 */
|
||||||
|
0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* 0F A0 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F B0 */
|
||||||
|
1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 0F C0 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F D0 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F E0 */
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* 0F F0 */
|
||||||
|
/* ------------------------------- */
|
||||||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||||
|
{
|
||||||
|
x86_insn insn = decode(is_32, is_64, cs_base, ip, instr, disbuf);
|
||||||
|
return insn.ilen;
|
||||||
|
}
|
||||||
|
|
||||||
|
x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||||
|
{
|
||||||
|
if (is_64) is_32 = 1;
|
||||||
|
x86_insn insn(is_32, is_64);
|
||||||
|
const Bit8u *instruction_begin = instruction = instr;
|
||||||
|
resolve_modrm = NULL;
|
||||||
|
|
||||||
|
db_eip = ip;
|
||||||
|
db_cs_base = cs_base; // cs linear base (cs_base for PM & cs<<4 for RM & VM)
|
||||||
|
|
||||||
|
disbufptr = disbuf; // start sprintf()'ing into beginning of buffer
|
||||||
|
|
||||||
|
#define SSE_PREFIX_NONE 0
|
||||||
|
#define SSE_PREFIX_66 1
|
||||||
|
#define SSE_PREFIX_F3 2
|
||||||
|
#define SSE_PREFIX_F2 3 /* only one SSE prefix could be used */
|
||||||
|
unsigned sse_prefix = SSE_PREFIX_NONE, sse_opcode = 0;
|
||||||
|
unsigned rex_prefix = 0, prefixes = 0;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
insn.b1 = fetch_byte();
|
||||||
|
prefixes++;
|
||||||
|
|
||||||
|
switch(insn.b1) {
|
||||||
|
case 0x40: // rex
|
||||||
|
case 0x41:
|
||||||
|
case 0x42:
|
||||||
|
case 0x43:
|
||||||
|
case 0x44:
|
||||||
|
case 0x45:
|
||||||
|
case 0x46:
|
||||||
|
case 0x47:
|
||||||
|
case 0x48:
|
||||||
|
case 0x49:
|
||||||
|
case 0x4A:
|
||||||
|
case 0x4B:
|
||||||
|
case 0x4C:
|
||||||
|
case 0x4D:
|
||||||
|
case 0x4E:
|
||||||
|
case 0x4F:
|
||||||
|
if (! is_64) break;
|
||||||
|
rex_prefix = insn.b1;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 0x26: // ES:
|
||||||
|
case 0x2e: // CS:
|
||||||
|
case 0x36: // SS:
|
||||||
|
case 0x3e: // DS:
|
||||||
|
if (! is_64) insn.seg_override = (insn.b1 >> 3) & 3;
|
||||||
|
rex_prefix = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 0x64: // FS:
|
||||||
|
case 0x65: // GS:
|
||||||
|
insn.seg_override = insn.b1 & 0xf;
|
||||||
|
rex_prefix = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 0x66: // operand size override
|
||||||
|
if (!insn.os_64) insn.os_32 = !is_32;
|
||||||
|
if (!sse_prefix) sse_prefix = SSE_PREFIX_66;
|
||||||
|
rex_prefix = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 0x67: // address size override
|
||||||
|
if (!is_64) insn.as_32 = !is_32;
|
||||||
|
insn.as_64 = 0;
|
||||||
|
rex_prefix = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 0xf0: // lock
|
||||||
|
rex_prefix = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 0xf2: // repne
|
||||||
|
case 0xf3: // rep
|
||||||
|
sse_prefix = (insn.b1 & 0xf) ^ 1;
|
||||||
|
rex_prefix = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// no more prefixes
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insn.b1 == 0x0f)
|
||||||
|
{
|
||||||
|
insn.b1 = 0x100 | fetch_byte();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rex_prefix) {
|
||||||
|
insn.extend8b = 1;
|
||||||
|
if (rex_prefix & 0x8) {
|
||||||
|
insn.os_64 = 1;
|
||||||
|
insn.os_32 = 1;
|
||||||
|
}
|
||||||
|
if (rex_prefix & 0x4) insn.rex_r = 8;
|
||||||
|
if (rex_prefix & 0x2) insn.rex_x = 8;
|
||||||
|
if (rex_prefix & 0x1) insn.rex_b = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BxDisasmOpcodeTable_t *opcode_table, *entry;
|
||||||
|
|
||||||
|
if (is_64) {
|
||||||
|
if (insn.os_64)
|
||||||
|
opcode_table = BxDisasmOpcodes64q;
|
||||||
|
else if (insn.os_32)
|
||||||
|
opcode_table = BxDisasmOpcodes64d;
|
||||||
|
else
|
||||||
|
opcode_table = BxDisasmOpcodes64w;
|
||||||
|
} else {
|
||||||
|
if (insn.os_32)
|
||||||
|
opcode_table = BxDisasmOpcodes32;
|
||||||
|
else
|
||||||
|
opcode_table = BxDisasmOpcodes16;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = opcode_table + insn.b1;
|
||||||
|
|
||||||
|
if ((insn.b1 & ~1) == 0xc4 && (is_64 || (peek_byte() & 0xc0) == 0xc0))
|
||||||
|
{
|
||||||
|
if (sse_prefix)
|
||||||
|
dis_sprintf("(bad vex+rex prefix) ");
|
||||||
|
if (rex_prefix)
|
||||||
|
dis_sprintf("(bad vex+sse prefix) ");
|
||||||
|
|
||||||
|
// decode 0xC4 or 0xC5 VEX prefix
|
||||||
|
sse_prefix = decode_vex(&insn);
|
||||||
|
if (insn.b1 < 256 || insn.b1 >= 1024)
|
||||||
|
entry = &BxDisasmGroupSSE_ERR[0];
|
||||||
|
else
|
||||||
|
entry = BxDisasmOpcodesAVX + (insn.b1 - 256);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (insn.b1== 0x62 && (is_64 || (peek_byte() & 0xc0) == 0xc0))
|
||||||
|
{
|
||||||
|
if (sse_prefix)
|
||||||
|
dis_sprintf("(bad evex+rex prefix) ");
|
||||||
|
if (rex_prefix)
|
||||||
|
dis_sprintf("(bad evex+sse prefix) ");
|
||||||
|
|
||||||
|
// decode 0x62 EVEX prefix
|
||||||
|
sse_prefix = decode_evex(&insn);
|
||||||
|
if (insn.b1 < 256 || insn.b1 >= 1024)
|
||||||
|
entry = &BxDisasmGroupSSE_ERR[0];
|
||||||
|
// else
|
||||||
|
// entry = BxDisasmOpcodesEVEX + (insn.b1 - 256);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else if (insn.b1 == 0x8f && (is_64 || (peek_byte() & 0xc0) == 0xc0) && (peek_byte() & 0x8) == 0x8)
|
||||||
|
{
|
||||||
|
if (sse_prefix)
|
||||||
|
dis_sprintf("(bad xop+rex prefix) ");
|
||||||
|
if (rex_prefix)
|
||||||
|
dis_sprintf("(bad xop+sse prefix) ");
|
||||||
|
|
||||||
|
// decode 0x8F XOP prefix
|
||||||
|
sse_prefix = decode_xop(&insn);
|
||||||
|
if (insn.b1 >= 768 || sse_prefix != 0)
|
||||||
|
entry = &BxDisasmGroupSSE_ERR[0];
|
||||||
|
else
|
||||||
|
entry = BxDisasmOpcodesXOP + insn.b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insn.b1 >= 512 || instruction_has_modrm[insn.b1] || insn.is_xop > 0)
|
||||||
|
{
|
||||||
|
// take 3rd byte for 3-byte opcode
|
||||||
|
if (entry->Attr == _GRP3BOP) {
|
||||||
|
entry = &(OPCODE_TABLE(entry)[fetch_byte()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
decode_modrm(&insn);
|
||||||
|
}
|
||||||
|
|
||||||
|
int attr = entry->Attr;
|
||||||
|
while(attr)
|
||||||
|
{
|
||||||
|
switch(attr) {
|
||||||
|
case _GROUPN:
|
||||||
|
entry = &(OPCODE_TABLE(entry)[insn.nnn & 7]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _GRPSSE66:
|
||||||
|
/* SSE opcode group with only prefix 0x66 allowed */
|
||||||
|
sse_opcode = 1;
|
||||||
|
if (sse_prefix != SSE_PREFIX_66)
|
||||||
|
entry = &(BxDisasmGroupSSE_ERR[sse_prefix]);
|
||||||
|
attr = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case _GRPSSEF2:
|
||||||
|
/* SSE opcode group with only prefix 0xF2 allowed */
|
||||||
|
sse_opcode = 1;
|
||||||
|
if (sse_prefix != SSE_PREFIX_F2)
|
||||||
|
entry = &(BxDisasmGroupSSE_ERR[sse_prefix]);
|
||||||
|
attr = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case _GRPSSEF3:
|
||||||
|
/* SSE opcode group with only prefix 0xF3 allowed */
|
||||||
|
sse_opcode = 1;
|
||||||
|
if (sse_prefix != SSE_PREFIX_F3)
|
||||||
|
entry = &(BxDisasmGroupSSE_ERR[sse_prefix]);
|
||||||
|
attr = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case _GRPSSENONE:
|
||||||
|
/* SSE opcode group with no prefix only allowed */
|
||||||
|
sse_opcode = 1;
|
||||||
|
if (sse_prefix != SSE_PREFIX_NONE)
|
||||||
|
entry = &(BxDisasmGroupSSE_ERR[sse_prefix]);
|
||||||
|
attr = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case _GRPSSE:
|
||||||
|
sse_opcode = 1;
|
||||||
|
/* For SSE opcodes, look into another 4 entries table
|
||||||
|
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3) */
|
||||||
|
entry = &(OPCODE_TABLE(entry)[sse_prefix]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _GRPSSE2:
|
||||||
|
sse_opcode = 1;
|
||||||
|
/* For SSE opcodes, look into another 2 entries table
|
||||||
|
with the opcode prefixes (NONE, 0x66)
|
||||||
|
SSE prefixes 0xF2 and 0xF3 are not allowed */
|
||||||
|
if (sse_prefix > SSE_PREFIX_66)
|
||||||
|
entry = &(BxDisasmGroupSSE_ERR[sse_prefix]);
|
||||||
|
else
|
||||||
|
entry = &(OPCODE_TABLE(entry)[sse_prefix]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _SPLIT11B:
|
||||||
|
entry = &(OPCODE_TABLE(entry)[insn.mod != 3]); /* REG/MEM */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _GRPRM:
|
||||||
|
entry = &(OPCODE_TABLE(entry)[insn.rm & 7]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _GRPFP:
|
||||||
|
if(insn.mod != 3)
|
||||||
|
{
|
||||||
|
entry = &(OPCODE_TABLE(entry)[insn.nnn & 7]);
|
||||||
|
} else {
|
||||||
|
int index = (insn.b1-0xD8)*64 + (insn.modrm & 0x3f);
|
||||||
|
entry = &(BxDisasmOpcodeInfoFP[index]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _GRP3DNOW:
|
||||||
|
entry = &(BxDisasm3DNowGroup[fetch_byte()]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _GRP64B:
|
||||||
|
entry = &(OPCODE_TABLE(entry)[insn.os_64 ? 2 : insn.os_32]);
|
||||||
|
if (sse_prefix == SSE_PREFIX_66)
|
||||||
|
sse_prefix = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _GRPVEXW:
|
||||||
|
entry = &(OPCODE_TABLE(entry)[insn.vex_w]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("Internal disassembler error - unknown attribute !\n");
|
||||||
|
return x86_insn(is_32, is_64);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get additional attributes from group table */
|
||||||
|
attr = entry->Attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BRANCH_NOT_TAKEN 0x2E
|
||||||
|
#define BRANCH_TAKEN 0x3E
|
||||||
|
|
||||||
|
unsigned branch_hint = 0;
|
||||||
|
|
||||||
|
// print prefixes
|
||||||
|
for(unsigned i=0;i<prefixes;i++)
|
||||||
|
{
|
||||||
|
Bit8u prefix_byte = *(instr+i);
|
||||||
|
|
||||||
|
if (prefix_byte == 0xF0) dis_sprintf("lock ");
|
||||||
|
|
||||||
|
if (! insn.is_xop && ! insn.is_vex) {
|
||||||
|
if (insn.b1 == 0x90 && !insn.rex_b && prefix_byte == 0xF3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (prefix_byte == 0xF3 || prefix_byte == 0xF2) {
|
||||||
|
if (! sse_opcode) {
|
||||||
|
const BxDisasmOpcodeTable_t *prefix = &(opcode_table[prefix_byte]);
|
||||||
|
dis_sprintf("%s ", OPCODE(prefix)->IntelOpcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// branch hint for jcc instructions
|
||||||
|
if ((insn.b1 >= 0x070 && insn.b1 <= 0x07F) ||
|
||||||
|
(insn.b1 >= 0x180 && insn.b1 <= 0x18F))
|
||||||
|
{
|
||||||
|
if (prefix_byte == BRANCH_NOT_TAKEN || prefix_byte == BRANCH_TAKEN)
|
||||||
|
branch_hint = prefix_byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const BxDisasmOpcodeInfo_t *opcode = OPCODE(entry);
|
||||||
|
|
||||||
|
if (! insn.is_xop && ! insn.is_vex) {
|
||||||
|
// patch jecx opcode
|
||||||
|
if (insn.b1 == 0xE3 && insn.as_32 && !insn.as_64)
|
||||||
|
opcode = &Ia_jecxz_Jb;
|
||||||
|
|
||||||
|
// fix nop opcode
|
||||||
|
if (insn.b1 == 0x90) {
|
||||||
|
if (sse_prefix == SSE_PREFIX_F3)
|
||||||
|
opcode = &Ia_pause;
|
||||||
|
else if (!insn.rex_b)
|
||||||
|
opcode = &Ia_nop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// print instruction disassembly
|
||||||
|
if (intel_mode)
|
||||||
|
print_disassembly_intel(&insn, opcode);
|
||||||
|
else
|
||||||
|
print_disassembly_att (&insn, opcode);
|
||||||
|
|
||||||
|
if (branch_hint == BRANCH_NOT_TAKEN)
|
||||||
|
{
|
||||||
|
dis_sprintf(", not taken");
|
||||||
|
}
|
||||||
|
else if (branch_hint == BRANCH_TAKEN)
|
||||||
|
{
|
||||||
|
dis_sprintf(", taken");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insn.is_vex < 0)
|
||||||
|
dis_sprintf(" (bad vex)");
|
||||||
|
else if (insn.is_evex < 0)
|
||||||
|
dis_sprintf(" (bad evex)");
|
||||||
|
else if (insn.is_xop < 0)
|
||||||
|
dis_sprintf(" (bad xop)");
|
||||||
|
|
||||||
|
insn.ilen = (unsigned)(instruction - instruction_begin);
|
||||||
|
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned disassembler::decode_vex(x86_insn *insn)
|
||||||
|
{
|
||||||
|
insn->is_vex = 1;
|
||||||
|
|
||||||
|
unsigned b2 = fetch_byte(), vex_opcode_extension = 1;
|
||||||
|
|
||||||
|
insn->rex_r = (b2 & 0x80) ? 0 : 0x8;
|
||||||
|
|
||||||
|
if (insn->b1 == 0xc4) {
|
||||||
|
// decode 3-byte VEX prefix
|
||||||
|
insn->rex_x = (b2 & 0x40) ? 0 : 0x8;
|
||||||
|
if (insn->is_64)
|
||||||
|
insn->rex_b = (b2 & 0x20) ? 0 : 0x8;
|
||||||
|
|
||||||
|
vex_opcode_extension = b2 & 0x1f;
|
||||||
|
if (! vex_opcode_extension || vex_opcode_extension > 3)
|
||||||
|
insn->is_vex = -1;
|
||||||
|
|
||||||
|
b2 = fetch_byte(); // fetch VEX3 byte
|
||||||
|
if (b2 & 0x80) {
|
||||||
|
insn->os_64 = 1;
|
||||||
|
insn->os_32 = 1;
|
||||||
|
insn->vex_w = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
insn->vex_vvv = 15 - ((b2 >> 3) & 0xf);
|
||||||
|
if (! insn->is_64) insn->vex_vvv &= 7;
|
||||||
|
insn->vex_l = (b2 >> 2) & 0x1;
|
||||||
|
insn->b1 = fetch_byte() + 256 * vex_opcode_extension;
|
||||||
|
return b2 & 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned disassembler::decode_evex(x86_insn *insn)
|
||||||
|
{
|
||||||
|
insn->is_evex = 1;
|
||||||
|
|
||||||
|
Bit32u evex = fetch_dword();
|
||||||
|
|
||||||
|
// check for reserved EVEX bits
|
||||||
|
if ((evex & 0x0c) != 0 || (evex & 0x400) == 0) {
|
||||||
|
insn->is_evex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned evex_opcext = evex & 0x3;
|
||||||
|
if (evex_opcext == 0) {
|
||||||
|
insn->is_evex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insn->is_64) {
|
||||||
|
insn->rex_r = ((evex >> 4) & 0x8) ^ 0x8;
|
||||||
|
insn->rex_r |= (evex & 0x10) ^ 0x10;
|
||||||
|
insn->rex_x = ((evex >> 3) & 0x8) ^ 0x8;
|
||||||
|
insn->rex_b = ((evex >> 2) & 0x8) ^ 0x8;
|
||||||
|
insn->rex_b |= (insn->rex_x << 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned sse_prefix = (evex >> 8) & 0x3;
|
||||||
|
|
||||||
|
insn->vex_vvv = 15 - ((evex >> 11) & 0xf);
|
||||||
|
unsigned evex_v = ((evex >> 15) & 0x10) ^ 0x10;
|
||||||
|
insn->vex_vvv |= evex_v;
|
||||||
|
if (! insn->is_64) insn->vex_vvv &= 7;
|
||||||
|
|
||||||
|
insn->vex_w = (evex >> 15) & 0x1;
|
||||||
|
if (insn->vex_w) {
|
||||||
|
insn->os_64 = 1;
|
||||||
|
insn->os_32 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
insn->evex_b = (evex >> 20) & 0x1;
|
||||||
|
insn->evex_ll_rc = (evex >> 21) & 0x3;
|
||||||
|
insn->evex_z = (evex >> 23) & 0x1;
|
||||||
|
|
||||||
|
insn->b1 = (evex >> 24);
|
||||||
|
insn->b1 += 256 * (evex_opcext-1);
|
||||||
|
|
||||||
|
return sse_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned disassembler::decode_xop(x86_insn *insn)
|
||||||
|
{
|
||||||
|
insn->is_xop = 1;
|
||||||
|
|
||||||
|
unsigned b2 = fetch_byte();
|
||||||
|
|
||||||
|
insn->rex_r = (b2 & 0x80) ? 0 : 0x8;
|
||||||
|
insn->rex_x = (b2 & 0x40) ? 0 : 0x8;
|
||||||
|
if (insn->is_64)
|
||||||
|
insn->rex_b = (b2 & 0x20) ? 0 : 0x8;
|
||||||
|
|
||||||
|
unsigned xop_opcode_extension = (b2 & 0x1f) - 8;
|
||||||
|
if (xop_opcode_extension >= 3)
|
||||||
|
insn->is_xop = -1;
|
||||||
|
|
||||||
|
b2 = fetch_byte(); // fetch VEX3 byte
|
||||||
|
if (b2 & 0x80) {
|
||||||
|
insn->os_64 = 1;
|
||||||
|
insn->os_32 = 1;
|
||||||
|
insn->vex_w = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
insn->vex_vvv = 15 - ((b2 >> 3) & 0xf);
|
||||||
|
if (! insn->is_64) insn->vex_vvv &= 7;
|
||||||
|
insn->vex_l = (b2 >> 2) & 0x1;
|
||||||
|
insn->b1 = fetch_byte() + 256 * xop_opcode_extension;
|
||||||
|
|
||||||
|
return b2 & 0x3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::dis_sprintf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsprintf(disbufptr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
disbufptr += strlen(disbufptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::dis_putc(char symbol)
|
||||||
|
{
|
||||||
|
*disbufptr++ = symbol;
|
||||||
|
*disbufptr = 0;
|
||||||
|
}
|
|
@ -1,328 +0,0 @@
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
// $Id: dis_decode.cc,v 1.32 2006/05/12 17:04:19 sshwarts Exp $
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "disasm.h"
|
|
||||||
#include "dis_tables.h"
|
|
||||||
|
|
||||||
#define OPCODE(entry) ((BxDisasmOpcodeInfo_t*) entry->OpcodeInfo)
|
|
||||||
#define OPCODE_TABLE(entry) ((BxDisasmOpcodeTable_t*) entry->OpcodeInfo)
|
|
||||||
|
|
||||||
#ifndef NULL
|
|
||||||
#define NULL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static const unsigned char instruction_has_modrm[512] = {
|
|
||||||
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
||||||
/* ------------------------------- */
|
|
||||||
/* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
|
|
||||||
/* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
|
|
||||||
/* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
|
|
||||||
/* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
|
|
||||||
/* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
/* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
/* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
|
|
||||||
/* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
/* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
||||||
/* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
/* A0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
/* B0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
/* C0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
|
|
||||||
/* D0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
|
|
||||||
/* E0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
/* F0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,
|
|
||||||
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
||||||
/* ------------------------------- */
|
|
||||||
1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0F 00 */
|
|
||||||
1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 0F 10 */
|
|
||||||
1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 0F 20 */
|
|
||||||
0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 0F 30 */
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 40 */
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 50 */
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 60 */
|
|
||||||
1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 0F 70 */
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0F 80 */
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 90 */
|
|
||||||
0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* 0F A0 */
|
|
||||||
1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* 0F B0 */
|
|
||||||
1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 0F C0 */
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F D0 */
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F E0 */
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* 0F F0 */
|
|
||||||
/* ------------------------------- */
|
|
||||||
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned disassembler::disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
|
||||||
{
|
|
||||||
x86_insn insn = decode(is_32, is_64, base, ip, instr, disbuf);
|
|
||||||
return insn.ilen;
|
|
||||||
}
|
|
||||||
|
|
||||||
x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
|
||||||
{
|
|
||||||
x86_insn insn(is_32, is_64);
|
|
||||||
const Bit8u *instruction_begin = instruction = instr;
|
|
||||||
resolve_modrm = NULL;
|
|
||||||
unsigned b3 = 0;
|
|
||||||
|
|
||||||
db_eip = ip;
|
|
||||||
db_base = base; // cs linear base (base for PM & cs<<4 for RM & VM)
|
|
||||||
|
|
||||||
disbufptr = disbuf; // start sprintf()'ing into beginning of buffer
|
|
||||||
|
|
||||||
#define SSE_PREFIX_NONE 0
|
|
||||||
#define SSE_PREFIX_66 1
|
|
||||||
#define SSE_PREFIX_F2 2
|
|
||||||
#define SSE_PREFIX_F3 3 /* only one SSE prefix could be used */
|
|
||||||
unsigned sse_prefix = SSE_PREFIX_NONE;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
insn.b1 = fetch_byte();
|
|
||||||
insn.prefixes++;
|
|
||||||
|
|
||||||
switch(insn.b1) {
|
|
||||||
case 0x40: // rex
|
|
||||||
case 0x41:
|
|
||||||
case 0x42:
|
|
||||||
case 0x43:
|
|
||||||
case 0x44:
|
|
||||||
case 0x45:
|
|
||||||
case 0x46:
|
|
||||||
case 0x47:
|
|
||||||
case 0x48:
|
|
||||||
case 0x49:
|
|
||||||
case 0x4A:
|
|
||||||
case 0x4B:
|
|
||||||
case 0x4C:
|
|
||||||
case 0x4D:
|
|
||||||
case 0x4E:
|
|
||||||
case 0x4F:
|
|
||||||
if (! is_64) break;
|
|
||||||
insn.extend8b = 1;
|
|
||||||
if (insn.b1 & 0x8) {
|
|
||||||
insn.os_64 = 1;
|
|
||||||
insn.os_32 = 1;
|
|
||||||
}
|
|
||||||
if (insn.b1 & 0x4) insn.rex_r = 8;
|
|
||||||
if (insn.b1 & 0x2) insn.rex_x = 8;
|
|
||||||
if (insn.b1 & 0x1) insn.rex_b = 8;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0x26: // ES:
|
|
||||||
if (! is_64) insn.seg_override = ES_REG;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0x2e: // CS:
|
|
||||||
if (! is_64) insn.seg_override = CS_REG;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0x36: // SS:
|
|
||||||
if (! is_64) insn.seg_override = SS_REG;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0x3e: // DS:
|
|
||||||
if (! is_64) insn.seg_override = DS_REG;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0x64: // FS:
|
|
||||||
insn.seg_override = FS_REG;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0x65: // GS:
|
|
||||||
insn.seg_override = GS_REG;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0x66: // operand size override
|
|
||||||
if (!insn.os_64) insn.os_32 = !is_32;
|
|
||||||
if (!sse_prefix) sse_prefix = SSE_PREFIX_66;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0x67: // address size override
|
|
||||||
if (!is_64) insn.as_32 = !is_32;
|
|
||||||
insn.as_64 = 0;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0xf0: // lock
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0xf2: // repne
|
|
||||||
if (!sse_prefix) sse_prefix = SSE_PREFIX_F2;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 0xf3: // rep
|
|
||||||
if (!sse_prefix) sse_prefix = SSE_PREFIX_F3;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// no more prefixes
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
insn.prefixes--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insn.b1 == 0x0f)
|
|
||||||
{
|
|
||||||
insn.b1 = 0x100 | fetch_byte();
|
|
||||||
}
|
|
||||||
|
|
||||||
const BxDisasmOpcodeTable_t *opcode_table, *entry;
|
|
||||||
|
|
||||||
if (is_64) {
|
|
||||||
if (insn.os_64)
|
|
||||||
opcode_table = BxDisasmOpcodes64q;
|
|
||||||
else if (insn.os_32)
|
|
||||||
opcode_table = BxDisasmOpcodes64d;
|
|
||||||
else
|
|
||||||
opcode_table = BxDisasmOpcodes64w;
|
|
||||||
} else {
|
|
||||||
if (insn.os_32)
|
|
||||||
opcode_table = BxDisasmOpcodes32;
|
|
||||||
else
|
|
||||||
opcode_table = BxDisasmOpcodes16;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = opcode_table + insn.b1;
|
|
||||||
|
|
||||||
// will require 3rd byte for 3-byte opcode
|
|
||||||
if (entry->Attr & _GRP3BTAB) b3 = fetch_byte();
|
|
||||||
|
|
||||||
if (instruction_has_modrm[insn.b1])
|
|
||||||
{
|
|
||||||
decode_modrm(&insn);
|
|
||||||
}
|
|
||||||
|
|
||||||
int attr = entry->Attr;
|
|
||||||
while(attr)
|
|
||||||
{
|
|
||||||
switch(attr) {
|
|
||||||
case _GROUPN:
|
|
||||||
entry = &(OPCODE_TABLE(entry)[insn.nnn]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _GRPSSE:
|
|
||||||
if(sse_prefix) insn.prefixes--;
|
|
||||||
/* For SSE opcodes, look into another 4 entries table
|
|
||||||
with the opcode prefixes (NONE, 0x66, 0xF2, 0xF3) */
|
|
||||||
entry = &(OPCODE_TABLE(entry)[sse_prefix]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _SPLIT11B:
|
|
||||||
entry = &(OPCODE_TABLE(entry)[insn.mod != 3]); /* REG/MEM */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _GRPRM:
|
|
||||||
entry = &(OPCODE_TABLE(entry)[insn.rm]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _GRPFP:
|
|
||||||
if(insn.mod != 3)
|
|
||||||
{
|
|
||||||
entry = &(OPCODE_TABLE(entry)[insn.nnn]);
|
|
||||||
} else {
|
|
||||||
int index = (insn.b1-0xD8)*64 + (insn.modrm & 0x3f);
|
|
||||||
entry = &(BxDisasmOpcodeInfoFP[index]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _GRP3DNOW:
|
|
||||||
entry = &(BxDisasm3DNowGroup[peek_byte()]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _GRP3BTAB:
|
|
||||||
entry = &(OPCODE_TABLE(entry)[b3 >> 4]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case _GRP3BOP:
|
|
||||||
entry = &(OPCODE_TABLE(entry)[b3 & 15]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("Internal disassembler error - unknown attribute !\n");
|
|
||||||
return x86_insn(is_32, is_64);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get additional attributes from group table */
|
|
||||||
attr = entry->Attr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BRANCH_NOT_TAKEN 0x2E
|
|
||||||
#define BRANCH_TAKEN 0x3E
|
|
||||||
|
|
||||||
unsigned branch_hint = 0;
|
|
||||||
|
|
||||||
// print prefixes
|
|
||||||
for(unsigned i=0;i<insn.prefixes;i++)
|
|
||||||
{
|
|
||||||
Bit8u prefix_byte = *(instr+i);
|
|
||||||
|
|
||||||
if (prefix_byte == 0xF3 || prefix_byte == 0xF2 || prefix_byte == 0xF0)
|
|
||||||
{
|
|
||||||
const BxDisasmOpcodeTable_t *prefix = &(opcode_table[prefix_byte]);
|
|
||||||
dis_sprintf("%s ", OPCODE(prefix)->IntelOpcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// branch hint for jcc instructions
|
|
||||||
if ((insn.b1 >= 0x070 && insn.b1 <= 0x07F) ||
|
|
||||||
(insn.b1 >= 0x180 && insn.b1 <= 0x18F))
|
|
||||||
{
|
|
||||||
if (prefix_byte == BRANCH_NOT_TAKEN || prefix_byte == BRANCH_TAKEN)
|
|
||||||
branch_hint = prefix_byte;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const BxDisasmOpcodeInfo_t *opcode = OPCODE(entry);
|
|
||||||
|
|
||||||
// patch jecx opcode
|
|
||||||
if (insn.b1 == 0xE3 && insn.as_32 && !insn.as_64)
|
|
||||||
opcode = &Ia_jecxz_Jb;
|
|
||||||
|
|
||||||
// fix nop opcode
|
|
||||||
if (insn.b1 == 0x90 && !insn.rex_b) {
|
|
||||||
opcode = &Ia_nop;
|
|
||||||
}
|
|
||||||
|
|
||||||
// print instruction disassembly
|
|
||||||
if (intel_mode)
|
|
||||||
print_disassembly_intel(&insn, opcode);
|
|
||||||
else
|
|
||||||
print_disassembly_att (&insn, opcode);
|
|
||||||
|
|
||||||
if (branch_hint == BRANCH_NOT_TAKEN)
|
|
||||||
{
|
|
||||||
dis_sprintf(", not taken");
|
|
||||||
}
|
|
||||||
else if (branch_hint == BRANCH_TAKEN)
|
|
||||||
{
|
|
||||||
dis_sprintf(", taken");
|
|
||||||
}
|
|
||||||
|
|
||||||
insn.ilen = (unsigned)(instruction - instruction_begin);
|
|
||||||
|
|
||||||
return insn;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::dis_sprintf(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(disbufptr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
disbufptr += strlen(disbufptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::dis_putc(char symbol)
|
|
||||||
{
|
|
||||||
*disbufptr++ = symbol;
|
|
||||||
*disbufptr = 0;
|
|
||||||
}
|
|
|
@ -1,6 +1,23 @@
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: dis_groups.cc,v 1.33 2006/08/13 09:40:07 sshwarts Exp $
|
// $Id: dis_groups.cc 11885 2013-10-15 17:19:18Z sshwarts $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005-2011 Stanislav Shwartsman
|
||||||
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -16,41 +33,46 @@ void disassembler::Apw(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
Bit16u imm16 = fetch_word();
|
Bit16u imm16 = fetch_word();
|
||||||
Bit16u cs_selector = fetch_word();
|
Bit16u cs_selector = fetch_word();
|
||||||
dis_sprintf("%04x:%04x", (unsigned) cs_selector, (unsigned) imm16);
|
dis_sprintf("0x%04x:%04x", (unsigned) cs_selector, (unsigned) imm16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Apd(const x86_insn *insn)
|
void disassembler::Apd(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
Bit32u imm32 = fetch_dword();
|
Bit32u imm32 = fetch_dword();
|
||||||
Bit16u cs_selector = fetch_word();
|
Bit16u cs_selector = fetch_word();
|
||||||
dis_sprintf("%04x:%08x", (unsigned) cs_selector, (unsigned) imm32);
|
dis_sprintf("0x%04x:%08x", (unsigned) cs_selector, (unsigned) imm32);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8-bit general purpose registers
|
// 8-bit general purpose registers
|
||||||
void disassembler::AL(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rAX_REG]); }
|
void disassembler::AL_Reg(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rAX_REG]); }
|
||||||
void disassembler::CL(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rCX_REG]); }
|
void disassembler::CL_Reg(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rCX_REG]); }
|
||||||
|
|
||||||
// 16-bit general purpose registers
|
// 16-bit general purpose registers
|
||||||
void disassembler::AX(const x86_insn *insn) {
|
void disassembler::AX_Reg(const x86_insn *insn) {
|
||||||
dis_sprintf("%s", general_16bit_regname[rAX_REG]);
|
dis_sprintf("%s", general_16bit_regname[rAX_REG]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::DX(const x86_insn *insn) {
|
void disassembler::DX_Reg(const x86_insn *insn) {
|
||||||
dis_sprintf("%s", general_16bit_regname[rDX_REG]);
|
dis_sprintf("%s", general_16bit_regname[rDX_REG]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 32-bit general purpose registers
|
// 32-bit general purpose registers
|
||||||
void disassembler::EAX(const x86_insn *insn)
|
void disassembler::EAX_Reg(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
dis_sprintf("%s", general_32bit_regname[rAX_REG]);
|
dis_sprintf("%s", general_32bit_regname[rAX_REG]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 64-bit general purpose registers
|
// 64-bit general purpose registers
|
||||||
void disassembler::RAX(const x86_insn *insn)
|
void disassembler::RAX_Reg(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
dis_sprintf("%s", general_64bit_regname[rAX_REG]);
|
dis_sprintf("%s", general_64bit_regname[rAX_REG]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disassembler::RCX_Reg(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
dis_sprintf("%s", general_64bit_regname[rCX_REG]);
|
||||||
|
}
|
||||||
|
|
||||||
// segment registers
|
// segment registers
|
||||||
void disassembler::CS(const x86_insn *insn) { dis_sprintf("%s", segment_name[CS_REG]); }
|
void disassembler::CS(const x86_insn *insn) { dis_sprintf("%s", segment_name[CS_REG]); }
|
||||||
void disassembler::DS(const x86_insn *insn) { dis_sprintf("%s", segment_name[DS_REG]); }
|
void disassembler::DS(const x86_insn *insn) { dis_sprintf("%s", segment_name[DS_REG]); }
|
||||||
|
@ -61,18 +83,9 @@ void disassembler::GS(const x86_insn *insn) { dis_sprintf("%s", segment_name[GS_
|
||||||
|
|
||||||
void disassembler::Sw(const x86_insn *insn) { dis_sprintf("%s", segment_name[insn->nnn]); }
|
void disassembler::Sw(const x86_insn *insn) { dis_sprintf("%s", segment_name[insn->nnn]); }
|
||||||
|
|
||||||
// test registers
|
|
||||||
void disassembler::Td(const x86_insn *insn)
|
|
||||||
{
|
|
||||||
if (intel_mode)
|
|
||||||
dis_sprintf ("tr%d", insn->nnn);
|
|
||||||
else
|
|
||||||
dis_sprintf("%%tr%d", insn->nnn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// control register
|
// control register
|
||||||
void disassembler::Cd(const x86_insn *insn)
|
void disassembler::Cd(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
dis_sprintf ("cr%d", insn->nnn);
|
dis_sprintf ("cr%d", insn->nnn);
|
||||||
else
|
else
|
||||||
|
@ -82,21 +95,21 @@ void disassembler::Cd(const x86_insn *insn)
|
||||||
void disassembler::Cq(const x86_insn *insn) { Cd(insn); }
|
void disassembler::Cq(const x86_insn *insn) { Cd(insn); }
|
||||||
|
|
||||||
// debug register
|
// debug register
|
||||||
void disassembler::Dd(const x86_insn *insn)
|
void disassembler::Dd(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
dis_sprintf ("db%d", insn->nnn);
|
dis_sprintf ("dr%d", insn->nnn);
|
||||||
else
|
else
|
||||||
dis_sprintf("%%db%d", insn->nnn);
|
dis_sprintf("%%dr%d", insn->nnn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Dq(const x86_insn *insn) { Dd(insn); }
|
void disassembler::Dq(const x86_insn *insn) { Dd(insn); }
|
||||||
|
|
||||||
// 8-bit general purpose register
|
// 8-bit general purpose register
|
||||||
void disassembler::R8(const x86_insn *insn)
|
void disassembler::Reg8(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
unsigned reg = (insn->b1 & 7) | insn->rex_b;
|
unsigned reg = (insn->b1 & 7) | insn->rex_b;
|
||||||
|
|
||||||
if (reg < 4 || insn->extend8b)
|
if (reg < 4 || insn->extend8b)
|
||||||
dis_sprintf("%s", general_8bit_regname_rex[reg]);
|
dis_sprintf("%s", general_8bit_regname_rex[reg]);
|
||||||
else
|
else
|
||||||
|
@ -105,24 +118,24 @@ void disassembler::R8(const x86_insn *insn)
|
||||||
|
|
||||||
// 16-bit general purpose register
|
// 16-bit general purpose register
|
||||||
void disassembler::RX(const x86_insn *insn)
|
void disassembler::RX(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
dis_sprintf("%s", general_16bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
dis_sprintf("%s", general_16bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 32-bit general purpose register
|
// 32-bit general purpose register
|
||||||
void disassembler::ERX(const x86_insn *insn)
|
void disassembler::ERX(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
dis_sprintf("%s", general_32bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
dis_sprintf("%s", general_32bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 64-bit general purpose register
|
// 64-bit general purpose register
|
||||||
void disassembler::RRX(const x86_insn *insn)
|
void disassembler::RRX(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
dis_sprintf("%s", general_64bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
dis_sprintf("%s", general_64bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// general purpose register or memory operand
|
// general purpose register or memory operand
|
||||||
void disassembler::Eb(const x86_insn *insn)
|
void disassembler::Eb(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (insn->mod == 3) {
|
if (insn->mod == 3) {
|
||||||
if (insn->rm < 4 || insn->extend8b)
|
if (insn->rm < 4 || insn->extend8b)
|
||||||
|
@ -134,7 +147,7 @@ void disassembler::Eb(const x86_insn *insn)
|
||||||
(this->*resolve_modrm)(insn, B_SIZE);
|
(this->*resolve_modrm)(insn, B_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Ew(const x86_insn *insn)
|
void disassembler::Ew(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (insn->mod == 3)
|
if (insn->mod == 3)
|
||||||
dis_sprintf("%s", general_16bit_regname[insn->rm]);
|
dis_sprintf("%s", general_16bit_regname[insn->rm]);
|
||||||
|
@ -142,7 +155,7 @@ void disassembler::Ew(const x86_insn *insn)
|
||||||
(this->*resolve_modrm)(insn, W_SIZE);
|
(this->*resolve_modrm)(insn, W_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Ed(const x86_insn *insn)
|
void disassembler::Ed(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (insn->mod == 3)
|
if (insn->mod == 3)
|
||||||
dis_sprintf("%s", general_32bit_regname[insn->rm]);
|
dis_sprintf("%s", general_32bit_regname[insn->rm]);
|
||||||
|
@ -150,7 +163,7 @@ void disassembler::Ed(const x86_insn *insn)
|
||||||
(this->*resolve_modrm)(insn, D_SIZE);
|
(this->*resolve_modrm)(insn, D_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Eq(const x86_insn *insn)
|
void disassembler::Eq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (insn->mod == 3)
|
if (insn->mod == 3)
|
||||||
dis_sprintf("%s", general_64bit_regname[insn->rm]);
|
dis_sprintf("%s", general_64bit_regname[insn->rm]);
|
||||||
|
@ -158,8 +171,30 @@ void disassembler::Eq(const x86_insn *insn)
|
||||||
(this->*resolve_modrm)(insn, Q_SIZE);
|
(this->*resolve_modrm)(insn, Q_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disassembler::Ey(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->os_64) Eq(insn);
|
||||||
|
else Ed(insn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::Ebd(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->mod == 3)
|
||||||
|
dis_sprintf("%s", general_32bit_regname[insn->rm]);
|
||||||
|
else
|
||||||
|
(this->*resolve_modrm)(insn, B_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::Ewd(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->mod == 3)
|
||||||
|
dis_sprintf("%s", general_32bit_regname[insn->rm]);
|
||||||
|
else
|
||||||
|
(this->*resolve_modrm)(insn, W_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
// general purpose register
|
// general purpose register
|
||||||
void disassembler::Gb(const x86_insn *insn)
|
void disassembler::Gb(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (insn->nnn < 4 || insn->extend8b)
|
if (insn->nnn < 4 || insn->extend8b)
|
||||||
dis_sprintf("%s", general_8bit_regname_rex[insn->nnn]);
|
dis_sprintf("%s", general_8bit_regname_rex[insn->nnn]);
|
||||||
|
@ -167,41 +202,69 @@ void disassembler::Gb(const x86_insn *insn)
|
||||||
dis_sprintf("%s", general_8bit_regname[insn->nnn]);
|
dis_sprintf("%s", general_8bit_regname[insn->nnn]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Gw(const x86_insn *insn)
|
void disassembler::Gw(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
dis_sprintf("%s", general_16bit_regname[insn->nnn]);
|
dis_sprintf("%s", general_16bit_regname[insn->nnn]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Gd(const x86_insn *insn)
|
void disassembler::Gd(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
dis_sprintf("%s", general_32bit_regname[insn->nnn]);
|
dis_sprintf("%s", general_32bit_regname[insn->nnn]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Gq(const x86_insn *insn)
|
void disassembler::Gq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
dis_sprintf("%s", general_64bit_regname[insn->nnn]);
|
dis_sprintf("%s", general_64bit_regname[insn->nnn]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disassembler::Gy(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->os_64) Gq(insn);
|
||||||
|
else Gd(insn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vex encoded general purpose register
|
||||||
|
void disassembler::By(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->os_64)
|
||||||
|
dis_sprintf("%s", general_64bit_regname[insn->vex_vvv]);
|
||||||
|
else
|
||||||
|
dis_sprintf("%s", general_32bit_regname[insn->vex_vvv]);
|
||||||
|
}
|
||||||
|
|
||||||
// immediate
|
// immediate
|
||||||
void disassembler::I1(const x86_insn *insn)
|
void disassembler::I1(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
dis_putc ('1');
|
dis_putc ('1');
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Ib(const x86_insn *insn)
|
void disassembler::Ib(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
dis_sprintf("0x%02x", (unsigned) fetch_byte());
|
dis_sprintf("0x%02x", (unsigned) fetch_byte());
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Iw(const x86_insn *insn)
|
void disassembler::Iw(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
dis_sprintf("0x%04x", (unsigned) fetch_word());
|
dis_sprintf("0x%04x", (unsigned) fetch_word());
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::IwIb(const x86_insn *insn)
|
void disassembler::IbIb(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
Bit8u ib1 = fetch_byte();
|
||||||
|
Bit8u ib2 = fetch_byte();
|
||||||
|
|
||||||
|
if (intel_mode) {
|
||||||
|
dis_sprintf("0x%02x, 0x%02x", ib1, ib2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf("$0x%02x, $0x%02x", ib2, ib1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::IwIb(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
Bit16u iw = fetch_word();
|
Bit16u iw = fetch_word();
|
||||||
Bit8u ib = fetch_byte();
|
Bit8u ib = fetch_byte();
|
||||||
|
@ -214,23 +277,22 @@ void disassembler::IwIb(const x86_insn *insn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Id(const x86_insn *insn)
|
void disassembler::Id(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
dis_sprintf("0x%08x", (unsigned) fetch_dword());
|
dis_sprintf("0x%08x", (unsigned) fetch_dword());
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Iq(const x86_insn *insn)
|
void disassembler::Iq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
Bit64u value = fetch_qword();
|
Bit64u value = fetch_qword();
|
||||||
|
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
dis_sprintf("0x%08x%08x",
|
dis_sprintf("0x%08x%08x", GET32H(value), GET32L(value));
|
||||||
(unsigned)(value>>32), (unsigned)(value & 0xffffffff));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign extended immediate
|
// sign extended immediate
|
||||||
void disassembler::sIbw(const x86_insn *insn)
|
void disassembler::sIbw(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
Bit16u imm16 = (Bit8s) fetch_byte();
|
Bit16u imm16 = (Bit8s) fetch_byte();
|
||||||
|
@ -238,7 +300,7 @@ void disassembler::sIbw(const x86_insn *insn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign extended immediate
|
// sign extended immediate
|
||||||
void disassembler::sIbd(const x86_insn *insn)
|
void disassembler::sIbd(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
Bit32u imm32 = (Bit8s) fetch_byte();
|
Bit32u imm32 = (Bit8s) fetch_byte();
|
||||||
|
@ -246,38 +308,36 @@ void disassembler::sIbd(const x86_insn *insn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign extended immediate
|
// sign extended immediate
|
||||||
void disassembler::sIbq(const x86_insn *insn)
|
void disassembler::sIbq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
Bit64u imm64 = (Bit8s) fetch_byte();
|
Bit64u imm64 = (Bit8s) fetch_byte();
|
||||||
dis_sprintf ("0x%08x%08x",
|
dis_sprintf ("0x%08x%08x", GET32H(imm64), GET32L(imm64));
|
||||||
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign extended immediate
|
// sign extended immediate
|
||||||
void disassembler::sIdq(const x86_insn *insn)
|
void disassembler::sIdq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (! intel_mode) dis_putc('$');
|
if (! intel_mode) dis_putc('$');
|
||||||
Bit64u imm64 = (Bit32s) fetch_dword();
|
Bit64u imm64 = (Bit32s) fetch_dword();
|
||||||
dis_sprintf ("0x%08x%08x",
|
dis_sprintf ("0x%08x%08x", GET32H(imm64), GET32L(imm64));
|
||||||
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// floating point
|
// floating point
|
||||||
void disassembler::ST0(const x86_insn *insn)
|
void disassembler::ST0(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
dis_sprintf ("st(0)");
|
dis_sprintf ("st(0)");
|
||||||
else
|
else
|
||||||
dis_sprintf("%%st(0)");
|
dis_sprintf("%%st(0)");
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::STi(const x86_insn *insn)
|
void disassembler::STi(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
dis_sprintf ("st(%d)", insn->rm);
|
dis_sprintf ("st(%d)", insn->rm & 7);
|
||||||
else
|
else
|
||||||
dis_sprintf("%%st(%d)", insn->rm);
|
dis_sprintf("%%st(%d)", insn->rm & 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16-bit general purpose register
|
// 16-bit general purpose register
|
||||||
|
@ -298,21 +358,27 @@ void disassembler::Rq(const x86_insn *insn)
|
||||||
dis_sprintf("%s", general_64bit_regname[insn->rm]);
|
dis_sprintf("%s", general_64bit_regname[insn->rm]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disassembler::Ry(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->os_64) Rq(insn);
|
||||||
|
else Rd(insn);
|
||||||
|
}
|
||||||
|
|
||||||
// mmx register
|
// mmx register
|
||||||
void disassembler::Pq(const x86_insn *insn)
|
void disassembler::Pq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
dis_sprintf ("mm%d", insn->nnn);
|
dis_sprintf ("mm%d", insn->nnn & 0x7);
|
||||||
else
|
else
|
||||||
dis_sprintf("%%mm%d", insn->nnn);
|
dis_sprintf("%%mm%d", insn->nnn & 0x7);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Nq(const x86_insn *insn)
|
void disassembler::Nq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
dis_sprintf ("mm%d", insn->rm);
|
dis_sprintf ("mm%d", insn->rm & 0x7);
|
||||||
else
|
else
|
||||||
dis_sprintf("%%mm%d", insn->rm);
|
dis_sprintf("%%mm%d", insn->rm & 0x7);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Qd(const x86_insn *insn)
|
void disassembler::Qd(const x86_insn *insn)
|
||||||
|
@ -320,9 +386,9 @@ void disassembler::Qd(const x86_insn *insn)
|
||||||
if (insn->mod == 3)
|
if (insn->mod == 3)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
dis_sprintf ("mm%d", insn->rm);
|
dis_sprintf ("mm%d", insn->rm & 0x7);
|
||||||
else
|
else
|
||||||
dis_sprintf("%%mm%d", insn->rm);
|
dis_sprintf("%%mm%d", insn->rm & 0x7);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(this->*resolve_modrm)(insn, D_SIZE);
|
(this->*resolve_modrm)(insn, D_SIZE);
|
||||||
|
@ -333,29 +399,27 @@ void disassembler::Qq(const x86_insn *insn)
|
||||||
if (insn->mod == 3)
|
if (insn->mod == 3)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
dis_sprintf ("mm%d", insn->rm);
|
dis_sprintf ("mm%d", insn->rm & 0x7);
|
||||||
else
|
else
|
||||||
dis_sprintf("%%mm%d", insn->rm);
|
dis_sprintf("%%mm%d", insn->rm & 0x7);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(this->*resolve_modrm)(insn, Q_SIZE);
|
(this->*resolve_modrm)(insn, Q_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// xmm register
|
// xmm/ymm register
|
||||||
void disassembler::Udq(const x86_insn *insn)
|
void disassembler::Udq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
dis_sprintf("%s%d", vector_reg_name[insn->vex_l], insn->rm);
|
||||||
dis_sprintf ("xmm%d", insn->rm);
|
|
||||||
else
|
|
||||||
dis_sprintf("%%xmm%d", insn->rm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disassembler::Ups(const x86_insn *insn) { Udq(insn); }
|
||||||
|
void disassembler::Upd(const x86_insn *insn) { Udq(insn); }
|
||||||
|
void disassembler::Uq(const x86_insn *insn) { Udq(insn); }
|
||||||
|
|
||||||
void disassembler::Vq(const x86_insn *insn)
|
void disassembler::Vq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (intel_mode)
|
dis_sprintf("%s%d", vector_reg_name[insn->vex_l], insn->nnn);
|
||||||
dis_sprintf ("xmm%d", insn->nnn);
|
|
||||||
else
|
|
||||||
dis_sprintf("%%xmm%d", insn->nnn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Vdq(const x86_insn *insn) { Vq(insn); }
|
void disassembler::Vdq(const x86_insn *insn) { Vq(insn); }
|
||||||
|
@ -364,47 +428,60 @@ void disassembler::Vsd(const x86_insn *insn) { Vq(insn); }
|
||||||
void disassembler::Vps(const x86_insn *insn) { Vq(insn); }
|
void disassembler::Vps(const x86_insn *insn) { Vq(insn); }
|
||||||
void disassembler::Vpd(const x86_insn *insn) { Vq(insn); }
|
void disassembler::Vpd(const x86_insn *insn) { Vq(insn); }
|
||||||
|
|
||||||
|
void disassembler::VIb(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
unsigned vreg = fetch_byte() >> 4;
|
||||||
|
if (! insn->is_64) vreg &= 7;
|
||||||
|
dis_sprintf("%s%d", vector_reg_name[insn->vex_l], vreg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::Hdq(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
dis_sprintf("%s%d", vector_reg_name[insn->vex_l], insn->vex_vvv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::Hps(const x86_insn *insn) { Hdq(insn); }
|
||||||
|
void disassembler::Hpd(const x86_insn *insn) { Hdq(insn); }
|
||||||
|
void disassembler::Hss(const x86_insn *insn) { Hdq(insn); }
|
||||||
|
void disassembler::Hsd(const x86_insn *insn) { Hdq(insn); }
|
||||||
|
|
||||||
|
void disassembler::Wb(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->mod == 3) Udq(insn);
|
||||||
|
else
|
||||||
|
(this->*resolve_modrm)(insn, B_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::Ww(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->mod == 3) Udq(insn);
|
||||||
|
else
|
||||||
|
(this->*resolve_modrm)(insn, W_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::Wd(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if (insn->mod == 3) Udq(insn);
|
||||||
|
else
|
||||||
|
(this->*resolve_modrm)(insn, D_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
void disassembler::Wq(const x86_insn *insn)
|
void disassembler::Wq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (insn->mod == 3)
|
if (insn->mod == 3) Udq(insn);
|
||||||
{
|
|
||||||
if (intel_mode)
|
|
||||||
dis_sprintf ("xmm%d", insn->rm);
|
|
||||||
else
|
|
||||||
dis_sprintf("%%xmm%d", insn->rm);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
(this->*resolve_modrm)(insn, Q_SIZE);
|
(this->*resolve_modrm)(insn, Q_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Wdq(const x86_insn *insn)
|
void disassembler::Wdq(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
if (insn->mod == 3)
|
if (insn->mod == 3) Udq(insn);
|
||||||
{
|
|
||||||
if (intel_mode)
|
|
||||||
dis_sprintf ("xmm%d", insn->rm);
|
|
||||||
else
|
|
||||||
dis_sprintf("%%xmm%d", insn->rm);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
(this->*resolve_modrm)(insn, O_SIZE);
|
(this->*resolve_modrm)(insn, XMM_SIZE + insn->vex_l);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::Wsd(const x86_insn *insn) { Wq(insn); }
|
void disassembler::Wsd(const x86_insn *insn) { Wq(insn); }
|
||||||
|
void disassembler::Wss(const x86_insn *insn) { Wd(insn); }
|
||||||
void disassembler::Wss(const x86_insn *insn)
|
|
||||||
{
|
|
||||||
if (insn->mod == 3)
|
|
||||||
{
|
|
||||||
if (intel_mode)
|
|
||||||
dis_sprintf ("xmm%d", insn->rm);
|
|
||||||
else
|
|
||||||
dis_sprintf("%%xmm%d", insn->rm);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(this->*resolve_modrm)(insn, D_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::Wpd(const x86_insn *insn) { Wdq(insn); }
|
void disassembler::Wpd(const x86_insn *insn) { Wdq(insn); }
|
||||||
void disassembler::Wps(const x86_insn *insn) { Wdq(insn); }
|
void disassembler::Wps(const x86_insn *insn) { Wdq(insn); }
|
||||||
|
|
||||||
|
@ -422,16 +499,15 @@ void disassembler::OP_O(const x86_insn *insn, unsigned size)
|
||||||
|
|
||||||
if (insn->as_64) {
|
if (insn->as_64) {
|
||||||
Bit64u imm64 = fetch_qword();
|
Bit64u imm64 = fetch_qword();
|
||||||
dis_sprintf("%s:0x%08x%08x", seg,
|
dis_sprintf("%s:0x%08x%08x", seg, GET32H(imm64), GET32L(imm64));
|
||||||
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
|
|
||||||
}
|
}
|
||||||
else if (insn->as_32) {
|
else if (insn->as_32) {
|
||||||
Bit32u imm32 = fetch_dword();
|
Bit32u imm32 = fetch_dword();
|
||||||
dis_sprintf("%s:0x%x", seg, (unsigned) imm32);
|
dis_sprintf("%s:0x%08x", seg, (unsigned) imm32);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Bit16u imm16 = fetch_word();
|
Bit16u imm16 = fetch_word();
|
||||||
dis_sprintf("%s:0x%x", seg, (unsigned) imm16);
|
dis_sprintf("%s:0x%04x", seg, (unsigned) imm16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,9 +536,20 @@ void disassembler::Md(const x86_insn *insn) { OP_M(insn, D_SIZE); }
|
||||||
void disassembler::Mq(const x86_insn *insn) { OP_M(insn, Q_SIZE); }
|
void disassembler::Mq(const x86_insn *insn) { OP_M(insn, Q_SIZE); }
|
||||||
void disassembler::Mt(const x86_insn *insn) { OP_M(insn, T_SIZE); }
|
void disassembler::Mt(const x86_insn *insn) { OP_M(insn, T_SIZE); }
|
||||||
|
|
||||||
void disassembler::Mdq(const x86_insn *insn) { OP_M(insn, O_SIZE); }
|
void disassembler::Mdq(const x86_insn *insn) { OP_M(insn, XMM_SIZE + insn->vex_l); }
|
||||||
void disassembler::Mps(const x86_insn *insn) { OP_M(insn, O_SIZE); }
|
void disassembler::Mps(const x86_insn *insn) { OP_M(insn, XMM_SIZE + insn->vex_l); }
|
||||||
void disassembler::Mpd(const x86_insn *insn) { OP_M(insn, O_SIZE); }
|
void disassembler::Mpd(const x86_insn *insn) { OP_M(insn, XMM_SIZE + insn->vex_l); }
|
||||||
|
void disassembler::Mss(const x86_insn *insn) { OP_M(insn, D_SIZE); }
|
||||||
|
void disassembler::Msd(const x86_insn *insn) { OP_M(insn, Q_SIZE); }
|
||||||
|
|
||||||
|
// gather VSib
|
||||||
|
void disassembler::VSib(const x86_insn *insn)
|
||||||
|
{
|
||||||
|
if(insn->mod == 3)
|
||||||
|
dis_sprintf("(bad)");
|
||||||
|
else
|
||||||
|
(this->*resolve_modrm)(insn, (XMM_SIZE + insn->vex_l) | VSIB_Index);
|
||||||
|
}
|
||||||
|
|
||||||
// string instructions
|
// string instructions
|
||||||
void disassembler::OP_X(const x86_insn *insn, unsigned size)
|
void disassembler::OP_X(const x86_insn *insn, unsigned size)
|
||||||
|
@ -478,7 +565,7 @@ void disassembler::OP_X(const x86_insn *insn, unsigned size)
|
||||||
else
|
else
|
||||||
rsi = general_16bit_regname[rSI_REG];
|
rsi = general_16bit_regname[rSI_REG];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
if (insn->is_seg_override())
|
||||||
seg = segment_name[insn->seg_override];
|
seg = segment_name[insn->seg_override];
|
||||||
else
|
else
|
||||||
|
@ -510,7 +597,7 @@ void disassembler::OP_Y(const x86_insn *insn, unsigned size)
|
||||||
else
|
else
|
||||||
rdi = general_16bit_regname[rDI_REG];
|
rdi = general_16bit_regname[rDI_REG];
|
||||||
}
|
}
|
||||||
|
|
||||||
print_datasize(size);
|
print_datasize(size);
|
||||||
|
|
||||||
if (intel_mode)
|
if (intel_mode)
|
||||||
|
@ -524,6 +611,36 @@ void disassembler::Yw(const x86_insn *insn) { OP_Y(insn, W_SIZE); }
|
||||||
void disassembler::Yd(const x86_insn *insn) { OP_Y(insn, D_SIZE); }
|
void disassembler::Yd(const x86_insn *insn) { OP_Y(insn, D_SIZE); }
|
||||||
void disassembler::Yq(const x86_insn *insn) { OP_Y(insn, Q_SIZE); }
|
void disassembler::Yq(const x86_insn *insn) { OP_Y(insn, Q_SIZE); }
|
||||||
|
|
||||||
|
void disassembler::OP_sY(const x86_insn *insn, unsigned size)
|
||||||
|
{
|
||||||
|
const char *rdi, *seg;
|
||||||
|
|
||||||
|
if (insn->as_64) {
|
||||||
|
rdi = general_64bit_regname[rDI_REG];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (insn->as_32)
|
||||||
|
rdi = general_32bit_regname[rDI_REG];
|
||||||
|
else
|
||||||
|
rdi = general_16bit_regname[rDI_REG];
|
||||||
|
}
|
||||||
|
|
||||||
|
print_datasize(size);
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = segment_name[DS_REG];
|
||||||
|
|
||||||
|
if (intel_mode)
|
||||||
|
dis_sprintf("%s:[%s]", seg, rdi);
|
||||||
|
else
|
||||||
|
dis_sprintf("%s:(%s)", seg, rdi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::sYq(const x86_insn *insn) { OP_sY(insn, Q_SIZE); }
|
||||||
|
void disassembler::sYdq(const x86_insn *insn) { OP_sY(insn, XMM_SIZE + insn->vex_l); }
|
||||||
|
|
||||||
#define BX_JUMP_TARGET_NOT_REQ ((bx_address)(-1))
|
#define BX_JUMP_TARGET_NOT_REQ ((bx_address)(-1))
|
||||||
|
|
||||||
// jump offset
|
// jump offset
|
||||||
|
@ -532,35 +649,52 @@ void disassembler::Jb(const x86_insn *insn)
|
||||||
Bit8s imm8 = (Bit8s) fetch_byte();
|
Bit8s imm8 = (Bit8s) fetch_byte();
|
||||||
|
|
||||||
if (insn->is_64) {
|
if (insn->is_64) {
|
||||||
Bit64u imm64 = (Bit64s) imm8;
|
Bit64u imm64 = (Bit8s) imm8;
|
||||||
dis_sprintf(".+0x%08x%08x",
|
|
||||||
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
|
|
||||||
|
|
||||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
if (offset_mode_hex) {
|
||||||
Bit64u target = db_eip + (Bit64s) imm64; target += db_base;
|
dis_sprintf(".+0x%08x%08x", GET32H(imm64), GET32L(imm64));
|
||||||
dis_sprintf(" (0x%08x%08x)",
|
}
|
||||||
(unsigned)(target>>32), (unsigned)(target & 0xffffffff));
|
else {
|
||||||
|
dis_sprintf(".%+d", (int) imm8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||||
|
Bit64u target = db_eip + imm64;
|
||||||
|
target += db_cs_base;
|
||||||
|
dis_sprintf(" (0x%08x%08x)", GET32H(target), GET32L(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insn->os_32) {
|
if (insn->os_32) {
|
||||||
Bit32u imm32 = (Bit32s) imm8;
|
Bit32u imm32 = (Bit8s) imm8;
|
||||||
dis_sprintf(".+0x%08x", (unsigned) imm32);
|
|
||||||
|
|
||||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
if (offset_mode_hex) {
|
||||||
Bit32u target = (Bit32u)(db_eip + (Bit32s) imm32); target += (Bit32u)db_base;
|
dis_sprintf(".+0x%08x", (unsigned) imm32);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf(".%+d", (int) imm8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||||
|
Bit32u target = (Bit32u)(db_cs_base + db_eip + (Bit32s) imm32);
|
||||||
dis_sprintf(" (0x%08x)", target);
|
dis_sprintf(" (0x%08x)", target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Bit16u imm16 = (Bit16s) imm8;
|
Bit16u imm16 = (Bit8s) imm8;
|
||||||
dis_sprintf(".+0x%04x", (unsigned) imm16);
|
|
||||||
|
|
||||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
if (offset_mode_hex) {
|
||||||
Bit16u target = (Bit32u)(db_eip + (Bit16s) imm16) & 0xffff;
|
dis_sprintf(".+0x%04x", (unsigned) imm16);
|
||||||
dis_sprintf(" (0x%08x)", target + db_base);
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf(".%+d", (int) imm8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||||
|
Bit16u target = (Bit16u)((db_eip + (Bit16s) imm16) & 0xffff);
|
||||||
|
dis_sprintf(" (0x%08x)", target + db_cs_base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,14 +703,19 @@ void disassembler::Jw(const x86_insn *insn)
|
||||||
{
|
{
|
||||||
// Jw supported in 16-bit mode only
|
// Jw supported in 16-bit mode only
|
||||||
assert(! insn->is_64);
|
assert(! insn->is_64);
|
||||||
assert(! insn->is_32);
|
|
||||||
|
|
||||||
Bit16u imm16 = (Bit16s) fetch_word();
|
Bit16s imm16 = (Bit16s) fetch_word();
|
||||||
dis_sprintf(".+0x%04x", (unsigned) imm16);
|
|
||||||
|
|
||||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
if (offset_mode_hex) {
|
||||||
Bit16u target = (Bit32u)(db_eip + (Bit16s) imm16) & 0xffff;
|
dis_sprintf(".+0x%04x", (unsigned) (Bit16u) imm16);
|
||||||
dis_sprintf(" (0x%08x)", target + db_base);
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf(".%+d", (int) imm16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||||
|
Bit16u target = (db_eip + imm16) & 0xffff;
|
||||||
|
dis_sprintf(" (0x%08x)", target + db_cs_base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,23 +724,32 @@ void disassembler::Jd(const x86_insn *insn)
|
||||||
Bit32s imm32 = (Bit32s) fetch_dword();
|
Bit32s imm32 = (Bit32s) fetch_dword();
|
||||||
|
|
||||||
if (insn->is_64) {
|
if (insn->is_64) {
|
||||||
Bit64u imm64 = (Bit64s) imm32;
|
Bit64u imm64 = (Bit32s) imm32;
|
||||||
dis_sprintf(".+0x%08x%08x",
|
|
||||||
(unsigned)(imm64>>32), (unsigned)(imm64 & 0xffffffff));
|
|
||||||
|
|
||||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
if (offset_mode_hex) {
|
||||||
Bit64u target = db_eip + (Bit64s) imm64; target += db_base;
|
dis_sprintf(".+0x%08x%08x", GET32H(imm64), GET32L(imm64));
|
||||||
dis_sprintf(" (0x%08x%08x)",
|
}
|
||||||
(unsigned)(target>>32), (unsigned)(target & 0xffffffff));
|
else {
|
||||||
|
dis_sprintf(".%+d", (int) imm32);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||||
|
Bit64u target = db_cs_base + db_eip + (Bit64s) imm64;
|
||||||
|
dis_sprintf(" (0x%08x%08x)", GET32H(target), GET32L(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dis_sprintf(".+0x%08x", (unsigned) imm32);
|
if (offset_mode_hex) {
|
||||||
|
dis_sprintf(".+0x%08x", (unsigned) imm32);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf(".%+d", (int) imm32);
|
||||||
|
}
|
||||||
|
|
||||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
if (db_cs_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||||
Bit32u target = (Bit32u)(db_eip + (Bit32s) imm32); target += (Bit32u)db_base;
|
Bit32u target = (Bit32u)(db_cs_base + db_eip + (Bit32s) imm32);
|
||||||
dis_sprintf(" (0x%08x)", target);
|
dis_sprintf(" (0x%08x)", target);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,23 @@
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: dis_tables.h,v 1.29 2006/04/27 15:11:45 sshwarts Exp $
|
// $Id: dis_tables.h 11878 2013-10-11 20:09:51Z sshwarts $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005-2012 Stanislav Shwartsman
|
||||||
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
#ifndef _BX_DISASM_TABLES_
|
#ifndef _BX_DISASM_TABLES_
|
||||||
#define _BX_DISASM_TABLES_
|
#define _BX_DISASM_TABLES_
|
||||||
|
@ -11,70 +28,93 @@
|
||||||
#define _GRPFP 3
|
#define _GRPFP 3
|
||||||
#define _GRP3DNOW 4
|
#define _GRP3DNOW 4
|
||||||
#define _GRPSSE 5
|
#define _GRPSSE 5
|
||||||
#define _GRPRM 6
|
#define _GRPSSE66 6
|
||||||
#define _GRP3BOP 7
|
#define _GRPSSEF2 7
|
||||||
#define _GRP3BTAB 8
|
#define _GRPSSEF3 8
|
||||||
|
#define _GRPSSENONE 9
|
||||||
|
#define _GRPSSE2 10
|
||||||
|
#define _GRPRM 11
|
||||||
|
#define _GRP3BOP 12
|
||||||
|
#define _GRP64B 13
|
||||||
|
#define _GRPVEXW 14
|
||||||
|
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
#define GRPSSE(n) _GRPSSE, BxDisasmGroupSSE_##n
|
#define GRPSSE(n) _GRPSSE, BxDisasmGroupSSE_##n
|
||||||
|
#define GRPSSE2(n) _GRPSSE2, BxDisasmGroupSSE_##n
|
||||||
|
#define GRPAVX(n) _GRPSSE, BxDisasmGroupAVX_##n
|
||||||
|
#define GRPAVX2(n) _GRPSSE2, BxDisasmGroupAVX_##n
|
||||||
#define GRPN(n) _GROUPN, BxDisasmGroup##n
|
#define GRPN(n) _GROUPN, BxDisasmGroup##n
|
||||||
#define GRPRM(n) _GRPRM, BxDisasmGroupRm##n
|
#define GRPRM(n) _GRPRM, BxDisasmGroupRm##n
|
||||||
#define GRPMOD(n) _SPLIT11B, BxDisasmGroupMod##n
|
#define GRPMOD(n) _SPLIT11B, BxDisasmGroupMod##n
|
||||||
#define GRPFP(n) _GRPFP, BxDisasmFPGroup##n
|
#define GRPFP(n) _GRPFP, BxDisasmFPGroup##n
|
||||||
#define GRP3DNOW _GRP3DNOW, BxDisasm3DNowGroup
|
#define GRP3DNOW _GRP3DNOW, BxDisasm3DNowGroup
|
||||||
#define GR3BOP(n) _GRP3BOP, BxDisasm3ByteOp##n
|
#define GR3BTAB(n) _GRP3BOP, BxDisasm3ByteOpTable##n
|
||||||
#define GR3BTAB(n) _GRP3BTAB, BxDisasm3ByteTable##n
|
#define GR64BIT(n) _GRP64B, BxDisasmGrpOs64B_##n
|
||||||
|
#define GRPVEXW(n) _GRPVEXW, BxDisasmGrpVexW_##n
|
||||||
|
/* ************************************************************************ */
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
|
#define GRPSSE66(n) _GRPSSE66, &n
|
||||||
|
#define GRPSSEF2(n) _GRPSSEF2, &n
|
||||||
|
#define GRPSSEF3(n) _GRPSSEF3, &n
|
||||||
|
#define GRPSSENONE(n) _GRPSSENONE, &n
|
||||||
/* ************************************************************************ */
|
/* ************************************************************************ */
|
||||||
|
|
||||||
#define Apw &disassembler::Apw
|
#define Apw &disassembler::Apw
|
||||||
#define Apd &disassembler::Apd
|
#define Apd &disassembler::Apd
|
||||||
|
|
||||||
#define AL &disassembler::AL
|
#define AL_Reg &disassembler::AL_Reg
|
||||||
#define CL &disassembler::CL
|
#define CL_Reg &disassembler::CL_Reg
|
||||||
#define AX &disassembler::AX
|
#define AX_Reg &disassembler::AX_Reg
|
||||||
#define DX &disassembler::DX
|
#define DX_Reg &disassembler::DX_Reg
|
||||||
|
|
||||||
#define EAX &disassembler::EAX
|
#define EAX_Reg &disassembler::EAX_Reg
|
||||||
#define RAX &disassembler::RAX
|
#define RAX_Reg &disassembler::RAX_Reg
|
||||||
|
#define RCX_Reg &disassembler::RCX_Reg
|
||||||
|
|
||||||
#define CS &disassembler::CS
|
#define CS &disassembler::CS
|
||||||
#define DS &disassembler::DS
|
#define DS &disassembler::DS
|
||||||
#define ES &disassembler::ES
|
#define ES &disassembler::ES
|
||||||
#define SS &disassembler::SS
|
#define SS &disassembler::SS
|
||||||
#define FS &disassembler::FS
|
#define FS &disassembler::FS
|
||||||
#define GS &disassembler::GS
|
#define GS &disassembler::GS
|
||||||
|
|
||||||
#define Sw &disassembler::Sw
|
#define Sw &disassembler::Sw
|
||||||
|
|
||||||
#define Td &disassembler::Td
|
#define Cd &disassembler::Cd
|
||||||
|
#define Cq &disassembler::Cq
|
||||||
|
|
||||||
#define Cd &disassembler::Cd
|
#define Dd &disassembler::Dd
|
||||||
#define Cq &disassembler::Cq
|
#define Dq &disassembler::Dq
|
||||||
|
|
||||||
#define Dd &disassembler::Dd
|
#define Reg8 &disassembler::Reg8
|
||||||
#define Dq &disassembler::Dq
|
#define RX &disassembler::RX
|
||||||
|
#define ERX &disassembler::ERX
|
||||||
|
#define RRX &disassembler::RRX
|
||||||
|
|
||||||
#define R8 &disassembler::R8
|
#define Eb &disassembler::Eb
|
||||||
#define RX &disassembler::RX
|
#define Ew &disassembler::Ew
|
||||||
#define ERX &disassembler::ERX
|
#define Ed &disassembler::Ed
|
||||||
#define RRX &disassembler::RRX
|
#define Eq &disassembler::Eq
|
||||||
|
#define Ey &disassembler::Ey
|
||||||
|
#define Ebd &disassembler::Ebd
|
||||||
|
#define Ewd &disassembler::Ewd
|
||||||
|
|
||||||
#define Eb &disassembler::Eb
|
#define Gb &disassembler::Gb
|
||||||
#define Ew &disassembler::Ew
|
#define Gw &disassembler::Gw
|
||||||
#define Ed &disassembler::Ed
|
#define Gd &disassembler::Gd
|
||||||
#define Eq &disassembler::Eq
|
#define Gq &disassembler::Gq
|
||||||
|
#define Gy &disassembler::Gy
|
||||||
|
|
||||||
#define Gb &disassembler::Gb
|
#define By &disassembler::By
|
||||||
#define Gw &disassembler::Gw
|
|
||||||
#define Gd &disassembler::Gd
|
|
||||||
#define Gq &disassembler::Gq
|
|
||||||
|
|
||||||
#define I1 &disassembler::I1
|
#define I1 &disassembler::I1
|
||||||
#define Ib &disassembler::Ib
|
#define Ib &disassembler::Ib
|
||||||
#define Iw &disassembler::Iw
|
#define Iw &disassembler::Iw
|
||||||
#define Id &disassembler::Id
|
#define Id &disassembler::Id
|
||||||
#define Iq &disassembler::Iq
|
#define Iq &disassembler::Iq
|
||||||
|
|
||||||
|
#define IbIb &disassembler::IbIb
|
||||||
#define IwIb &disassembler::IwIb
|
#define IwIb &disassembler::IwIb
|
||||||
|
|
||||||
#define sIbw &disassembler::sIbw
|
#define sIbw &disassembler::sIbw
|
||||||
|
@ -85,14 +125,15 @@
|
||||||
#define ST0 &disassembler::ST0
|
#define ST0 &disassembler::ST0
|
||||||
#define STi &disassembler::STi
|
#define STi &disassembler::STi
|
||||||
|
|
||||||
#define Rw &disassembler::Rw
|
#define Rw &disassembler::Rw
|
||||||
#define Rd &disassembler::Rd
|
#define Rd &disassembler::Rd
|
||||||
#define Rq &disassembler::Rq
|
#define Rq &disassembler::Rq
|
||||||
|
#define Ry &disassembler::Ry
|
||||||
|
|
||||||
#define Pq &disassembler::Pq
|
#define Pq &disassembler::Pq
|
||||||
#define Qd &disassembler::Qd
|
#define Qd &disassembler::Qd
|
||||||
#define Qq &disassembler::Qq
|
#define Qq &disassembler::Qq
|
||||||
#define Nq &disassembler::Nq
|
#define Nq &disassembler::Nq
|
||||||
|
|
||||||
#define Vq &disassembler::Vq
|
#define Vq &disassembler::Vq
|
||||||
#define Vdq &disassembler::Vdq
|
#define Vdq &disassembler::Vdq
|
||||||
|
@ -100,8 +141,16 @@
|
||||||
#define Vsd &disassembler::Vsd
|
#define Vsd &disassembler::Vsd
|
||||||
#define Vps &disassembler::Vps
|
#define Vps &disassembler::Vps
|
||||||
#define Vpd &disassembler::Vpd
|
#define Vpd &disassembler::Vpd
|
||||||
#define Udq &disassembler::Udq
|
#define VIb &disassembler::VIb
|
||||||
|
|
||||||
|
#define Ups &disassembler::Ups
|
||||||
|
#define Upd &disassembler::Upd
|
||||||
|
#define Udq &disassembler::Udq
|
||||||
|
#define Uq &disassembler::Uq
|
||||||
|
|
||||||
|
#define Wb &disassembler::Wb
|
||||||
|
#define Ww &disassembler::Ww
|
||||||
|
#define Wd &disassembler::Wd
|
||||||
#define Wq &disassembler::Wq
|
#define Wq &disassembler::Wq
|
||||||
#define Wdq &disassembler::Wdq
|
#define Wdq &disassembler::Wdq
|
||||||
#define Wss &disassembler::Wss
|
#define Wss &disassembler::Wss
|
||||||
|
@ -109,10 +158,16 @@
|
||||||
#define Wps &disassembler::Wps
|
#define Wps &disassembler::Wps
|
||||||
#define Wpd &disassembler::Wpd
|
#define Wpd &disassembler::Wpd
|
||||||
|
|
||||||
#define Ob &disassembler::Ob
|
#define Hdq &disassembler::Hdq
|
||||||
#define Ow &disassembler::Ow
|
#define Hps &disassembler::Hps
|
||||||
#define Od &disassembler::Od
|
#define Hpd &disassembler::Hpd
|
||||||
#define Oq &disassembler::Oq
|
#define Hss &disassembler::Hss
|
||||||
|
#define Hsd &disassembler::Hsd
|
||||||
|
|
||||||
|
#define Ob &disassembler::Ob
|
||||||
|
#define Ow &disassembler::Ow
|
||||||
|
#define Od &disassembler::Od
|
||||||
|
#define Oq &disassembler::Oq
|
||||||
|
|
||||||
#define Ma &disassembler::Ma
|
#define Ma &disassembler::Ma
|
||||||
#define Mp &disassembler::Mp
|
#define Mp &disassembler::Mp
|
||||||
|
@ -126,26 +181,37 @@
|
||||||
#define Mdq &disassembler::Mdq
|
#define Mdq &disassembler::Mdq
|
||||||
#define Mps &disassembler::Mps
|
#define Mps &disassembler::Mps
|
||||||
#define Mpd &disassembler::Mpd
|
#define Mpd &disassembler::Mpd
|
||||||
|
#define Mss &disassembler::Mss
|
||||||
|
#define Msd &disassembler::Msd
|
||||||
|
|
||||||
#define Xb &disassembler::Xb
|
#define VSib &disassembler::VSib
|
||||||
#define Xw &disassembler::Xw
|
|
||||||
#define Xd &disassembler::Xd
|
|
||||||
#define Xq &disassembler::Xq
|
|
||||||
|
|
||||||
#define Yb &disassembler::Yb
|
#define Xb &disassembler::Xb
|
||||||
#define Yw &disassembler::Yw
|
#define Xw &disassembler::Xw
|
||||||
#define Yd &disassembler::Yd
|
#define Xd &disassembler::Xd
|
||||||
#define Yq &disassembler::Yq
|
#define Xq &disassembler::Xq
|
||||||
|
|
||||||
#define Jb &disassembler::Jb
|
#define Yb &disassembler::Yb
|
||||||
#define Jw &disassembler::Jw
|
#define Yw &disassembler::Yw
|
||||||
#define Jd &disassembler::Jd
|
#define Yd &disassembler::Yd
|
||||||
|
#define Yq &disassembler::Yq
|
||||||
|
|
||||||
#define XX 0
|
#define sYq &disassembler::sYq
|
||||||
|
#define sYdq &disassembler::sYdq
|
||||||
|
|
||||||
|
#define Jb &disassembler::Jb
|
||||||
|
#define Jw &disassembler::Jw
|
||||||
|
#define Jd &disassembler::Jd
|
||||||
|
|
||||||
|
#define XX 0
|
||||||
|
|
||||||
const struct BxDisasmOpcodeInfo_t
|
const struct BxDisasmOpcodeInfo_t
|
||||||
#include "opcodes.inl"
|
#include "opcodes.inc"
|
||||||
#include "dis_tables.inl"
|
#include "dis_tables_x87.inc"
|
||||||
|
#include "dis_tables_sse.inc"
|
||||||
|
#include "dis_tables_avx.inc"
|
||||||
|
#include "dis_tables_xop.inc"
|
||||||
|
#include "dis_tables.inc"
|
||||||
|
|
||||||
#undef XX
|
#undef XX
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,919 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// $Id: dis_tables_x87.inc 10298 2011-04-03 10:29:19Z vruppert $
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005-2010 Stanislav Shwartsman
|
||||||
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
|
/* 3DNow! opcodes */
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasm3DNowGroup[256] = {
|
||||||
|
// 256 entries for 3DNow opcodes_by suffix
|
||||||
|
/* 00 */ { 0, &Ia_Invalid },
|
||||||
|
/* 01 */ { 0, &Ia_Invalid },
|
||||||
|
/* 02 */ { 0, &Ia_Invalid },
|
||||||
|
/* 03 */ { 0, &Ia_Invalid },
|
||||||
|
/* 04 */ { 0, &Ia_Invalid },
|
||||||
|
/* 05 */ { 0, &Ia_Invalid },
|
||||||
|
/* 06 */ { 0, &Ia_Invalid },
|
||||||
|
/* 07 */ { 0, &Ia_Invalid },
|
||||||
|
/* 08 */ { 0, &Ia_Invalid },
|
||||||
|
/* 09 */ { 0, &Ia_Invalid },
|
||||||
|
/* 0A */ { 0, &Ia_Invalid },
|
||||||
|
/* 0B */ { 0, &Ia_Invalid },
|
||||||
|
/* 0C */ { 0, &Ia_pi2fw_Pq_Qq },
|
||||||
|
/* 0D */ { 0, &Ia_pi2fd_Pq_Qq },
|
||||||
|
/* 0E */ { 0, &Ia_Invalid },
|
||||||
|
/* 0F */ { 0, &Ia_Invalid },
|
||||||
|
/* 10 */ { 0, &Ia_Invalid },
|
||||||
|
/* 11 */ { 0, &Ia_Invalid },
|
||||||
|
/* 12 */ { 0, &Ia_Invalid },
|
||||||
|
/* 13 */ { 0, &Ia_Invalid },
|
||||||
|
/* 14 */ { 0, &Ia_Invalid },
|
||||||
|
/* 15 */ { 0, &Ia_Invalid },
|
||||||
|
/* 16 */ { 0, &Ia_Invalid },
|
||||||
|
/* 17 */ { 0, &Ia_Invalid },
|
||||||
|
/* 18 */ { 0, &Ia_Invalid },
|
||||||
|
/* 19 */ { 0, &Ia_Invalid },
|
||||||
|
/* 1A */ { 0, &Ia_Invalid },
|
||||||
|
/* 1B */ { 0, &Ia_Invalid },
|
||||||
|
/* 1C */ { 0, &Ia_pf2iw_Pq_Qq },
|
||||||
|
/* 1D */ { 0, &Ia_pf2id_Pq_Qq },
|
||||||
|
/* 1E */ { 0, &Ia_Invalid },
|
||||||
|
/* 1F */ { 0, &Ia_Invalid },
|
||||||
|
/* 20 */ { 0, &Ia_Invalid },
|
||||||
|
/* 21 */ { 0, &Ia_Invalid },
|
||||||
|
/* 22 */ { 0, &Ia_Invalid },
|
||||||
|
/* 23 */ { 0, &Ia_Invalid },
|
||||||
|
/* 24 */ { 0, &Ia_Invalid },
|
||||||
|
/* 25 */ { 0, &Ia_Invalid },
|
||||||
|
/* 26 */ { 0, &Ia_Invalid },
|
||||||
|
/* 27 */ { 0, &Ia_Invalid },
|
||||||
|
/* 28 */ { 0, &Ia_Invalid },
|
||||||
|
/* 29 */ { 0, &Ia_Invalid },
|
||||||
|
/* 2A */ { 0, &Ia_Invalid },
|
||||||
|
/* 2B */ { 0, &Ia_Invalid },
|
||||||
|
/* 2C */ { 0, &Ia_Invalid },
|
||||||
|
/* 2D */ { 0, &Ia_Invalid },
|
||||||
|
/* 2E */ { 0, &Ia_Invalid },
|
||||||
|
/* 2F */ { 0, &Ia_Invalid },
|
||||||
|
/* 30 */ { 0, &Ia_Invalid },
|
||||||
|
/* 31 */ { 0, &Ia_Invalid },
|
||||||
|
/* 32 */ { 0, &Ia_Invalid },
|
||||||
|
/* 33 */ { 0, &Ia_Invalid },
|
||||||
|
/* 34 */ { 0, &Ia_Invalid },
|
||||||
|
/* 35 */ { 0, &Ia_Invalid },
|
||||||
|
/* 36 */ { 0, &Ia_Invalid },
|
||||||
|
/* 37 */ { 0, &Ia_Invalid },
|
||||||
|
/* 38 */ { 0, &Ia_Invalid },
|
||||||
|
/* 39 */ { 0, &Ia_Invalid },
|
||||||
|
/* 3A */ { 0, &Ia_Invalid },
|
||||||
|
/* 3B */ { 0, &Ia_Invalid },
|
||||||
|
/* 3C */ { 0, &Ia_Invalid },
|
||||||
|
/* 3D */ { 0, &Ia_Invalid },
|
||||||
|
/* 3E */ { 0, &Ia_Invalid },
|
||||||
|
/* 3F */ { 0, &Ia_Invalid },
|
||||||
|
/* 40 */ { 0, &Ia_Invalid },
|
||||||
|
/* 41 */ { 0, &Ia_Invalid },
|
||||||
|
/* 42 */ { 0, &Ia_Invalid },
|
||||||
|
/* 43 */ { 0, &Ia_Invalid },
|
||||||
|
/* 44 */ { 0, &Ia_Invalid },
|
||||||
|
/* 45 */ { 0, &Ia_Invalid },
|
||||||
|
/* 46 */ { 0, &Ia_Invalid },
|
||||||
|
/* 47 */ { 0, &Ia_Invalid },
|
||||||
|
/* 48 */ { 0, &Ia_Invalid },
|
||||||
|
/* 49 */ { 0, &Ia_Invalid },
|
||||||
|
/* 4A */ { 0, &Ia_Invalid },
|
||||||
|
/* 4B */ { 0, &Ia_Invalid },
|
||||||
|
/* 4C */ { 0, &Ia_Invalid },
|
||||||
|
/* 4D */ { 0, &Ia_Invalid },
|
||||||
|
/* 4E */ { 0, &Ia_Invalid },
|
||||||
|
/* 4F */ { 0, &Ia_Invalid },
|
||||||
|
/* 50 */ { 0, &Ia_Invalid },
|
||||||
|
/* 51 */ { 0, &Ia_Invalid },
|
||||||
|
/* 52 */ { 0, &Ia_Invalid },
|
||||||
|
/* 53 */ { 0, &Ia_Invalid },
|
||||||
|
/* 54 */ { 0, &Ia_Invalid },
|
||||||
|
/* 55 */ { 0, &Ia_Invalid },
|
||||||
|
/* 56 */ { 0, &Ia_Invalid },
|
||||||
|
/* 57 */ { 0, &Ia_Invalid },
|
||||||
|
/* 58 */ { 0, &Ia_Invalid },
|
||||||
|
/* 59 */ { 0, &Ia_Invalid },
|
||||||
|
/* 5A */ { 0, &Ia_Invalid },
|
||||||
|
/* 5B */ { 0, &Ia_Invalid },
|
||||||
|
/* 5C */ { 0, &Ia_Invalid },
|
||||||
|
/* 5D */ { 0, &Ia_Invalid },
|
||||||
|
/* 5E */ { 0, &Ia_Invalid },
|
||||||
|
/* 5F */ { 0, &Ia_Invalid },
|
||||||
|
/* 60 */ { 0, &Ia_Invalid },
|
||||||
|
/* 61 */ { 0, &Ia_Invalid },
|
||||||
|
/* 62 */ { 0, &Ia_Invalid },
|
||||||
|
/* 63 */ { 0, &Ia_Invalid },
|
||||||
|
/* 64 */ { 0, &Ia_Invalid },
|
||||||
|
/* 65 */ { 0, &Ia_Invalid },
|
||||||
|
/* 66 */ { 0, &Ia_Invalid },
|
||||||
|
/* 67 */ { 0, &Ia_Invalid },
|
||||||
|
/* 68 */ { 0, &Ia_Invalid },
|
||||||
|
/* 69 */ { 0, &Ia_Invalid },
|
||||||
|
/* 6A */ { 0, &Ia_Invalid },
|
||||||
|
/* 6B */ { 0, &Ia_Invalid },
|
||||||
|
/* 6C */ { 0, &Ia_Invalid },
|
||||||
|
/* 6D */ { 0, &Ia_Invalid },
|
||||||
|
/* 6E */ { 0, &Ia_Invalid },
|
||||||
|
/* 6F */ { 0, &Ia_Invalid },
|
||||||
|
/* 70 */ { 0, &Ia_Invalid },
|
||||||
|
/* 71 */ { 0, &Ia_Invalid },
|
||||||
|
/* 72 */ { 0, &Ia_Invalid },
|
||||||
|
/* 73 */ { 0, &Ia_Invalid },
|
||||||
|
/* 74 */ { 0, &Ia_Invalid },
|
||||||
|
/* 75 */ { 0, &Ia_Invalid },
|
||||||
|
/* 76 */ { 0, &Ia_Invalid },
|
||||||
|
/* 77 */ { 0, &Ia_Invalid },
|
||||||
|
/* 78 */ { 0, &Ia_Invalid },
|
||||||
|
/* 79 */ { 0, &Ia_Invalid },
|
||||||
|
/* 7A */ { 0, &Ia_Invalid },
|
||||||
|
/* 7B */ { 0, &Ia_Invalid },
|
||||||
|
/* 7C */ { 0, &Ia_Invalid },
|
||||||
|
/* 7D */ { 0, &Ia_Invalid },
|
||||||
|
/* 7E */ { 0, &Ia_Invalid },
|
||||||
|
/* 7F */ { 0, &Ia_Invalid },
|
||||||
|
/* 80 */ { 0, &Ia_Invalid },
|
||||||
|
/* 81 */ { 0, &Ia_Invalid },
|
||||||
|
/* 82 */ { 0, &Ia_Invalid },
|
||||||
|
/* 83 */ { 0, &Ia_Invalid },
|
||||||
|
/* 84 */ { 0, &Ia_Invalid },
|
||||||
|
/* 85 */ { 0, &Ia_Invalid },
|
||||||
|
/* 86 */ { 0, &Ia_Invalid },
|
||||||
|
/* 87 */ { 0, &Ia_Invalid },
|
||||||
|
/* 88 */ { 0, &Ia_Invalid },
|
||||||
|
/* 89 */ { 0, &Ia_Invalid },
|
||||||
|
/* 8A */ { 0, &Ia_pfnacc_Pq_Qq },
|
||||||
|
/* 8B */ { 0, &Ia_Invalid },
|
||||||
|
/* 8C */ { 0, &Ia_Invalid },
|
||||||
|
/* 8D */ { 0, &Ia_Invalid },
|
||||||
|
/* 8E */ { 0, &Ia_pfpnacc_Pq_Qq },
|
||||||
|
/* 8F */ { 0, &Ia_Invalid },
|
||||||
|
/* 90 */ { 0, &Ia_pfcmpge_Pq_Qq },
|
||||||
|
/* 91 */ { 0, &Ia_Invalid },
|
||||||
|
/* 92 */ { 0, &Ia_Invalid },
|
||||||
|
/* 93 */ { 0, &Ia_Invalid },
|
||||||
|
/* 94 */ { 0, &Ia_pfmin_Pq_Qq },
|
||||||
|
/* 95 */ { 0, &Ia_Invalid },
|
||||||
|
/* 96 */ { 0, &Ia_pfrcp_Pq_Qq },
|
||||||
|
/* 97 */ { 0, &Ia_pfrsqrt_Pq_Qq },
|
||||||
|
/* 98 */ { 0, &Ia_Invalid },
|
||||||
|
/* 99 */ { 0, &Ia_Invalid },
|
||||||
|
/* 9A */ { 0, &Ia_pfsub_Pq_Qq },
|
||||||
|
/* 9B */ { 0, &Ia_Invalid },
|
||||||
|
/* 9C */ { 0, &Ia_Invalid },
|
||||||
|
/* 9D */ { 0, &Ia_Invalid },
|
||||||
|
/* 9E */ { 0, &Ia_pfadd_Pq_Qq },
|
||||||
|
/* 9F */ { 0, &Ia_Invalid },
|
||||||
|
/* A0 */ { 0, &Ia_pfcmpgt_Pq_Qq },
|
||||||
|
/* A1 */ { 0, &Ia_Invalid },
|
||||||
|
/* A2 */ { 0, &Ia_Invalid },
|
||||||
|
/* A3 */ { 0, &Ia_Invalid },
|
||||||
|
/* A4 */ { 0, &Ia_pfmax_Pq_Qq },
|
||||||
|
/* A5 */ { 0, &Ia_Invalid },
|
||||||
|
/* A6 */ { 0, &Ia_pfrcpit1_Pq_Qq },
|
||||||
|
/* A7 */ { 0, &Ia_pfrsqit1_Pq_Qq },
|
||||||
|
/* A8 */ { 0, &Ia_Invalid },
|
||||||
|
/* A9 */ { 0, &Ia_Invalid },
|
||||||
|
/* AA */ { 0, &Ia_pfsubr_Pq_Qq },
|
||||||
|
/* AB */ { 0, &Ia_Invalid },
|
||||||
|
/* AC */ { 0, &Ia_Invalid },
|
||||||
|
/* AD */ { 0, &Ia_Invalid },
|
||||||
|
/* AE */ { 0, &Ia_pfacc_Pq_Qq },
|
||||||
|
/* AF */ { 0, &Ia_Invalid },
|
||||||
|
/* B0 */ { 0, &Ia_pfcmpeq_Pq_Qq },
|
||||||
|
/* B1 */ { 0, &Ia_Invalid },
|
||||||
|
/* B2 */ { 0, &Ia_Invalid },
|
||||||
|
/* B3 */ { 0, &Ia_Invalid },
|
||||||
|
/* B4 */ { 0, &Ia_pfmul_Pq_Qq },
|
||||||
|
/* B5 */ { 0, &Ia_Invalid },
|
||||||
|
/* B6 */ { 0, &Ia_pfrcpit2_Pq_Qq },
|
||||||
|
/* B7 */ { 0, &Ia_pmulhrw_Pq_Qq },
|
||||||
|
/* B8 */ { 0, &Ia_Invalid },
|
||||||
|
/* B9 */ { 0, &Ia_Invalid },
|
||||||
|
/* BA */ { 0, &Ia_Invalid },
|
||||||
|
/* BB */ { 0, &Ia_pswapd_Pq_Qq },
|
||||||
|
/* BC */ { 0, &Ia_Invalid },
|
||||||
|
/* BD */ { 0, &Ia_Invalid },
|
||||||
|
/* BE */ { 0, &Ia_Invalid },
|
||||||
|
/* BF */ { 0, &Ia_pavgb_Pq_Qq },
|
||||||
|
/* C0 */ { 0, &Ia_Invalid },
|
||||||
|
/* C1 */ { 0, &Ia_Invalid },
|
||||||
|
/* C2 */ { 0, &Ia_Invalid },
|
||||||
|
/* C3 */ { 0, &Ia_Invalid },
|
||||||
|
/* C4 */ { 0, &Ia_Invalid },
|
||||||
|
/* C5 */ { 0, &Ia_Invalid },
|
||||||
|
/* C6 */ { 0, &Ia_Invalid },
|
||||||
|
/* C7 */ { 0, &Ia_Invalid },
|
||||||
|
/* C8 */ { 0, &Ia_Invalid },
|
||||||
|
/* C9 */ { 0, &Ia_Invalid },
|
||||||
|
/* CA */ { 0, &Ia_Invalid },
|
||||||
|
/* CB */ { 0, &Ia_Invalid },
|
||||||
|
/* CC */ { 0, &Ia_Invalid },
|
||||||
|
/* CD */ { 0, &Ia_Invalid },
|
||||||
|
/* CE */ { 0, &Ia_Invalid },
|
||||||
|
/* CF */ { 0, &Ia_Invalid },
|
||||||
|
/* D0 */ { 0, &Ia_Invalid },
|
||||||
|
/* D1 */ { 0, &Ia_Invalid },
|
||||||
|
/* D2 */ { 0, &Ia_Invalid },
|
||||||
|
/* D3 */ { 0, &Ia_Invalid },
|
||||||
|
/* D4 */ { 0, &Ia_Invalid },
|
||||||
|
/* D5 */ { 0, &Ia_Invalid },
|
||||||
|
/* D6 */ { 0, &Ia_Invalid },
|
||||||
|
/* D7 */ { 0, &Ia_Invalid },
|
||||||
|
/* D8 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA */ { 0, &Ia_Invalid },
|
||||||
|
/* DB */ { 0, &Ia_Invalid },
|
||||||
|
/* DC */ { 0, &Ia_Invalid },
|
||||||
|
/* DD */ { 0, &Ia_Invalid },
|
||||||
|
/* DE */ { 0, &Ia_Invalid },
|
||||||
|
/* DF */ { 0, &Ia_Invalid },
|
||||||
|
/* E0 */ { 0, &Ia_Invalid },
|
||||||
|
/* E1 */ { 0, &Ia_Invalid },
|
||||||
|
/* E2 */ { 0, &Ia_Invalid },
|
||||||
|
/* E3 */ { 0, &Ia_Invalid },
|
||||||
|
/* E4 */ { 0, &Ia_Invalid },
|
||||||
|
/* E5 */ { 0, &Ia_Invalid },
|
||||||
|
/* E6 */ { 0, &Ia_Invalid },
|
||||||
|
/* E7 */ { 0, &Ia_Invalid },
|
||||||
|
/* E8 */ { 0, &Ia_Invalid },
|
||||||
|
/* E9 */ { 0, &Ia_Invalid },
|
||||||
|
/* EA */ { 0, &Ia_Invalid },
|
||||||
|
/* EB */ { 0, &Ia_Invalid },
|
||||||
|
/* EC */ { 0, &Ia_Invalid },
|
||||||
|
/* ED */ { 0, &Ia_Invalid },
|
||||||
|
/* EE */ { 0, &Ia_Invalid },
|
||||||
|
/* EF */ { 0, &Ia_Invalid },
|
||||||
|
/* F0 */ { 0, &Ia_Invalid },
|
||||||
|
/* F1 */ { 0, &Ia_Invalid },
|
||||||
|
/* F2 */ { 0, &Ia_Invalid },
|
||||||
|
/* F3 */ { 0, &Ia_Invalid },
|
||||||
|
/* F4 */ { 0, &Ia_Invalid },
|
||||||
|
/* F5 */ { 0, &Ia_Invalid },
|
||||||
|
/* F6 */ { 0, &Ia_Invalid },
|
||||||
|
/* F7 */ { 0, &Ia_Invalid },
|
||||||
|
/* F8 */ { 0, &Ia_Invalid },
|
||||||
|
/* F9 */ { 0, &Ia_Invalid },
|
||||||
|
/* FA */ { 0, &Ia_Invalid },
|
||||||
|
/* FB */ { 0, &Ia_Invalid },
|
||||||
|
/* FC */ { 0, &Ia_Invalid },
|
||||||
|
/* FD */ { 0, &Ia_Invalid },
|
||||||
|
/* FE */ { 0, &Ia_Invalid },
|
||||||
|
/* FF */ { 0, &Ia_Invalid }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
|
/* FPU Opcodes */
|
||||||
|
|
||||||
|
// floating point instructions when mod!=11b.
|
||||||
|
// the following tables will be accessed like groups using the nnn (reg) field of
|
||||||
|
// the modrm byte. (the first byte is D8-DF)
|
||||||
|
|
||||||
|
// D8 (modrm is outside 00h - BFh) (mod != 11)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmFPGroupD8[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_fadds_Md },
|
||||||
|
/* 1 */ { 0, &Ia_fmuls_Md },
|
||||||
|
/* 2 */ { 0, &Ia_fcoms_Md },
|
||||||
|
/* 3 */ { 0, &Ia_fcomps_Md },
|
||||||
|
/* 4 */ { 0, &Ia_fsubs_Md },
|
||||||
|
/* 5 */ { 0, &Ia_fsubrs_Md },
|
||||||
|
/* 6 */ { 0, &Ia_fdivs_Md },
|
||||||
|
/* 7 */ { 0, &Ia_fdivrs_Md }
|
||||||
|
};
|
||||||
|
|
||||||
|
// D9 (modrm is outside 00h - BFh) (mod != 11)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmFPGroupD9[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_flds_Md },
|
||||||
|
/* 1 */ { 0, &Ia_Invalid },
|
||||||
|
/* 2 */ { 0, &Ia_fsts_Md },
|
||||||
|
/* 3 */ { 0, &Ia_fstps_Md },
|
||||||
|
/* 4 */ { 0, &Ia_fldenv },
|
||||||
|
/* 5 */ { 0, &Ia_fldcw },
|
||||||
|
/* 6 */ { 0, &Ia_fnstenv },
|
||||||
|
/* 7 */ { 0, &Ia_fnstcw }
|
||||||
|
};
|
||||||
|
|
||||||
|
// DA (modrm is outside 00h - BFh) (mod != 11)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmFPGroupDA[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_fiaddl_Md },
|
||||||
|
/* 1 */ { 0, &Ia_fimull_Md },
|
||||||
|
/* 2 */ { 0, &Ia_ficoml_Md },
|
||||||
|
/* 3 */ { 0, &Ia_ficompl_Md },
|
||||||
|
/* 4 */ { 0, &Ia_fisubl_Md },
|
||||||
|
/* 5 */ { 0, &Ia_fisubrl_Md },
|
||||||
|
/* 6 */ { 0, &Ia_fidivl_Md },
|
||||||
|
/* 7 */ { 0, &Ia_fidivrl_Md }
|
||||||
|
};
|
||||||
|
|
||||||
|
// DB (modrm is outside 00h - BFh) (mod != 11)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmFPGroupDB[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_fildl_Md },
|
||||||
|
/* 1 */ { 0, &Ia_fisttpl_Md },
|
||||||
|
/* 2 */ { 0, &Ia_fistl_Md },
|
||||||
|
/* 3 */ { 0, &Ia_fistpl_Md },
|
||||||
|
/* 4 */ { 0, &Ia_Invalid },
|
||||||
|
/* 5 */ { 0, &Ia_fldt_Mt },
|
||||||
|
/* 6 */ { 0, &Ia_Invalid },
|
||||||
|
/* 7 */ { 0, &Ia_fstpt_Mt }
|
||||||
|
};
|
||||||
|
|
||||||
|
// DC (modrm is outside 00h - BFh) (mod != 11)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmFPGroupDC[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_faddl_Mq },
|
||||||
|
/* 1 */ { 0, &Ia_fmull_Mq },
|
||||||
|
/* 2 */ { 0, &Ia_fcoml_Mq },
|
||||||
|
/* 3 */ { 0, &Ia_fcompl_Mq },
|
||||||
|
/* 4 */ { 0, &Ia_fsubl_Mq },
|
||||||
|
/* 5 */ { 0, &Ia_fsubrl_Mq },
|
||||||
|
/* 6 */ { 0, &Ia_fdivl_Mq },
|
||||||
|
/* 7 */ { 0, &Ia_fdivrl_Mq }
|
||||||
|
};
|
||||||
|
|
||||||
|
// DD (modrm is outside 00h - BFh) (mod != 11)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmFPGroupDD[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_fldl_Mq },
|
||||||
|
/* 1 */ { 0, &Ia_fisttpq_Mq },
|
||||||
|
/* 2 */ { 0, &Ia_fstl_Mq },
|
||||||
|
/* 3 */ { 0, &Ia_fstpl_Mq },
|
||||||
|
/* 4 */ { 0, &Ia_frstor },
|
||||||
|
/* 5 */ { 0, &Ia_Invalid },
|
||||||
|
/* 6 */ { 0, &Ia_fnsave },
|
||||||
|
/* 7 */ { 0, &Ia_fnstsw }
|
||||||
|
};
|
||||||
|
|
||||||
|
// DE (modrm is outside 00h - BFh) (mod != 11)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmFPGroupDE[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_fiadds_Mw },
|
||||||
|
/* 1 */ { 0, &Ia_fimuls_Mw },
|
||||||
|
/* 2 */ { 0, &Ia_ficoms_Mw },
|
||||||
|
/* 3 */ { 0, &Ia_ficomps_Mw },
|
||||||
|
/* 4 */ { 0, &Ia_fisubs_Mw },
|
||||||
|
/* 5 */ { 0, &Ia_fisubrs_Mw },
|
||||||
|
/* 6 */ { 0, &Ia_fidivs_Mw },
|
||||||
|
/* 7 */ { 0, &Ia_fidivrs_Mw }
|
||||||
|
};
|
||||||
|
|
||||||
|
// DF (modrm is outside 00h - BFh) (mod != 11)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmFPGroupDF[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_filds_Mw },
|
||||||
|
/* 1 */ { 0, &Ia_fisttps_Mw },
|
||||||
|
/* 2 */ { 0, &Ia_fists_Mw },
|
||||||
|
/* 3 */ { 0, &Ia_fistps_Mw },
|
||||||
|
/* 4 */ { 0, &Ia_fbldt_Mt },
|
||||||
|
/* 5 */ { 0, &Ia_fildq_Mq },
|
||||||
|
/* 6 */ { 0, &Ia_fbstpt_Mt },
|
||||||
|
/* 7 */ { 0, &Ia_fistpq_Mq }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 512 entries for second byte of floating point instructions. (when mod==11b)
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmOpcodeInfoFP[512] = {
|
||||||
|
// D8 (modrm is outside 00h - BFh) (mod == 11)
|
||||||
|
/* D8 C0 */ { 0, &Ia_fadd_ST0_STi },
|
||||||
|
/* D8 C1 */ { 0, &Ia_fadd_ST0_STi },
|
||||||
|
/* D8 C2 */ { 0, &Ia_fadd_ST0_STi },
|
||||||
|
/* D8 C3 */ { 0, &Ia_fadd_ST0_STi },
|
||||||
|
/* D8 C4 */ { 0, &Ia_fadd_ST0_STi },
|
||||||
|
/* D8 C5 */ { 0, &Ia_fadd_ST0_STi },
|
||||||
|
/* D8 C6 */ { 0, &Ia_fadd_ST0_STi },
|
||||||
|
/* D8 C7 */ { 0, &Ia_fadd_ST0_STi },
|
||||||
|
/* D8 C8 */ { 0, &Ia_fmul_ST0_STi },
|
||||||
|
/* D8 C9 */ { 0, &Ia_fmul_ST0_STi },
|
||||||
|
/* D8 CA */ { 0, &Ia_fmul_ST0_STi },
|
||||||
|
/* D8 CB */ { 0, &Ia_fmul_ST0_STi },
|
||||||
|
/* D8 CC */ { 0, &Ia_fmul_ST0_STi },
|
||||||
|
/* D8 CD */ { 0, &Ia_fmul_ST0_STi },
|
||||||
|
/* D8 CE */ { 0, &Ia_fmul_ST0_STi },
|
||||||
|
/* D8 CF */ { 0, &Ia_fmul_ST0_STi },
|
||||||
|
/* D8 D0 */ { 0, &Ia_fcom_STi },
|
||||||
|
/* D8 D1 */ { 0, &Ia_fcom_STi },
|
||||||
|
/* D8 D2 */ { 0, &Ia_fcom_STi },
|
||||||
|
/* D8 D3 */ { 0, &Ia_fcom_STi },
|
||||||
|
/* D8 D4 */ { 0, &Ia_fcom_STi },
|
||||||
|
/* D8 D5 */ { 0, &Ia_fcom_STi },
|
||||||
|
/* D8 D6 */ { 0, &Ia_fcom_STi },
|
||||||
|
/* D8 D7 */ { 0, &Ia_fcom_STi },
|
||||||
|
/* D8 D8 */ { 0, &Ia_fcomp_STi },
|
||||||
|
/* D8 D9 */ { 0, &Ia_fcomp_STi },
|
||||||
|
/* D8 DA */ { 0, &Ia_fcomp_STi },
|
||||||
|
/* D8 DB */ { 0, &Ia_fcomp_STi },
|
||||||
|
/* D8 DC */ { 0, &Ia_fcomp_STi },
|
||||||
|
/* D8 DD */ { 0, &Ia_fcomp_STi },
|
||||||
|
/* D8 DE */ { 0, &Ia_fcomp_STi },
|
||||||
|
/* D8 DF */ { 0, &Ia_fcomp_STi },
|
||||||
|
/* D8 E0 */ { 0, &Ia_fsub_ST0_STi },
|
||||||
|
/* D8 E1 */ { 0, &Ia_fsub_ST0_STi },
|
||||||
|
/* D8 E2 */ { 0, &Ia_fsub_ST0_STi },
|
||||||
|
/* D8 E3 */ { 0, &Ia_fsub_ST0_STi },
|
||||||
|
/* D8 E4 */ { 0, &Ia_fsub_ST0_STi },
|
||||||
|
/* D8 E5 */ { 0, &Ia_fsub_ST0_STi },
|
||||||
|
/* D8 E6 */ { 0, &Ia_fsub_ST0_STi },
|
||||||
|
/* D8 E7 */ { 0, &Ia_fsub_ST0_STi },
|
||||||
|
/* D8 E8 */ { 0, &Ia_fsubr_ST0_STi },
|
||||||
|
/* D8 E9 */ { 0, &Ia_fsubr_ST0_STi },
|
||||||
|
/* D8 EA */ { 0, &Ia_fsubr_ST0_STi },
|
||||||
|
/* D8 EB */ { 0, &Ia_fsubr_ST0_STi },
|
||||||
|
/* D8 EC */ { 0, &Ia_fsubr_ST0_STi },
|
||||||
|
/* D8 ED */ { 0, &Ia_fsubr_ST0_STi },
|
||||||
|
/* D8 EE */ { 0, &Ia_fsubr_ST0_STi },
|
||||||
|
/* D8 EF */ { 0, &Ia_fsubr_ST0_STi },
|
||||||
|
/* D8 F0 */ { 0, &Ia_fdiv_ST0_STi },
|
||||||
|
/* D8 F1 */ { 0, &Ia_fdiv_ST0_STi },
|
||||||
|
/* D8 F2 */ { 0, &Ia_fdiv_ST0_STi },
|
||||||
|
/* D8 F3 */ { 0, &Ia_fdiv_ST0_STi },
|
||||||
|
/* D8 F4 */ { 0, &Ia_fdiv_ST0_STi },
|
||||||
|
/* D8 F5 */ { 0, &Ia_fdiv_ST0_STi },
|
||||||
|
/* D8 F6 */ { 0, &Ia_fdiv_ST0_STi },
|
||||||
|
/* D8 F7 */ { 0, &Ia_fdiv_ST0_STi },
|
||||||
|
/* D8 F8 */ { 0, &Ia_fdivr_ST0_STi },
|
||||||
|
/* D8 F9 */ { 0, &Ia_fdivr_ST0_STi },
|
||||||
|
/* D8 FA */ { 0, &Ia_fdivr_ST0_STi },
|
||||||
|
/* D8 FB */ { 0, &Ia_fdivr_ST0_STi },
|
||||||
|
/* D8 FC */ { 0, &Ia_fdivr_ST0_STi },
|
||||||
|
/* D8 FD */ { 0, &Ia_fdivr_ST0_STi },
|
||||||
|
/* D8 FE */ { 0, &Ia_fdivr_ST0_STi },
|
||||||
|
/* D8 FF */ { 0, &Ia_fdivr_ST0_STi },
|
||||||
|
|
||||||
|
// D9 (modrm is outside 00h - BFh) (mod == 11)
|
||||||
|
/* D9 C0 */ { 0, &Ia_fld_STi },
|
||||||
|
/* D9 C1 */ { 0, &Ia_fld_STi },
|
||||||
|
/* D9 C2 */ { 0, &Ia_fld_STi },
|
||||||
|
/* D9 C3 */ { 0, &Ia_fld_STi },
|
||||||
|
/* D9 C4 */ { 0, &Ia_fld_STi },
|
||||||
|
/* D9 C5 */ { 0, &Ia_fld_STi },
|
||||||
|
/* D9 C6 */ { 0, &Ia_fld_STi },
|
||||||
|
/* D9 C7 */ { 0, &Ia_fld_STi },
|
||||||
|
/* D9 C8 */ { 0, &Ia_fxch },
|
||||||
|
/* D9 C9 */ { 0, &Ia_fxch },
|
||||||
|
/* D9 CA */ { 0, &Ia_fxch },
|
||||||
|
/* D9 CB */ { 0, &Ia_fxch },
|
||||||
|
/* D9 CC */ { 0, &Ia_fxch },
|
||||||
|
/* D9 CD */ { 0, &Ia_fxch },
|
||||||
|
/* D9 CE */ { 0, &Ia_fxch },
|
||||||
|
/* D9 CF */ { 0, &Ia_fxch },
|
||||||
|
/* D9 D0 */ { 0, &Ia_fnop },
|
||||||
|
/* D9 D1 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 D2 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 D3 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 D4 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 D5 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 D6 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 D7 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 D8 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* D9 D9 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* D9 DA */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* D9 DB */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* D9 DC */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* D9 DD */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* D9 DE */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* D9 DF */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* D9 E0 */ { 0, &Ia_fchs },
|
||||||
|
/* D9 E1 */ { 0, &Ia_fabs },
|
||||||
|
/* D9 E2 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 E3 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 E4 */ { 0, &Ia_ftst },
|
||||||
|
/* D9 E5 */ { 0, &Ia_fxam },
|
||||||
|
/* D9 E6 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 E7 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 E8 */ { 0, &Ia_fld1 },
|
||||||
|
/* D9 E9 */ { 0, &Ia_fldl2t },
|
||||||
|
/* D9 EA */ { 0, &Ia_fldl2e },
|
||||||
|
/* D9 EB */ { 0, &Ia_fldpi },
|
||||||
|
/* D9 EC */ { 0, &Ia_fldlg2 },
|
||||||
|
/* D9 ED */ { 0, &Ia_fldln2 },
|
||||||
|
/* D9 EE */ { 0, &Ia_fldz },
|
||||||
|
/* D9 EF */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 F0 */ { 0, &Ia_f2xm1 },
|
||||||
|
/* D9 F1 */ { 0, &Ia_fyl2x },
|
||||||
|
/* D9 F2 */ { 0, &Ia_fptan },
|
||||||
|
/* D9 F3 */ { 0, &Ia_fpatan },
|
||||||
|
/* D9 F4 */ { 0, &Ia_fxtract },
|
||||||
|
/* D9 F5 */ { 0, &Ia_fprem1 },
|
||||||
|
/* D9 F6 */ { 0, &Ia_fdecstp },
|
||||||
|
/* D9 F7 */ { 0, &Ia_fincstp },
|
||||||
|
/* D9 F8 */ { 0, &Ia_fprem },
|
||||||
|
/* D9 F9 */ { 0, &Ia_fyl2xp1 },
|
||||||
|
/* D9 FA */ { 0, &Ia_fsqrt },
|
||||||
|
/* D9 FB */ { 0, &Ia_fsincos },
|
||||||
|
/* D9 FC */ { 0, &Ia_frndint },
|
||||||
|
/* D9 FD */ { 0, &Ia_fscale },
|
||||||
|
/* D9 FE */ { 0, &Ia_fsin },
|
||||||
|
/* D9 FF */ { 0, &Ia_fcos },
|
||||||
|
|
||||||
|
// DA (modrm is outside 00h - BFh) (mod == 11)
|
||||||
|
/* DA C0 */ { 0, &Ia_fcmovb_ST0_STi },
|
||||||
|
/* DA C1 */ { 0, &Ia_fcmovb_ST0_STi },
|
||||||
|
/* DA C2 */ { 0, &Ia_fcmovb_ST0_STi },
|
||||||
|
/* DA C3 */ { 0, &Ia_fcmovb_ST0_STi },
|
||||||
|
/* DA C4 */ { 0, &Ia_fcmovb_ST0_STi },
|
||||||
|
/* DA C5 */ { 0, &Ia_fcmovb_ST0_STi },
|
||||||
|
/* DA C6 */ { 0, &Ia_fcmovb_ST0_STi },
|
||||||
|
/* DA C7 */ { 0, &Ia_fcmovb_ST0_STi },
|
||||||
|
/* DA C8 */ { 0, &Ia_fcmove_ST0_STi },
|
||||||
|
/* DA C9 */ { 0, &Ia_fcmove_ST0_STi },
|
||||||
|
/* DA CA */ { 0, &Ia_fcmove_ST0_STi },
|
||||||
|
/* DA CB */ { 0, &Ia_fcmove_ST0_STi },
|
||||||
|
/* DA CC */ { 0, &Ia_fcmove_ST0_STi },
|
||||||
|
/* DA CD */ { 0, &Ia_fcmove_ST0_STi },
|
||||||
|
/* DA CE */ { 0, &Ia_fcmove_ST0_STi },
|
||||||
|
/* DA CF */ { 0, &Ia_fcmove_ST0_STi },
|
||||||
|
/* DA D0 */ { 0, &Ia_fcmovbe_ST0_STi },
|
||||||
|
/* DA D1 */ { 0, &Ia_fcmovbe_ST0_STi },
|
||||||
|
/* DA D2 */ { 0, &Ia_fcmovbe_ST0_STi },
|
||||||
|
/* DA D3 */ { 0, &Ia_fcmovbe_ST0_STi },
|
||||||
|
/* DA D4 */ { 0, &Ia_fcmovbe_ST0_STi },
|
||||||
|
/* DA D5 */ { 0, &Ia_fcmovbe_ST0_STi },
|
||||||
|
/* DA D6 */ { 0, &Ia_fcmovbe_ST0_STi },
|
||||||
|
/* DA D7 */ { 0, &Ia_fcmovbe_ST0_STi },
|
||||||
|
/* DA D8 */ { 0, &Ia_fcmovu_ST0_STi },
|
||||||
|
/* DA D9 */ { 0, &Ia_fcmovu_ST0_STi },
|
||||||
|
/* DA DA */ { 0, &Ia_fcmovu_ST0_STi },
|
||||||
|
/* DA DB */ { 0, &Ia_fcmovu_ST0_STi },
|
||||||
|
/* DA DC */ { 0, &Ia_fcmovu_ST0_STi },
|
||||||
|
/* DA DD */ { 0, &Ia_fcmovu_ST0_STi },
|
||||||
|
/* DA DE */ { 0, &Ia_fcmovu_ST0_STi },
|
||||||
|
/* DA DF */ { 0, &Ia_fcmovu_ST0_STi },
|
||||||
|
/* DA E0 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E1 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E2 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E3 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E4 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E5 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E6 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E7 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E8 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA E9 */ { 0, &Ia_fucompp },
|
||||||
|
/* DA EA */ { 0, &Ia_Invalid },
|
||||||
|
/* DA EB */ { 0, &Ia_Invalid },
|
||||||
|
/* DA EC */ { 0, &Ia_Invalid },
|
||||||
|
/* DA ED */ { 0, &Ia_Invalid },
|
||||||
|
/* DA EE */ { 0, &Ia_Invalid },
|
||||||
|
/* DA EF */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F0 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F1 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F2 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F3 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F4 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F5 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F6 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F7 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F8 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA F9 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA FA */ { 0, &Ia_Invalid },
|
||||||
|
/* DA FB */ { 0, &Ia_Invalid },
|
||||||
|
/* DA FC */ { 0, &Ia_Invalid },
|
||||||
|
/* DA FD */ { 0, &Ia_Invalid },
|
||||||
|
/* DA FE */ { 0, &Ia_Invalid },
|
||||||
|
/* DA FF */ { 0, &Ia_Invalid },
|
||||||
|
|
||||||
|
// DB (modrm is outside 00h - BFh) (mod == 11)
|
||||||
|
/* DB C0 */ { 0, &Ia_fcmovnb_ST0_STi },
|
||||||
|
/* DB C1 */ { 0, &Ia_fcmovnb_ST0_STi },
|
||||||
|
/* DB C2 */ { 0, &Ia_fcmovnb_ST0_STi },
|
||||||
|
/* DB C3 */ { 0, &Ia_fcmovnb_ST0_STi },
|
||||||
|
/* DB C4 */ { 0, &Ia_fcmovnb_ST0_STi },
|
||||||
|
/* DB C5 */ { 0, &Ia_fcmovnb_ST0_STi },
|
||||||
|
/* DB C6 */ { 0, &Ia_fcmovnb_ST0_STi },
|
||||||
|
/* DB C7 */ { 0, &Ia_fcmovnb_ST0_STi },
|
||||||
|
/* DB C8 */ { 0, &Ia_fcmovne_ST0_STi },
|
||||||
|
/* DB C9 */ { 0, &Ia_fcmovne_ST0_STi },
|
||||||
|
/* DB CA */ { 0, &Ia_fcmovne_ST0_STi },
|
||||||
|
/* DB CB */ { 0, &Ia_fcmovne_ST0_STi },
|
||||||
|
/* DB CC */ { 0, &Ia_fcmovne_ST0_STi },
|
||||||
|
/* DB CD */ { 0, &Ia_fcmovne_ST0_STi },
|
||||||
|
/* DB CE */ { 0, &Ia_fcmovne_ST0_STi },
|
||||||
|
/* DB CF */ { 0, &Ia_fcmovne_ST0_STi },
|
||||||
|
/* DB D0 */ { 0, &Ia_fcmovnbe_ST0_STi },
|
||||||
|
/* DB D1 */ { 0, &Ia_fcmovnbe_ST0_STi },
|
||||||
|
/* DB D2 */ { 0, &Ia_fcmovnbe_ST0_STi },
|
||||||
|
/* DB D3 */ { 0, &Ia_fcmovnbe_ST0_STi },
|
||||||
|
/* DB D4 */ { 0, &Ia_fcmovnbe_ST0_STi },
|
||||||
|
/* DB D5 */ { 0, &Ia_fcmovnbe_ST0_STi },
|
||||||
|
/* DB D6 */ { 0, &Ia_fcmovnbe_ST0_STi },
|
||||||
|
/* DB D7 */ { 0, &Ia_fcmovnbe_ST0_STi },
|
||||||
|
/* DB D8 */ { 0, &Ia_fcmovnu_ST0_STi },
|
||||||
|
/* DB D9 */ { 0, &Ia_fcmovnu_ST0_STi },
|
||||||
|
/* DB DA */ { 0, &Ia_fcmovnu_ST0_STi },
|
||||||
|
/* DB DB */ { 0, &Ia_fcmovnu_ST0_STi },
|
||||||
|
/* DB DC */ { 0, &Ia_fcmovnu_ST0_STi },
|
||||||
|
/* DB DD */ { 0, &Ia_fcmovnu_ST0_STi },
|
||||||
|
/* DB DE */ { 0, &Ia_fcmovnu_ST0_STi },
|
||||||
|
/* DB DF */ { 0, &Ia_fcmovnu_ST0_STi },
|
||||||
|
/* DB E0 */ { 0, &Ia_feni },
|
||||||
|
/* DB E1 */ { 0, &Ia_fdisi },
|
||||||
|
/* DB E2 */ { 0, &Ia_fnclex },
|
||||||
|
/* DB E3 */ { 0, &Ia_fninit },
|
||||||
|
/* DB E4 */ { 0, &Ia_fsetpm },
|
||||||
|
/* DB E5 */ { 0, &Ia_Invalid },
|
||||||
|
/* DB E6 */ { 0, &Ia_Invalid },
|
||||||
|
/* DB E7 */ { 0, &Ia_Invalid },
|
||||||
|
/* DB E8 */ { 0, &Ia_fucomi_ST0_STi },
|
||||||
|
/* DB E9 */ { 0, &Ia_fucomi_ST0_STi },
|
||||||
|
/* DB EA */ { 0, &Ia_fucomi_ST0_STi },
|
||||||
|
/* DB EB */ { 0, &Ia_fucomi_ST0_STi },
|
||||||
|
/* DB EC */ { 0, &Ia_fucomi_ST0_STi },
|
||||||
|
/* DB ED */ { 0, &Ia_fucomi_ST0_STi },
|
||||||
|
/* DB EE */ { 0, &Ia_fucomi_ST0_STi },
|
||||||
|
/* DB EF */ { 0, &Ia_fucomi_ST0_STi },
|
||||||
|
/* DB F0 */ { 0, &Ia_fcomi_ST0_STi },
|
||||||
|
/* DB F1 */ { 0, &Ia_fcomi_ST0_STi },
|
||||||
|
/* DB F2 */ { 0, &Ia_fcomi_ST0_STi },
|
||||||
|
/* DB F3 */ { 0, &Ia_fcomi_ST0_STi },
|
||||||
|
/* DB F4 */ { 0, &Ia_fcomi_ST0_STi },
|
||||||
|
/* DB F5 */ { 0, &Ia_fcomi_ST0_STi },
|
||||||
|
/* DB F6 */ { 0, &Ia_fcomi_ST0_STi },
|
||||||
|
/* DB F7 */ { 0, &Ia_fcomi_ST0_STi },
|
||||||
|
/* DB F8 */ { 0, &Ia_Invalid },
|
||||||
|
/* DB F9 */ { 0, &Ia_Invalid },
|
||||||
|
/* DB FA */ { 0, &Ia_Invalid },
|
||||||
|
/* DB FB */ { 0, &Ia_Invalid },
|
||||||
|
/* DB FC */ { 0, &Ia_Invalid },
|
||||||
|
/* DB FD */ { 0, &Ia_Invalid },
|
||||||
|
/* DB FE */ { 0, &Ia_Invalid },
|
||||||
|
/* DB FF */ { 0, &Ia_Invalid },
|
||||||
|
|
||||||
|
// DC (modrm is outside 00h - BFh) (mod == 11)
|
||||||
|
/* DC C0 */ { 0, &Ia_fadd_STi_ST0 },
|
||||||
|
/* DC C1 */ { 0, &Ia_fadd_STi_ST0 },
|
||||||
|
/* DC C2 */ { 0, &Ia_fadd_STi_ST0 },
|
||||||
|
/* DC C3 */ { 0, &Ia_fadd_STi_ST0 },
|
||||||
|
/* DC C4 */ { 0, &Ia_fadd_STi_ST0 },
|
||||||
|
/* DC C5 */ { 0, &Ia_fadd_STi_ST0 },
|
||||||
|
/* DC C6 */ { 0, &Ia_fadd_STi_ST0 },
|
||||||
|
/* DC C7 */ { 0, &Ia_fadd_STi_ST0 },
|
||||||
|
/* DC C8 */ { 0, &Ia_fmul_STi_ST0 },
|
||||||
|
/* DC C9 */ { 0, &Ia_fmul_STi_ST0 },
|
||||||
|
/* DC CA */ { 0, &Ia_fmul_STi_ST0 },
|
||||||
|
/* DC CB */ { 0, &Ia_fmul_STi_ST0 },
|
||||||
|
/* DC CC */ { 0, &Ia_fmul_STi_ST0 },
|
||||||
|
/* DC CD */ { 0, &Ia_fmul_STi_ST0 },
|
||||||
|
/* DC CE */ { 0, &Ia_fmul_STi_ST0 },
|
||||||
|
/* DC CF */ { 0, &Ia_fmul_STi_ST0 },
|
||||||
|
/* DC D0 */ { 0, &Ia_fcom_STi }, // undocumented
|
||||||
|
/* DC D1 */ { 0, &Ia_fcom_STi }, // undocumented
|
||||||
|
/* DC D2 */ { 0, &Ia_fcom_STi }, // undocumented
|
||||||
|
/* DC D3 */ { 0, &Ia_fcom_STi }, // undocumented
|
||||||
|
/* DC D4 */ { 0, &Ia_fcom_STi }, // undocumented
|
||||||
|
/* DC D5 */ { 0, &Ia_fcom_STi }, // undocumented
|
||||||
|
/* DC D6 */ { 0, &Ia_fcom_STi }, // undocumented
|
||||||
|
/* DC D7 */ { 0, &Ia_fcom_STi }, // undocumented
|
||||||
|
/* DC D8 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DC D9 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DC DA */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DC DB */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DC DC */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DC DD */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DC DE */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DC DF */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DC E0 */ { 0, &Ia_fsubr_STi_ST0 },
|
||||||
|
/* DC E1 */ { 0, &Ia_fsubr_STi_ST0 },
|
||||||
|
/* DC E2 */ { 0, &Ia_fsubr_STi_ST0 },
|
||||||
|
/* DC E3 */ { 0, &Ia_fsubr_STi_ST0 },
|
||||||
|
/* DC E4 */ { 0, &Ia_fsubr_STi_ST0 },
|
||||||
|
/* DC E5 */ { 0, &Ia_fsubr_STi_ST0 },
|
||||||
|
/* DC E6 */ { 0, &Ia_fsubr_STi_ST0 },
|
||||||
|
/* DC E7 */ { 0, &Ia_fsubr_STi_ST0 },
|
||||||
|
/* DC E8 */ { 0, &Ia_fsub_STi_ST0 },
|
||||||
|
/* DC E9 */ { 0, &Ia_fsub_STi_ST0 },
|
||||||
|
/* DC EA */ { 0, &Ia_fsub_STi_ST0 },
|
||||||
|
/* DC EB */ { 0, &Ia_fsub_STi_ST0 },
|
||||||
|
/* DC EC */ { 0, &Ia_fsub_STi_ST0 },
|
||||||
|
/* DC ED */ { 0, &Ia_fsub_STi_ST0 },
|
||||||
|
/* DC EE */ { 0, &Ia_fsub_STi_ST0 },
|
||||||
|
/* DC EF */ { 0, &Ia_fsub_STi_ST0 },
|
||||||
|
/* DC F0 */ { 0, &Ia_fdivr_STi_ST0 },
|
||||||
|
/* DC F1 */ { 0, &Ia_fdivr_STi_ST0 },
|
||||||
|
/* DC F2 */ { 0, &Ia_fdivr_STi_ST0 },
|
||||||
|
/* DC F3 */ { 0, &Ia_fdivr_STi_ST0 },
|
||||||
|
/* DC F4 */ { 0, &Ia_fdivr_STi_ST0 },
|
||||||
|
/* DC F5 */ { 0, &Ia_fdivr_STi_ST0 },
|
||||||
|
/* DC F6 */ { 0, &Ia_fdivr_STi_ST0 },
|
||||||
|
/* DC F7 */ { 0, &Ia_fdivr_STi_ST0 },
|
||||||
|
/* DC F8 */ { 0, &Ia_fdiv_STi_ST0 },
|
||||||
|
/* DC F9 */ { 0, &Ia_fdiv_STi_ST0 },
|
||||||
|
/* DC FA */ { 0, &Ia_fdiv_STi_ST0 },
|
||||||
|
/* DC FB */ { 0, &Ia_fdiv_STi_ST0 },
|
||||||
|
/* DC FC */ { 0, &Ia_fdiv_STi_ST0 },
|
||||||
|
/* DC FD */ { 0, &Ia_fdiv_STi_ST0 },
|
||||||
|
/* DC FE */ { 0, &Ia_fdiv_STi_ST0 },
|
||||||
|
/* DC FF */ { 0, &Ia_fdiv_STi_ST0 },
|
||||||
|
|
||||||
|
// DD (modrm is outside 00h - BFh) (mod == 11)
|
||||||
|
/* DD C0 */ { 0, &Ia_ffree_STi },
|
||||||
|
/* DD C1 */ { 0, &Ia_ffree_STi },
|
||||||
|
/* DD C2 */ { 0, &Ia_ffree_STi },
|
||||||
|
/* DD C3 */ { 0, &Ia_ffree_STi },
|
||||||
|
/* DD C4 */ { 0, &Ia_ffree_STi },
|
||||||
|
/* DD C5 */ { 0, &Ia_ffree_STi },
|
||||||
|
/* DD C6 */ { 0, &Ia_ffree_STi },
|
||||||
|
/* DD C7 */ { 0, &Ia_ffree_STi },
|
||||||
|
/* DD C8 */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DD C9 */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DD CA */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DD CB */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DD CC */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DD CD */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DD CE */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DD CF */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DD D0 */ { 0, &Ia_fst_STi },
|
||||||
|
/* DD D1 */ { 0, &Ia_fst_STi },
|
||||||
|
/* DD D2 */ { 0, &Ia_fst_STi },
|
||||||
|
/* DD D3 */ { 0, &Ia_fst_STi },
|
||||||
|
/* DD D4 */ { 0, &Ia_fst_STi },
|
||||||
|
/* DD D5 */ { 0, &Ia_fst_STi },
|
||||||
|
/* DD D6 */ { 0, &Ia_fst_STi },
|
||||||
|
/* DD D7 */ { 0, &Ia_fst_STi },
|
||||||
|
/* DD D8 */ { 0, &Ia_fstp_STi },
|
||||||
|
/* DD D9 */ { 0, &Ia_fstp_STi },
|
||||||
|
/* DD DA */ { 0, &Ia_fstp_STi },
|
||||||
|
/* DD DB */ { 0, &Ia_fstp_STi },
|
||||||
|
/* DD DC */ { 0, &Ia_fstp_STi },
|
||||||
|
/* DD DD */ { 0, &Ia_fstp_STi },
|
||||||
|
/* DD DE */ { 0, &Ia_fstp_STi },
|
||||||
|
/* DD DF */ { 0, &Ia_fstp_STi },
|
||||||
|
/* DD E0 */ { 0, &Ia_fucom_STi },
|
||||||
|
/* DD E1 */ { 0, &Ia_fucom_STi },
|
||||||
|
/* DD E2 */ { 0, &Ia_fucom_STi },
|
||||||
|
/* DD E3 */ { 0, &Ia_fucom_STi },
|
||||||
|
/* DD E4 */ { 0, &Ia_fucom_STi },
|
||||||
|
/* DD E5 */ { 0, &Ia_fucom_STi },
|
||||||
|
/* DD E6 */ { 0, &Ia_fucom_STi },
|
||||||
|
/* DD E7 */ { 0, &Ia_fucom_STi },
|
||||||
|
/* DD E8 */ { 0, &Ia_fucomp_STi },
|
||||||
|
/* DD E9 */ { 0, &Ia_fucomp_STi },
|
||||||
|
/* DD EA */ { 0, &Ia_fucomp_STi },
|
||||||
|
/* DD EB */ { 0, &Ia_fucomp_STi },
|
||||||
|
/* DD EC */ { 0, &Ia_fucomp_STi },
|
||||||
|
/* DD ED */ { 0, &Ia_fucomp_STi },
|
||||||
|
/* DD EE */ { 0, &Ia_fucomp_STi },
|
||||||
|
/* DD EF */ { 0, &Ia_fucomp_STi },
|
||||||
|
/* DD F0 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F1 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F2 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F3 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F4 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F5 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F6 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F7 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F8 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD F9 */ { 0, &Ia_Invalid },
|
||||||
|
/* DD FA */ { 0, &Ia_Invalid },
|
||||||
|
/* DD FB */ { 0, &Ia_Invalid },
|
||||||
|
/* DD FC */ { 0, &Ia_Invalid },
|
||||||
|
/* DD FD */ { 0, &Ia_Invalid },
|
||||||
|
/* DD FE */ { 0, &Ia_Invalid },
|
||||||
|
/* DD FF */ { 0, &Ia_Invalid },
|
||||||
|
|
||||||
|
// DE (modrm is outside 00h - BFh) (mod == 11)
|
||||||
|
/* DE C0 */ { 0, &Ia_faddp_STi_ST0 },
|
||||||
|
/* DE C1 */ { 0, &Ia_faddp_STi_ST0 },
|
||||||
|
/* DE C2 */ { 0, &Ia_faddp_STi_ST0 },
|
||||||
|
/* DE C3 */ { 0, &Ia_faddp_STi_ST0 },
|
||||||
|
/* DE C4 */ { 0, &Ia_faddp_STi_ST0 },
|
||||||
|
/* DE C5 */ { 0, &Ia_faddp_STi_ST0 },
|
||||||
|
/* DE C6 */ { 0, &Ia_faddp_STi_ST0 },
|
||||||
|
/* DE C7 */ { 0, &Ia_faddp_STi_ST0 },
|
||||||
|
/* DE C8 */ { 0, &Ia_fmulp_STi_ST0 },
|
||||||
|
/* DE C9 */ { 0, &Ia_fmulp_STi_ST0 },
|
||||||
|
/* DE CA */ { 0, &Ia_fmulp_STi_ST0 },
|
||||||
|
/* DE CB */ { 0, &Ia_fmulp_STi_ST0 },
|
||||||
|
/* DE CC */ { 0, &Ia_fmulp_STi_ST0 },
|
||||||
|
/* DE CD */ { 0, &Ia_fmulp_STi_ST0 },
|
||||||
|
/* DE CE */ { 0, &Ia_fmulp_STi_ST0 },
|
||||||
|
/* DE CF */ { 0, &Ia_fmulp_STi_ST0 },
|
||||||
|
/* DE D0 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DE D1 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DE D2 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DE D3 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DE D4 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DE D5 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DE D6 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DE D7 */ { 0, &Ia_fcomp_STi }, // undocumented
|
||||||
|
/* DE D8 */ { 0, &Ia_Invalid },
|
||||||
|
/* DE D9 */ { 0, &Ia_fcompp },
|
||||||
|
/* DE DA */ { 0, &Ia_Invalid },
|
||||||
|
/* DE DB */ { 0, &Ia_Invalid },
|
||||||
|
/* DE DC */ { 0, &Ia_Invalid },
|
||||||
|
/* DE DD */ { 0, &Ia_Invalid },
|
||||||
|
/* DE DE */ { 0, &Ia_Invalid },
|
||||||
|
/* DE DF */ { 0, &Ia_Invalid },
|
||||||
|
/* DE E0 */ { 0, &Ia_fsubrp_STi_ST0 },
|
||||||
|
/* DE E1 */ { 0, &Ia_fsubrp_STi_ST0 },
|
||||||
|
/* DE E2 */ { 0, &Ia_fsubrp_STi_ST0 },
|
||||||
|
/* DE E3 */ { 0, &Ia_fsubrp_STi_ST0 },
|
||||||
|
/* DE E4 */ { 0, &Ia_fsubrp_STi_ST0 },
|
||||||
|
/* DE E5 */ { 0, &Ia_fsubrp_STi_ST0 },
|
||||||
|
/* DE E6 */ { 0, &Ia_fsubrp_STi_ST0 },
|
||||||
|
/* DE E7 */ { 0, &Ia_fsubrp_STi_ST0 },
|
||||||
|
/* DE E8 */ { 0, &Ia_fsubp_STi_ST0 },
|
||||||
|
/* DE E9 */ { 0, &Ia_fsubp_STi_ST0 },
|
||||||
|
/* DE EA */ { 0, &Ia_fsubp_STi_ST0 },
|
||||||
|
/* DE EB */ { 0, &Ia_fsubp_STi_ST0 },
|
||||||
|
/* DE EC */ { 0, &Ia_fsubp_STi_ST0 },
|
||||||
|
/* DE ED */ { 0, &Ia_fsubp_STi_ST0 },
|
||||||
|
/* DE EE */ { 0, &Ia_fsubp_STi_ST0 },
|
||||||
|
/* DE EF */ { 0, &Ia_fsubp_STi_ST0 },
|
||||||
|
/* DE F0 */ { 0, &Ia_fdivrp_STi_ST0 },
|
||||||
|
/* DE F1 */ { 0, &Ia_fdivrp_STi_ST0 },
|
||||||
|
/* DE F2 */ { 0, &Ia_fdivrp_STi_ST0 },
|
||||||
|
/* DE F3 */ { 0, &Ia_fdivrp_STi_ST0 },
|
||||||
|
/* DE F4 */ { 0, &Ia_fdivrp_STi_ST0 },
|
||||||
|
/* DE F5 */ { 0, &Ia_fdivrp_STi_ST0 },
|
||||||
|
/* DE F6 */ { 0, &Ia_fdivrp_STi_ST0 },
|
||||||
|
/* DE F7 */ { 0, &Ia_fdivrp_STi_ST0 },
|
||||||
|
/* DE F8 */ { 0, &Ia_fdivp_STi_ST0 },
|
||||||
|
/* DE F9 */ { 0, &Ia_fdivp_STi_ST0 },
|
||||||
|
/* DE FA */ { 0, &Ia_fdivp_STi_ST0 },
|
||||||
|
/* DE FB */ { 0, &Ia_fdivp_STi_ST0 },
|
||||||
|
/* DE FC */ { 0, &Ia_fdivp_STi_ST0 },
|
||||||
|
/* DE FD */ { 0, &Ia_fdivp_STi_ST0 },
|
||||||
|
/* DE FE */ { 0, &Ia_fdivp_STi_ST0 },
|
||||||
|
/* DE FF */ { 0, &Ia_fdivp_STi_ST0 },
|
||||||
|
|
||||||
|
// DF (modrm is outside 00h - BFh) (mod == 11)
|
||||||
|
/* DF C0 */ { 0, &Ia_ffreep_STi }, // 287 compatibility opcode
|
||||||
|
/* DF C1 */ { 0, &Ia_ffreep_STi },
|
||||||
|
/* DF C2 */ { 0, &Ia_ffreep_STi },
|
||||||
|
/* DF C3 */ { 0, &Ia_ffreep_STi },
|
||||||
|
/* DF C4 */ { 0, &Ia_ffreep_STi },
|
||||||
|
/* DF C5 */ { 0, &Ia_ffreep_STi },
|
||||||
|
/* DF C6 */ { 0, &Ia_ffreep_STi },
|
||||||
|
/* DF C7 */ { 0, &Ia_ffreep_STi },
|
||||||
|
/* DF C8 */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DF C9 */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DF CA */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DF CB */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DF CC */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DF CD */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DF CE */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DF CF */ { 0, &Ia_fxch }, // undocumented
|
||||||
|
/* DF D0 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D1 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D2 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D3 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D4 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D5 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D6 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D7 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D8 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF D9 */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF DA */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF DB */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF DC */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF DD */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF DE */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF DF */ { 0, &Ia_fstp_STi }, // undocumented
|
||||||
|
/* DF E0 */ { 0, &Ia_fnstsw_AX },
|
||||||
|
/* DF E1 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF E2 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF E3 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF E4 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF E5 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF E6 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF E7 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF E8 */ { 0, &Ia_fucomip_ST0_STi },
|
||||||
|
/* DF E9 */ { 0, &Ia_fucomip_ST0_STi },
|
||||||
|
/* DF EA */ { 0, &Ia_fucomip_ST0_STi },
|
||||||
|
/* DF EB */ { 0, &Ia_fucomip_ST0_STi },
|
||||||
|
/* DF EC */ { 0, &Ia_fucomip_ST0_STi },
|
||||||
|
/* DF ED */ { 0, &Ia_fucomip_ST0_STi },
|
||||||
|
/* DF EE */ { 0, &Ia_fucomip_ST0_STi },
|
||||||
|
/* DF EF */ { 0, &Ia_fucomip_ST0_STi },
|
||||||
|
/* DF F0 */ { 0, &Ia_fcomip_ST0_STi },
|
||||||
|
/* DF F1 */ { 0, &Ia_fcomip_ST0_STi },
|
||||||
|
/* DF F2 */ { 0, &Ia_fcomip_ST0_STi },
|
||||||
|
/* DF F3 */ { 0, &Ia_fcomip_ST0_STi },
|
||||||
|
/* DF F4 */ { 0, &Ia_fcomip_ST0_STi },
|
||||||
|
/* DF F5 */ { 0, &Ia_fcomip_ST0_STi },
|
||||||
|
/* DF F6 */ { 0, &Ia_fcomip_ST0_STi },
|
||||||
|
/* DF F7 */ { 0, &Ia_fcomip_ST0_STi },
|
||||||
|
/* DF F8 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF F9 */ { 0, &Ia_Invalid },
|
||||||
|
/* DF FA */ { 0, &Ia_Invalid },
|
||||||
|
/* DF FB */ { 0, &Ia_Invalid },
|
||||||
|
/* DF FC */ { 0, &Ia_Invalid },
|
||||||
|
/* DF FD */ { 0, &Ia_Invalid },
|
||||||
|
/* DF FE */ { 0, &Ia_Invalid },
|
||||||
|
/* DF FF */ { 0, &Ia_Invalid },
|
||||||
|
};
|
|
@ -0,0 +1,890 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// $Id: dis_tables_xop.inc 11863 2013-10-07 19:23:19Z sshwarts $
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2011-2013 Stanislav Shwartsman
|
||||||
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGroupXOP_G1[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_Invalid },
|
||||||
|
/* 1 */ { 0, &Ia_blcfill_By_Ey },
|
||||||
|
/* 2 */ { 0, &Ia_blsfill_By_Ey },
|
||||||
|
/* 3 */ { 0, &Ia_blcs_By_Ey },
|
||||||
|
/* 4 */ { 0, &Ia_tzmsk_By_Ey },
|
||||||
|
/* 5 */ { 0, &Ia_blcic_By_Ey },
|
||||||
|
/* 6 */ { 0, &Ia_blsic_By_Ey },
|
||||||
|
/* 7 */ { 0, &Ia_t1mskc_By_Ey }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGroupXOP_G2[8] = {
|
||||||
|
/* 0 */ { 0, &Ia_Invalid },
|
||||||
|
/* 1 */ { 0, &Ia_blcmsk_By_Ey },
|
||||||
|
/* 2 */ { 0, &Ia_Invalid },
|
||||||
|
/* 3 */ { 0, &Ia_Invalid },
|
||||||
|
/* 4 */ { 0, &Ia_Invalid },
|
||||||
|
/* 5 */ { 0, &Ia_Invalid },
|
||||||
|
/* 6 */ { 0, &Ia_blci_By_Ey },
|
||||||
|
/* 7 */ { 0, &Ia_Invalid }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop8_a2[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpcmov_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 1 */ { 0, &Ia_vpcmov_Vdq_Hdq_VIb_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop8_a3[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpperm_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 1 */ { 0, &Ia_vpperm_Vdq_Hdq_VIb_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_88[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpshab_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vpshab_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_89[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpshaw_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vpshaw_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_8a[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpshad_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vpshad_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_8b[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpshaq_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vpshaq_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_90[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vprotb_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vprotb_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_91[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vprotw_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vprotw_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_92[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vprotd_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vprotd_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_93[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vprotq_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vprotq_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_94[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpshlb_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vpshlb_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_95[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpshlw_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vpshlw_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_96[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpshld_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vpshld_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmGrpVexW_xop9_97[2] = {
|
||||||
|
/* 0 */ { 0, &Ia_vpshlq_Vdq_Wdq_Hdq },
|
||||||
|
/* 1 */ { 0, &Ia_vpshlq_Vdq_Hdq_Wdq }
|
||||||
|
};
|
||||||
|
|
||||||
|
static BxDisasmOpcodeTable_t BxDisasmOpcodesXOP[256*3] = {
|
||||||
|
// 256 entries for XOP map 0x8 opcodes
|
||||||
|
/* 00 */ { 0, &Ia_Invalid },
|
||||||
|
/* 01 */ { GRPN(XOP_G1) },
|
||||||
|
/* 02 */ { GRPN(XOP_G2) },
|
||||||
|
/* 03 */ { 0, &Ia_Invalid },
|
||||||
|
/* 04 */ { 0, &Ia_Invalid },
|
||||||
|
/* 05 */ { 0, &Ia_Invalid },
|
||||||
|
/* 06 */ { 0, &Ia_Invalid },
|
||||||
|
/* 07 */ { 0, &Ia_Invalid },
|
||||||
|
/* 08 */ { 0, &Ia_Invalid },
|
||||||
|
/* 09 */ { 0, &Ia_Invalid },
|
||||||
|
/* 0A */ { 0, &Ia_Invalid },
|
||||||
|
/* 0B */ { 0, &Ia_Invalid },
|
||||||
|
/* 0C */ { 0, &Ia_Invalid },
|
||||||
|
/* 0D */ { 0, &Ia_Invalid },
|
||||||
|
/* 0E */ { 0, &Ia_Invalid },
|
||||||
|
/* 0F */ { 0, &Ia_Invalid },
|
||||||
|
/* 10 */ { 0, &Ia_Invalid },
|
||||||
|
/* 11 */ { 0, &Ia_Invalid },
|
||||||
|
/* 12 */ { 0, &Ia_Invalid },
|
||||||
|
/* 13 */ { 0, &Ia_Invalid },
|
||||||
|
/* 14 */ { 0, &Ia_Invalid },
|
||||||
|
/* 15 */ { 0, &Ia_Invalid },
|
||||||
|
/* 16 */ { 0, &Ia_Invalid },
|
||||||
|
/* 17 */ { 0, &Ia_Invalid },
|
||||||
|
/* 18 */ { 0, &Ia_Invalid },
|
||||||
|
/* 19 */ { 0, &Ia_Invalid },
|
||||||
|
/* 1A */ { 0, &Ia_Invalid },
|
||||||
|
/* 1B */ { 0, &Ia_Invalid },
|
||||||
|
/* 1C */ { 0, &Ia_Invalid },
|
||||||
|
/* 1D */ { 0, &Ia_Invalid },
|
||||||
|
/* 1E */ { 0, &Ia_Invalid },
|
||||||
|
/* 1F */ { 0, &Ia_Invalid },
|
||||||
|
/* 20 */ { 0, &Ia_Invalid },
|
||||||
|
/* 21 */ { 0, &Ia_Invalid },
|
||||||
|
/* 22 */ { 0, &Ia_Invalid },
|
||||||
|
/* 23 */ { 0, &Ia_Invalid },
|
||||||
|
/* 24 */ { 0, &Ia_Invalid },
|
||||||
|
/* 25 */ { 0, &Ia_Invalid },
|
||||||
|
/* 26 */ { 0, &Ia_Invalid },
|
||||||
|
/* 27 */ { 0, &Ia_Invalid },
|
||||||
|
/* 28 */ { 0, &Ia_Invalid },
|
||||||
|
/* 29 */ { 0, &Ia_Invalid },
|
||||||
|
/* 2A */ { 0, &Ia_Invalid },
|
||||||
|
/* 2B */ { 0, &Ia_Invalid },
|
||||||
|
/* 2C */ { 0, &Ia_Invalid },
|
||||||
|
/* 2D */ { 0, &Ia_Invalid },
|
||||||
|
/* 2E */ { 0, &Ia_Invalid },
|
||||||
|
/* 2F */ { 0, &Ia_Invalid },
|
||||||
|
/* 30 */ { 0, &Ia_Invalid },
|
||||||
|
/* 31 */ { 0, &Ia_Invalid },
|
||||||
|
/* 32 */ { 0, &Ia_Invalid },
|
||||||
|
/* 33 */ { 0, &Ia_Invalid },
|
||||||
|
/* 34 */ { 0, &Ia_Invalid },
|
||||||
|
/* 35 */ { 0, &Ia_Invalid },
|
||||||
|
/* 36 */ { 0, &Ia_Invalid },
|
||||||
|
/* 37 */ { 0, &Ia_Invalid },
|
||||||
|
/* 38 */ { 0, &Ia_Invalid },
|
||||||
|
/* 39 */ { 0, &Ia_Invalid },
|
||||||
|
/* 3A */ { 0, &Ia_Invalid },
|
||||||
|
/* 3B */ { 0, &Ia_Invalid },
|
||||||
|
/* 3C */ { 0, &Ia_Invalid },
|
||||||
|
/* 3D */ { 0, &Ia_Invalid },
|
||||||
|
/* 3E */ { 0, &Ia_Invalid },
|
||||||
|
/* 3F */ { 0, &Ia_Invalid },
|
||||||
|
/* 40 */ { 0, &Ia_Invalid },
|
||||||
|
/* 41 */ { 0, &Ia_Invalid },
|
||||||
|
/* 42 */ { 0, &Ia_Invalid },
|
||||||
|
/* 43 */ { 0, &Ia_Invalid },
|
||||||
|
/* 44 */ { 0, &Ia_Invalid },
|
||||||
|
/* 45 */ { 0, &Ia_Invalid },
|
||||||
|
/* 46 */ { 0, &Ia_Invalid },
|
||||||
|
/* 47 */ { 0, &Ia_Invalid },
|
||||||
|
/* 48 */ { 0, &Ia_Invalid },
|
||||||
|
/* 49 */ { 0, &Ia_Invalid },
|
||||||
|
/* 4A */ { 0, &Ia_Invalid },
|
||||||
|
/* 4B */ { 0, &Ia_Invalid },
|
||||||
|
/* 4C */ { 0, &Ia_Invalid },
|
||||||
|
/* 4D */ { 0, &Ia_Invalid },
|
||||||
|
/* 4E */ { 0, &Ia_Invalid },
|
||||||
|
/* 4F */ { 0, &Ia_Invalid },
|
||||||
|
/* 50 */ { 0, &Ia_Invalid },
|
||||||
|
/* 51 */ { 0, &Ia_Invalid },
|
||||||
|
/* 52 */ { 0, &Ia_Invalid },
|
||||||
|
/* 53 */ { 0, &Ia_Invalid },
|
||||||
|
/* 54 */ { 0, &Ia_Invalid },
|
||||||
|
/* 55 */ { 0, &Ia_Invalid },
|
||||||
|
/* 56 */ { 0, &Ia_Invalid },
|
||||||
|
/* 57 */ { 0, &Ia_Invalid },
|
||||||
|
/* 58 */ { 0, &Ia_Invalid },
|
||||||
|
/* 59 */ { 0, &Ia_Invalid },
|
||||||
|
/* 5A */ { 0, &Ia_Invalid },
|
||||||
|
/* 5B */ { 0, &Ia_Invalid },
|
||||||
|
/* 5C */ { 0, &Ia_Invalid },
|
||||||
|
/* 5D */ { 0, &Ia_Invalid },
|
||||||
|
/* 5E */ { 0, &Ia_Invalid },
|
||||||
|
/* 5F */ { 0, &Ia_Invalid },
|
||||||
|
/* 60 */ { 0, &Ia_Invalid },
|
||||||
|
/* 61 */ { 0, &Ia_Invalid },
|
||||||
|
/* 62 */ { 0, &Ia_Invalid },
|
||||||
|
/* 63 */ { 0, &Ia_Invalid },
|
||||||
|
/* 64 */ { 0, &Ia_Invalid },
|
||||||
|
/* 65 */ { 0, &Ia_Invalid },
|
||||||
|
/* 66 */ { 0, &Ia_Invalid },
|
||||||
|
/* 67 */ { 0, &Ia_Invalid },
|
||||||
|
/* 68 */ { 0, &Ia_Invalid },
|
||||||
|
/* 69 */ { 0, &Ia_Invalid },
|
||||||
|
/* 6A */ { 0, &Ia_Invalid },
|
||||||
|
/* 6B */ { 0, &Ia_Invalid },
|
||||||
|
/* 6C */ { 0, &Ia_Invalid },
|
||||||
|
/* 6D */ { 0, &Ia_Invalid },
|
||||||
|
/* 6E */ { 0, &Ia_Invalid },
|
||||||
|
/* 6F */ { 0, &Ia_Invalid },
|
||||||
|
/* 70 */ { 0, &Ia_Invalid },
|
||||||
|
/* 71 */ { 0, &Ia_Invalid },
|
||||||
|
/* 72 */ { 0, &Ia_Invalid },
|
||||||
|
/* 73 */ { 0, &Ia_Invalid },
|
||||||
|
/* 74 */ { 0, &Ia_Invalid },
|
||||||
|
/* 75 */ { 0, &Ia_Invalid },
|
||||||
|
/* 76 */ { 0, &Ia_Invalid },
|
||||||
|
/* 77 */ { 0, &Ia_Invalid },
|
||||||
|
/* 78 */ { 0, &Ia_Invalid },
|
||||||
|
/* 79 */ { 0, &Ia_Invalid },
|
||||||
|
/* 7A */ { 0, &Ia_Invalid },
|
||||||
|
/* 7B */ { 0, &Ia_Invalid },
|
||||||
|
/* 7C */ { 0, &Ia_Invalid },
|
||||||
|
/* 7D */ { 0, &Ia_Invalid },
|
||||||
|
/* 7E */ { 0, &Ia_Invalid },
|
||||||
|
/* 7F */ { 0, &Ia_Invalid },
|
||||||
|
/* 80 */ { 0, &Ia_Invalid },
|
||||||
|
/* 81 */ { 0, &Ia_Invalid },
|
||||||
|
/* 82 */ { 0, &Ia_Invalid },
|
||||||
|
/* 83 */ { 0, &Ia_Invalid },
|
||||||
|
/* 84 */ { 0, &Ia_Invalid },
|
||||||
|
/* 85 */ { 0, &Ia_vpmacssww_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 86 */ { 0, &Ia_vpmacsswd_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 87 */ { 0, &Ia_vpmacssdql_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 88 */ { 0, &Ia_Invalid },
|
||||||
|
/* 89 */ { 0, &Ia_Invalid },
|
||||||
|
/* 8A */ { 0, &Ia_Invalid },
|
||||||
|
/* 8B */ { 0, &Ia_Invalid },
|
||||||
|
/* 8C */ { 0, &Ia_Invalid },
|
||||||
|
/* 8D */ { 0, &Ia_Invalid },
|
||||||
|
/* 8E */ { 0, &Ia_vpmacssdd_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 8F */ { 0, &Ia_vpmacssdqh_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 90 */ { 0, &Ia_Invalid },
|
||||||
|
/* 91 */ { 0, &Ia_Invalid },
|
||||||
|
/* 92 */ { 0, &Ia_Invalid },
|
||||||
|
/* 93 */ { 0, &Ia_Invalid },
|
||||||
|
/* 94 */ { 0, &Ia_Invalid },
|
||||||
|
/* 95 */ { 0, &Ia_vpmacsww_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 96 */ { 0, &Ia_vpmacswd_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 97 */ { 0, &Ia_vpmacsdql_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 98 */ { 0, &Ia_Invalid },
|
||||||
|
/* 99 */ { 0, &Ia_Invalid },
|
||||||
|
/* 9A */ { 0, &Ia_Invalid },
|
||||||
|
/* 9B */ { 0, &Ia_Invalid },
|
||||||
|
/* 9C */ { 0, &Ia_Invalid },
|
||||||
|
/* 9D */ { 0, &Ia_Invalid },
|
||||||
|
/* 9E */ { 0, &Ia_vpmacsdd_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* 9F */ { 0, &Ia_vpmacsdqh_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* A0 */ { 0, &Ia_Invalid },
|
||||||
|
/* A1 */ { 0, &Ia_Invalid },
|
||||||
|
/* A2 */ { GRPVEXW(xop8_a2) },
|
||||||
|
/* A3 */ { GRPVEXW(xop8_a3) },
|
||||||
|
/* A4 */ { 0, &Ia_Invalid },
|
||||||
|
/* A5 */ { 0, &Ia_Invalid },
|
||||||
|
/* A6 */ { 0, &Ia_vpmadcsswd_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* A7 */ { 0, &Ia_Invalid },
|
||||||
|
/* A8 */ { 0, &Ia_Invalid },
|
||||||
|
/* A9 */ { 0, &Ia_Invalid },
|
||||||
|
/* AA */ { 0, &Ia_Invalid },
|
||||||
|
/* AB */ { 0, &Ia_Invalid },
|
||||||
|
/* AC */ { 0, &Ia_Invalid },
|
||||||
|
/* AD */ { 0, &Ia_Invalid },
|
||||||
|
/* AE */ { 0, &Ia_Invalid },
|
||||||
|
/* AF */ { 0, &Ia_Invalid },
|
||||||
|
/* B0 */ { 0, &Ia_Invalid },
|
||||||
|
/* B1 */ { 0, &Ia_Invalid },
|
||||||
|
/* B2 */ { 0, &Ia_Invalid },
|
||||||
|
/* B3 */ { 0, &Ia_Invalid },
|
||||||
|
/* B4 */ { 0, &Ia_Invalid },
|
||||||
|
/* B5 */ { 0, &Ia_Invalid },
|
||||||
|
/* B6 */ { 0, &Ia_vpmadcswd_Vdq_Hdq_Wdq_VIb },
|
||||||
|
/* B7 */ { 0, &Ia_Invalid },
|
||||||
|
/* B8 */ { 0, &Ia_Invalid },
|
||||||
|
/* B9 */ { 0, &Ia_Invalid },
|
||||||
|
/* BA */ { 0, &Ia_Invalid },
|
||||||
|
/* BB */ { 0, &Ia_Invalid },
|
||||||
|
/* BC */ { 0, &Ia_Invalid },
|
||||||
|
/* BD */ { 0, &Ia_Invalid },
|
||||||
|
/* BE */ { 0, &Ia_Invalid },
|
||||||
|
/* BF */ { 0, &Ia_Invalid },
|
||||||
|
/* C0 */ { 0, &Ia_vprotb_Vdq_Wdq_Ib },
|
||||||
|
/* C1 */ { 0, &Ia_vprotw_Vdq_Wdq_Ib },
|
||||||
|
/* C2 */ { 0, &Ia_vprotd_Vdq_Wdq_Ib },
|
||||||
|
/* C3 */ { 0, &Ia_vprotq_Vdq_Wdq_Ib },
|
||||||
|
/* C4 */ { 0, &Ia_Invalid },
|
||||||
|
/* C5 */ { 0, &Ia_Invalid },
|
||||||
|
/* C6 */ { 0, &Ia_Invalid },
|
||||||
|
/* C7 */ { 0, &Ia_Invalid },
|
||||||
|
/* C8 */ { 0, &Ia_Invalid },
|
||||||
|
/* C9 */ { 0, &Ia_Invalid },
|
||||||
|
/* CA */ { 0, &Ia_Invalid },
|
||||||
|
/* CB */ { 0, &Ia_Invalid },
|
||||||
|
/* CC */ { 0, &Ia_vpcomb_Vdq_Hdq_Wdq_Ib },
|
||||||
|
/* CD */ { 0, &Ia_vpcomw_Vdq_Hdq_Wdq_Ib },
|
||||||
|
/* CE */ { 0, &Ia_vpcomd_Vdq_Hdq_Wdq_Ib },
|
||||||
|
/* CF */ { 0, &Ia_vpcomq_Vdq_Hdq_Wdq_Ib },
|
||||||
|
/* D0 */ { 0, &Ia_Invalid },
|
||||||
|
/* D1 */ { 0, &Ia_Invalid },
|
||||||
|
/* D2 */ { 0, &Ia_Invalid },
|
||||||
|
/* D3 */ { 0, &Ia_Invalid },
|
||||||
|
/* D4 */ { 0, &Ia_Invalid },
|
||||||
|
/* D5 */ { 0, &Ia_Invalid },
|
||||||
|
/* D6 */ { 0, &Ia_Invalid },
|
||||||
|
/* D7 */ { 0, &Ia_Invalid },
|
||||||
|
/* D8 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA */ { 0, &Ia_Invalid },
|
||||||
|
/* DB */ { 0, &Ia_Invalid },
|
||||||
|
/* DC */ { 0, &Ia_Invalid },
|
||||||
|
/* DD */ { 0, &Ia_Invalid },
|
||||||
|
/* DE */ { 0, &Ia_Invalid },
|
||||||
|
/* DF */ { 0, &Ia_Invalid },
|
||||||
|
/* E0 */ { 0, &Ia_Invalid },
|
||||||
|
/* E1 */ { 0, &Ia_Invalid },
|
||||||
|
/* E2 */ { 0, &Ia_Invalid },
|
||||||
|
/* E3 */ { 0, &Ia_Invalid },
|
||||||
|
/* E4 */ { 0, &Ia_Invalid },
|
||||||
|
/* E5 */ { 0, &Ia_Invalid },
|
||||||
|
/* E6 */ { 0, &Ia_Invalid },
|
||||||
|
/* E7 */ { 0, &Ia_Invalid },
|
||||||
|
/* E8 */ { 0, &Ia_Invalid },
|
||||||
|
/* E9 */ { 0, &Ia_Invalid },
|
||||||
|
/* EA */ { 0, &Ia_Invalid },
|
||||||
|
/* EB */ { 0, &Ia_Invalid },
|
||||||
|
/* EC */ { 0, &Ia_vpcomub_Vdq_Hdq_Wdq_Ib },
|
||||||
|
/* ED */ { 0, &Ia_vpcomuw_Vdq_Hdq_Wdq_Ib },
|
||||||
|
/* EE */ { 0, &Ia_vpcomud_Vdq_Hdq_Wdq_Ib },
|
||||||
|
/* EF */ { 0, &Ia_vpcomuq_Vdq_Hdq_Wdq_Ib },
|
||||||
|
/* F0 */ { 0, &Ia_Invalid },
|
||||||
|
/* F1 */ { 0, &Ia_Invalid },
|
||||||
|
/* F2 */ { 0, &Ia_Invalid },
|
||||||
|
/* F3 */ { 0, &Ia_Invalid },
|
||||||
|
/* F4 */ { 0, &Ia_Invalid },
|
||||||
|
/* F5 */ { 0, &Ia_Invalid },
|
||||||
|
/* F6 */ { 0, &Ia_Invalid },
|
||||||
|
/* F7 */ { 0, &Ia_Invalid },
|
||||||
|
/* F8 */ { 0, &Ia_Invalid },
|
||||||
|
/* F9 */ { 0, &Ia_Invalid },
|
||||||
|
/* FA */ { 0, &Ia_Invalid },
|
||||||
|
/* FB */ { 0, &Ia_Invalid },
|
||||||
|
/* FC */ { 0, &Ia_Invalid },
|
||||||
|
/* FD */ { 0, &Ia_Invalid },
|
||||||
|
/* FE */ { 0, &Ia_Invalid },
|
||||||
|
/* FF */ { 0, &Ia_Invalid },
|
||||||
|
|
||||||
|
// 256 entries for XOP map 0x9 opcodes
|
||||||
|
/* 00 */ { 0, &Ia_Invalid },
|
||||||
|
/* 01 */ { 0, &Ia_Invalid },
|
||||||
|
/* 02 */ { 0, &Ia_Invalid },
|
||||||
|
/* 03 */ { 0, &Ia_Invalid },
|
||||||
|
/* 04 */ { 0, &Ia_Invalid },
|
||||||
|
/* 05 */ { 0, &Ia_Invalid },
|
||||||
|
/* 06 */ { 0, &Ia_Invalid },
|
||||||
|
/* 07 */ { 0, &Ia_Invalid },
|
||||||
|
/* 08 */ { 0, &Ia_Invalid },
|
||||||
|
/* 09 */ { 0, &Ia_Invalid },
|
||||||
|
/* 0A */ { 0, &Ia_Invalid },
|
||||||
|
/* 0B */ { 0, &Ia_Invalid },
|
||||||
|
/* 0C */ { 0, &Ia_Invalid },
|
||||||
|
/* 0D */ { 0, &Ia_Invalid },
|
||||||
|
/* 0E */ { 0, &Ia_Invalid },
|
||||||
|
/* 0F */ { 0, &Ia_Invalid },
|
||||||
|
/* 10 */ { 0, &Ia_Invalid },
|
||||||
|
/* 11 */ { 0, &Ia_Invalid },
|
||||||
|
/* 12 */ { 0, &Ia_Invalid },
|
||||||
|
/* 13 */ { 0, &Ia_Invalid },
|
||||||
|
/* 14 */ { 0, &Ia_Invalid },
|
||||||
|
/* 15 */ { 0, &Ia_Invalid },
|
||||||
|
/* 16 */ { 0, &Ia_Invalid },
|
||||||
|
/* 17 */ { 0, &Ia_Invalid },
|
||||||
|
/* 18 */ { 0, &Ia_Invalid },
|
||||||
|
/* 19 */ { 0, &Ia_Invalid },
|
||||||
|
/* 1A */ { 0, &Ia_Invalid },
|
||||||
|
/* 1B */ { 0, &Ia_Invalid },
|
||||||
|
/* 1C */ { 0, &Ia_Invalid },
|
||||||
|
/* 1D */ { 0, &Ia_Invalid },
|
||||||
|
/* 1E */ { 0, &Ia_Invalid },
|
||||||
|
/* 1F */ { 0, &Ia_Invalid },
|
||||||
|
/* 20 */ { 0, &Ia_Invalid },
|
||||||
|
/* 21 */ { 0, &Ia_Invalid },
|
||||||
|
/* 22 */ { 0, &Ia_Invalid },
|
||||||
|
/* 23 */ { 0, &Ia_Invalid },
|
||||||
|
/* 24 */ { 0, &Ia_Invalid },
|
||||||
|
/* 25 */ { 0, &Ia_Invalid },
|
||||||
|
/* 26 */ { 0, &Ia_Invalid },
|
||||||
|
/* 27 */ { 0, &Ia_Invalid },
|
||||||
|
/* 28 */ { 0, &Ia_Invalid },
|
||||||
|
/* 29 */ { 0, &Ia_Invalid },
|
||||||
|
/* 2A */ { 0, &Ia_Invalid },
|
||||||
|
/* 2B */ { 0, &Ia_Invalid },
|
||||||
|
/* 2C */ { 0, &Ia_Invalid },
|
||||||
|
/* 2D */ { 0, &Ia_Invalid },
|
||||||
|
/* 2E */ { 0, &Ia_Invalid },
|
||||||
|
/* 2F */ { 0, &Ia_Invalid },
|
||||||
|
/* 30 */ { 0, &Ia_Invalid },
|
||||||
|
/* 31 */ { 0, &Ia_Invalid },
|
||||||
|
/* 32 */ { 0, &Ia_Invalid },
|
||||||
|
/* 33 */ { 0, &Ia_Invalid },
|
||||||
|
/* 34 */ { 0, &Ia_Invalid },
|
||||||
|
/* 35 */ { 0, &Ia_Invalid },
|
||||||
|
/* 36 */ { 0, &Ia_Invalid },
|
||||||
|
/* 37 */ { 0, &Ia_Invalid },
|
||||||
|
/* 38 */ { 0, &Ia_Invalid },
|
||||||
|
/* 39 */ { 0, &Ia_Invalid },
|
||||||
|
/* 3A */ { 0, &Ia_Invalid },
|
||||||
|
/* 3B */ { 0, &Ia_Invalid },
|
||||||
|
/* 3C */ { 0, &Ia_Invalid },
|
||||||
|
/* 3D */ { 0, &Ia_Invalid },
|
||||||
|
/* 3E */ { 0, &Ia_Invalid },
|
||||||
|
/* 3F */ { 0, &Ia_Invalid },
|
||||||
|
/* 40 */ { 0, &Ia_Invalid },
|
||||||
|
/* 41 */ { 0, &Ia_Invalid },
|
||||||
|
/* 42 */ { 0, &Ia_Invalid },
|
||||||
|
/* 43 */ { 0, &Ia_Invalid },
|
||||||
|
/* 44 */ { 0, &Ia_Invalid },
|
||||||
|
/* 45 */ { 0, &Ia_Invalid },
|
||||||
|
/* 46 */ { 0, &Ia_Invalid },
|
||||||
|
/* 47 */ { 0, &Ia_Invalid },
|
||||||
|
/* 48 */ { 0, &Ia_Invalid },
|
||||||
|
/* 49 */ { 0, &Ia_Invalid },
|
||||||
|
/* 4A */ { 0, &Ia_Invalid },
|
||||||
|
/* 4B */ { 0, &Ia_Invalid },
|
||||||
|
/* 4C */ { 0, &Ia_Invalid },
|
||||||
|
/* 4D */ { 0, &Ia_Invalid },
|
||||||
|
/* 4E */ { 0, &Ia_Invalid },
|
||||||
|
/* 4F */ { 0, &Ia_Invalid },
|
||||||
|
/* 50 */ { 0, &Ia_Invalid },
|
||||||
|
/* 51 */ { 0, &Ia_Invalid },
|
||||||
|
/* 52 */ { 0, &Ia_Invalid },
|
||||||
|
/* 53 */ { 0, &Ia_Invalid },
|
||||||
|
/* 54 */ { 0, &Ia_Invalid },
|
||||||
|
/* 55 */ { 0, &Ia_Invalid },
|
||||||
|
/* 56 */ { 0, &Ia_Invalid },
|
||||||
|
/* 57 */ { 0, &Ia_Invalid },
|
||||||
|
/* 58 */ { 0, &Ia_Invalid },
|
||||||
|
/* 59 */ { 0, &Ia_Invalid },
|
||||||
|
/* 5A */ { 0, &Ia_Invalid },
|
||||||
|
/* 5B */ { 0, &Ia_Invalid },
|
||||||
|
/* 5C */ { 0, &Ia_Invalid },
|
||||||
|
/* 5D */ { 0, &Ia_Invalid },
|
||||||
|
/* 5E */ { 0, &Ia_Invalid },
|
||||||
|
/* 5F */ { 0, &Ia_Invalid },
|
||||||
|
/* 60 */ { 0, &Ia_Invalid },
|
||||||
|
/* 61 */ { 0, &Ia_Invalid },
|
||||||
|
/* 62 */ { 0, &Ia_Invalid },
|
||||||
|
/* 63 */ { 0, &Ia_Invalid },
|
||||||
|
/* 64 */ { 0, &Ia_Invalid },
|
||||||
|
/* 65 */ { 0, &Ia_Invalid },
|
||||||
|
/* 66 */ { 0, &Ia_Invalid },
|
||||||
|
/* 67 */ { 0, &Ia_Invalid },
|
||||||
|
/* 68 */ { 0, &Ia_Invalid },
|
||||||
|
/* 69 */ { 0, &Ia_Invalid },
|
||||||
|
/* 6A */ { 0, &Ia_Invalid },
|
||||||
|
/* 6B */ { 0, &Ia_Invalid },
|
||||||
|
/* 6C */ { 0, &Ia_Invalid },
|
||||||
|
/* 6D */ { 0, &Ia_Invalid },
|
||||||
|
/* 6E */ { 0, &Ia_Invalid },
|
||||||
|
/* 6F */ { 0, &Ia_Invalid },
|
||||||
|
/* 70 */ { 0, &Ia_Invalid },
|
||||||
|
/* 71 */ { 0, &Ia_Invalid },
|
||||||
|
/* 72 */ { 0, &Ia_Invalid },
|
||||||
|
/* 73 */ { 0, &Ia_Invalid },
|
||||||
|
/* 74 */ { 0, &Ia_Invalid },
|
||||||
|
/* 75 */ { 0, &Ia_Invalid },
|
||||||
|
/* 76 */ { 0, &Ia_Invalid },
|
||||||
|
/* 77 */ { 0, &Ia_Invalid },
|
||||||
|
/* 78 */ { 0, &Ia_Invalid },
|
||||||
|
/* 79 */ { 0, &Ia_Invalid },
|
||||||
|
/* 7A */ { 0, &Ia_Invalid },
|
||||||
|
/* 7B */ { 0, &Ia_Invalid },
|
||||||
|
/* 7C */ { 0, &Ia_Invalid },
|
||||||
|
/* 7D */ { 0, &Ia_Invalid },
|
||||||
|
/* 7E */ { 0, &Ia_Invalid },
|
||||||
|
/* 7F */ { 0, &Ia_Invalid },
|
||||||
|
/* 80 */ { 0, &Ia_frczps_Vps_Wps },
|
||||||
|
/* 81 */ { 0, &Ia_frczpd_Vpd_Wpd },
|
||||||
|
/* 82 */ { 0, &Ia_frczss_Vss_Wss },
|
||||||
|
/* 83 */ { 0, &Ia_frczsd_Vsd_Wsd },
|
||||||
|
/* 84 */ { 0, &Ia_Invalid },
|
||||||
|
/* 85 */ { 0, &Ia_Invalid },
|
||||||
|
/* 86 */ { 0, &Ia_Invalid },
|
||||||
|
/* 87 */ { 0, &Ia_Invalid },
|
||||||
|
/* 88 */ { GRPVEXW(xop9_88) },
|
||||||
|
/* 89 */ { GRPVEXW(xop9_89) },
|
||||||
|
/* 8A */ { GRPVEXW(xop9_8a) },
|
||||||
|
/* 8B */ { GRPVEXW(xop9_8b) },
|
||||||
|
/* 8C */ { 0, &Ia_Invalid },
|
||||||
|
/* 8D */ { 0, &Ia_Invalid },
|
||||||
|
/* 8E */ { 0, &Ia_Invalid },
|
||||||
|
/* 8F */ { 0, &Ia_Invalid },
|
||||||
|
/* 90 */ { GRPVEXW(xop9_90) },
|
||||||
|
/* 91 */ { GRPVEXW(xop9_91) },
|
||||||
|
/* 92 */ { GRPVEXW(xop9_92) },
|
||||||
|
/* 93 */ { GRPVEXW(xop9_93) },
|
||||||
|
/* 94 */ { GRPVEXW(xop9_94) },
|
||||||
|
/* 95 */ { GRPVEXW(xop9_95) },
|
||||||
|
/* 96 */ { GRPVEXW(xop9_96) },
|
||||||
|
/* 97 */ { GRPVEXW(xop9_97) },
|
||||||
|
/* 98 */ { 0, &Ia_Invalid },
|
||||||
|
/* 99 */ { 0, &Ia_Invalid },
|
||||||
|
/* 9A */ { 0, &Ia_Invalid },
|
||||||
|
/* 9B */ { 0, &Ia_Invalid },
|
||||||
|
/* 9C */ { 0, &Ia_Invalid },
|
||||||
|
/* 9D */ { 0, &Ia_Invalid },
|
||||||
|
/* 9E */ { 0, &Ia_Invalid },
|
||||||
|
/* 9F */ { 0, &Ia_Invalid },
|
||||||
|
/* A0 */ { 0, &Ia_Invalid },
|
||||||
|
/* A1 */ { 0, &Ia_Invalid },
|
||||||
|
/* A2 */ { 0, &Ia_Invalid },
|
||||||
|
/* A3 */ { 0, &Ia_Invalid },
|
||||||
|
/* A4 */ { 0, &Ia_Invalid },
|
||||||
|
/* A5 */ { 0, &Ia_Invalid },
|
||||||
|
/* A6 */ { 0, &Ia_Invalid },
|
||||||
|
/* A7 */ { 0, &Ia_Invalid },
|
||||||
|
/* A8 */ { 0, &Ia_Invalid },
|
||||||
|
/* A9 */ { 0, &Ia_Invalid },
|
||||||
|
/* AA */ { 0, &Ia_Invalid },
|
||||||
|
/* AB */ { 0, &Ia_Invalid },
|
||||||
|
/* AC */ { 0, &Ia_Invalid },
|
||||||
|
/* AD */ { 0, &Ia_Invalid },
|
||||||
|
/* AE */ { 0, &Ia_Invalid },
|
||||||
|
/* AF */ { 0, &Ia_Invalid },
|
||||||
|
/* B0 */ { 0, &Ia_Invalid },
|
||||||
|
/* B1 */ { 0, &Ia_Invalid },
|
||||||
|
/* B2 */ { 0, &Ia_Invalid },
|
||||||
|
/* B3 */ { 0, &Ia_Invalid },
|
||||||
|
/* B4 */ { 0, &Ia_Invalid },
|
||||||
|
/* B5 */ { 0, &Ia_Invalid },
|
||||||
|
/* B6 */ { 0, &Ia_Invalid },
|
||||||
|
/* B7 */ { 0, &Ia_Invalid },
|
||||||
|
/* B8 */ { 0, &Ia_Invalid },
|
||||||
|
/* B9 */ { 0, &Ia_Invalid },
|
||||||
|
/* BA */ { 0, &Ia_Invalid },
|
||||||
|
/* BB */ { 0, &Ia_Invalid },
|
||||||
|
/* BC */ { 0, &Ia_Invalid },
|
||||||
|
/* BD */ { 0, &Ia_Invalid },
|
||||||
|
/* BE */ { 0, &Ia_Invalid },
|
||||||
|
/* BF */ { 0, &Ia_Invalid },
|
||||||
|
/* C0 */ { 0, &Ia_Invalid },
|
||||||
|
/* C1 */ { 0, &Ia_vphaddbw_Vdq_Wdq },
|
||||||
|
/* C2 */ { 0, &Ia_vphaddbd_Vdq_Wdq },
|
||||||
|
/* C3 */ { 0, &Ia_vphaddbq_Vdq_Wdq },
|
||||||
|
/* C4 */ { 0, &Ia_Invalid },
|
||||||
|
/* C5 */ { 0, &Ia_Invalid },
|
||||||
|
/* C6 */ { 0, &Ia_vphaddwd_Vdq_Wdq },
|
||||||
|
/* C7 */ { 0, &Ia_vphaddwq_Vdq_Wdq },
|
||||||
|
/* C8 */ { 0, &Ia_Invalid },
|
||||||
|
/* C9 */ { 0, &Ia_Invalid },
|
||||||
|
/* CA */ { 0, &Ia_Invalid },
|
||||||
|
/* CB */ { 0, &Ia_vphadddq_Vdq_Wdq },
|
||||||
|
/* CC */ { 0, &Ia_Invalid },
|
||||||
|
/* CD */ { 0, &Ia_Invalid },
|
||||||
|
/* CE */ { 0, &Ia_Invalid },
|
||||||
|
/* CF */ { 0, &Ia_Invalid },
|
||||||
|
/* D0 */ { 0, &Ia_Invalid },
|
||||||
|
/* D1 */ { 0, &Ia_vphaddubw_Vdq_Wdq },
|
||||||
|
/* D2 */ { 0, &Ia_vphaddubd_Vdq_Wdq },
|
||||||
|
/* D3 */ { 0, &Ia_vphaddubq_Vdq_Wdq },
|
||||||
|
/* D4 */ { 0, &Ia_Invalid },
|
||||||
|
/* D5 */ { 0, &Ia_Invalid },
|
||||||
|
/* D6 */ { 0, &Ia_vphadduwd_Vdq_Wdq },
|
||||||
|
/* D7 */ { 0, &Ia_vphadduwq_Vdq_Wdq },
|
||||||
|
/* D8 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA */ { 0, &Ia_Invalid },
|
||||||
|
/* DB */ { 0, &Ia_vphaddudq_Vdq_Wdq },
|
||||||
|
/* DC */ { 0, &Ia_Invalid },
|
||||||
|
/* DD */ { 0, &Ia_Invalid },
|
||||||
|
/* DE */ { 0, &Ia_Invalid },
|
||||||
|
/* DF */ { 0, &Ia_Invalid },
|
||||||
|
/* E0 */ { 0, &Ia_Invalid },
|
||||||
|
/* E1 */ { 0, &Ia_vphsubbw_Vdq_Wdq },
|
||||||
|
/* E2 */ { 0, &Ia_vphsubwd_Vdq_Wdq },
|
||||||
|
/* E3 */ { 0, &Ia_vphsubdq_Vdq_Wdq },
|
||||||
|
/* E4 */ { 0, &Ia_Invalid },
|
||||||
|
/* E5 */ { 0, &Ia_Invalid },
|
||||||
|
/* E6 */ { 0, &Ia_Invalid },
|
||||||
|
/* E7 */ { 0, &Ia_Invalid },
|
||||||
|
/* E8 */ { 0, &Ia_Invalid },
|
||||||
|
/* E9 */ { 0, &Ia_Invalid },
|
||||||
|
/* EA */ { 0, &Ia_Invalid },
|
||||||
|
/* EB */ { 0, &Ia_Invalid },
|
||||||
|
/* EC */ { 0, &Ia_Invalid },
|
||||||
|
/* ED */ { 0, &Ia_Invalid },
|
||||||
|
/* EE */ { 0, &Ia_Invalid },
|
||||||
|
/* EF */ { 0, &Ia_Invalid },
|
||||||
|
/* F0 */ { 0, &Ia_Invalid },
|
||||||
|
/* F1 */ { 0, &Ia_Invalid },
|
||||||
|
/* F2 */ { 0, &Ia_Invalid },
|
||||||
|
/* F3 */ { 0, &Ia_Invalid },
|
||||||
|
/* F4 */ { 0, &Ia_Invalid },
|
||||||
|
/* F5 */ { 0, &Ia_Invalid },
|
||||||
|
/* F6 */ { 0, &Ia_Invalid },
|
||||||
|
/* F7 */ { 0, &Ia_Invalid },
|
||||||
|
/* F8 */ { 0, &Ia_Invalid },
|
||||||
|
/* F9 */ { 0, &Ia_Invalid },
|
||||||
|
/* FA */ { 0, &Ia_Invalid },
|
||||||
|
/* FB */ { 0, &Ia_Invalid },
|
||||||
|
/* FC */ { 0, &Ia_Invalid },
|
||||||
|
/* FD */ { 0, &Ia_Invalid },
|
||||||
|
/* FE */ { 0, &Ia_Invalid },
|
||||||
|
/* FF */ { 0, &Ia_Invalid },
|
||||||
|
|
||||||
|
// 256 entries for XOP map 0xA opcodes
|
||||||
|
/* 00 */ { 0, &Ia_Invalid },
|
||||||
|
/* 01 */ { 0, &Ia_Invalid },
|
||||||
|
/* 02 */ { 0, &Ia_Invalid },
|
||||||
|
/* 03 */ { 0, &Ia_Invalid },
|
||||||
|
/* 04 */ { 0, &Ia_Invalid },
|
||||||
|
/* 05 */ { 0, &Ia_Invalid },
|
||||||
|
/* 06 */ { 0, &Ia_Invalid },
|
||||||
|
/* 07 */ { 0, &Ia_Invalid },
|
||||||
|
/* 08 */ { 0, &Ia_Invalid },
|
||||||
|
/* 09 */ { 0, &Ia_Invalid },
|
||||||
|
/* 0A */ { 0, &Ia_Invalid },
|
||||||
|
/* 0B */ { 0, &Ia_Invalid },
|
||||||
|
/* 0C */ { 0, &Ia_Invalid },
|
||||||
|
/* 0D */ { 0, &Ia_Invalid },
|
||||||
|
/* 0E */ { 0, &Ia_Invalid },
|
||||||
|
/* 0F */ { 0, &Ia_Invalid },
|
||||||
|
/* 10 */ { 0, &Ia_bextr_Gy_Ey_Id },
|
||||||
|
/* 11 */ { 0, &Ia_Invalid },
|
||||||
|
/* 12 */ { 0, &Ia_Invalid },
|
||||||
|
/* 13 */ { 0, &Ia_Invalid },
|
||||||
|
/* 14 */ { 0, &Ia_Invalid },
|
||||||
|
/* 15 */ { 0, &Ia_Invalid },
|
||||||
|
/* 16 */ { 0, &Ia_Invalid },
|
||||||
|
/* 17 */ { 0, &Ia_Invalid },
|
||||||
|
/* 18 */ { 0, &Ia_Invalid },
|
||||||
|
/* 19 */ { 0, &Ia_Invalid },
|
||||||
|
/* 1A */ { 0, &Ia_Invalid },
|
||||||
|
/* 1B */ { 0, &Ia_Invalid },
|
||||||
|
/* 1C */ { 0, &Ia_Invalid },
|
||||||
|
/* 1D */ { 0, &Ia_Invalid },
|
||||||
|
/* 1E */ { 0, &Ia_Invalid },
|
||||||
|
/* 1F */ { 0, &Ia_Invalid },
|
||||||
|
/* 20 */ { 0, &Ia_Invalid },
|
||||||
|
/* 21 */ { 0, &Ia_Invalid },
|
||||||
|
/* 22 */ { 0, &Ia_Invalid },
|
||||||
|
/* 23 */ { 0, &Ia_Invalid },
|
||||||
|
/* 24 */ { 0, &Ia_Invalid },
|
||||||
|
/* 25 */ { 0, &Ia_Invalid },
|
||||||
|
/* 26 */ { 0, &Ia_Invalid },
|
||||||
|
/* 27 */ { 0, &Ia_Invalid },
|
||||||
|
/* 28 */ { 0, &Ia_Invalid },
|
||||||
|
/* 29 */ { 0, &Ia_Invalid },
|
||||||
|
/* 2A */ { 0, &Ia_Invalid },
|
||||||
|
/* 2B */ { 0, &Ia_Invalid },
|
||||||
|
/* 2C */ { 0, &Ia_Invalid },
|
||||||
|
/* 2D */ { 0, &Ia_Invalid },
|
||||||
|
/* 2E */ { 0, &Ia_Invalid },
|
||||||
|
/* 2F */ { 0, &Ia_Invalid },
|
||||||
|
/* 30 */ { 0, &Ia_Invalid },
|
||||||
|
/* 31 */ { 0, &Ia_Invalid },
|
||||||
|
/* 32 */ { 0, &Ia_Invalid },
|
||||||
|
/* 33 */ { 0, &Ia_Invalid },
|
||||||
|
/* 34 */ { 0, &Ia_Invalid },
|
||||||
|
/* 35 */ { 0, &Ia_Invalid },
|
||||||
|
/* 36 */ { 0, &Ia_Invalid },
|
||||||
|
/* 37 */ { 0, &Ia_Invalid },
|
||||||
|
/* 38 */ { 0, &Ia_Invalid },
|
||||||
|
/* 39 */ { 0, &Ia_Invalid },
|
||||||
|
/* 3A */ { 0, &Ia_Invalid },
|
||||||
|
/* 3B */ { 0, &Ia_Invalid },
|
||||||
|
/* 3C */ { 0, &Ia_Invalid },
|
||||||
|
/* 3D */ { 0, &Ia_Invalid },
|
||||||
|
/* 3E */ { 0, &Ia_Invalid },
|
||||||
|
/* 3F */ { 0, &Ia_Invalid },
|
||||||
|
/* 40 */ { 0, &Ia_Invalid },
|
||||||
|
/* 41 */ { 0, &Ia_Invalid },
|
||||||
|
/* 42 */ { 0, &Ia_Invalid },
|
||||||
|
/* 43 */ { 0, &Ia_Invalid },
|
||||||
|
/* 44 */ { 0, &Ia_Invalid },
|
||||||
|
/* 45 */ { 0, &Ia_Invalid },
|
||||||
|
/* 46 */ { 0, &Ia_Invalid },
|
||||||
|
/* 47 */ { 0, &Ia_Invalid },
|
||||||
|
/* 48 */ { 0, &Ia_Invalid },
|
||||||
|
/* 49 */ { 0, &Ia_Invalid },
|
||||||
|
/* 4A */ { 0, &Ia_Invalid },
|
||||||
|
/* 4B */ { 0, &Ia_Invalid },
|
||||||
|
/* 4C */ { 0, &Ia_Invalid },
|
||||||
|
/* 4D */ { 0, &Ia_Invalid },
|
||||||
|
/* 4E */ { 0, &Ia_Invalid },
|
||||||
|
/* 4F */ { 0, &Ia_Invalid },
|
||||||
|
/* 50 */ { 0, &Ia_Invalid },
|
||||||
|
/* 51 */ { 0, &Ia_Invalid },
|
||||||
|
/* 52 */ { 0, &Ia_Invalid },
|
||||||
|
/* 53 */ { 0, &Ia_Invalid },
|
||||||
|
/* 54 */ { 0, &Ia_Invalid },
|
||||||
|
/* 55 */ { 0, &Ia_Invalid },
|
||||||
|
/* 56 */ { 0, &Ia_Invalid },
|
||||||
|
/* 57 */ { 0, &Ia_Invalid },
|
||||||
|
/* 58 */ { 0, &Ia_Invalid },
|
||||||
|
/* 59 */ { 0, &Ia_Invalid },
|
||||||
|
/* 5A */ { 0, &Ia_Invalid },
|
||||||
|
/* 5B */ { 0, &Ia_Invalid },
|
||||||
|
/* 5C */ { 0, &Ia_Invalid },
|
||||||
|
/* 5D */ { 0, &Ia_Invalid },
|
||||||
|
/* 5E */ { 0, &Ia_Invalid },
|
||||||
|
/* 5F */ { 0, &Ia_Invalid },
|
||||||
|
/* 60 */ { 0, &Ia_Invalid },
|
||||||
|
/* 61 */ { 0, &Ia_Invalid },
|
||||||
|
/* 62 */ { 0, &Ia_Invalid },
|
||||||
|
/* 63 */ { 0, &Ia_Invalid },
|
||||||
|
/* 64 */ { 0, &Ia_Invalid },
|
||||||
|
/* 65 */ { 0, &Ia_Invalid },
|
||||||
|
/* 66 */ { 0, &Ia_Invalid },
|
||||||
|
/* 67 */ { 0, &Ia_Invalid },
|
||||||
|
/* 68 */ { 0, &Ia_Invalid },
|
||||||
|
/* 69 */ { 0, &Ia_Invalid },
|
||||||
|
/* 6A */ { 0, &Ia_Invalid },
|
||||||
|
/* 6B */ { 0, &Ia_Invalid },
|
||||||
|
/* 6C */ { 0, &Ia_Invalid },
|
||||||
|
/* 6D */ { 0, &Ia_Invalid },
|
||||||
|
/* 6E */ { 0, &Ia_Invalid },
|
||||||
|
/* 6F */ { 0, &Ia_Invalid },
|
||||||
|
/* 70 */ { 0, &Ia_Invalid },
|
||||||
|
/* 71 */ { 0, &Ia_Invalid },
|
||||||
|
/* 72 */ { 0, &Ia_Invalid },
|
||||||
|
/* 73 */ { 0, &Ia_Invalid },
|
||||||
|
/* 74 */ { 0, &Ia_Invalid },
|
||||||
|
/* 75 */ { 0, &Ia_Invalid },
|
||||||
|
/* 76 */ { 0, &Ia_Invalid },
|
||||||
|
/* 77 */ { 0, &Ia_Invalid },
|
||||||
|
/* 78 */ { 0, &Ia_Invalid },
|
||||||
|
/* 79 */ { 0, &Ia_Invalid },
|
||||||
|
/* 7A */ { 0, &Ia_Invalid },
|
||||||
|
/* 7B */ { 0, &Ia_Invalid },
|
||||||
|
/* 7C */ { 0, &Ia_Invalid },
|
||||||
|
/* 7D */ { 0, &Ia_Invalid },
|
||||||
|
/* 7E */ { 0, &Ia_Invalid },
|
||||||
|
/* 7F */ { 0, &Ia_Invalid },
|
||||||
|
/* 80 */ { 0, &Ia_Invalid },
|
||||||
|
/* 81 */ { 0, &Ia_Invalid },
|
||||||
|
/* 82 */ { 0, &Ia_Invalid },
|
||||||
|
/* 83 */ { 0, &Ia_Invalid },
|
||||||
|
/* 84 */ { 0, &Ia_Invalid },
|
||||||
|
/* 85 */ { 0, &Ia_Invalid },
|
||||||
|
/* 86 */ { 0, &Ia_Invalid },
|
||||||
|
/* 87 */ { 0, &Ia_Invalid },
|
||||||
|
/* 88 */ { 0, &Ia_Invalid },
|
||||||
|
/* 89 */ { 0, &Ia_Invalid },
|
||||||
|
/* 8A */ { 0, &Ia_Invalid },
|
||||||
|
/* 8B */ { 0, &Ia_Invalid },
|
||||||
|
/* 8C */ { 0, &Ia_Invalid },
|
||||||
|
/* 8D */ { 0, &Ia_Invalid },
|
||||||
|
/* 8E */ { 0, &Ia_Invalid },
|
||||||
|
/* 8F */ { 0, &Ia_Invalid },
|
||||||
|
/* 90 */ { 0, &Ia_Invalid },
|
||||||
|
/* 91 */ { 0, &Ia_Invalid },
|
||||||
|
/* 92 */ { 0, &Ia_Invalid },
|
||||||
|
/* 93 */ { 0, &Ia_Invalid },
|
||||||
|
/* 94 */ { 0, &Ia_Invalid },
|
||||||
|
/* 95 */ { 0, &Ia_Invalid },
|
||||||
|
/* 96 */ { 0, &Ia_Invalid },
|
||||||
|
/* 97 */ { 0, &Ia_Invalid },
|
||||||
|
/* 98 */ { 0, &Ia_Invalid },
|
||||||
|
/* 99 */ { 0, &Ia_Invalid },
|
||||||
|
/* 9A */ { 0, &Ia_Invalid },
|
||||||
|
/* 9B */ { 0, &Ia_Invalid },
|
||||||
|
/* 9C */ { 0, &Ia_Invalid },
|
||||||
|
/* 9D */ { 0, &Ia_Invalid },
|
||||||
|
/* 9E */ { 0, &Ia_Invalid },
|
||||||
|
/* 9F */ { 0, &Ia_Invalid },
|
||||||
|
/* A0 */ { 0, &Ia_Invalid },
|
||||||
|
/* A1 */ { 0, &Ia_Invalid },
|
||||||
|
/* A2 */ { 0, &Ia_Invalid },
|
||||||
|
/* A3 */ { 0, &Ia_Invalid },
|
||||||
|
/* A4 */ { 0, &Ia_Invalid },
|
||||||
|
/* A5 */ { 0, &Ia_Invalid },
|
||||||
|
/* A6 */ { 0, &Ia_Invalid },
|
||||||
|
/* A7 */ { 0, &Ia_Invalid },
|
||||||
|
/* A8 */ { 0, &Ia_Invalid },
|
||||||
|
/* A9 */ { 0, &Ia_Invalid },
|
||||||
|
/* AA */ { 0, &Ia_Invalid },
|
||||||
|
/* AB */ { 0, &Ia_Invalid },
|
||||||
|
/* AC */ { 0, &Ia_Invalid },
|
||||||
|
/* AD */ { 0, &Ia_Invalid },
|
||||||
|
/* AE */ { 0, &Ia_Invalid },
|
||||||
|
/* AF */ { 0, &Ia_Invalid },
|
||||||
|
/* B0 */ { 0, &Ia_Invalid },
|
||||||
|
/* B1 */ { 0, &Ia_Invalid },
|
||||||
|
/* B2 */ { 0, &Ia_Invalid },
|
||||||
|
/* B3 */ { 0, &Ia_Invalid },
|
||||||
|
/* B4 */ { 0, &Ia_Invalid },
|
||||||
|
/* B5 */ { 0, &Ia_Invalid },
|
||||||
|
/* B6 */ { 0, &Ia_Invalid },
|
||||||
|
/* B7 */ { 0, &Ia_Invalid },
|
||||||
|
/* B8 */ { 0, &Ia_Invalid },
|
||||||
|
/* B9 */ { 0, &Ia_Invalid },
|
||||||
|
/* BA */ { 0, &Ia_Invalid },
|
||||||
|
/* BB */ { 0, &Ia_Invalid },
|
||||||
|
/* BC */ { 0, &Ia_Invalid },
|
||||||
|
/* BD */ { 0, &Ia_Invalid },
|
||||||
|
/* BE */ { 0, &Ia_Invalid },
|
||||||
|
/* BF */ { 0, &Ia_Invalid },
|
||||||
|
/* C0 */ { 0, &Ia_Invalid },
|
||||||
|
/* C1 */ { 0, &Ia_Invalid },
|
||||||
|
/* C2 */ { 0, &Ia_Invalid },
|
||||||
|
/* C3 */ { 0, &Ia_Invalid },
|
||||||
|
/* C4 */ { 0, &Ia_Invalid },
|
||||||
|
/* C5 */ { 0, &Ia_Invalid },
|
||||||
|
/* C6 */ { 0, &Ia_Invalid },
|
||||||
|
/* C7 */ { 0, &Ia_Invalid },
|
||||||
|
/* C8 */ { 0, &Ia_Invalid },
|
||||||
|
/* C9 */ { 0, &Ia_Invalid },
|
||||||
|
/* CA */ { 0, &Ia_Invalid },
|
||||||
|
/* CB */ { 0, &Ia_Invalid },
|
||||||
|
/* CC */ { 0, &Ia_Invalid },
|
||||||
|
/* CD */ { 0, &Ia_Invalid },
|
||||||
|
/* CE */ { 0, &Ia_Invalid },
|
||||||
|
/* CF */ { 0, &Ia_Invalid },
|
||||||
|
/* D0 */ { 0, &Ia_Invalid },
|
||||||
|
/* D1 */ { 0, &Ia_Invalid },
|
||||||
|
/* D2 */ { 0, &Ia_Invalid },
|
||||||
|
/* D3 */ { 0, &Ia_Invalid },
|
||||||
|
/* D4 */ { 0, &Ia_Invalid },
|
||||||
|
/* D5 */ { 0, &Ia_Invalid },
|
||||||
|
/* D6 */ { 0, &Ia_Invalid },
|
||||||
|
/* D7 */ { 0, &Ia_Invalid },
|
||||||
|
/* D8 */ { 0, &Ia_Invalid },
|
||||||
|
/* D9 */ { 0, &Ia_Invalid },
|
||||||
|
/* DA */ { 0, &Ia_Invalid },
|
||||||
|
/* DB */ { 0, &Ia_Invalid },
|
||||||
|
/* DC */ { 0, &Ia_Invalid },
|
||||||
|
/* DD */ { 0, &Ia_Invalid },
|
||||||
|
/* DE */ { 0, &Ia_Invalid },
|
||||||
|
/* DF */ { 0, &Ia_Invalid },
|
||||||
|
/* E0 */ { 0, &Ia_Invalid },
|
||||||
|
/* E1 */ { 0, &Ia_Invalid },
|
||||||
|
/* E2 */ { 0, &Ia_Invalid },
|
||||||
|
/* E3 */ { 0, &Ia_Invalid },
|
||||||
|
/* E4 */ { 0, &Ia_Invalid },
|
||||||
|
/* E5 */ { 0, &Ia_Invalid },
|
||||||
|
/* E6 */ { 0, &Ia_Invalid },
|
||||||
|
/* E7 */ { 0, &Ia_Invalid },
|
||||||
|
/* E8 */ { 0, &Ia_Invalid },
|
||||||
|
/* E9 */ { 0, &Ia_Invalid },
|
||||||
|
/* EA */ { 0, &Ia_Invalid },
|
||||||
|
/* EB */ { 0, &Ia_Invalid },
|
||||||
|
/* EC */ { 0, &Ia_Invalid },
|
||||||
|
/* ED */ { 0, &Ia_Invalid },
|
||||||
|
/* EE */ { 0, &Ia_Invalid },
|
||||||
|
/* EF */ { 0, &Ia_Invalid },
|
||||||
|
/* F0 */ { 0, &Ia_Invalid },
|
||||||
|
/* F1 */ { 0, &Ia_Invalid },
|
||||||
|
/* F2 */ { 0, &Ia_Invalid },
|
||||||
|
/* F3 */ { 0, &Ia_Invalid },
|
||||||
|
/* F4 */ { 0, &Ia_Invalid },
|
||||||
|
/* F5 */ { 0, &Ia_Invalid },
|
||||||
|
/* F6 */ { 0, &Ia_Invalid },
|
||||||
|
/* F7 */ { 0, &Ia_Invalid },
|
||||||
|
/* F8 */ { 0, &Ia_Invalid },
|
||||||
|
/* F9 */ { 0, &Ia_Invalid },
|
||||||
|
/* FA */ { 0, &Ia_Invalid },
|
||||||
|
/* FB */ { 0, &Ia_Invalid },
|
||||||
|
/* FC */ { 0, &Ia_Invalid },
|
||||||
|
/* FD */ { 0, &Ia_Invalid },
|
||||||
|
/* FE */ { 0, &Ia_Invalid },
|
||||||
|
/* FF */ { 0, &Ia_Invalid }
|
||||||
|
};
|
|
@ -1,3 +1,26 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// $Id: disasm.h 12420 2014-07-18 11:14:25Z sshwarts $
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005-2014 Stanislav Shwartsman
|
||||||
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef _BX_DISASM_H_
|
#ifndef _BX_DISASM_H_
|
||||||
#define _BX_DISASM_H_
|
#define _BX_DISASM_H_
|
||||||
|
|
||||||
|
@ -15,23 +38,61 @@
|
||||||
base = sib_byte & 0x07; \
|
base = sib_byte & 0x07; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// will be used in future
|
/* Instruction set attributes (duplicated in cpu.h) */
|
||||||
#define IA_286 0x00000001 /* 286+ instruction */
|
#define IA_X87 (BX_CONST64(1) << 0) /* FPU (X87) instruction */
|
||||||
#define IA_386 0x00000002 /* 386+ instruction */
|
#define IA_486 (BX_CONST64(1) << 1) /* 486 new instruction */
|
||||||
#define IA_486 0x00000004 /* 486+ instruction */
|
#define IA_PENTIUM (BX_CONST64(1) << 2) /* Pentium new instruction */
|
||||||
#define IA_PENTIUM 0x00000008 /* Pentium+ instruction */
|
#define IA_P6 (BX_CONST64(1) << 3) /* P6 new instruction */
|
||||||
#define IA_P6 0x00000010 /* P6 new instruction */
|
#define IA_MMX (BX_CONST64(1) << 4) /* MMX instruction */
|
||||||
#define IA_SYSTEM 0x00000020 /* system instruction (require CPL=0) */
|
#define IA_3DNOW (BX_CONST64(1) << 5) /* 3DNow! instruction (AMD) */
|
||||||
#define IA_LEGACY 0x00000040 /* legacy instruction */
|
#define IA_SYSCALL_SYSRET (BX_CONST64(1) << 6) /* SYSCALL/SYSRET in legacy mode (AMD) */
|
||||||
#define IA_X87 0x00000080 /* FPU (X87) instruction */
|
#define IA_SYSENTER_SYSEXIT (BX_CONST64(1) << 7) /* SYSENTER/SYSEXIT instruction */
|
||||||
#define IA_MMX 0x00000100 /* MMX instruction */
|
#define IA_CLFLUSH (BX_CONST64(1) << 8) /* CLFLUSH instruction */
|
||||||
#define IA_3DNOW 0x00000200 /* 3DNow! instruction */
|
#define IA_SSE (BX_CONST64(1) << 9) /* SSE instruction */
|
||||||
#define IA_PREFETCH 0x00000400 /* Prefetch instruction */
|
#define IA_SSE2 (BX_CONST64(1) << 10) /* SSE2 instruction */
|
||||||
#define IA_SSE 0x00000800 /* SSE instruction */
|
#define IA_SSE3 (BX_CONST64(1) << 11) /* SSE3 instruction */
|
||||||
#define IA_SSE2 0x00001000 /* SSE2 instruction */
|
#define IA_SSSE3 (BX_CONST64(1) << 12) /* SSSE3 instruction */
|
||||||
#define IA_SSE3 0x00002000 /* SSE3 instruction */
|
#define IA_SSE4_1 (BX_CONST64(1) << 13) /* SSE4_1 instruction */
|
||||||
#define IA_SSE4 0x00004000 /* SSE4 instruction */
|
#define IA_SSE4_2 (BX_CONST64(1) << 14) /* SSE4_2 instruction */
|
||||||
#define IA_X86_64 0x00008000 /* x86-64 instruction */
|
#define IA_POPCNT (BX_CONST64(1) << 15) /* POPCNT instruction */
|
||||||
|
#define IA_MONITOR_MWAIT (BX_CONST64(1) << 16) /* MONITOR/MWAIT instruction */
|
||||||
|
#define IA_VMX (BX_CONST64(1) << 17) /* VMX instruction */
|
||||||
|
#define IA_SMX (BX_CONST64(1) << 18) /* SMX instruction */
|
||||||
|
#define IA_LM_LAHF_SAHF (BX_CONST64(1) << 19) /* Long Mode LAHF/SAHF instruction */
|
||||||
|
#define IA_CMPXCHG16B (BX_CONST64(1) << 20) /* CMPXCHG16B instruction */
|
||||||
|
#define IA_RDTSCP (BX_CONST64(1) << 21) /* RDTSCP instruction */
|
||||||
|
#define IA_XSAVE (BX_CONST64(1) << 22) /* XSAVE/XRSTOR extensions instruction */
|
||||||
|
#define IA_XSAVEOPT (BX_CONST64(1) << 23) /* XSAVEOPT instruction */
|
||||||
|
#define IA_AES_PCLMULQDQ (BX_CONST64(1) << 24) /* AES+PCLMULQDQ instruction */
|
||||||
|
#define IA_MOVBE (BX_CONST64(1) << 25) /* MOVBE Intel Atom(R) instruction */
|
||||||
|
#define IA_FSGSBASE (BX_CONST64(1) << 26) /* FS/GS BASE access instruction */
|
||||||
|
#define IA_INVPCID (BX_CONST64(1) << 27) /* INVPCID instruction */
|
||||||
|
#define IA_AVX (BX_CONST64(1) << 28) /* AVX instruction */
|
||||||
|
#define IA_AVX2 (BX_CONST64(1) << 29) /* AVX2 instruction */
|
||||||
|
#define IA_AVX_F16C (BX_CONST64(1) << 30) /* AVX F16 convert instruction */
|
||||||
|
#define IA_AVX_FMA (BX_CONST64(1) << 31) /* AVX FMA instruction */
|
||||||
|
#define IA_SSE4A (BX_CONST64(1) << 32) /* SSE4A instruction (AMD) */
|
||||||
|
#define IA_LZCNT (BX_CONST64(1) << 33) /* LZCNT instruction */
|
||||||
|
#define IA_BMI1 (BX_CONST64(1) << 34) /* BMI1 instruction */
|
||||||
|
#define IA_BMI2 (BX_CONST64(1) << 35) /* BMI2 instruction */
|
||||||
|
#define IA_FMA4 (BX_CONST64(1) << 36) /* FMA4 instruction (AMD) */
|
||||||
|
#define IA_XOP (BX_CONST64(1) << 37) /* XOP instruction (AMD) */
|
||||||
|
#define IA_TBM (BX_CONST64(1) << 38) /* TBM instruction (AMD) */
|
||||||
|
#define IA_SVM (BX_CONST64(1) << 39) /* SVM instruction (AMD) */
|
||||||
|
#define IA_RDRAND (BX_CONST64(1) << 40) /* RDRAND instruction */
|
||||||
|
#define IA_ADX (BX_CONST64(1) << 41) /* ADCX/ADOX instruction */
|
||||||
|
#define IA_SMAP (BX_CONST64(1) << 42) /* SMAP support */
|
||||||
|
#define IA_RDSEED (BX_CONST64(1) << 43) /* RDSEED instruction */
|
||||||
|
#define IA_SHA (BX_CONST64(1) << 44) /* SHA instruction */
|
||||||
|
#define IA_AVX512 (BX_CONST64(1) << 45) /* AVX-512 instruction */
|
||||||
|
#define IA_AVX512_CD (BX_CONST64(1) << 46) /* AVX-512 Conflict Detection instruction */
|
||||||
|
#define IA_AVX512_PF (BX_CONST64(1) << 47) /* AVX-512 Sparse Prefetch instruction */
|
||||||
|
#define IA_AVX512_ER (BX_CONST64(1) << 48) /* AVX-512 Exponential/Reciprocal instruction */
|
||||||
|
#define IA_AVX512_DQ (BX_CONST64(1) << 49) /* AVX-512DQ instruction */
|
||||||
|
#define IA_AVX512_BW (BX_CONST64(1) << 50) /* AVX-512 Byte/Word instruction */
|
||||||
|
#define IA_CLFLUSHOPT (BX_CONST64(1) << 51) /* CLFLUSHOPT instruction */
|
||||||
|
#define IA_XSAVEC (BX_CONST64(1) << 52) /* XSAVEC instruction */
|
||||||
|
#define IA_XSAVES (BX_CONST64(1) << 53) /* XSAVES instruction */
|
||||||
|
|
||||||
/* general purpose bit register */
|
/* general purpose bit register */
|
||||||
enum {
|
enum {
|
||||||
|
@ -70,6 +131,8 @@ struct BxDisasmOpcodeInfo_t
|
||||||
BxDisasmPtr_t Operand1;
|
BxDisasmPtr_t Operand1;
|
||||||
BxDisasmPtr_t Operand2;
|
BxDisasmPtr_t Operand2;
|
||||||
BxDisasmPtr_t Operand3;
|
BxDisasmPtr_t Operand3;
|
||||||
|
BxDisasmPtr_t Operand4;
|
||||||
|
Bit64u Feature;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BxDisasmOpcodeTable_t
|
struct BxDisasmOpcodeTable_t
|
||||||
|
@ -82,26 +145,27 @@ struct BxDisasmOpcodeTable_t
|
||||||
#define NO_SEG_OVERRIDE 0xFF
|
#define NO_SEG_OVERRIDE 0xFF
|
||||||
|
|
||||||
// datasize attributes
|
// datasize attributes
|
||||||
#define X_SIZE 0x0000
|
#define X_SIZE 0x00 /* no size */
|
||||||
#define B_SIZE 0x0100
|
#define B_SIZE 0x01 /* byte */
|
||||||
#define W_SIZE 0x0200
|
#define W_SIZE 0x02 /* word */
|
||||||
#define D_SIZE 0x0300
|
#define D_SIZE 0x03 /* double word */
|
||||||
#define Q_SIZE 0x0400
|
#define Q_SIZE 0x04 /* quad word */
|
||||||
#define Z_SIZE 0x0500
|
#define Z_SIZE 0x05 /* double word in 32-bit mode, quad word in 64-bit mode */
|
||||||
#define V_SIZE 0x0600
|
#define T_SIZE 0x06 /* 10-byte x87 floating point */
|
||||||
#define O_SIZE 0x0700
|
#define XMM_SIZE 0x07 /* double quad word (XMM) */
|
||||||
#define T_SIZE 0x0800
|
#define YMM_SIZE 0x08 /* quadruple quad word (YMM) */
|
||||||
#define P_SIZE 0x0900
|
|
||||||
|
#define VSIB_Index 0x80
|
||||||
|
|
||||||
// branch hint attribute
|
// branch hint attribute
|
||||||
#define BRANCH_HINT 0x1000
|
#define BRANCH_HINT 0x1000
|
||||||
|
|
||||||
struct x86_insn
|
struct x86_insn
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
x86_insn(bx_bool is32, bx_bool is64);
|
x86_insn(bx_bool is32, bx_bool is64);
|
||||||
|
|
||||||
bx_bool is_seg_override() const {
|
bx_bool is_seg_override() const {
|
||||||
return (seg_override != NO_SEG_OVERRIDE);
|
return (seg_override != NO_SEG_OVERRIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,15 +177,25 @@ public:
|
||||||
Bit8u extend8b;
|
Bit8u extend8b;
|
||||||
Bit8u rex_r, rex_x, rex_b;
|
Bit8u rex_r, rex_x, rex_b;
|
||||||
Bit8u seg_override;
|
Bit8u seg_override;
|
||||||
unsigned b1, prefixes;
|
unsigned b1;
|
||||||
unsigned ilen;
|
unsigned ilen;
|
||||||
|
|
||||||
|
#define BX_AVX_VL128 0
|
||||||
|
#define BX_AVX_VL256 1
|
||||||
|
Bit8u vex_vvv, vex_l, vex_w;
|
||||||
|
int is_vex; // 0 - no VEX used, 1 - VEX is used, -1 - invalid VEX
|
||||||
|
int is_evex; // 0 - no EVEX used, 1 - EVEX is used, -1 - invalid EVEX
|
||||||
|
int is_xop; // 0 - no XOP used, 1 - XOP is used, -1 - invalid XOP
|
||||||
Bit8u modrm, mod, nnn, rm;
|
Bit8u modrm, mod, nnn, rm;
|
||||||
Bit8u sib, scale, index, base;
|
Bit8u sib, scale, index, base;
|
||||||
union {
|
union {
|
||||||
Bit16u displ16;
|
Bit16u displ16;
|
||||||
Bit32u displ32;
|
Bit32u displ32;
|
||||||
} displacement;
|
} displacement;
|
||||||
|
|
||||||
|
bx_bool evex_b;
|
||||||
|
bx_bool evex_z;
|
||||||
|
unsigned evex_ll_rc;
|
||||||
};
|
};
|
||||||
|
|
||||||
BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
|
BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
|
||||||
|
@ -145,48 +219,60 @@ BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
|
||||||
extend8b = 0;
|
extend8b = 0;
|
||||||
rex_r = rex_b = rex_x = 0;
|
rex_r = rex_b = rex_x = 0;
|
||||||
seg_override = NO_SEG_OVERRIDE;
|
seg_override = NO_SEG_OVERRIDE;
|
||||||
prefixes = 0;
|
|
||||||
ilen = 0;
|
ilen = 0;
|
||||||
b1 = 0;
|
b1 = 0;
|
||||||
|
|
||||||
|
is_vex = 0;
|
||||||
|
is_evex = 0;
|
||||||
|
is_xop = 0;
|
||||||
|
vex_vvv = 0;
|
||||||
|
vex_l = BX_AVX_VL128;
|
||||||
|
vex_w = 0;
|
||||||
modrm = mod = nnn = rm = 0;
|
modrm = mod = nnn = rm = 0;
|
||||||
sib = scale = index = base = 0;
|
sib = scale = index = base = 0;
|
||||||
displacement.displ32 = 0;
|
displacement.displ32 = 0;
|
||||||
|
|
||||||
|
evex_b = 0;
|
||||||
|
evex_ll_rc = 0;
|
||||||
|
evex_z = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class disassembler {
|
class disassembler {
|
||||||
public:
|
public:
|
||||||
disassembler() { set_syntax_intel(); }
|
disassembler(): offset_mode_hex(0), print_mem_datasize(1) { set_syntax_intel(); }
|
||||||
|
|
||||||
unsigned disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf);
|
unsigned disasm(bx_bool is_32, bx_bool is_64, bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf);
|
||||||
|
|
||||||
unsigned disasm16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
unsigned disasm16(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||||
{ return disasm(0, 0, base, ip, instr, disbuf); }
|
{ return disasm(0, 0, cs_base, ip, instr, disbuf); }
|
||||||
|
|
||||||
unsigned disasm32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
unsigned disasm32(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||||
{ return disasm(1, 0, base, ip, instr, disbuf); }
|
{ return disasm(1, 0, cs_base, ip, instr, disbuf); }
|
||||||
|
|
||||||
unsigned disasm64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
unsigned disasm64(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||||
{ return disasm(1, 1, base, ip, instr, disbuf); }
|
{ return disasm(1, 1, cs_base, ip, instr, disbuf); }
|
||||||
|
|
||||||
x86_insn decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf);
|
x86_insn decode(bx_bool is_32, bx_bool is_64, bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf);
|
||||||
|
|
||||||
x86_insn decode16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
x86_insn decode16(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||||
{ return decode(0, 0, base, ip, instr, disbuf); }
|
{ return decode(0, 0, cs_base, ip, instr, disbuf); }
|
||||||
|
|
||||||
x86_insn decode32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
x86_insn decode32(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||||
{ return decode(1, 0, base, ip, instr, disbuf); }
|
{ return decode(1, 0, cs_base, ip, instr, disbuf); }
|
||||||
|
|
||||||
x86_insn decode64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
x86_insn decode64(bx_address cs_base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||||
{ return decode(1, 1, base, ip, instr, disbuf); }
|
{ return decode(1, 1, cs_base, ip, instr, disbuf); }
|
||||||
|
|
||||||
void set_syntax_intel();
|
void set_syntax_intel();
|
||||||
void set_syntax_att ();
|
void set_syntax_att();
|
||||||
|
|
||||||
|
void set_offset_mode_hex(bx_bool mode) { offset_mode_hex = mode; }
|
||||||
|
void set_mem_datasize_print(bx_bool mode) { print_mem_datasize = mode; }
|
||||||
|
|
||||||
void toggle_syntax_mode();
|
void toggle_syntax_mode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bx_bool intel_mode;
|
bx_bool intel_mode, offset_mode_hex, print_mem_datasize;
|
||||||
|
|
||||||
const char **general_16bit_regname;
|
const char **general_16bit_regname;
|
||||||
const char **general_8bit_regname;
|
const char **general_8bit_regname;
|
||||||
|
@ -196,16 +282,16 @@ private:
|
||||||
|
|
||||||
const char **segment_name;
|
const char **segment_name;
|
||||||
const char **index16;
|
const char **index16;
|
||||||
|
const char **vector_reg_name;
|
||||||
|
|
||||||
const char *sreg_mod01or10_rm32[8];
|
const char *sreg_mod00_base32[16];
|
||||||
const char *sreg_mod00_base32[8];
|
const char *sreg_mod01or10_base32[16];
|
||||||
const char *sreg_mod01or10_base32[8];
|
|
||||||
const char *sreg_mod00_rm16[8];
|
const char *sreg_mod00_rm16[8];
|
||||||
const char *sreg_mod01or10_rm16[8];
|
const char *sreg_mod01or10_rm16[8];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bx_address db_eip, db_base;
|
bx_address db_eip, db_cs_base;
|
||||||
|
|
||||||
const Bit8u *instruction; // for fetching of next byte of instruction
|
const Bit8u *instruction; // for fetching of next byte of instruction
|
||||||
|
|
||||||
|
@ -250,6 +336,9 @@ private:
|
||||||
void dis_putc(char symbol);
|
void dis_putc(char symbol);
|
||||||
void dis_sprintf(const char *fmt, ...);
|
void dis_sprintf(const char *fmt, ...);
|
||||||
void decode_modrm(x86_insn *insn);
|
void decode_modrm(x86_insn *insn);
|
||||||
|
unsigned decode_vex(x86_insn *insn);
|
||||||
|
unsigned decode_evex(x86_insn *insn);
|
||||||
|
unsigned decode_xop(x86_insn *insn);
|
||||||
|
|
||||||
void resolve16_mod0 (const x86_insn *insn, unsigned mode);
|
void resolve16_mod0 (const x86_insn *insn, unsigned mode);
|
||||||
void resolve16_mod1or2(const x86_insn *insn, unsigned mode);
|
void resolve16_mod1or2(const x86_insn *insn, unsigned mode);
|
||||||
|
@ -268,85 +357,88 @@ private:
|
||||||
|
|
||||||
void initialize_modrm_segregs();
|
void initialize_modrm_segregs();
|
||||||
|
|
||||||
void print_datasize (unsigned mode);
|
void print_datasize(unsigned mode);
|
||||||
|
|
||||||
void print_memory_access16(int datasize,
|
void print_memory_access16(int datasize,
|
||||||
const char *seg, const char *index, Bit16u disp);
|
const char *seg, const char *index, Bit16u disp);
|
||||||
void print_memory_access (int datasize,
|
void print_memory_access32(int datasize,
|
||||||
const char *seg, const char *base, const char *index, int scale, Bit32u disp);
|
const char *seg, const char *base, const char *index, int scale, Bit32s disp);
|
||||||
|
void print_memory_access64(int datasize,
|
||||||
|
const char *seg, const char *base, const char *index, int scale, Bit32s disp);
|
||||||
|
|
||||||
void print_disassembly_intel(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
|
void print_disassembly_intel(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
|
||||||
void print_disassembly_att (const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
|
void print_disassembly_att (const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Codes for Addressing Method:
|
* Codes for Addressing Method:
|
||||||
* ---------------------------
|
* ---------------------------
|
||||||
* A - Direct address. The instruction has no ModR/M byte; the address
|
* A - Direct address. The instruction has no ModR/M byte; the address
|
||||||
* of the operand is encoded in the instruction; and no base register,
|
* of the operand is encoded in the instruction; and no base register,
|
||||||
* index register, or scaling factor can be applied.
|
* index register, or scaling factor can be applied.
|
||||||
* C - The reg field of the ModR/M byte selects a control register.
|
* C - The reg field of the ModR/M byte selects a control register.
|
||||||
* D - The reg field of the ModR/M byte selects a debug register.
|
* D - The reg field of the ModR/M byte selects a debug register.
|
||||||
* E - A ModR/M byte follows the opcode and specifies the operand. The
|
* E - A ModR/M byte follows the opcode and specifies the operand. The
|
||||||
* operand is either a general-purpose register or a memory address.
|
* operand is either a general-purpose register or a memory address.
|
||||||
* If it is a memory address, the address is computed from a segment
|
* In case of the register operand, the R/M field of the ModR/M byte
|
||||||
* register and any of the following values: a base register, an
|
* selects a general register.
|
||||||
* index register, a scaling factor, a displacement.
|
|
||||||
* F - Flags Register.
|
* F - Flags Register.
|
||||||
* G - The reg field of the ModR/M byte selects a general register.
|
* G - The reg field of the ModR/M byte selects a general register.
|
||||||
* I - Immediate data. The operand value is encoded in subsequent bytes of
|
* I - Immediate data. The operand value is encoded in subsequent bytes of
|
||||||
* the instruction.
|
* the instruction.
|
||||||
* J - The instruction contains a relative offset to be added to the
|
* J - The instruction contains a relative offset to be added to the
|
||||||
* instruction pointer register.
|
* instruction pointer register.
|
||||||
* M - The ModR/M byte may refer only to memory.
|
* M - The ModR/M byte may refer only to memory.
|
||||||
* N - The R/M field of the ModR/M byte selects a packed-quadword MMX
|
* N - The R/M field of the ModR/M byte selects a packed-quadword MMX
|
||||||
technology register.
|
technology register.
|
||||||
* O - The instruction has no ModR/M byte; the offset of the operand is
|
* O - The instruction has no ModR/M byte; the offset of the operand is
|
||||||
* coded as a word or double word (depending on address size attribute)
|
* coded as a word or double word (depending on address size attribute)
|
||||||
* in the instruction. No base register, index register, or scaling
|
* in the instruction. No base register, index register, or scaling
|
||||||
* factor can be applied.
|
* factor can be applied.
|
||||||
* P - The reg field of the ModR/M byte selects a packed quadword MMX
|
* P - The reg field of the ModR/M byte selects a packed quadword MMX
|
||||||
* technology register.
|
* technology register.
|
||||||
* Q - A ModR/M byte follows the opcode and specifies the operand. The
|
* Q - A ModR/M byte follows the opcode and specifies the operand. The
|
||||||
* operand is either an MMX technology register or a memory address.
|
* operand is either an MMX technology register or a memory address.
|
||||||
* If it is a memory address, the address is computed from a segment
|
* If it is a memory address, the address is computed from a segment
|
||||||
* register and any of the following values: a base register, an
|
* register and any of the following values: a base register, an
|
||||||
* index register, a scaling factor, and a displacement.
|
* index register, a scaling factor, and a displacement.
|
||||||
* R - The mod field of the ModR/M byte may refer only to a general register.
|
* R - The mod field of the ModR/M byte may refer only to a general register.
|
||||||
* S - The reg field of the ModR/M byte selects a segment register.
|
* S - The reg field of the ModR/M byte selects a segment register.
|
||||||
* U - The R/M field of the ModR/M byte selects a 128-bit XMM register.
|
|
||||||
* T - The reg field of the ModR/M byte selects a test register.
|
* T - The reg field of the ModR/M byte selects a test register.
|
||||||
* V - The reg field of the ModR/M byte selects a 128-bit XMM register.
|
* U - The R/M field of the ModR/M byte selects a 128-bit XMM/256-bit YMM register.
|
||||||
* W - A ModR/M byte follows the opcode and specifies the operand. The
|
* V - The reg field of the ModR/M byte selects a 128-bit XMM/256-bit YMM register.
|
||||||
* operand is either a 128-bit XMM register or a memory address. If
|
* W - A ModR/M byte follows the opcode and specifies the operand. The
|
||||||
* it is a memory address, the address is computed from a segment
|
* operand is either a 128-bit XMM/256-bit YMM register or a memory address.
|
||||||
|
* If it is a memory address, the address is computed from a segment
|
||||||
* register and any of the following values: a base register, an
|
* register and any of the following values: a base register, an
|
||||||
* index register, a scaling factor, and a displacement.
|
* index register, a scaling factor, and a displacement.
|
||||||
* X - Memory addressed by the DS:rSI register pair.
|
* X - Memory addressed by the DS:rSI register pair.
|
||||||
* Y - Memory addressed by the ES:rDI register pair.
|
* Y - Memory addressed by the ES:rDI register pair.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Codes for Operand Type:
|
* Codes for Operand Type:
|
||||||
* ----------------------
|
* ----------------------
|
||||||
* a - Two one-word operands in memory or two double-word operands in
|
* a - Two one-word operands in memory or two double-word operands in
|
||||||
* memory, depending on operand-size attribute (used only by the BOUND
|
* memory, depending on operand-size attribute (used only by the BOUND
|
||||||
* instruction).
|
* instruction).
|
||||||
* b - Byte, regardless of operand-size attribute.
|
* b - Byte, regardless of operand-size attribute.
|
||||||
* d - Doubleword, regardless of operand-size attribute.
|
* d - Doubleword, regardless of operand-size attribute.
|
||||||
* dq - Double-quadword, regardless of operand-size attribute.
|
* dq - Double-quadword, regardless of operand-size attribute.
|
||||||
* p - 32-bit or 48-bit pointer, depending on operand-size attribute.
|
* p - 32-bit or 48-bit pointer, depending on operand-size attribute.
|
||||||
* pd - 128-bit packed double-precision floating-point data.
|
* pd - 128-bit/256-bit packed double-precision floating-point data.
|
||||||
* pi - Quadword MMX technology register (packed integer)
|
* pi - Quadword MMX technology register (packed integer)
|
||||||
* ps - 128-bit packed single-precision floating-point data.
|
* ps - 128-bit/256-bit packed single-precision floating-point data.
|
||||||
* q - Quadword, regardless of operand-size attribute.
|
* q - Quadword, regardless of operand-size attribute.
|
||||||
* s - 6-byte or 10-byte pseudo-descriptor.
|
* s - 6-byte or 10-byte pseudo-descriptor.
|
||||||
* si - Doubleword integer register (scalar integer)
|
* si - Doubleword integer register (scalar integer)
|
||||||
* ss - Scalar element of a 128-bit packed single-precision floating data.
|
* ss - Scalar element of a packed single-precision floating data.
|
||||||
* sd - Scalar element of a 128-bit packed double-precision floating data.
|
* sd - Scalar element of a packed double-precision floating data.
|
||||||
* v - Word, doubleword or quadword, depending on operand-size attribute.
|
* v - Word, doubleword or quadword, depending on operand-size attribute.
|
||||||
* w - Word, regardless of operand-size attr.
|
* w - Word, regardless of operand-size attr.
|
||||||
|
* y - Doubleword or quadword (in 64-bit mode) depending on 32/64 bit
|
||||||
|
* operand size.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// far call/jmp
|
// far call/jmp
|
||||||
|
@ -354,18 +446,19 @@ public:
|
||||||
void Apd(const x86_insn *insn);
|
void Apd(const x86_insn *insn);
|
||||||
|
|
||||||
// 8-bit general purpose registers
|
// 8-bit general purpose registers
|
||||||
void AL(const x86_insn *insn);
|
void AL_Reg(const x86_insn *insn);
|
||||||
void CL(const x86_insn *insn);
|
void CL_Reg(const x86_insn *insn);
|
||||||
|
|
||||||
// 16-bit general purpose registers
|
// 16-bit general purpose registers
|
||||||
void AX(const x86_insn *insn);
|
void AX_Reg(const x86_insn *insn);
|
||||||
void DX(const x86_insn *insn);
|
void DX_Reg(const x86_insn *insn);
|
||||||
|
|
||||||
// 32-bit general purpose registers
|
// 32-bit general purpose registers
|
||||||
void EAX(const x86_insn *insn);
|
void EAX_Reg(const x86_insn *insn);
|
||||||
|
|
||||||
// 64-bit general purpose registers
|
// 64-bit general purpose registers
|
||||||
void RAX(const x86_insn *insn);
|
void RAX_Reg(const x86_insn *insn);
|
||||||
|
void RCX_Reg(const x86_insn *insn);
|
||||||
|
|
||||||
// segment registers
|
// segment registers
|
||||||
void CS(const x86_insn *insn);
|
void CS(const x86_insn *insn);
|
||||||
|
@ -378,9 +471,6 @@ public:
|
||||||
// segment registers
|
// segment registers
|
||||||
void Sw(const x86_insn *insn);
|
void Sw(const x86_insn *insn);
|
||||||
|
|
||||||
// test registers
|
|
||||||
void Td(const x86_insn *insn);
|
|
||||||
|
|
||||||
// control register
|
// control register
|
||||||
void Cd(const x86_insn *insn);
|
void Cd(const x86_insn *insn);
|
||||||
void Cq(const x86_insn *insn);
|
void Cq(const x86_insn *insn);
|
||||||
|
@ -390,7 +480,7 @@ public:
|
||||||
void Dq(const x86_insn *insn);
|
void Dq(const x86_insn *insn);
|
||||||
|
|
||||||
// 8-bit general purpose register
|
// 8-bit general purpose register
|
||||||
void R8(const x86_insn *insn);
|
void Reg8(const x86_insn *insn);
|
||||||
|
|
||||||
// 16-bit general purpose register
|
// 16-bit general purpose register
|
||||||
void RX(const x86_insn *insn);
|
void RX(const x86_insn *insn);
|
||||||
|
@ -406,12 +496,20 @@ public:
|
||||||
void Ew(const x86_insn *insn);
|
void Ew(const x86_insn *insn);
|
||||||
void Ed(const x86_insn *insn);
|
void Ed(const x86_insn *insn);
|
||||||
void Eq(const x86_insn *insn);
|
void Eq(const x86_insn *insn);
|
||||||
|
void Ey(const x86_insn *insn);
|
||||||
|
void Ebd(const x86_insn *insn);
|
||||||
|
void Ewd(const x86_insn *insn);
|
||||||
|
void Edq(const x86_insn *insn);
|
||||||
|
|
||||||
// general purpose register
|
// general purpose register
|
||||||
void Gb(const x86_insn *insn);
|
void Gb(const x86_insn *insn);
|
||||||
void Gw(const x86_insn *insn);
|
void Gw(const x86_insn *insn);
|
||||||
void Gd(const x86_insn *insn);
|
void Gd(const x86_insn *insn);
|
||||||
void Gq(const x86_insn *insn);
|
void Gq(const x86_insn *insn);
|
||||||
|
void Gy(const x86_insn *insn);
|
||||||
|
|
||||||
|
// vex encoded general purpose register
|
||||||
|
void By(const x86_insn *insn);
|
||||||
|
|
||||||
// immediate
|
// immediate
|
||||||
void I1(const x86_insn *insn);
|
void I1(const x86_insn *insn);
|
||||||
|
@ -420,7 +518,8 @@ public:
|
||||||
void Id(const x86_insn *insn);
|
void Id(const x86_insn *insn);
|
||||||
void Iq(const x86_insn *insn);
|
void Iq(const x86_insn *insn);
|
||||||
|
|
||||||
// two immediates Iw/Ib
|
// double immediate
|
||||||
|
void IbIb(const x86_insn *insn);
|
||||||
void IwIb(const x86_insn *insn);
|
void IwIb(const x86_insn *insn);
|
||||||
|
|
||||||
// sign extended immediate
|
// sign extended immediate
|
||||||
|
@ -437,6 +536,7 @@ public:
|
||||||
void Rw(const x86_insn *insn);
|
void Rw(const x86_insn *insn);
|
||||||
void Rd(const x86_insn *insn);
|
void Rd(const x86_insn *insn);
|
||||||
void Rq(const x86_insn *insn);
|
void Rq(const x86_insn *insn);
|
||||||
|
void Ry(const x86_insn *insn);
|
||||||
|
|
||||||
// mmx register
|
// mmx register
|
||||||
void Pq(const x86_insn *insn);
|
void Pq(const x86_insn *insn);
|
||||||
|
@ -447,22 +547,39 @@ public:
|
||||||
void Vq(const x86_insn *insn);
|
void Vq(const x86_insn *insn);
|
||||||
void Nq(const x86_insn *insn);
|
void Nq(const x86_insn *insn);
|
||||||
|
|
||||||
// xmm register
|
// xmm/ymm register
|
||||||
|
void Ups(const x86_insn *insn);
|
||||||
|
void Upd(const x86_insn *insn);
|
||||||
void Udq(const x86_insn *insn);
|
void Udq(const x86_insn *insn);
|
||||||
|
void Uq(const x86_insn *insn);
|
||||||
|
|
||||||
void Vdq(const x86_insn *insn);
|
void Vdq(const x86_insn *insn);
|
||||||
void Vss(const x86_insn *insn);
|
void Vss(const x86_insn *insn);
|
||||||
void Vsd(const x86_insn *insn);
|
void Vsd(const x86_insn *insn);
|
||||||
void Vps(const x86_insn *insn);
|
void Vps(const x86_insn *insn);
|
||||||
void Vpd(const x86_insn *insn);
|
void Vpd(const x86_insn *insn);
|
||||||
|
// xmm/ymm register through imm byte
|
||||||
|
void VIb(const x86_insn *insn);
|
||||||
|
|
||||||
// xmm register or memory operand
|
// xmm/ymm register or memory operand
|
||||||
|
void Wb(const x86_insn *insn);
|
||||||
|
void Ww(const x86_insn *insn);
|
||||||
|
void Wd(const x86_insn *insn);
|
||||||
void Wq(const x86_insn *insn);
|
void Wq(const x86_insn *insn);
|
||||||
|
|
||||||
void Wdq(const x86_insn *insn);
|
void Wdq(const x86_insn *insn);
|
||||||
void Wss(const x86_insn *insn);
|
void Wss(const x86_insn *insn);
|
||||||
void Wsd(const x86_insn *insn);
|
void Wsd(const x86_insn *insn);
|
||||||
void Wps(const x86_insn *insn);
|
void Wps(const x86_insn *insn);
|
||||||
void Wpd(const x86_insn *insn);
|
void Wpd(const x86_insn *insn);
|
||||||
|
|
||||||
|
// vex encoded xmm/ymm register
|
||||||
|
void Hdq(const x86_insn *insn);
|
||||||
|
void Hps(const x86_insn *insn);
|
||||||
|
void Hpd(const x86_insn *insn);
|
||||||
|
void Hss(const x86_insn *insn);
|
||||||
|
void Hsd(const x86_insn *insn);
|
||||||
|
|
||||||
// direct memory access
|
// direct memory access
|
||||||
void OP_O(const x86_insn *insn, unsigned size);
|
void OP_O(const x86_insn *insn, unsigned size);
|
||||||
void Ob(const x86_insn *insn);
|
void Ob(const x86_insn *insn);
|
||||||
|
@ -484,6 +601,11 @@ public:
|
||||||
void Mdq(const x86_insn *insn);
|
void Mdq(const x86_insn *insn);
|
||||||
void Mps(const x86_insn *insn);
|
void Mps(const x86_insn *insn);
|
||||||
void Mpd(const x86_insn *insn);
|
void Mpd(const x86_insn *insn);
|
||||||
|
void Mss(const x86_insn *insn);
|
||||||
|
void Msd(const x86_insn *insn);
|
||||||
|
|
||||||
|
// gather VSib
|
||||||
|
void VSib(const x86_insn *insn);
|
||||||
|
|
||||||
// string instructions
|
// string instructions
|
||||||
void OP_X(const x86_insn *insn, unsigned size);
|
void OP_X(const x86_insn *insn, unsigned size);
|
||||||
|
@ -499,6 +621,11 @@ public:
|
||||||
void Yd(const x86_insn *insn);
|
void Yd(const x86_insn *insn);
|
||||||
void Yq(const x86_insn *insn);
|
void Yq(const x86_insn *insn);
|
||||||
|
|
||||||
|
// maskmovdq/maskmovdqu
|
||||||
|
void OP_sY(const x86_insn *insn, unsigned size);
|
||||||
|
void sYq(const x86_insn *insn);
|
||||||
|
void sYdq(const x86_insn *insn);
|
||||||
|
|
||||||
// jump offset
|
// jump offset
|
||||||
void Jb(const x86_insn *insn);
|
void Jb(const x86_insn *insn);
|
||||||
void Jw(const x86_insn *insn);
|
void Jw(const x86_insn *insn);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,696 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// $Id: resolve.cc 11863 2013-10-07 19:23:19Z sshwarts $
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005-2013 Stanislav Shwartsman
|
||||||
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "disasm.h"
|
||||||
|
|
||||||
|
void disassembler::decode_modrm(x86_insn *insn)
|
||||||
|
{
|
||||||
|
insn->modrm = fetch_byte();
|
||||||
|
BX_DECODE_MODRM(insn->modrm, insn->mod, insn->nnn, insn->rm);
|
||||||
|
// MOVs with CRx and DRx always use register ops and ignore the mod field.
|
||||||
|
if ((insn->b1 & ~3) == 0x120) insn->mod = 3;
|
||||||
|
insn->nnn |= insn->rex_r;
|
||||||
|
insn->rm |= insn->rex_b;
|
||||||
|
|
||||||
|
if (insn->mod == 3) {
|
||||||
|
return; /* mod, reg, reg */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insn->as_64)
|
||||||
|
{
|
||||||
|
if ((insn->rm & 7) != 4) { /* rm != 100b, no s-i-b byte */
|
||||||
|
// one byte modrm
|
||||||
|
switch (insn->mod) {
|
||||||
|
case 0:
|
||||||
|
resolve_modrm = &disassembler::resolve64_mod0;
|
||||||
|
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
||||||
|
insn->displacement.displ32 = fetch_dword();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* reg, 8-bit displacement, sign extend */
|
||||||
|
resolve_modrm = &disassembler::resolve64_mod1or2;
|
||||||
|
insn->displacement.displ32 = (Bit8s) fetch_byte();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* reg, 32-bit displacement */
|
||||||
|
resolve_modrm = &disassembler::resolve64_mod1or2;
|
||||||
|
insn->displacement.displ32 = fetch_dword();
|
||||||
|
break;
|
||||||
|
} /* switch (mod) */
|
||||||
|
} /* if (rm != 4) */
|
||||||
|
else { /* rm == 4, s-i-b byte follows */
|
||||||
|
insn->sib = fetch_byte();
|
||||||
|
BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
|
||||||
|
insn->base |= insn->rex_b;
|
||||||
|
insn->index |= insn->rex_x;
|
||||||
|
|
||||||
|
switch (insn->mod) {
|
||||||
|
case 0:
|
||||||
|
resolve_modrm = &disassembler::resolve64_mod0_rm4;
|
||||||
|
if ((insn->base & 7) == 5)
|
||||||
|
insn->displacement.displ32 = fetch_dword();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
resolve_modrm = &disassembler::resolve64_mod1or2_rm4;
|
||||||
|
insn->displacement.displ32 = (Bit8s) fetch_byte();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
resolve_modrm = &disassembler::resolve64_mod1or2_rm4;
|
||||||
|
insn->displacement.displ32 = fetch_dword();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} /* s-i-b byte follows */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (insn->as_32)
|
||||||
|
{
|
||||||
|
if ((insn->rm & 7) != 4) { /* rm != 100b, no s-i-b byte */
|
||||||
|
// one byte modrm
|
||||||
|
switch (insn->mod) {
|
||||||
|
case 0:
|
||||||
|
resolve_modrm = &disassembler::resolve32_mod0;
|
||||||
|
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
||||||
|
insn->displacement.displ32 = fetch_dword();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* reg, 8-bit displacement, sign extend */
|
||||||
|
resolve_modrm = &disassembler::resolve32_mod1or2;
|
||||||
|
insn->displacement.displ32 = (Bit8s) fetch_byte();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* reg, 32-bit displacement */
|
||||||
|
resolve_modrm = &disassembler::resolve32_mod1or2;
|
||||||
|
insn->displacement.displ32 = fetch_dword();
|
||||||
|
break;
|
||||||
|
} /* switch (mod) */
|
||||||
|
} /* if (rm != 4) */
|
||||||
|
else { /* rm == 4, s-i-b byte follows */
|
||||||
|
insn->sib = fetch_byte();
|
||||||
|
BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
|
||||||
|
insn->base |= insn->rex_b;
|
||||||
|
insn->index |= insn->rex_x;
|
||||||
|
|
||||||
|
switch (insn->mod) {
|
||||||
|
case 0:
|
||||||
|
resolve_modrm = &disassembler::resolve32_mod0_rm4;
|
||||||
|
if ((insn->base & 7) == 5)
|
||||||
|
insn->displacement.displ32 = fetch_dword();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
|
||||||
|
insn->displacement.displ32 = (Bit8s) fetch_byte();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
|
||||||
|
insn->displacement.displ32 = fetch_dword();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} /* s-i-b byte follows */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(insn->rex_b == 0);
|
||||||
|
assert(insn->rex_x == 0);
|
||||||
|
assert(insn->rex_r == 0);
|
||||||
|
/* 16 bit addressing modes. */
|
||||||
|
switch (insn->mod) {
|
||||||
|
case 0:
|
||||||
|
resolve_modrm = &disassembler::resolve16_mod0;
|
||||||
|
if(insn->rm == 6)
|
||||||
|
insn->displacement.displ16 = fetch_word();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* reg, 8-bit displacement, sign extend */
|
||||||
|
resolve_modrm = &disassembler::resolve16_mod1or2;
|
||||||
|
insn->displacement.displ16 = (Bit8s) fetch_byte();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
resolve_modrm = &disassembler::resolve16_mod1or2;
|
||||||
|
insn->displacement.displ16 = fetch_word();
|
||||||
|
break;
|
||||||
|
} /* switch (mod) ... */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve16_mod0(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
const char *seg;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = sreg_mod00_rm16[insn->rm];
|
||||||
|
|
||||||
|
if(insn->rm == 6)
|
||||||
|
print_memory_access16(datasize, seg, NULL, insn->displacement.displ16);
|
||||||
|
else
|
||||||
|
print_memory_access16(datasize, seg, index16[insn->rm], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve16_mod1or2(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
const char *seg;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = sreg_mod01or10_rm16[insn->rm];
|
||||||
|
|
||||||
|
print_memory_access16(datasize, seg, index16[insn->rm], insn->displacement.displ16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve32_mod0(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
const char *seg, *eip_regname = NULL;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = segment_name[DS_REG];
|
||||||
|
|
||||||
|
if (insn->is_64) {
|
||||||
|
if (intel_mode) eip_regname = "eip";
|
||||||
|
else eip_regname = "%eip";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
||||||
|
print_memory_access32(datasize, seg, eip_regname, NULL, 0, insn->displacement.displ32);
|
||||||
|
else
|
||||||
|
print_memory_access32(datasize, seg, general_32bit_regname[insn->rm], NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve32_mod1or2(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
const char *seg;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = sreg_mod01or10_base32[insn->rm];
|
||||||
|
|
||||||
|
print_memory_access32(datasize, seg,
|
||||||
|
general_32bit_regname[insn->rm], NULL, 0, insn->displacement.displ32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve32_mod0_rm4(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
char vsib_index[8];
|
||||||
|
const char *seg, *base = NULL, *index = NULL;
|
||||||
|
Bit32u disp32 = 0;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = sreg_mod00_base32[insn->base];
|
||||||
|
|
||||||
|
if ((insn->base & 7) != 5)
|
||||||
|
base = general_32bit_regname[insn->base];
|
||||||
|
else
|
||||||
|
disp32 = insn->displacement.displ32;
|
||||||
|
|
||||||
|
if (datasize & VSIB_Index) {
|
||||||
|
sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
|
||||||
|
index = vsib_index;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (insn->index != 4)
|
||||||
|
index = general_32bit_regname[insn->index];
|
||||||
|
}
|
||||||
|
|
||||||
|
print_memory_access32(datasize, seg, base, index, insn->scale, disp32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve32_mod1or2_rm4(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
char vsib_index[8];
|
||||||
|
const char *seg, *index = NULL;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = sreg_mod01or10_base32[insn->base];
|
||||||
|
|
||||||
|
if (datasize & VSIB_Index) {
|
||||||
|
sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
|
||||||
|
index = vsib_index;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (insn->index != 4)
|
||||||
|
index = general_32bit_regname[insn->index];
|
||||||
|
}
|
||||||
|
|
||||||
|
print_memory_access32(datasize, seg,
|
||||||
|
general_32bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve64_mod0(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
const char *seg, *rip_regname;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = segment_name[DS_REG];
|
||||||
|
|
||||||
|
if (intel_mode) rip_regname = "rip";
|
||||||
|
else rip_regname = "%rip";
|
||||||
|
|
||||||
|
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
||||||
|
print_memory_access64(datasize, seg, rip_regname, NULL, 0, (Bit32s) insn->displacement.displ32);
|
||||||
|
else
|
||||||
|
print_memory_access64(datasize, seg, general_64bit_regname[insn->rm], NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve64_mod1or2(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
const char *seg;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = sreg_mod01or10_base32[insn->rm];
|
||||||
|
|
||||||
|
print_memory_access64(datasize, seg,
|
||||||
|
general_64bit_regname[insn->rm], NULL, 0, (Bit32s) insn->displacement.displ32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
char vsib_index[8];
|
||||||
|
const char *seg, *base = NULL, *index = NULL;
|
||||||
|
Bit32s disp32 = 0;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = sreg_mod00_base32[insn->base];
|
||||||
|
|
||||||
|
if ((insn->base & 7) != 5)
|
||||||
|
base = general_64bit_regname[insn->base];
|
||||||
|
else
|
||||||
|
disp32 = (Bit32s) insn->displacement.displ32;
|
||||||
|
|
||||||
|
if (datasize & VSIB_Index) {
|
||||||
|
sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
|
||||||
|
index = vsib_index;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (insn->index != 4)
|
||||||
|
index = general_64bit_regname[insn->index];
|
||||||
|
}
|
||||||
|
|
||||||
|
print_memory_access64(datasize, seg, base, index, insn->scale, disp32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::resolve64_mod1or2_rm4(const x86_insn *insn, unsigned datasize)
|
||||||
|
{
|
||||||
|
char vsib_index[8];
|
||||||
|
const char *seg, *index = NULL;
|
||||||
|
|
||||||
|
if (insn->is_seg_override())
|
||||||
|
seg = segment_name[insn->seg_override];
|
||||||
|
else
|
||||||
|
seg = sreg_mod01or10_base32[insn->base];
|
||||||
|
|
||||||
|
if (datasize & VSIB_Index) {
|
||||||
|
sprintf(vsib_index, "%s%d", vector_reg_name[insn->vex_l], insn->index);
|
||||||
|
index = vsib_index;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (insn->index != 4)
|
||||||
|
index = general_64bit_regname[insn->index];
|
||||||
|
}
|
||||||
|
|
||||||
|
print_memory_access64(datasize, seg,
|
||||||
|
general_64bit_regname[insn->base], index, insn->scale, (Bit32s) insn->displacement.displ32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::print_datasize(unsigned size)
|
||||||
|
{
|
||||||
|
if (!intel_mode || !print_mem_datasize) return;
|
||||||
|
|
||||||
|
switch(size & 0xf)
|
||||||
|
{
|
||||||
|
case B_SIZE:
|
||||||
|
dis_sprintf("byte ptr ");
|
||||||
|
break;
|
||||||
|
case W_SIZE:
|
||||||
|
dis_sprintf("word ptr ");
|
||||||
|
break;
|
||||||
|
case D_SIZE:
|
||||||
|
dis_sprintf("dword ptr ");
|
||||||
|
break;
|
||||||
|
case Q_SIZE:
|
||||||
|
dis_sprintf("qword ptr ");
|
||||||
|
break;
|
||||||
|
case T_SIZE:
|
||||||
|
dis_sprintf("tbyte ptr ");
|
||||||
|
break;
|
||||||
|
case XMM_SIZE:
|
||||||
|
dis_sprintf("dqword ptr ");
|
||||||
|
break;
|
||||||
|
case YMM_SIZE:
|
||||||
|
dis_sprintf("qqword ptr ");
|
||||||
|
break;
|
||||||
|
case X_SIZE:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::print_memory_access16(int datasize,
|
||||||
|
const char *seg, const char *index, Bit16u disp)
|
||||||
|
{
|
||||||
|
print_datasize(datasize);
|
||||||
|
|
||||||
|
dis_sprintf("%s:", seg);
|
||||||
|
|
||||||
|
if (intel_mode)
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
dis_sprintf("0x%04x", (unsigned) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+0x%04x]", index, (unsigned) disp);
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s%+d]", index, (int) (Bit16s) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s]", index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
dis_sprintf("0x%04x", (unsigned) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("0x%04x(%s,1)", (unsigned) disp, index);
|
||||||
|
else
|
||||||
|
dis_sprintf("%d(%s,1)", (int) (Bit16s) disp, index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("(%s,1)", index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::print_memory_access32(int datasize,
|
||||||
|
const char *seg, const char *base, const char *index, int scale, Bit32s disp)
|
||||||
|
{
|
||||||
|
print_datasize(datasize);
|
||||||
|
|
||||||
|
dis_sprintf("%s:", seg);
|
||||||
|
|
||||||
|
scale = 1 << scale;
|
||||||
|
|
||||||
|
if (intel_mode)
|
||||||
|
{
|
||||||
|
if (base == NULL)
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
dis_sprintf("0x%08x", (unsigned) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (scale != 1)
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s*%d+0x%08x]", index, scale, (unsigned) disp);
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s*%d%+d]", index, scale, (int) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s*%d]", index, scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+0x%08x]", index, (unsigned) disp);
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s%+d]", index, (int) disp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf("[%s]", index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+0x%08x]", base, (unsigned) disp);
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s%+d]", base, (int) disp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf("[%s]", base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (scale != 1)
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+%s*%d+0x%08x]", base, index, scale, (unsigned) disp);
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s+%s*%d%+d]", base, index, scale, (int) disp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf("[%s+%s*%d]", base, index, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+%s+0x%08x]", base, index, (unsigned) disp);
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s+%s%+d]", base, index, (int) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s+%s]", base, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (base == NULL)
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
dis_sprintf("0x%08x", (unsigned) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("0x%08x(,%s,%d)", (unsigned) disp, index, scale);
|
||||||
|
else
|
||||||
|
dis_sprintf("%d(,%s,%d)", (int) disp, index, scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("(,%s,%d)", index, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("0x%08x(%s)", (unsigned) disp, base);
|
||||||
|
else
|
||||||
|
dis_sprintf("%d(%s)", (int) disp, base);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("(%s)", base);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("0x%08x(%s,%s,%d)", (unsigned) disp, base, index, scale);
|
||||||
|
else
|
||||||
|
dis_sprintf("%d(%s,%s,%d)", (int) disp, base, index, scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("(%s,%s,%d)", base, index, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassembler::print_memory_access64(int datasize,
|
||||||
|
const char *seg, const char *base, const char *index, int scale, Bit32s disp)
|
||||||
|
{
|
||||||
|
Bit64u disp64 = (Bit64s) disp;
|
||||||
|
|
||||||
|
print_datasize(datasize);
|
||||||
|
|
||||||
|
dis_sprintf("%s:", seg);
|
||||||
|
|
||||||
|
scale = 1 << scale;
|
||||||
|
|
||||||
|
if (intel_mode)
|
||||||
|
{
|
||||||
|
if (base == NULL)
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
dis_sprintf("0x%08x%08x", GET32H(disp64), GET32L(disp64));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (scale != 1)
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s*%d+0x%08x%08x]", index, scale, GET32H(disp64), GET32L(disp64));
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s*%d%+d]", index, scale, (int) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s*%d]", index, scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+0x%08x%08x]", index, GET32H(disp64), GET32L(disp64));
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s%+d]", index, (int) disp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf("[%s]", index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+0x%08x%08x]", base, GET32H(disp64), GET32L(disp64));
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s%+d]", base, (int) disp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf("[%s]", base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (scale != 1)
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+%s*%d+0x%08x%08x]", base, index, scale, GET32H(disp64), GET32L(disp64));
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s+%s*%d%+d]", base, index, scale, (int) disp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis_sprintf("[%s+%s*%d]", base, index, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("[%s+%s+0x%08x%08x]", base, index, GET32H(disp64), GET32L(disp64));
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s+%s%+d]", base, index, (int) disp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("[%s+%s]", base, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (base == NULL)
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
dis_sprintf("0x%08x%08x", GET32H(disp64), GET32L(disp64));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("0x%08x%08x(,%s,%d)", GET32H(disp64), GET32L(disp64), index, scale);
|
||||||
|
else
|
||||||
|
dis_sprintf("%d(,%s,%d)", (int) disp, index, scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("(,%s,%d)", index, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("0x%08x%08x(%s)", GET32H(disp64), GET32L(disp64), base);
|
||||||
|
else
|
||||||
|
dis_sprintf("%d(%s)", (int) disp, base);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("(%s)", base);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (disp != 0) {
|
||||||
|
if (offset_mode_hex)
|
||||||
|
dis_sprintf("0x%08x%08x(%s,%s,%d)", GET32H(disp64), GET32L(disp64), base, index, scale);
|
||||||
|
else
|
||||||
|
dis_sprintf("%d(%s,%s,%d)", (int) disp, base, index, scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dis_sprintf("(%s,%s,%d)", base, index, scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,460 +0,0 @@
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
// $Id: resolve.cc,v 1.13 2006/08/11 17:22:43 sshwarts Exp $
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "disasm.h"
|
|
||||||
|
|
||||||
void disassembler::decode_modrm(x86_insn *insn)
|
|
||||||
{
|
|
||||||
insn->modrm = fetch_byte();
|
|
||||||
BX_DECODE_MODRM(insn->modrm, insn->mod, insn->nnn, insn->rm);
|
|
||||||
// MOVs with CRx and DRx always use register ops and ignore the mod field.
|
|
||||||
if ((insn->b1 & ~3) == 0x120) insn->mod = 3;
|
|
||||||
insn->nnn |= insn->rex_r;
|
|
||||||
|
|
||||||
if (insn->mod == 3) {
|
|
||||||
/* mod, reg, reg */
|
|
||||||
insn->rm |= insn->rex_b;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insn->as_64)
|
|
||||||
{
|
|
||||||
if (insn->rm != 4) { /* rm != 100b, no s-i-b byte */
|
|
||||||
insn->rm |= insn->rex_b;
|
|
||||||
// one byte modrm
|
|
||||||
switch (insn->mod) {
|
|
||||||
case 0:
|
|
||||||
resolve_modrm = &disassembler::resolve64_mod0;
|
|
||||||
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
|
||||||
insn->displacement.displ32 = fetch_dword();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* reg, 8-bit displacement, sign extend */
|
|
||||||
resolve_modrm = &disassembler::resolve64_mod1or2;
|
|
||||||
insn->displacement.displ32 = (Bit8s) fetch_byte();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* reg, 32-bit displacement */
|
|
||||||
resolve_modrm = &disassembler::resolve64_mod1or2;
|
|
||||||
insn->displacement.displ32 = fetch_dword();
|
|
||||||
break;
|
|
||||||
} /* switch (mod) */
|
|
||||||
} /* if (rm != 4) */
|
|
||||||
else { /* rm == 4, s-i-b byte follows */
|
|
||||||
insn->sib = fetch_byte();
|
|
||||||
BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
|
|
||||||
insn->base |= insn->rex_b;
|
|
||||||
insn->index |= insn->rex_x;
|
|
||||||
|
|
||||||
switch (insn->mod) {
|
|
||||||
case 0:
|
|
||||||
resolve_modrm = &disassembler::resolve64_mod0_rm4;
|
|
||||||
if ((insn->base & 7) == 5)
|
|
||||||
insn->displacement.displ32 = fetch_dword();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
resolve_modrm = &disassembler::resolve64_mod1or2_rm4;
|
|
||||||
insn->displacement.displ32 = (Bit8s) fetch_byte();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
resolve_modrm = &disassembler::resolve64_mod1or2_rm4;
|
|
||||||
insn->displacement.displ32 = fetch_dword();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} /* s-i-b byte follows */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (insn->as_32)
|
|
||||||
{
|
|
||||||
if (insn->rm != 4) { /* rm != 100b, no s-i-b byte */
|
|
||||||
insn->rm |= insn->rex_b;
|
|
||||||
// one byte modrm
|
|
||||||
switch (insn->mod) {
|
|
||||||
case 0:
|
|
||||||
resolve_modrm = &disassembler::resolve32_mod0;
|
|
||||||
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
|
||||||
insn->displacement.displ32 = fetch_dword();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* reg, 8-bit displacement, sign extend */
|
|
||||||
resolve_modrm = &disassembler::resolve32_mod1or2;
|
|
||||||
insn->displacement.displ32 = (Bit8s) fetch_byte();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* reg, 32-bit displacement */
|
|
||||||
resolve_modrm = &disassembler::resolve32_mod1or2;
|
|
||||||
insn->displacement.displ32 = fetch_dword();
|
|
||||||
break;
|
|
||||||
} /* switch (mod) */
|
|
||||||
} /* if (rm != 4) */
|
|
||||||
else { /* rm == 4, s-i-b byte follows */
|
|
||||||
insn->sib = fetch_byte();
|
|
||||||
BX_DECODE_SIB(insn->sib, insn->scale, insn->index, insn->base);
|
|
||||||
insn->base |= insn->rex_b;
|
|
||||||
insn->index |= insn->rex_x;
|
|
||||||
|
|
||||||
switch (insn->mod) {
|
|
||||||
case 0:
|
|
||||||
resolve_modrm = &disassembler::resolve32_mod0_rm4;
|
|
||||||
if ((insn->base & 7) == 5)
|
|
||||||
insn->displacement.displ32 = fetch_dword();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
|
|
||||||
insn->displacement.displ32 = (Bit8s) fetch_byte();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
|
|
||||||
insn->displacement.displ32 = fetch_dword();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} /* s-i-b byte follows */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(insn->rex_b == 0);
|
|
||||||
assert(insn->rex_x == 0);
|
|
||||||
assert(insn->rex_r == 0);
|
|
||||||
/* 16 bit addressing modes. */
|
|
||||||
switch (insn->mod) {
|
|
||||||
case 0:
|
|
||||||
resolve_modrm = &disassembler::resolve16_mod0;
|
|
||||||
if(insn->rm == 6)
|
|
||||||
insn->displacement.displ16 = fetch_word();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* reg, 8-bit displacement, sign extend */
|
|
||||||
resolve_modrm = &disassembler::resolve16_mod1or2;
|
|
||||||
insn->displacement.displ16 = (Bit8s) fetch_byte();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
resolve_modrm = &disassembler::resolve16_mod1or2;
|
|
||||||
insn->displacement.displ16 = fetch_word();
|
|
||||||
break;
|
|
||||||
} /* switch (mod) ... */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve16_mod0(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = sreg_mod00_rm16[insn->rm];
|
|
||||||
|
|
||||||
if(insn->rm == 6)
|
|
||||||
print_memory_access16(mode, seg, NULL, insn->displacement.displ16);
|
|
||||||
else
|
|
||||||
print_memory_access16(mode, seg, index16[insn->rm], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve16_mod1or2(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = sreg_mod01or10_rm16[insn->rm];
|
|
||||||
|
|
||||||
print_memory_access16(mode, seg, index16[insn->rm], insn->displacement.displ16);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve32_mod0(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = segment_name[DS_REG];
|
|
||||||
|
|
||||||
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
|
||||||
print_memory_access(mode, seg, NULL, NULL, 0, insn->displacement.displ32);
|
|
||||||
else
|
|
||||||
print_memory_access(mode, seg, general_32bit_regname[insn->rm], NULL, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve32_mod1or2(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = sreg_mod01or10_rm32[insn->rm];
|
|
||||||
|
|
||||||
print_memory_access(mode, seg,
|
|
||||||
general_32bit_regname[insn->rm], NULL, 0, insn->displacement.displ32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve32_mod0_rm4(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg, *base = NULL, *index = NULL;
|
|
||||||
Bit32u disp32 = 0;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = sreg_mod00_base32[insn->base];
|
|
||||||
|
|
||||||
if ((insn->base & 7) != 5)
|
|
||||||
base = general_32bit_regname[insn->base];
|
|
||||||
else
|
|
||||||
disp32 = insn->displacement.displ32;
|
|
||||||
|
|
||||||
if (insn->index != 4)
|
|
||||||
index = general_32bit_regname[insn->index];
|
|
||||||
|
|
||||||
print_memory_access(mode, seg, base, index, insn->scale, disp32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg, *index = NULL;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = sreg_mod01or10_base32[insn->base];
|
|
||||||
|
|
||||||
if (insn->index != 4)
|
|
||||||
index = general_32bit_regname[insn->index];
|
|
||||||
|
|
||||||
print_memory_access(mode, seg,
|
|
||||||
general_32bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve64_mod0(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg, *rip_regname;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = segment_name[DS_REG];
|
|
||||||
|
|
||||||
if (intel_mode) rip_regname = "rip";
|
|
||||||
else rip_regname = "%rip";
|
|
||||||
|
|
||||||
if ((insn->rm & 7) == 5) /* no reg, 32-bit displacement */
|
|
||||||
print_memory_access(mode, seg, rip_regname, NULL, 0, insn->displacement.displ32);
|
|
||||||
else
|
|
||||||
print_memory_access(mode, seg, general_64bit_regname[insn->rm], NULL, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve64_mod1or2(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = sreg_mod01or10_rm32[insn->rm];
|
|
||||||
|
|
||||||
print_memory_access(mode, seg,
|
|
||||||
general_64bit_regname[insn->rm], NULL, 0, insn->displacement.displ32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg, *base = NULL, *index = NULL;
|
|
||||||
Bit32u disp32 = 0;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = sreg_mod00_base32[insn->base];
|
|
||||||
|
|
||||||
if ((insn->base & 7) != 5)
|
|
||||||
base = general_64bit_regname[insn->base];
|
|
||||||
else
|
|
||||||
disp32 = insn->displacement.displ32;
|
|
||||||
|
|
||||||
if (insn->index != 4)
|
|
||||||
index = general_64bit_regname[insn->index];
|
|
||||||
|
|
||||||
print_memory_access(mode, seg, base, index, insn->scale, disp32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode)
|
|
||||||
{
|
|
||||||
const char *seg, *index = NULL;
|
|
||||||
|
|
||||||
if (insn->is_seg_override())
|
|
||||||
seg = segment_name[insn->seg_override];
|
|
||||||
else
|
|
||||||
seg = sreg_mod01or10_base32[insn->base];
|
|
||||||
|
|
||||||
if (insn->index != 4)
|
|
||||||
index = general_64bit_regname[insn->index];
|
|
||||||
|
|
||||||
print_memory_access(mode, seg,
|
|
||||||
general_64bit_regname[insn->base], index, insn->scale, insn->displacement.displ32);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::print_datasize(unsigned size)
|
|
||||||
{
|
|
||||||
if (!intel_mode) return;
|
|
||||||
|
|
||||||
switch(size)
|
|
||||||
{
|
|
||||||
case B_SIZE:
|
|
||||||
dis_sprintf("byte ptr ");
|
|
||||||
break;
|
|
||||||
case W_SIZE:
|
|
||||||
dis_sprintf("word ptr ");
|
|
||||||
break;
|
|
||||||
case D_SIZE:
|
|
||||||
dis_sprintf("dword ptr ");
|
|
||||||
break;
|
|
||||||
case Q_SIZE:
|
|
||||||
dis_sprintf("qword ptr ");
|
|
||||||
break;
|
|
||||||
case O_SIZE:
|
|
||||||
dis_sprintf("dqword ptr ");
|
|
||||||
break;
|
|
||||||
case T_SIZE:
|
|
||||||
dis_sprintf("tbyte ptr ");
|
|
||||||
break;
|
|
||||||
case P_SIZE:
|
|
||||||
break;
|
|
||||||
case X_SIZE:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::print_memory_access16(int datasize,
|
|
||||||
const char *seg, const char *index, Bit16u disp)
|
|
||||||
{
|
|
||||||
print_datasize(datasize);
|
|
||||||
|
|
||||||
if (intel_mode)
|
|
||||||
{
|
|
||||||
if (index == NULL)
|
|
||||||
{
|
|
||||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:[%s]", seg, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (index == NULL)
|
|
||||||
{
|
|
||||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:0x%x(%s,1)", seg, (unsigned) disp, index);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:(%s,1)", seg, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void disassembler::print_memory_access(int datasize,
|
|
||||||
const char *seg, const char *base, const char *index, int scale, Bit32u disp)
|
|
||||||
{
|
|
||||||
print_datasize(datasize);
|
|
||||||
|
|
||||||
if (intel_mode)
|
|
||||||
{
|
|
||||||
if (base == NULL)
|
|
||||||
{
|
|
||||||
if (index == NULL)
|
|
||||||
{
|
|
||||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (scale != 0)
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:[%s*%d+0x%x]", seg, index, 1<<scale, (unsigned) disp);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:[%s*%d]", seg, index, 1<<scale);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:[%s]", seg, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (index == NULL)
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:[%s+0x%x]", seg, base, (unsigned) disp);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:[%s]", seg, base);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (scale != 0)
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:[%s+%s*%d+0x%x]", seg, base, index, 1<<scale, (unsigned) disp);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:[%s+%s*%d]", seg, base, index, 1<<scale);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:[%s+%s+0x%x]", seg, base, index, (unsigned) disp);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:[%s+%s]", seg, base, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (base == NULL)
|
|
||||||
{
|
|
||||||
if (index == NULL)
|
|
||||||
{
|
|
||||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:0x%x(,%s,%d)", seg, (unsigned) disp, index, 1<<scale);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:(,%s,%d)", seg, index, 1<<scale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (index == NULL)
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:0x%x(%s)", seg, (unsigned) disp, base);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:(%s)", seg, base);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (disp != 0)
|
|
||||||
dis_sprintf("%s:0x%x(%s,%s,%d)", seg, (unsigned) disp, base, index, 1<<scale);
|
|
||||||
else
|
|
||||||
dis_sprintf("%s:(%s,%s,%d)", seg, base, index, 1<<scale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,26 @@
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: syntax.cc,v 1.10 2006/04/27 15:11:45 sshwarts Exp $
|
// $Id: syntax.cc 11968 2013-11-29 20:49:20Z sshwarts $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2005-2011 Stanislav Shwartsman
|
||||||
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "disasm.h"
|
#include "disasm.h"
|
||||||
|
|
||||||
|
@ -8,10 +28,6 @@
|
||||||
// Intel STYLE
|
// Intel STYLE
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
#define BX_DISASM_SUPPORT_X86_64
|
|
||||||
|
|
||||||
#ifdef BX_DISASM_SUPPORT_X86_64
|
|
||||||
|
|
||||||
static const char *intel_general_16bit_regname[16] = {
|
static const char *intel_general_16bit_regname[16] = {
|
||||||
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
|
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
|
||||||
"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
|
"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
|
||||||
|
@ -32,18 +48,6 @@ static const char *intel_general_8bit_regname_rex[16] = {
|
||||||
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
|
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static const char *intel_general_16bit_regname[8] = {
|
|
||||||
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *intel_general_32bit_regname[8] = {
|
|
||||||
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *intel_general_8bit_regname[8] = {
|
static const char *intel_general_8bit_regname[8] = {
|
||||||
"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
|
"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
|
||||||
};
|
};
|
||||||
|
@ -53,23 +57,24 @@ static const char *intel_segment_name[8] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *intel_index16[8] = {
|
static const char *intel_index16[8] = {
|
||||||
"bx+si",
|
"bx+si",
|
||||||
"bx+di",
|
"bx+di",
|
||||||
"bp+si",
|
"bp+si",
|
||||||
"bp+di",
|
"bp+di",
|
||||||
"si",
|
"si",
|
||||||
"di",
|
"di",
|
||||||
"bp",
|
"bp",
|
||||||
"bx"
|
"bx"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *intel_vector_reg_name[4] = {
|
||||||
|
"xmm", "ymm", "???", "zmm"
|
||||||
|
};
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// AT&T STYLE
|
// AT&T STYLE
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
#ifdef BX_DISASM_SUPPORT_X86_64
|
|
||||||
|
|
||||||
static const char *att_general_16bit_regname[16] = {
|
static const char *att_general_16bit_regname[16] = {
|
||||||
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
|
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
|
||||||
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
|
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
|
||||||
|
@ -90,18 +95,6 @@ static const char *att_general_8bit_regname_rex[16] = {
|
||||||
"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
|
"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static const char *att_general_16bit_regname[8] = {
|
|
||||||
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *att_general_32bit_regname[8] = {
|
|
||||||
"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *att_general_8bit_regname[8] = {
|
static const char *att_general_8bit_regname[8] = {
|
||||||
"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh"
|
"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh"
|
||||||
};
|
};
|
||||||
|
@ -111,16 +104,20 @@ static const char *att_segment_name[8] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *att_index16[8] = {
|
static const char *att_index16[8] = {
|
||||||
"%bx, %si",
|
"%bx,%si",
|
||||||
"%bx, %di",
|
"%bx,%di",
|
||||||
"%bp, %si",
|
"%bp,%si",
|
||||||
"%bp, %di",
|
"%bp,%di",
|
||||||
"%si",
|
"%si",
|
||||||
"%di",
|
"%di",
|
||||||
"%bp",
|
"%bp",
|
||||||
"%bx"
|
"%bx"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *att_vector_reg_name[4] = {
|
||||||
|
"%xmm", "%ymm", "%???", "%zmm"
|
||||||
|
};
|
||||||
|
|
||||||
#define NULL_SEGMENT_REGISTER 7
|
#define NULL_SEGMENT_REGISTER 7
|
||||||
|
|
||||||
void disassembler::initialize_modrm_segregs()
|
void disassembler::initialize_modrm_segregs()
|
||||||
|
@ -143,32 +140,39 @@ void disassembler::initialize_modrm_segregs()
|
||||||
sreg_mod01or10_rm16[6] = segment_name[SS_REG];
|
sreg_mod01or10_rm16[6] = segment_name[SS_REG];
|
||||||
sreg_mod01or10_rm16[7] = segment_name[DS_REG];
|
sreg_mod01or10_rm16[7] = segment_name[DS_REG];
|
||||||
|
|
||||||
sreg_mod01or10_rm32[0] = segment_name[DS_REG];
|
sreg_mod00_base32[0] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_rm32[1] = segment_name[DS_REG];
|
sreg_mod00_base32[1] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_rm32[2] = segment_name[DS_REG];
|
sreg_mod00_base32[2] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_rm32[3] = segment_name[DS_REG];
|
sreg_mod00_base32[3] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_rm32[4] = segment_name[NULL_SEGMENT_REGISTER];
|
sreg_mod00_base32[4] = segment_name[SS_REG];
|
||||||
sreg_mod01or10_rm32[5] = segment_name[SS_REG];
|
sreg_mod00_base32[5] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_rm32[6] = segment_name[DS_REG];
|
sreg_mod00_base32[6] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_rm32[7] = segment_name[DS_REG];
|
sreg_mod00_base32[7] = segment_name[DS_REG];
|
||||||
|
sreg_mod00_base32[8] = segment_name[DS_REG];
|
||||||
|
sreg_mod00_base32[9] = segment_name[DS_REG];
|
||||||
|
sreg_mod00_base32[10] = segment_name[DS_REG];
|
||||||
|
sreg_mod00_base32[11] = segment_name[DS_REG];
|
||||||
|
sreg_mod00_base32[12] = segment_name[DS_REG];
|
||||||
|
sreg_mod00_base32[13] = segment_name[DS_REG];
|
||||||
|
sreg_mod00_base32[14] = segment_name[DS_REG];
|
||||||
|
sreg_mod00_base32[15] = segment_name[DS_REG];
|
||||||
|
|
||||||
sreg_mod00_base32[0] = segment_name[DS_REG];
|
sreg_mod01or10_base32[0] = segment_name[DS_REG];
|
||||||
sreg_mod00_base32[1] = segment_name[DS_REG];
|
sreg_mod01or10_base32[1] = segment_name[DS_REG];
|
||||||
sreg_mod00_base32[2] = segment_name[DS_REG];
|
sreg_mod01or10_base32[2] = segment_name[DS_REG];
|
||||||
sreg_mod00_base32[3] = segment_name[DS_REG];
|
sreg_mod01or10_base32[3] = segment_name[DS_REG];
|
||||||
sreg_mod00_base32[4] = segment_name[SS_REG];
|
sreg_mod01or10_base32[4] = segment_name[SS_REG];
|
||||||
sreg_mod00_base32[5] = segment_name[DS_REG];
|
sreg_mod01or10_base32[5] = segment_name[SS_REG];
|
||||||
sreg_mod00_base32[6] = segment_name[DS_REG];
|
sreg_mod01or10_base32[6] = segment_name[DS_REG];
|
||||||
sreg_mod00_base32[7] = segment_name[DS_REG];
|
sreg_mod01or10_base32[7] = segment_name[DS_REG];
|
||||||
|
sreg_mod01or10_base32[8] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_base32[0] = segment_name[DS_REG];
|
sreg_mod01or10_base32[9] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_base32[1] = segment_name[DS_REG];
|
sreg_mod01or10_base32[10] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_base32[2] = segment_name[DS_REG];
|
sreg_mod01or10_base32[11] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_base32[3] = segment_name[DS_REG];
|
sreg_mod01or10_base32[12] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_base32[4] = segment_name[SS_REG];
|
sreg_mod01or10_base32[13] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_base32[5] = segment_name[SS_REG];
|
sreg_mod01or10_base32[14] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_base32[6] = segment_name[DS_REG];
|
sreg_mod01or10_base32[15] = segment_name[DS_REG];
|
||||||
sreg_mod01or10_base32[7] = segment_name[DS_REG];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
|
@ -187,6 +191,7 @@ void disassembler::set_syntax_intel()
|
||||||
|
|
||||||
segment_name = intel_segment_name;
|
segment_name = intel_segment_name;
|
||||||
index16 = intel_index16;
|
index16 = intel_index16;
|
||||||
|
vector_reg_name = intel_vector_reg_name;
|
||||||
|
|
||||||
initialize_modrm_segregs();
|
initialize_modrm_segregs();
|
||||||
}
|
}
|
||||||
|
@ -207,12 +212,16 @@ void disassembler::print_disassembly_intel(const x86_insn *insn, const BxDisasmO
|
||||||
dis_sprintf(", ");
|
dis_sprintf(", ");
|
||||||
(this->*entry->Operand3)(insn);
|
(this->*entry->Operand3)(insn);
|
||||||
}
|
}
|
||||||
|
if (entry->Operand4) {
|
||||||
|
dis_sprintf(", ");
|
||||||
|
(this->*entry->Operand4)(insn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// AT&T STYLE
|
// AT&T STYLE
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
void disassembler::set_syntax_att()
|
void disassembler::set_syntax_att()
|
||||||
{
|
{
|
||||||
intel_mode = 0;
|
intel_mode = 0;
|
||||||
|
@ -225,6 +234,7 @@ void disassembler::set_syntax_att()
|
||||||
|
|
||||||
segment_name = att_segment_name;
|
segment_name = att_segment_name;
|
||||||
index16 = att_index16;
|
index16 = att_index16;
|
||||||
|
vector_reg_name = att_vector_reg_name;
|
||||||
|
|
||||||
initialize_modrm_segregs();
|
initialize_modrm_segregs();
|
||||||
}
|
}
|
||||||
|
@ -240,7 +250,11 @@ void disassembler::print_disassembly_att(const x86_insn *insn, const BxDisasmOpc
|
||||||
// print opcode
|
// print opcode
|
||||||
dis_sprintf("%s ", entry->AttOpcode);
|
dis_sprintf("%s ", entry->AttOpcode);
|
||||||
|
|
||||||
if (entry->Operand3) {
|
if (entry->Operand4) {
|
||||||
|
(this->*entry->Operand4)(insn);
|
||||||
|
dis_sprintf(", ");
|
||||||
|
}
|
||||||
|
if (entry->Operand3) {
|
||||||
(this->*entry->Operand3)(insn);
|
(this->*entry->Operand3)(insn);
|
||||||
dis_sprintf(", ");
|
dis_sprintf(", ");
|
||||||
}
|
}
|
Loading…
Reference in New Issue