Fail* directories reorganized, Code-cleanup (-> coding-style), Typos+comments fixed.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1321 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
81
simulators/bochs/disasm/Makefile.in
Normal file
81
simulators/bochs/disasm/Makefile.in
Normal file
@ -0,0 +1,81 @@
|
||||
# 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 = /bin/sh
|
||||
|
||||
@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_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
|
||||
369
simulators/bochs/disasm/dis_decode.cc
Normal file
369
simulators/bochs/disasm/dis_decode.cc
Normal file
@ -0,0 +1,369 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005-2009 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 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)
|
||||
{
|
||||
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_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_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 (instruction_has_modrm[insn.b1])
|
||||
{
|
||||
// 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 _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 _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]);
|
||||
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) {
|
||||
const BxDisasmOpcodeTable_t *prefix = &(opcode_table[prefix_byte]);
|
||||
dis_sprintf("%s ", OPCODE(prefix)->IntelOpcode);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
722
simulators/bochs/disasm/dis_groups.cc
Normal file
722
simulators/bochs/disasm/dis_groups.cc
Normal file
@ -0,0 +1,722 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005-2009 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"
|
||||
|
||||
/*
|
||||
#if BX_DEBUGGER
|
||||
#include "../bx_debug/debug.h"
|
||||
#endif
|
||||
*/
|
||||
|
||||
void disassembler::Apw(const x86_insn *insn)
|
||||
{
|
||||
Bit16u imm16 = fetch_word();
|
||||
Bit16u cs_selector = fetch_word();
|
||||
dis_sprintf("%04x:%04x", (unsigned) cs_selector, (unsigned) imm16);
|
||||
}
|
||||
|
||||
void disassembler::Apd(const x86_insn *insn)
|
||||
{
|
||||
Bit32u imm32 = fetch_dword();
|
||||
Bit16u cs_selector = fetch_word();
|
||||
dis_sprintf("%04x:%08x", (unsigned) cs_selector, (unsigned) imm32);
|
||||
}
|
||||
|
||||
// 8-bit general purpose registers
|
||||
void disassembler::AL_Reg(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rAX_REG]); }
|
||||
void disassembler::CL_Reg(const x86_insn *insn) { dis_sprintf("%s", general_8bit_regname[rCX_REG]); }
|
||||
|
||||
// 16-bit general purpose registers
|
||||
void disassembler::AX_Reg(const x86_insn *insn) {
|
||||
dis_sprintf("%s", general_16bit_regname[rAX_REG]);
|
||||
}
|
||||
|
||||
void disassembler::DX_Reg(const x86_insn *insn) {
|
||||
dis_sprintf("%s", general_16bit_regname[rDX_REG]);
|
||||
}
|
||||
|
||||
// 32-bit general purpose registers
|
||||
void disassembler::EAX_Reg(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_32bit_regname[rAX_REG]);
|
||||
}
|
||||
|
||||
// 64-bit general purpose registers
|
||||
void disassembler::RAX_Reg(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_64bit_regname[rAX_REG]);
|
||||
}
|
||||
|
||||
// segment registers
|
||||
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::ES(const x86_insn *insn) { dis_sprintf("%s", segment_name[ES_REG]); }
|
||||
void disassembler::SS(const x86_insn *insn) { dis_sprintf("%s", segment_name[SS_REG]); }
|
||||
void disassembler::FS(const x86_insn *insn) { dis_sprintf("%s", segment_name[FS_REG]); }
|
||||
void disassembler::GS(const x86_insn *insn) { dis_sprintf("%s", segment_name[GS_REG]); }
|
||||
|
||||
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
|
||||
void disassembler::Cd(const x86_insn *insn)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("cr%d", insn->nnn);
|
||||
else
|
||||
dis_sprintf("%%cr%d", insn->nnn);
|
||||
}
|
||||
|
||||
void disassembler::Cq(const x86_insn *insn) { Cd(insn); }
|
||||
|
||||
// debug register
|
||||
void disassembler::Dd(const x86_insn *insn)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("dr%d", insn->nnn);
|
||||
else
|
||||
dis_sprintf("%%dr%d", insn->nnn);
|
||||
}
|
||||
|
||||
void disassembler::Dq(const x86_insn *insn) { Dd(insn); }
|
||||
|
||||
// 8-bit general purpose register
|
||||
void disassembler::Reg8(const x86_insn *insn)
|
||||
{
|
||||
unsigned reg = (insn->b1 & 7) | insn->rex_b;
|
||||
|
||||
if (reg < 4 || insn->extend8b)
|
||||
dis_sprintf("%s", general_8bit_regname_rex[reg]);
|
||||
else
|
||||
dis_sprintf("%s", general_8bit_regname[reg]);
|
||||
}
|
||||
|
||||
// 16-bit general purpose register
|
||||
void disassembler::RX(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_16bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
||||
}
|
||||
|
||||
// 32-bit general purpose register
|
||||
void disassembler::ERX(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_32bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
||||
}
|
||||
|
||||
// 64-bit general purpose register
|
||||
void disassembler::RRX(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_64bit_regname[(insn->b1 & 7) | insn->rex_b]);
|
||||
}
|
||||
|
||||
// general purpose register or memory operand
|
||||
void disassembler::Eb(const x86_insn *insn)
|
||||
{
|
||||
if (insn->mod == 3) {
|
||||
if (insn->rm < 4 || insn->extend8b)
|
||||
dis_sprintf("%s", general_8bit_regname_rex[insn->rm]);
|
||||
else
|
||||
dis_sprintf("%s", general_8bit_regname[insn->rm]);
|
||||
}
|
||||
else
|
||||
(this->*resolve_modrm)(insn, B_SIZE);
|
||||
}
|
||||
|
||||
void disassembler::Ew(const x86_insn *insn)
|
||||
{
|
||||
if (insn->mod == 3)
|
||||
dis_sprintf("%s", general_16bit_regname[insn->rm]);
|
||||
else
|
||||
(this->*resolve_modrm)(insn, W_SIZE);
|
||||
}
|
||||
|
||||
void disassembler::Ed(const x86_insn *insn)
|
||||
{
|
||||
if (insn->mod == 3)
|
||||
dis_sprintf("%s", general_32bit_regname[insn->rm]);
|
||||
else
|
||||
(this->*resolve_modrm)(insn, D_SIZE);
|
||||
}
|
||||
|
||||
void disassembler::Eq(const x86_insn *insn)
|
||||
{
|
||||
if (insn->mod == 3)
|
||||
dis_sprintf("%s", general_64bit_regname[insn->rm]);
|
||||
else
|
||||
(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
|
||||
void disassembler::Gb(const x86_insn *insn)
|
||||
{
|
||||
if (insn->nnn < 4 || insn->extend8b)
|
||||
dis_sprintf("%s", general_8bit_regname_rex[insn->nnn]);
|
||||
else
|
||||
dis_sprintf("%s", general_8bit_regname[insn->nnn]);
|
||||
}
|
||||
|
||||
void disassembler::Gw(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_16bit_regname[insn->nnn]);
|
||||
}
|
||||
|
||||
void disassembler::Gd(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_32bit_regname[insn->nnn]);
|
||||
}
|
||||
|
||||
void disassembler::Gq(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_64bit_regname[insn->nnn]);
|
||||
}
|
||||
|
||||
void disassembler::Gy(const x86_insn *insn)
|
||||
{
|
||||
if (insn->os_64) Gq(insn);
|
||||
else Gd(insn);
|
||||
}
|
||||
|
||||
// immediate
|
||||
void disassembler::I1(const x86_insn *insn)
|
||||
{
|
||||
if (! intel_mode) dis_putc('$');
|
||||
dis_putc ('1');
|
||||
}
|
||||
|
||||
void disassembler::Ib(const x86_insn *insn)
|
||||
{
|
||||
if (! intel_mode) dis_putc('$');
|
||||
dis_sprintf("0x%02x", (unsigned) fetch_byte());
|
||||
}
|
||||
|
||||
void disassembler::Iw(const x86_insn *insn)
|
||||
{
|
||||
if (! intel_mode) dis_putc('$');
|
||||
dis_sprintf("0x%04x", (unsigned) fetch_word());
|
||||
}
|
||||
|
||||
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();
|
||||
Bit8u ib = fetch_byte();
|
||||
|
||||
if (intel_mode) {
|
||||
dis_sprintf("0x%04x, 0x%02x", iw, ib);
|
||||
}
|
||||
else {
|
||||
dis_sprintf("$0x%02x, $0x%04x", ib, iw);
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::Id(const x86_insn *insn)
|
||||
{
|
||||
if (! intel_mode) dis_putc('$');
|
||||
dis_sprintf("0x%08x", (unsigned) fetch_dword());
|
||||
}
|
||||
|
||||
void disassembler::Iq(const x86_insn *insn)
|
||||
{
|
||||
Bit64u value = fetch_qword();
|
||||
|
||||
if (! intel_mode) dis_putc('$');
|
||||
dis_sprintf("0x%08x%08x", GET32H(value), GET32L(value));
|
||||
}
|
||||
|
||||
// sign extended immediate
|
||||
void disassembler::sIbw(const x86_insn *insn)
|
||||
{
|
||||
if (! intel_mode) dis_putc('$');
|
||||
Bit16u imm16 = (Bit8s) fetch_byte();
|
||||
dis_sprintf("0x%04x", (unsigned) imm16);
|
||||
}
|
||||
|
||||
// sign extended immediate
|
||||
void disassembler::sIbd(const x86_insn *insn)
|
||||
{
|
||||
if (! intel_mode) dis_putc('$');
|
||||
Bit32u imm32 = (Bit8s) fetch_byte();
|
||||
dis_sprintf ("0x%08x", (unsigned) imm32);
|
||||
}
|
||||
|
||||
// sign extended immediate
|
||||
void disassembler::sIbq(const x86_insn *insn)
|
||||
{
|
||||
if (! intel_mode) dis_putc('$');
|
||||
Bit64u imm64 = (Bit8s) fetch_byte();
|
||||
dis_sprintf ("0x%08x%08x", GET32H(imm64), GET32L(imm64));
|
||||
}
|
||||
|
||||
// sign extended immediate
|
||||
void disassembler::sIdq(const x86_insn *insn)
|
||||
{
|
||||
if (! intel_mode) dis_putc('$');
|
||||
Bit64u imm64 = (Bit32s) fetch_dword();
|
||||
dis_sprintf ("0x%08x%08x", GET32H(imm64), GET32L(imm64));
|
||||
}
|
||||
|
||||
// floating point
|
||||
void disassembler::ST0(const x86_insn *insn)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("st(0)");
|
||||
else
|
||||
dis_sprintf("%%st(0)");
|
||||
}
|
||||
|
||||
void disassembler::STi(const x86_insn *insn)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("st(%d)", insn->rm & 7);
|
||||
else
|
||||
dis_sprintf("%%st(%d)", insn->rm & 7);
|
||||
}
|
||||
|
||||
// 16-bit general purpose register
|
||||
void disassembler::Rw(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_16bit_regname[insn->rm]);
|
||||
}
|
||||
|
||||
// 32-bit general purpose register
|
||||
void disassembler::Rd(const x86_insn *insn)
|
||||
{
|
||||
dis_sprintf("%s", general_32bit_regname[insn->rm]);
|
||||
}
|
||||
|
||||
// 64-bit general purpose register
|
||||
void disassembler::Rq(const x86_insn *insn)
|
||||
{
|
||||
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
|
||||
void disassembler::Pq(const x86_insn *insn)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("mm%d", insn->nnn & 0x7);
|
||||
else
|
||||
dis_sprintf("%%mm%d", insn->nnn & 0x7);
|
||||
}
|
||||
|
||||
void disassembler::Nq(const x86_insn *insn)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("mm%d", insn->rm & 0x7);
|
||||
else
|
||||
dis_sprintf("%%mm%d", insn->rm & 0x7);
|
||||
}
|
||||
|
||||
void disassembler::Qd(const x86_insn *insn)
|
||||
{
|
||||
if (insn->mod == 3)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("mm%d", insn->rm & 0x7);
|
||||
else
|
||||
dis_sprintf("%%mm%d", insn->rm & 0x7);
|
||||
}
|
||||
else
|
||||
(this->*resolve_modrm)(insn, D_SIZE);
|
||||
}
|
||||
|
||||
void disassembler::Qq(const x86_insn *insn)
|
||||
{
|
||||
if (insn->mod == 3)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("mm%d", insn->rm & 0x7);
|
||||
else
|
||||
dis_sprintf("%%mm%d", insn->rm & 0x7);
|
||||
}
|
||||
else
|
||||
(this->*resolve_modrm)(insn, Q_SIZE);
|
||||
}
|
||||
|
||||
// xmm register
|
||||
void disassembler::Udq(const x86_insn *insn)
|
||||
{
|
||||
if (intel_mode)
|
||||
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::Vq(const x86_insn *insn)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("xmm%d", insn->nnn);
|
||||
else
|
||||
dis_sprintf("%%xmm%d", insn->nnn);
|
||||
}
|
||||
|
||||
void disassembler::Vdq(const x86_insn *insn) { Vq(insn); }
|
||||
void disassembler::Vss(const x86_insn *insn) { Vq(insn); }
|
||||
void disassembler::Vsd(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::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)
|
||||
{
|
||||
if (insn->mod == 3) Udq(insn);
|
||||
else
|
||||
(this->*resolve_modrm)(insn, Q_SIZE);
|
||||
}
|
||||
|
||||
void disassembler::Wdq(const x86_insn *insn)
|
||||
{
|
||||
if (insn->mod == 3) Udq(insn);
|
||||
else
|
||||
(this->*resolve_modrm)(insn, O_SIZE);
|
||||
}
|
||||
|
||||
void disassembler::Wsd(const x86_insn *insn) { Wq(insn); }
|
||||
void disassembler::Wss(const x86_insn *insn) { Wd(insn); }
|
||||
void disassembler::Wpd(const x86_insn *insn) { Wdq(insn); }
|
||||
void disassembler::Wps(const x86_insn *insn) { Wdq(insn); }
|
||||
|
||||
// direct memory access
|
||||
void disassembler::OP_O(const x86_insn *insn, unsigned size)
|
||||
{
|
||||
const char *seg;
|
||||
|
||||
if (insn->is_seg_override())
|
||||
seg = segment_name[insn->seg_override];
|
||||
else
|
||||
seg = segment_name[DS_REG];
|
||||
|
||||
print_datasize(size);
|
||||
|
||||
if (insn->as_64) {
|
||||
Bit64u imm64 = fetch_qword();
|
||||
dis_sprintf("%s:0x%08x%08x", seg, GET32H(imm64), GET32L(imm64));
|
||||
}
|
||||
else if (insn->as_32) {
|
||||
Bit32u imm32 = fetch_dword();
|
||||
dis_sprintf("%s:0x%x", seg, (unsigned) imm32);
|
||||
}
|
||||
else {
|
||||
Bit16u imm16 = fetch_word();
|
||||
dis_sprintf("%s:0x%x", seg, (unsigned) imm16);
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::Ob(const x86_insn *insn) { OP_O(insn, B_SIZE); }
|
||||
void disassembler::Ow(const x86_insn *insn) { OP_O(insn, W_SIZE); }
|
||||
void disassembler::Od(const x86_insn *insn) { OP_O(insn, D_SIZE); }
|
||||
void disassembler::Oq(const x86_insn *insn) { OP_O(insn, Q_SIZE); }
|
||||
|
||||
// memory operand
|
||||
void disassembler::OP_M(const x86_insn *insn, unsigned size)
|
||||
{
|
||||
if(insn->mod == 3)
|
||||
dis_sprintf("(bad)");
|
||||
else
|
||||
(this->*resolve_modrm)(insn, size);
|
||||
}
|
||||
|
||||
void disassembler::Ma(const x86_insn *insn) { OP_M(insn, X_SIZE); }
|
||||
void disassembler::Mp(const x86_insn *insn) { OP_M(insn, X_SIZE); }
|
||||
void disassembler::Ms(const x86_insn *insn) { OP_M(insn, X_SIZE); }
|
||||
void disassembler::Mx(const x86_insn *insn) { OP_M(insn, X_SIZE); }
|
||||
|
||||
void disassembler::Mb(const x86_insn *insn) { OP_M(insn, B_SIZE); }
|
||||
void disassembler::Mw(const x86_insn *insn) { OP_M(insn, W_SIZE); }
|
||||
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::Mt(const x86_insn *insn) { OP_M(insn, T_SIZE); }
|
||||
|
||||
void disassembler::Mdq(const x86_insn *insn) { OP_M(insn, O_SIZE); }
|
||||
void disassembler::Mps(const x86_insn *insn) { OP_M(insn, O_SIZE); }
|
||||
void disassembler::Mpd(const x86_insn *insn) { OP_M(insn, O_SIZE); }
|
||||
void disassembler::Mss(const x86_insn *insn) { OP_M(insn, D_SIZE); }
|
||||
void disassembler::Msd(const x86_insn *insn) { OP_M(insn, Q_SIZE); }
|
||||
|
||||
// string instructions
|
||||
void disassembler::OP_X(const x86_insn *insn, unsigned size)
|
||||
{
|
||||
const char *rsi, *seg;
|
||||
|
||||
if (insn->as_64) {
|
||||
rsi = general_64bit_regname[rSI_REG];
|
||||
}
|
||||
else {
|
||||
if (insn->as_32)
|
||||
rsi = general_32bit_regname[rSI_REG];
|
||||
else
|
||||
rsi = general_16bit_regname[rSI_REG];
|
||||
}
|
||||
|
||||
if (insn->is_seg_override())
|
||||
seg = segment_name[insn->seg_override];
|
||||
else
|
||||
seg = segment_name[DS_REG];
|
||||
|
||||
print_datasize(size);
|
||||
|
||||
if (intel_mode)
|
||||
dis_sprintf("%s:[%s]", seg, rsi);
|
||||
else
|
||||
dis_sprintf("%s:(%s)", seg, rsi);
|
||||
}
|
||||
|
||||
void disassembler::Xb(const x86_insn *insn) { OP_X(insn, B_SIZE); }
|
||||
void disassembler::Xw(const x86_insn *insn) { OP_X(insn, W_SIZE); }
|
||||
void disassembler::Xd(const x86_insn *insn) { OP_X(insn, D_SIZE); }
|
||||
void disassembler::Xq(const x86_insn *insn) { OP_X(insn, Q_SIZE); }
|
||||
|
||||
void disassembler::OP_Y(const x86_insn *insn, unsigned size)
|
||||
{
|
||||
const char *rdi;
|
||||
|
||||
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 (intel_mode)
|
||||
dis_sprintf("%s:[%s]", segment_name[ES_REG], rdi);
|
||||
else
|
||||
dis_sprintf("%s:(%s)", segment_name[ES_REG], rdi);
|
||||
}
|
||||
|
||||
void disassembler::Yb(const x86_insn *insn) { OP_Y(insn, B_SIZE); }
|
||||
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::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, O_SIZE); }
|
||||
|
||||
#define BX_JUMP_TARGET_NOT_REQ ((bx_address)(-1))
|
||||
|
||||
// jump offset
|
||||
void disassembler::Jb(const x86_insn *insn)
|
||||
{
|
||||
Bit8s imm8 = (Bit8s) fetch_byte();
|
||||
|
||||
if (insn->is_64) {
|
||||
Bit64u imm64 = (Bit8s) imm8;
|
||||
|
||||
if (offset_mode_hex) {
|
||||
dis_sprintf(".+0x%08x%08x", GET32H(imm64), GET32L(imm64));
|
||||
}
|
||||
else {
|
||||
dis_sprintf(".%+d", (int) imm8);
|
||||
}
|
||||
|
||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||
Bit64u target = db_eip + imm64;
|
||||
target += db_base;
|
||||
dis_sprintf(" (0x%08x%08x)", GET32H(target), GET32L(target));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (insn->os_32) {
|
||||
Bit32u imm32 = (Bit8s) imm8;
|
||||
|
||||
if (offset_mode_hex) {
|
||||
dis_sprintf(".+0x%08x", (unsigned) imm32);
|
||||
}
|
||||
else {
|
||||
dis_sprintf(".%+d", (int) imm8);
|
||||
}
|
||||
|
||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||
Bit32u target = (Bit32u)(db_base + db_eip + (Bit32s) imm32);
|
||||
dis_sprintf(" (0x%08x)", target);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Bit16u imm16 = (Bit8s) imm8;
|
||||
|
||||
if (offset_mode_hex) {
|
||||
dis_sprintf(".+0x%04x", (unsigned) imm16);
|
||||
}
|
||||
else {
|
||||
dis_sprintf(".%+d", (int) imm8);
|
||||
}
|
||||
|
||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||
Bit16u target = (Bit16u)((db_eip + (Bit16s) imm16) & 0xffff);
|
||||
dis_sprintf(" (0x%08x)", target + db_base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::Jw(const x86_insn *insn)
|
||||
{
|
||||
// Jw supported in 16-bit mode only
|
||||
assert(! insn->is_64);
|
||||
|
||||
Bit16s imm16 = (Bit16s) fetch_word();
|
||||
|
||||
if (offset_mode_hex) {
|
||||
dis_sprintf(".+0x%04x", (unsigned) (Bit16u) imm16);
|
||||
}
|
||||
else {
|
||||
dis_sprintf(".%+d", (int) imm16);
|
||||
}
|
||||
|
||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||
Bit16u target = (db_eip + imm16) & 0xffff;
|
||||
dis_sprintf(" (0x%08x)", target + db_base);
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::Jd(const x86_insn *insn)
|
||||
{
|
||||
Bit32s imm32 = (Bit32s) fetch_dword();
|
||||
|
||||
if (insn->is_64) {
|
||||
Bit64u imm64 = (Bit32s) imm32;
|
||||
|
||||
if (offset_mode_hex) {
|
||||
dis_sprintf(".+0x%08x%08x", GET32H(imm64), GET32L(imm64));
|
||||
}
|
||||
else {
|
||||
dis_sprintf(".%+d", (int) imm32);
|
||||
}
|
||||
|
||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||
Bit64u target = db_base + db_eip + (Bit64s) imm64;
|
||||
dis_sprintf(" (0x%08x%08x)", GET32H(target), GET32L(target));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset_mode_hex) {
|
||||
dis_sprintf(".+0x%08x", (unsigned) imm32);
|
||||
}
|
||||
else {
|
||||
dis_sprintf(".%+d", (int) imm32);
|
||||
}
|
||||
|
||||
if (db_base != BX_JUMP_TARGET_NOT_REQ) {
|
||||
Bit32u target = (Bit32u)(db_base + db_eip + (Bit32s) imm32);
|
||||
dis_sprintf(" (0x%08x)", target);
|
||||
}
|
||||
}
|
||||
203
simulators/bochs/disasm/dis_tables.h
Executable file
203
simulators/bochs/disasm/dis_tables.h
Executable file
@ -0,0 +1,203 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
|
||||
#ifndef _BX_DISASM_TABLES_
|
||||
#define _BX_DISASM_TABLES_
|
||||
|
||||
// opcode table attributes
|
||||
#define _GROUPN 1
|
||||
#define _SPLIT11B 2
|
||||
#define _GRPFP 3
|
||||
#define _GRP3DNOW 4
|
||||
#define _GRPSSE 5
|
||||
#define _GRPSSE66 6
|
||||
#define _GRPSSEF2 7
|
||||
#define _GRPSSEF3 8
|
||||
#define _GRPRM 9
|
||||
#define _GRP3BOP 10
|
||||
#define _GRP64B 11
|
||||
|
||||
/* ************************************************************************ */
|
||||
#define GRPSSE(n) _GRPSSE, BxDisasmGroupSSE_##n
|
||||
#define GRPN(n) _GROUPN, BxDisasmGroup##n
|
||||
#define GRPRM(n) _GRPRM, BxDisasmGroupRm##n
|
||||
#define GRPMOD(n) _SPLIT11B, BxDisasmGroupMod##n
|
||||
#define GRPFP(n) _GRPFP, BxDisasmFPGroup##n
|
||||
#define GRP3DNOW _GRP3DNOW, BxDisasm3DNowGroup
|
||||
#define GR3BTAB(n) _GRP3BOP, BxDisasm3ByteOpTable##n
|
||||
#define GR64BIT(n) _GRP64B, BxDisasmGrpOs64B_##n
|
||||
/* ************************************************************************ */
|
||||
|
||||
/* ************************************************************************ */
|
||||
#define GRPSSE66(n) _GRPSSE66, &n
|
||||
#define GRPSSEF2(n) _GRPSSEF2, &n
|
||||
#define GRPSSEF3(n) _GRPSSEF3, &n
|
||||
/* ************************************************************************ */
|
||||
|
||||
#define Apw &disassembler::Apw
|
||||
#define Apd &disassembler::Apd
|
||||
|
||||
#define AL_Reg &disassembler::AL_Reg
|
||||
#define CL_Reg &disassembler::CL_Reg
|
||||
#define AX_Reg &disassembler::AX_Reg
|
||||
#define DX_Reg &disassembler::DX_Reg
|
||||
|
||||
#define EAX_Reg &disassembler::EAX_Reg
|
||||
#define RAX_Reg &disassembler::RAX_Reg
|
||||
|
||||
#define CS &disassembler::CS
|
||||
#define DS &disassembler::DS
|
||||
#define ES &disassembler::ES
|
||||
#define SS &disassembler::SS
|
||||
#define FS &disassembler::FS
|
||||
#define GS &disassembler::GS
|
||||
|
||||
#define Sw &disassembler::Sw
|
||||
|
||||
#define Td &disassembler::Td
|
||||
|
||||
#define Cd &disassembler::Cd
|
||||
#define Cq &disassembler::Cq
|
||||
|
||||
#define Dd &disassembler::Dd
|
||||
#define Dq &disassembler::Dq
|
||||
|
||||
#define Reg8 &disassembler::Reg8
|
||||
#define RX &disassembler::RX
|
||||
#define ERX &disassembler::ERX
|
||||
#define RRX &disassembler::RRX
|
||||
|
||||
#define Eb &disassembler::Eb
|
||||
#define Ew &disassembler::Ew
|
||||
#define Ed &disassembler::Ed
|
||||
#define Eq &disassembler::Eq
|
||||
#define Ey &disassembler::Ey
|
||||
#define Ebd &disassembler::Ebd
|
||||
#define Ewd &disassembler::Ewd
|
||||
|
||||
#define Gb &disassembler::Gb
|
||||
#define Gw &disassembler::Gw
|
||||
#define Gd &disassembler::Gd
|
||||
#define Gq &disassembler::Gq
|
||||
#define Gy &disassembler::Gy
|
||||
|
||||
#define I1 &disassembler::I1
|
||||
#define Ib &disassembler::Ib
|
||||
#define Iw &disassembler::Iw
|
||||
#define Id &disassembler::Id
|
||||
#define Iq &disassembler::Iq
|
||||
|
||||
#define IbIb &disassembler::IbIb
|
||||
#define IwIb &disassembler::IwIb
|
||||
|
||||
#define sIbw &disassembler::sIbw
|
||||
#define sIbd &disassembler::sIbd
|
||||
#define sIbq &disassembler::sIbq
|
||||
#define sIdq &disassembler::sIdq
|
||||
|
||||
#define ST0 &disassembler::ST0
|
||||
#define STi &disassembler::STi
|
||||
|
||||
#define Rw &disassembler::Rw
|
||||
#define Rd &disassembler::Rd
|
||||
#define Rq &disassembler::Rq
|
||||
#define Ry &disassembler::Ry
|
||||
|
||||
#define Pq &disassembler::Pq
|
||||
#define Qd &disassembler::Qd
|
||||
#define Qq &disassembler::Qq
|
||||
#define Nq &disassembler::Nq
|
||||
|
||||
#define Vq &disassembler::Vq
|
||||
#define Vdq &disassembler::Vdq
|
||||
#define Vss &disassembler::Vss
|
||||
#define Vsd &disassembler::Vsd
|
||||
#define Vps &disassembler::Vps
|
||||
#define Vpd &disassembler::Vpd
|
||||
|
||||
#define Ups &disassembler::Ups
|
||||
#define Upd &disassembler::Upd
|
||||
#define Udq &disassembler::Udq
|
||||
|
||||
#define Ww &disassembler::Ww
|
||||
#define Wd &disassembler::Wd
|
||||
#define Wq &disassembler::Wq
|
||||
#define Wdq &disassembler::Wdq
|
||||
#define Wss &disassembler::Wss
|
||||
#define Wsd &disassembler::Wsd
|
||||
#define Wps &disassembler::Wps
|
||||
#define Wpd &disassembler::Wpd
|
||||
|
||||
#define Ob &disassembler::Ob
|
||||
#define Ow &disassembler::Ow
|
||||
#define Od &disassembler::Od
|
||||
#define Oq &disassembler::Oq
|
||||
|
||||
#define Ma &disassembler::Ma
|
||||
#define Mp &disassembler::Mp
|
||||
#define Ms &disassembler::Ms
|
||||
#define Mx &disassembler::Mx
|
||||
#define Mb &disassembler::Mb
|
||||
#define Mw &disassembler::Mw
|
||||
#define Md &disassembler::Md
|
||||
#define Mq &disassembler::Mq
|
||||
#define Mt &disassembler::Mt
|
||||
#define Mdq &disassembler::Mdq
|
||||
#define Mps &disassembler::Mps
|
||||
#define Mpd &disassembler::Mpd
|
||||
#define Mss &disassembler::Mss
|
||||
#define Msd &disassembler::Msd
|
||||
|
||||
#define Xb &disassembler::Xb
|
||||
#define Xw &disassembler::Xw
|
||||
#define Xd &disassembler::Xd
|
||||
#define Xq &disassembler::Xq
|
||||
|
||||
#define Yb &disassembler::Yb
|
||||
#define Yw &disassembler::Yw
|
||||
#define Yd &disassembler::Yd
|
||||
#define Yq &disassembler::Yq
|
||||
|
||||
#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
|
||||
#include "opcodes.inc"
|
||||
#include "dis_tables_x87.inc"
|
||||
#include "dis_tables_sse.inc"
|
||||
#include "dis_tables.inc"
|
||||
|
||||
#undef XX
|
||||
|
||||
//DanceOS
|
||||
// workaround for include file clash with cpu/instr.h in conjunction with AspectC++
|
||||
#undef Id
|
||||
#undef Iq
|
||||
#undef Iw
|
||||
#undef Ib
|
||||
|
||||
#endif
|
||||
3237
simulators/bochs/disasm/dis_tables.inc
Executable file
3237
simulators/bochs/disasm/dis_tables.inc
Executable file
File diff suppressed because it is too large
Load Diff
1587
simulators/bochs/disasm/dis_tables_sse.inc
Executable file
1587
simulators/bochs/disasm/dis_tables_sse.inc
Executable file
File diff suppressed because it is too large
Load Diff
919
simulators/bochs/disasm/dis_tables_x87.inc
Executable file
919
simulators/bochs/disasm/dis_tables_x87.inc
Executable file
@ -0,0 +1,919 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 },
|
||||
};
|
||||
567
simulators/bochs/disasm/disasm.h
Normal file
567
simulators/bochs/disasm/disasm.h
Normal file
@ -0,0 +1,567 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005-2009 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_
|
||||
#define _BX_DISASM_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define BX_DECODE_MODRM(modrm_byte, mod, opcode, rm) { \
|
||||
mod = (modrm_byte >> 6) & 0x03; \
|
||||
opcode = (modrm_byte >> 3) & 0x07; \
|
||||
rm = modrm_byte & 0x07; \
|
||||
}
|
||||
|
||||
#define BX_DECODE_SIB(sib_byte, scale, index, base) { \
|
||||
scale = sib_byte >> 6; \
|
||||
index = (sib_byte >> 3) & 0x07; \
|
||||
base = sib_byte & 0x07; \
|
||||
}
|
||||
|
||||
/* Instruction set attributes (duplicated in cpu.h) */
|
||||
#define IA_X87 0x00000001 /* FPU (X87) instruction */
|
||||
#define IA_486 0x00000002 /* 486 new instruction */
|
||||
#define IA_PENTIUM 0x00000004 /* Pentium new instruction */
|
||||
#define IA_P6 0x00000008 /* P6 new instruction */
|
||||
#define IA_MMX 0x00000010 /* MMX instruction */
|
||||
#define IA_3DNOW 0x00000020 /* 3DNow! instruction */
|
||||
#define IA_FXSAVE_FXRSTOR 0x00000040 /* FXSAVE/FXRSTOR instruction */
|
||||
#define IA_SYSENTER_SYSEXIT 0x00000080 /* SYSENTER/SYSEXIT instruction */
|
||||
#define IA_CLFLUSH 0x00000100 /* CLFLUSH instruction */
|
||||
#define IA_SSE 0x00000200 /* SSE instruction */
|
||||
#define IA_SSE2 0x00000400 /* SSE2 instruction */
|
||||
#define IA_SSE3 0x00000800 /* SSE3 instruction */
|
||||
#define IA_SSSE3 0x00001000 /* SSSE3 instruction */
|
||||
#define IA_SSE4_1 0x00002000 /* SSE4_1 instruction */
|
||||
#define IA_SSE4_2 0x00004000 /* SSE4_2 instruction */
|
||||
#define IA_SSE4A 0x00008000 /* SSE4A instruction */
|
||||
#define IA_MONITOR_MWAIT 0x00010000 /* MONITOR/MWAIT instruction */
|
||||
#define IA_VMX 0x00020000 /* VMX instruction */
|
||||
#define IA_SMX 0x00040000 /* SMX instruction */
|
||||
#define IA_SVM 0x00080000 /* SVM instruction */
|
||||
#define IA_XSAVE 0x00100000 /* XSAVE/XRSTOR extensions instruction */
|
||||
#define IA_XSAVEOPT 0x00200000 /* XSAVEOPT instruction */
|
||||
#define IA_AES_PCLMULQDQ 0x00400000 /* AES+PCLMULQDQ instructions */
|
||||
#define IA_MOVBE 0x00800000 /* MOVBE Intel Atom(R) instruction */
|
||||
#define IA_FSGSBASE 0x01000000 /* FS/GS BASE access instructions */
|
||||
#define IA_AVX 0x02000000 /* AVX instruction */
|
||||
#define IA_AVX_FMA 0x04000000 /* AVX FMA instruction */
|
||||
#define IA_X86_64 0x08000000 /* x86-64 instruction */
|
||||
|
||||
/* general purpose bit register */
|
||||
enum {
|
||||
rAX_REG,
|
||||
rCX_REG,
|
||||
rDX_REG,
|
||||
rBX_REG,
|
||||
rSP_REG,
|
||||
rBP_REG,
|
||||
rSI_REG,
|
||||
rDI_REG
|
||||
};
|
||||
|
||||
/* segment register */
|
||||
enum {
|
||||
ES_REG,
|
||||
CS_REG,
|
||||
SS_REG,
|
||||
DS_REG,
|
||||
FS_REG,
|
||||
GS_REG,
|
||||
INVALID_SEG1,
|
||||
INVALID_SEG2
|
||||
};
|
||||
|
||||
class disassembler;
|
||||
struct x86_insn;
|
||||
|
||||
typedef void (disassembler::*BxDisasmPtr_t)(const x86_insn *insn);
|
||||
typedef void (disassembler::*BxDisasmResolveModrmPtr_t)(const x86_insn *insn, unsigned attr);
|
||||
|
||||
struct BxDisasmOpcodeInfo_t
|
||||
{
|
||||
const char *IntelOpcode;
|
||||
const char *AttOpcode;
|
||||
BxDisasmPtr_t Operand1;
|
||||
BxDisasmPtr_t Operand2;
|
||||
BxDisasmPtr_t Operand3;
|
||||
BxDisasmPtr_t Operand4;
|
||||
Bit32u Attr;
|
||||
};
|
||||
|
||||
struct BxDisasmOpcodeTable_t
|
||||
{
|
||||
Bit32u Attr;
|
||||
const void *OpcodeInfo;
|
||||
};
|
||||
|
||||
// segment override not used
|
||||
#define NO_SEG_OVERRIDE 0xFF
|
||||
|
||||
// datasize attributes
|
||||
#define X_SIZE 0x0000
|
||||
#define B_SIZE 0x0100
|
||||
#define W_SIZE 0x0200
|
||||
#define D_SIZE 0x0300
|
||||
#define Q_SIZE 0x0400
|
||||
#define Z_SIZE 0x0500
|
||||
#define V_SIZE 0x0600
|
||||
#define O_SIZE 0x0700
|
||||
#define T_SIZE 0x0800
|
||||
#define P_SIZE 0x0900
|
||||
|
||||
// branch hint attribute
|
||||
#define BRANCH_HINT 0x1000
|
||||
|
||||
struct x86_insn
|
||||
{
|
||||
public:
|
||||
x86_insn(bx_bool is32, bx_bool is64);
|
||||
|
||||
bx_bool is_seg_override() const {
|
||||
return (seg_override != NO_SEG_OVERRIDE);
|
||||
}
|
||||
|
||||
public:
|
||||
bx_bool is_32, is_64;
|
||||
bx_bool as_32, as_64;
|
||||
bx_bool os_32, os_64;
|
||||
|
||||
Bit8u extend8b;
|
||||
Bit8u rex_r, rex_x, rex_b;
|
||||
Bit8u seg_override;
|
||||
unsigned b1;
|
||||
unsigned ilen;
|
||||
|
||||
Bit8u modrm, mod, nnn, rm;
|
||||
Bit8u sib, scale, index, base;
|
||||
union {
|
||||
Bit16u displ16;
|
||||
Bit32u displ32;
|
||||
} displacement;
|
||||
};
|
||||
|
||||
BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
|
||||
{
|
||||
is_32 = is32;
|
||||
is_64 = is64;
|
||||
|
||||
if (is_64) {
|
||||
os_64 = 0;
|
||||
as_64 = 1;
|
||||
os_32 = 1;
|
||||
as_32 = 1;
|
||||
}
|
||||
else {
|
||||
os_64 = 0;
|
||||
as_64 = 0;
|
||||
os_32 = is_32;
|
||||
as_32 = is_32;
|
||||
}
|
||||
|
||||
extend8b = 0;
|
||||
rex_r = rex_b = rex_x = 0;
|
||||
seg_override = NO_SEG_OVERRIDE;
|
||||
ilen = 0;
|
||||
b1 = 0;
|
||||
|
||||
modrm = mod = nnn = rm = 0;
|
||||
sib = scale = index = base = 0;
|
||||
displacement.displ32 = 0;
|
||||
}
|
||||
|
||||
class disassembler {
|
||||
public:
|
||||
disassembler(): offset_mode_hex(0) { 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 disasm16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||
{ return disasm(0, 0, base, ip, instr, disbuf); }
|
||||
|
||||
unsigned disasm32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||
{ return disasm(1, 0, base, ip, instr, disbuf); }
|
||||
|
||||
unsigned disasm64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||
{ return disasm(1, 1, 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 decode16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||
{ return decode(0, 0, base, ip, instr, disbuf); }
|
||||
|
||||
x86_insn decode32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||
{ return decode(1, 0, base, ip, instr, disbuf); }
|
||||
|
||||
x86_insn decode64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
||||
{ return decode(1, 1, base, ip, instr, disbuf); }
|
||||
|
||||
void set_syntax_intel();
|
||||
void set_syntax_att();
|
||||
|
||||
void set_offset_mode_hex(bx_bool mode) { offset_mode_hex = mode; }
|
||||
|
||||
void toggle_syntax_mode();
|
||||
|
||||
private:
|
||||
bx_bool intel_mode, offset_mode_hex;
|
||||
|
||||
const char **general_16bit_regname;
|
||||
const char **general_8bit_regname;
|
||||
const char **general_32bit_regname;
|
||||
const char **general_8bit_regname_rex;
|
||||
const char **general_64bit_regname;
|
||||
|
||||
const char **segment_name;
|
||||
const char **index16;
|
||||
|
||||
const char *sreg_mod00_base32[16];
|
||||
const char *sreg_mod01or10_base32[16];
|
||||
const char *sreg_mod00_rm16[8];
|
||||
const char *sreg_mod01or10_rm16[8];
|
||||
|
||||
private:
|
||||
|
||||
bx_address db_eip, db_base;
|
||||
|
||||
const Bit8u *instruction; // for fetching of next byte of instruction
|
||||
|
||||
char *disbufptr;
|
||||
|
||||
BxDisasmResolveModrmPtr_t resolve_modrm;
|
||||
|
||||
BX_CPP_INLINE Bit8u fetch_byte() {
|
||||
db_eip++;
|
||||
return(*instruction++);
|
||||
};
|
||||
|
||||
BX_CPP_INLINE Bit8u peek_byte() {
|
||||
return(*instruction);
|
||||
};
|
||||
|
||||
BX_CPP_INLINE Bit16u fetch_word() {
|
||||
Bit8u b0 = * (Bit8u *) instruction++;
|
||||
Bit8u b1 = * (Bit8u *) instruction++;
|
||||
Bit16u ret16 = (b1<<8) | b0;
|
||||
db_eip += 2;
|
||||
return(ret16);
|
||||
};
|
||||
|
||||
BX_CPP_INLINE Bit32u fetch_dword() {
|
||||
Bit8u b0 = * (Bit8u *) instruction++;
|
||||
Bit8u b1 = * (Bit8u *) instruction++;
|
||||
Bit8u b2 = * (Bit8u *) instruction++;
|
||||
Bit8u b3 = * (Bit8u *) instruction++;
|
||||
Bit32u ret32 = (b3<<24) | (b2<<16) | (b1<<8) | b0;
|
||||
db_eip += 4;
|
||||
return(ret32);
|
||||
};
|
||||
|
||||
BX_CPP_INLINE Bit64u fetch_qword() {
|
||||
Bit64u d0 = fetch_dword();
|
||||
Bit64u d1 = fetch_dword();
|
||||
Bit64u ret64 = (d1<<32) | d0;
|
||||
return(ret64);
|
||||
};
|
||||
|
||||
void dis_putc(char symbol);
|
||||
void dis_sprintf(const char *fmt, ...);
|
||||
void decode_modrm(x86_insn *insn);
|
||||
|
||||
void resolve16_mod0 (const x86_insn *insn, unsigned mode);
|
||||
void resolve16_mod1or2(const x86_insn *insn, unsigned mode);
|
||||
|
||||
void resolve32_mod0 (const x86_insn *insn, unsigned mode);
|
||||
void resolve32_mod1or2(const x86_insn *insn, unsigned mode);
|
||||
|
||||
void resolve32_mod0_rm4 (const x86_insn *insn, unsigned mode);
|
||||
void resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode);
|
||||
|
||||
void resolve64_mod0 (const x86_insn *insn, unsigned mode);
|
||||
void resolve64_mod1or2(const x86_insn *insn, unsigned mode);
|
||||
|
||||
void resolve64_mod0_rm4 (const x86_insn *insn, unsigned mode);
|
||||
void resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode);
|
||||
|
||||
void initialize_modrm_segregs();
|
||||
|
||||
void print_datasize(unsigned mode);
|
||||
|
||||
void print_memory_access16(int datasize,
|
||||
const char *seg, const char *index, Bit16u disp);
|
||||
void print_memory_access32(int datasize,
|
||||
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_att (const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Codes for Addressing Method:
|
||||
* ---------------------------
|
||||
* A - Direct address. The instruction has no ModR/M byte; the address
|
||||
* of the operand is encoded in the instruction; and no base register,
|
||||
* index register, or scaling factor can be applied.
|
||||
* 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.
|
||||
* E - A ModR/M byte follows the opcode and specifies the operand. The
|
||||
* operand is either a general-purpose register or a memory address.
|
||||
* In case of the register operand, the R/M field of the ModR/M byte
|
||||
* selects a general register.
|
||||
* F - Flags 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
|
||||
* the instruction.
|
||||
* J - The instruction contains a relative offset to be added to the
|
||||
* instruction pointer register.
|
||||
* 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
|
||||
technology register.
|
||||
* 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)
|
||||
* in the instruction. No base register, index register, or scaling
|
||||
* factor can be applied.
|
||||
* P - The reg field of the ModR/M byte selects a packed quadword MMX
|
||||
* technology register.
|
||||
* Q - A ModR/M byte follows the opcode and specifies the operand. The
|
||||
* operand is either an MMX technology 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
|
||||
* index register, a scaling factor, and a displacement.
|
||||
* 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.
|
||||
* T - The reg field of the ModR/M byte selects a test register.
|
||||
* U - The R/M field of the ModR/M byte selects a 128-bit XMM register.
|
||||
* V - The reg field of the ModR/M byte selects a 128-bit XMM register.
|
||||
* W - A ModR/M byte follows the opcode and specifies the operand. The
|
||||
* operand is either a 128-bit XMM 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
|
||||
* index register, a scaling factor, and a displacement.
|
||||
* X - Memory addressed by the DS:rSI register pair.
|
||||
* Y - Memory addressed by the ES:rDI register pair.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Codes for Operand Type:
|
||||
* ----------------------
|
||||
* a - Two one-word operands in memory or two double-word operands in
|
||||
* memory, depending on operand-size attribute (used only by the BOUND
|
||||
* instruction).
|
||||
* b - Byte, regardless of operand-size attribute.
|
||||
* d - Doubleword, 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.
|
||||
* pd - 128-bit packed double-precision floating-point data.
|
||||
* pi - Quadword MMX technology register (packed integer)
|
||||
* ps - 128-bit packed single-precision floating-point data.
|
||||
* q - Quadword, regardless of operand-size attribute.
|
||||
* s - 6-byte or 10-byte pseudo-descriptor.
|
||||
* si - Doubleword integer register (scalar integer)
|
||||
* ss - Scalar element of a 128-bit packed single-precision floating data.
|
||||
* sd - Scalar element of a 128-bit packed double-precision floating data.
|
||||
* v - Word, doubleword or quadword, depending on operand-size attribute.
|
||||
* 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
|
||||
void Apw(const x86_insn *insn);
|
||||
void Apd(const x86_insn *insn);
|
||||
|
||||
// 8-bit general purpose registers
|
||||
void AL_Reg(const x86_insn *insn);
|
||||
void CL_Reg(const x86_insn *insn);
|
||||
|
||||
// 16-bit general purpose registers
|
||||
void AX_Reg(const x86_insn *insn);
|
||||
void DX_Reg(const x86_insn *insn);
|
||||
|
||||
// 32-bit general purpose registers
|
||||
void EAX_Reg(const x86_insn *insn);
|
||||
|
||||
// 64-bit general purpose registers
|
||||
void RAX_Reg(const x86_insn *insn);
|
||||
|
||||
// segment registers
|
||||
void CS(const x86_insn *insn);
|
||||
void DS(const x86_insn *insn);
|
||||
void ES(const x86_insn *insn);
|
||||
void SS(const x86_insn *insn);
|
||||
void FS(const x86_insn *insn);
|
||||
void GS(const x86_insn *insn);
|
||||
|
||||
// segment registers
|
||||
void Sw(const x86_insn *insn);
|
||||
|
||||
// test registers
|
||||
void Td(const x86_insn *insn);
|
||||
|
||||
// control register
|
||||
void Cd(const x86_insn *insn);
|
||||
void Cq(const x86_insn *insn);
|
||||
|
||||
// debug register
|
||||
void Dd(const x86_insn *insn);
|
||||
void Dq(const x86_insn *insn);
|
||||
|
||||
// 8-bit general purpose register
|
||||
void Reg8(const x86_insn *insn);
|
||||
|
||||
// 16-bit general purpose register
|
||||
void RX(const x86_insn *insn);
|
||||
|
||||
// 32-bit general purpose register
|
||||
void ERX(const x86_insn *insn);
|
||||
|
||||
// 64-bit general purpose register
|
||||
void RRX(const x86_insn *insn);
|
||||
|
||||
// general purpose register or memory operand
|
||||
void Eb(const x86_insn *insn);
|
||||
void Ew(const x86_insn *insn);
|
||||
void Ed(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);
|
||||
|
||||
// general purpose register
|
||||
void Gb(const x86_insn *insn);
|
||||
void Gw(const x86_insn *insn);
|
||||
void Gd(const x86_insn *insn);
|
||||
void Gq(const x86_insn *insn);
|
||||
void Gy(const x86_insn *insn);
|
||||
|
||||
// immediate
|
||||
void I1(const x86_insn *insn);
|
||||
void Ib(const x86_insn *insn);
|
||||
void Iw(const x86_insn *insn);
|
||||
void Id(const x86_insn *insn);
|
||||
void Iq(const x86_insn *insn);
|
||||
|
||||
// double immediate
|
||||
void IbIb(const x86_insn *insn);
|
||||
void IwIb(const x86_insn *insn);
|
||||
|
||||
// sign extended immediate
|
||||
void sIbw(const x86_insn *insn);
|
||||
void sIbd(const x86_insn *insn);
|
||||
void sIbq(const x86_insn *insn);
|
||||
void sIdq(const x86_insn *insn);
|
||||
|
||||
// floating point
|
||||
void ST0(const x86_insn *insn);
|
||||
void STi(const x86_insn *insn);
|
||||
|
||||
// general purpose register
|
||||
void Rw(const x86_insn *insn);
|
||||
void Rd(const x86_insn *insn);
|
||||
void Rq(const x86_insn *insn);
|
||||
void Ry(const x86_insn *insn);
|
||||
|
||||
// mmx register
|
||||
void Pq(const x86_insn *insn);
|
||||
|
||||
// mmx register or memory operand
|
||||
void Qd(const x86_insn *insn);
|
||||
void Qq(const x86_insn *insn);
|
||||
void Vq(const x86_insn *insn);
|
||||
void Nq(const x86_insn *insn);
|
||||
|
||||
// xmm register
|
||||
void Ups(const x86_insn *insn);
|
||||
void Upd(const x86_insn *insn);
|
||||
void Udq(const x86_insn *insn);
|
||||
|
||||
void Vdq(const x86_insn *insn);
|
||||
void Vss(const x86_insn *insn);
|
||||
void Vsd(const x86_insn *insn);
|
||||
void Vps(const x86_insn *insn);
|
||||
void Vpd(const x86_insn *insn);
|
||||
|
||||
// xmm register or memory operand
|
||||
void Ww(const x86_insn *insn);
|
||||
void Wd(const x86_insn *insn);
|
||||
void Wq(const x86_insn *insn);
|
||||
|
||||
void Wdq(const x86_insn *insn);
|
||||
void Wss(const x86_insn *insn);
|
||||
void Wsd(const x86_insn *insn);
|
||||
void Wps(const x86_insn *insn);
|
||||
void Wpd(const x86_insn *insn);
|
||||
|
||||
// direct memory access
|
||||
void OP_O(const x86_insn *insn, unsigned size);
|
||||
void Ob(const x86_insn *insn);
|
||||
void Ow(const x86_insn *insn);
|
||||
void Od(const x86_insn *insn);
|
||||
void Oq(const x86_insn *insn);
|
||||
|
||||
// memory operand
|
||||
void OP_M(const x86_insn *insn, unsigned size);
|
||||
void Ma(const x86_insn *insn);
|
||||
void Mp(const x86_insn *insn);
|
||||
void Ms(const x86_insn *insn);
|
||||
void Mx(const x86_insn *insn);
|
||||
void Mb(const x86_insn *insn);
|
||||
void Mw(const x86_insn *insn);
|
||||
void Md(const x86_insn *insn);
|
||||
void Mq(const x86_insn *insn);
|
||||
void Mt(const x86_insn *insn);
|
||||
void Mdq(const x86_insn *insn);
|
||||
void Mps(const x86_insn *insn);
|
||||
void Mpd(const x86_insn *insn);
|
||||
void Mss(const x86_insn *insn);
|
||||
void Msd(const x86_insn *insn);
|
||||
|
||||
// string instructions
|
||||
void OP_X(const x86_insn *insn, unsigned size);
|
||||
void Xb(const x86_insn *insn);
|
||||
void Xw(const x86_insn *insn);
|
||||
void Xd(const x86_insn *insn);
|
||||
void Xq(const x86_insn *insn);
|
||||
|
||||
// string instructions
|
||||
void OP_Y(const x86_insn *insn, unsigned size);
|
||||
void Yb(const x86_insn *insn);
|
||||
void Yw(const x86_insn *insn);
|
||||
void Yd(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
|
||||
void Jb(const x86_insn *insn);
|
||||
void Jw(const x86_insn *insn);
|
||||
void Jd(const x86_insn *insn);
|
||||
};
|
||||
|
||||
#endif
|
||||
1352
simulators/bochs/disasm/opcodes.inc
Executable file
1352
simulators/bochs/disasm/opcodes.inc
Executable file
File diff suppressed because it is too large
Load Diff
661
simulators/bochs/disasm/resolve.cc
Executable file
661
simulators/bochs/disasm/resolve.cc
Executable file
@ -0,0 +1,661 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005-2009 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 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, *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(mode, seg, eip_regname, NULL, 0, insn->displacement.displ32);
|
||||
else
|
||||
print_memory_access32(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_base32[insn->rm];
|
||||
|
||||
print_memory_access32(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_access32(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_access32(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_access64(mode, seg, rip_regname, NULL, 0, (Bit32s) insn->displacement.displ32);
|
||||
else
|
||||
print_memory_access64(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_base32[insn->rm];
|
||||
|
||||
print_memory_access64(mode, seg,
|
||||
general_64bit_regname[insn->rm], NULL, 0, (Bit32s) insn->displacement.displ32);
|
||||
}
|
||||
|
||||
void disassembler::resolve64_mod0_rm4(const x86_insn *insn, unsigned mode)
|
||||
{
|
||||
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 (insn->index != 4)
|
||||
index = general_64bit_regname[insn->index];
|
||||
|
||||
print_memory_access64(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_access64(mode, seg,
|
||||
general_64bit_regname[insn->base], index, insn->scale, (Bit32s) 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) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s%+d]", seg, index, (int) (Bit16s) disp);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:[%s]", seg, index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:0x%x(%s,1)", seg, (unsigned) disp, index);
|
||||
else
|
||||
dis_sprintf("%s:%d(%s,1)", seg, (int) (Bit16s) disp, index);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:(%s,1)", seg, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::print_memory_access32(int datasize,
|
||||
const char *seg, const char *base, const char *index, int scale, Bit32s disp)
|
||||
{
|
||||
print_datasize(datasize);
|
||||
|
||||
scale = 1 << scale;
|
||||
|
||||
if (intel_mode)
|
||||
{
|
||||
if (base == NULL)
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scale != 1)
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s*%d+0x%x]", seg, index, scale, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s*%d%+d]", seg, index, scale, (int) disp);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:[%s*%d]", seg, index, scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s%+d]", seg, index, (int) disp);
|
||||
}
|
||||
else {
|
||||
dis_sprintf("%s:[%s]", seg, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+0x%x]", seg, base, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s%+d]", seg, base, (int) disp);
|
||||
}
|
||||
else {
|
||||
dis_sprintf("%s:[%s]", seg, base);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scale != 1)
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+%s*%d+0x%x]", seg, base, index, scale, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s+%s*%d%+d]", seg, base, index, scale, (int) disp);
|
||||
}
|
||||
else {
|
||||
dis_sprintf("%s:[%s+%s*%d]", seg, base, index, scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+%s+0x%x]", seg, base, index, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s+%s%+d]", seg, base, index, (int) 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) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:0x%x(,%s,%d)", seg, (unsigned) disp, index, scale);
|
||||
else
|
||||
dis_sprintf("%s:%d(,%s,%d)", seg, (int) disp, index, scale);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:(,%s,%d)", seg, index, scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:0x%x(%s)", seg, (unsigned) disp, base);
|
||||
else
|
||||
dis_sprintf("%s:%d(%s)", seg, (int) disp, base);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:(%s)", seg, base);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:0x%x(%s,%s,%d)", seg, (unsigned) disp, base, index, scale);
|
||||
else
|
||||
dis_sprintf("%s:%d(%s,%s,%d)", seg, (int) disp, base, index, scale);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:(%s,%s,%d)", seg, 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);
|
||||
|
||||
scale = 1 << scale;
|
||||
|
||||
if (intel_mode)
|
||||
{
|
||||
if (base == NULL)
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
dis_sprintf("%s:0x%08x%08x", seg, GET32H(disp64), GET32L(disp64));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scale != 1)
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s*%d+0x%08x%08x]", seg, index, scale, GET32H(disp64), GET32L(disp64));
|
||||
else
|
||||
dis_sprintf("%s:[%s*%d%+d]", seg, index, scale, (int) disp);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:[%s*%d]", seg, index, scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+0x%08x%08x]", seg, index, GET32H(disp64), GET32L(disp64));
|
||||
else
|
||||
dis_sprintf("%s:[%s%+d]", seg, index, (int) disp);
|
||||
}
|
||||
else {
|
||||
dis_sprintf("%s:[%s]", seg, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+0x%08x%08x]", seg, base, GET32H(disp64), GET32L(disp64));
|
||||
else
|
||||
dis_sprintf("%s:[%s%+d]", seg, base, (int) disp);
|
||||
}
|
||||
else {
|
||||
dis_sprintf("%s:[%s]", seg, base);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scale != 1)
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+%s*%d+0x%08x%08x]", seg, base, index, scale, GET32H(disp64), GET32L(disp64));
|
||||
else
|
||||
dis_sprintf("%s:[%s+%s*%d%+d]", seg, base, index, scale, (int) disp);
|
||||
}
|
||||
else {
|
||||
dis_sprintf("%s:[%s+%s*%d]", seg, base, index, scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:[%s+%s+0x%08x%08x]", seg, base, index, GET32H(disp64), GET32L(disp64));
|
||||
else
|
||||
dis_sprintf("%s:[%s+%s%+d]", seg, base, index, (int) disp);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:[%s+%s]", seg, base, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (base == NULL)
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
dis_sprintf("%s:0x%08x%08x", seg, GET32H(disp64), GET32L(disp64));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:0x%08x%08x(,%s,%d)", seg, GET32H(disp64), GET32L(disp64), index, scale);
|
||||
else
|
||||
dis_sprintf("%s:%d(,%s,%d)", seg, (int) disp, index, scale);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:(,%s,%d)", seg, index, scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:0x%08x%08x(%s)", seg, GET32H(disp64), GET32L(disp64), base);
|
||||
else
|
||||
dis_sprintf("%s:%d(%s)", seg, (int) disp, base);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:(%s)", seg, base);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0) {
|
||||
if (offset_mode_hex)
|
||||
dis_sprintf("%s:0x%08x%08x(%s,%s,%d)", seg, GET32H(disp64), GET32L(disp64), base, index, scale);
|
||||
else
|
||||
dis_sprintf("%s:%d(%s,%s,%d)", seg, (int) disp, base, index, scale);
|
||||
}
|
||||
else
|
||||
dis_sprintf("%s:(%s,%s,%d)", seg, base, index, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
289
simulators/bochs/disasm/syntax.cc
Executable file
289
simulators/bochs/disasm/syntax.cc
Executable file
@ -0,0 +1,289 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005-2009 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 "disasm.h"
|
||||
|
||||
//////////////////
|
||||
// Intel STYLE
|
||||
//////////////////
|
||||
|
||||
#define BX_DISASM_SUPPORT_X86_64
|
||||
|
||||
#ifdef BX_DISASM_SUPPORT_X86_64
|
||||
|
||||
static const char *intel_general_16bit_regname[16] = {
|
||||
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
|
||||
"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
|
||||
};
|
||||
|
||||
static const char *intel_general_32bit_regname[16] = {
|
||||
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
|
||||
"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
|
||||
};
|
||||
|
||||
static const char *intel_general_64bit_regname[16] = {
|
||||
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
|
||||
};
|
||||
|
||||
static const char *intel_general_8bit_regname_rex[16] = {
|
||||
"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
|
||||
"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] = {
|
||||
"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
|
||||
};
|
||||
|
||||
static const char *intel_segment_name[8] = {
|
||||
"es", "cs", "ss", "ds", "fs", "gs", "??", "??"
|
||||
};
|
||||
|
||||
static const char *intel_index16[8] = {
|
||||
"bx+si",
|
||||
"bx+di",
|
||||
"bp+si",
|
||||
"bp+di",
|
||||
"si",
|
||||
"di",
|
||||
"bp",
|
||||
"bx"
|
||||
};
|
||||
|
||||
|
||||
//////////////////
|
||||
// AT&T STYLE
|
||||
//////////////////
|
||||
|
||||
#ifdef BX_DISASM_SUPPORT_X86_64
|
||||
|
||||
static const char *att_general_16bit_regname[16] = {
|
||||
"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
|
||||
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
|
||||
};
|
||||
|
||||
static const char *att_general_32bit_regname[16] = {
|
||||
"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
|
||||
"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
|
||||
};
|
||||
|
||||
static const char *att_general_64bit_regname[16] = {
|
||||
"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
|
||||
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
|
||||
};
|
||||
|
||||
static const char *att_general_8bit_regname_rex[16] = {
|
||||
"%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
|
||||
"%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] = {
|
||||
"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh"
|
||||
};
|
||||
|
||||
static const char *att_segment_name[8] = {
|
||||
"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%??", "%??"
|
||||
};
|
||||
|
||||
static const char *att_index16[8] = {
|
||||
"%bx,%si",
|
||||
"%bx,%di",
|
||||
"%bp,%si",
|
||||
"%bp,%di",
|
||||
"%si",
|
||||
"%di",
|
||||
"%bp",
|
||||
"%bx"
|
||||
};
|
||||
|
||||
#define NULL_SEGMENT_REGISTER 7
|
||||
|
||||
void disassembler::initialize_modrm_segregs()
|
||||
{
|
||||
sreg_mod00_rm16[0] = segment_name[DS_REG];
|
||||
sreg_mod00_rm16[1] = segment_name[DS_REG];
|
||||
sreg_mod00_rm16[2] = segment_name[SS_REG];
|
||||
sreg_mod00_rm16[3] = segment_name[SS_REG];
|
||||
sreg_mod00_rm16[4] = segment_name[DS_REG];
|
||||
sreg_mod00_rm16[5] = segment_name[DS_REG];
|
||||
sreg_mod00_rm16[6] = segment_name[DS_REG];
|
||||
sreg_mod00_rm16[7] = segment_name[DS_REG];
|
||||
|
||||
sreg_mod01or10_rm16[0] = segment_name[DS_REG];
|
||||
sreg_mod01or10_rm16[1] = segment_name[DS_REG];
|
||||
sreg_mod01or10_rm16[2] = segment_name[SS_REG];
|
||||
sreg_mod01or10_rm16[3] = segment_name[SS_REG];
|
||||
sreg_mod01or10_rm16[4] = segment_name[DS_REG];
|
||||
sreg_mod01or10_rm16[5] = segment_name[DS_REG];
|
||||
sreg_mod01or10_rm16[6] = segment_name[SS_REG];
|
||||
sreg_mod01or10_rm16[7] = segment_name[DS_REG];
|
||||
|
||||
sreg_mod00_base32[0] = segment_name[DS_REG];
|
||||
sreg_mod00_base32[1] = segment_name[DS_REG];
|
||||
sreg_mod00_base32[2] = segment_name[DS_REG];
|
||||
sreg_mod00_base32[3] = segment_name[DS_REG];
|
||||
sreg_mod00_base32[4] = segment_name[SS_REG];
|
||||
sreg_mod00_base32[5] = segment_name[DS_REG];
|
||||
sreg_mod00_base32[6] = 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_mod01or10_base32[0] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[1] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[2] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[3] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[4] = segment_name[SS_REG];
|
||||
sreg_mod01or10_base32[5] = segment_name[SS_REG];
|
||||
sreg_mod01or10_base32[6] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[7] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[8] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[9] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[10] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[11] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[12] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[13] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[14] = segment_name[DS_REG];
|
||||
sreg_mod01or10_base32[15] = segment_name[DS_REG];
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Intel STYLE
|
||||
//////////////////
|
||||
|
||||
void disassembler::set_syntax_intel()
|
||||
{
|
||||
intel_mode = 1;
|
||||
|
||||
general_16bit_regname = intel_general_16bit_regname;
|
||||
general_8bit_regname = intel_general_8bit_regname;
|
||||
general_32bit_regname = intel_general_32bit_regname;
|
||||
general_8bit_regname_rex = intel_general_8bit_regname_rex;
|
||||
general_64bit_regname = intel_general_64bit_regname;
|
||||
|
||||
segment_name = intel_segment_name;
|
||||
index16 = intel_index16;
|
||||
|
||||
initialize_modrm_segregs();
|
||||
}
|
||||
|
||||
void disassembler::print_disassembly_intel(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry)
|
||||
{
|
||||
// print opcode
|
||||
dis_sprintf("%s ", entry->IntelOpcode);
|
||||
|
||||
if (entry->Operand1) {
|
||||
(this->*entry->Operand1)(insn);
|
||||
}
|
||||
if (entry->Operand2) {
|
||||
dis_sprintf(", ");
|
||||
(this->*entry->Operand2)(insn);
|
||||
}
|
||||
if (entry->Operand3) {
|
||||
dis_sprintf(", ");
|
||||
(this->*entry->Operand3)(insn);
|
||||
}
|
||||
if (entry->Operand4) {
|
||||
dis_sprintf(", ");
|
||||
(this->*entry->Operand4)(insn);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// AT&T STYLE
|
||||
//////////////////
|
||||
|
||||
void disassembler::set_syntax_att()
|
||||
{
|
||||
intel_mode = 0;
|
||||
|
||||
general_16bit_regname = att_general_16bit_regname;
|
||||
general_8bit_regname = att_general_8bit_regname;
|
||||
general_32bit_regname = att_general_32bit_regname;
|
||||
general_8bit_regname_rex = att_general_8bit_regname_rex;
|
||||
general_64bit_regname = att_general_64bit_regname;
|
||||
|
||||
segment_name = att_segment_name;
|
||||
index16 = att_index16;
|
||||
|
||||
initialize_modrm_segregs();
|
||||
}
|
||||
|
||||
void disassembler::toggle_syntax_mode()
|
||||
{
|
||||
if (intel_mode) set_syntax_att();
|
||||
else set_syntax_intel();
|
||||
}
|
||||
|
||||
void disassembler::print_disassembly_att(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry)
|
||||
{
|
||||
// print opcode
|
||||
dis_sprintf("%s ", entry->AttOpcode);
|
||||
|
||||
if (entry->Operand4) {
|
||||
(this->*entry->Operand4)(insn);
|
||||
dis_sprintf(", ");
|
||||
}
|
||||
if (entry->Operand3) {
|
||||
(this->*entry->Operand3)(insn);
|
||||
dis_sprintf(", ");
|
||||
}
|
||||
if (entry->Operand2) {
|
||||
(this->*entry->Operand2)(insn);
|
||||
dis_sprintf(", ");
|
||||
}
|
||||
if (entry->Operand1) {
|
||||
(this->*entry->Operand1)(insn);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user