What year is it! This file has no reason to be written in C, and has doubly no

reason to expose a global symbol 'decodeInstruction' nor to pollute the global
scope with a bunch of external linkage entities (some of which conflict with
others elsewhere in LLVM).

This is just the initial transition to C++; more cleanups to follow.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206717 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith 2014-04-20 21:07:34 +00:00
parent 8612f6be58
commit fe0e7bb571
5 changed files with 103 additions and 109 deletions

View File

@ -1,4 +1,4 @@
add_llvm_library(LLVMX86Disassembler add_llvm_library(LLVMX86Disassembler
X86Disassembler.cpp X86Disassembler.cpp
X86DisassemblerDecoder.c X86DisassemblerDecoder.cpp
) )

View File

@ -37,18 +37,18 @@
using namespace llvm; using namespace llvm;
using namespace llvm::X86Disassembler; using namespace llvm::X86Disassembler;
void x86DisassemblerDebug(const char *file, void llvm::X86Disassembler::Debug(const char *file, unsigned line,
unsigned line,
const char *s) { const char *s) {
dbgs() << file << ":" << line << ": " << s; dbgs() << file << ":" << line << ": " << s;
} }
const char *x86DisassemblerGetInstrName(unsigned Opcode, const void *mii) { const char *llvm::X86Disassembler::GetInstrName(unsigned Opcode,
const void *mii) {
const MCInstrInfo *MII = static_cast<const MCInstrInfo *>(mii); const MCInstrInfo *MII = static_cast<const MCInstrInfo *>(mii);
return MII->getName(Opcode); return MII->getName(Opcode);
} }
#define debug(s) DEBUG(x86DisassemblerDebug(__FILE__, __LINE__, s)); #define debug(s) DEBUG(Debug(__FILE__, __LINE__, s));
namespace llvm { namespace llvm {

View File

@ -1,17 +1,17 @@
/*===-- X86DisassemblerDecoder.c - Disassembler decoder ------------*- C -*-===* //===-- X86DisassemblerDecoder.c - Disassembler decoder -------------------===//
* //
* The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
* //
* This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
* //
*===----------------------------------------------------------------------===* //===----------------------------------------------------------------------===//
* //
* This file is part of the X86 Disassembler. // This file is part of the X86 Disassembler.
* It contains the implementation of the instruction decoder. // It contains the implementation of the instruction decoder.
* Documentation for the disassembler can be found in X86Disassembler.h. // Documentation for the disassembler can be found in X86Disassembler.h.
* //
*===----------------------------------------------------------------------===*/ //===----------------------------------------------------------------------===//
#include <stdarg.h> /* for va_*() */ #include <stdarg.h> /* for va_*() */
#include <stdio.h> /* for vsnprintf() */ #include <stdio.h> /* for vsnprintf() */
@ -20,13 +20,15 @@
#include "X86DisassemblerDecoder.h" #include "X86DisassemblerDecoder.h"
using namespace llvm::X86Disassembler;
#include "X86GenDisassemblerTables.inc" #include "X86GenDisassemblerTables.inc"
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
#ifndef NDEBUG #ifndef NDEBUG
#define debug(s) do { x86DisassemblerDebug(__FILE__, __LINE__, s); } while (0) #define debug(s) do { Debug(__FILE__, __LINE__, s); } while (0)
#else #else
#define debug(s) do { } while (0) #define debug(s) do { } while (0)
#endif #endif
@ -41,7 +43,7 @@
* an instruction with these attributes. * an instruction with these attributes.
*/ */
static InstructionContext contextForAttrs(uint16_t attrMask) { static InstructionContext contextForAttrs(uint16_t attrMask) {
return CONTEXTS_SYM[attrMask]; return static_cast<InstructionContext>(CONTEXTS_SYM[attrMask]);
} }
/* /*
@ -792,9 +794,7 @@ static int getIDWithAttrMask(uint16_t* instructionID,
uint16_t attrMask) { uint16_t attrMask) {
BOOL hasModRMExtension; BOOL hasModRMExtension;
uint16_t instructionClass; InstructionContext instructionClass = contextForAttrs(attrMask);
instructionClass = contextForAttrs(attrMask);
hasModRMExtension = modRMRequired(insn->opcodeType, hasModRMExtension = modRMRequired(insn->opcodeType,
instructionClass, instructionClass,
@ -1011,9 +1011,8 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
return 0; return 0;
} }
specName = x86DisassemblerGetInstrName(instructionID, miiArg); specName = GetInstrName(instructionID, miiArg);
specWithOpSizeName = specWithOpSizeName = GetInstrName(instructionIDWithOpsize, miiArg);
x86DisassemblerGetInstrName(instructionIDWithOpsize, miiArg);
if (is16BitEquivalent(specName, specWithOpSizeName) && if (is16BitEquivalent(specName, specWithOpSizeName) &&
(insn->mode == MODE_16BIT) ^ insn->prefixPresent[0x66]) { (insn->mode == MODE_16BIT) ^ insn->prefixPresent[0x66]) {
@ -1077,8 +1076,8 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
* @return - 0 if the SIB byte was successfully read; nonzero otherwise. * @return - 0 if the SIB byte was successfully read; nonzero otherwise.
*/ */
static int readSIB(struct InternalInstruction* insn) { static int readSIB(struct InternalInstruction* insn) {
SIBIndex sibIndexBase = 0; SIBIndex sibIndexBase = SIB_INDEX_NONE;
SIBBase sibBaseBase = 0; SIBBase sibBaseBase = SIB_BASE_NONE;
uint8_t index, base; uint8_t index, base;
dbgprintf(insn, "readSIB()"); dbgprintf(insn, "readSIB()");
@ -1599,20 +1598,22 @@ static int readImmediate(struct InternalInstruction* insn, uint8_t size) {
static int readVVVV(struct InternalInstruction* insn) { static int readVVVV(struct InternalInstruction* insn) {
dbgprintf(insn, "readVVVV()"); dbgprintf(insn, "readVVVV()");
int vvvv;
if (insn->vectorExtensionType == TYPE_EVEX) if (insn->vectorExtensionType == TYPE_EVEX)
insn->vvvv = vvvvFromEVEX3of4(insn->vectorExtensionPrefix[2]); vvvv = vvvvFromEVEX3of4(insn->vectorExtensionPrefix[2]);
else if (insn->vectorExtensionType == TYPE_VEX_3B) else if (insn->vectorExtensionType == TYPE_VEX_3B)
insn->vvvv = vvvvFromVEX3of3(insn->vectorExtensionPrefix[2]); vvvv = vvvvFromVEX3of3(insn->vectorExtensionPrefix[2]);
else if (insn->vectorExtensionType == TYPE_VEX_2B) else if (insn->vectorExtensionType == TYPE_VEX_2B)
insn->vvvv = vvvvFromVEX2of2(insn->vectorExtensionPrefix[1]); vvvv = vvvvFromVEX2of2(insn->vectorExtensionPrefix[1]);
else if (insn->vectorExtensionType == TYPE_XOP) else if (insn->vectorExtensionType == TYPE_XOP)
insn->vvvv = vvvvFromXOP3of3(insn->vectorExtensionPrefix[2]); vvvv = vvvvFromXOP3of3(insn->vectorExtensionPrefix[2]);
else else
return -1; return -1;
if (insn->mode != MODE_64BIT) if (insn->mode != MODE_64BIT)
insn->vvvv &= 0x7; vvvv &= 0x7;
insn->vvvv = static_cast<Reg>(vvvv);
return 0; return 0;
} }
@ -1629,7 +1630,8 @@ static int readMaskRegister(struct InternalInstruction* insn) {
if (insn->vectorExtensionType != TYPE_EVEX) if (insn->vectorExtensionType != TYPE_EVEX)
return -1; return -1;
insn->writemask = aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]); insn->writemask =
static_cast<Reg>(aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]));
return 0; return 0;
} }
@ -1781,14 +1783,10 @@ static int readOperands(struct InternalInstruction* insn) {
* @return - 0 if the instruction's memory could be read; nonzero if * @return - 0 if the instruction's memory could be read; nonzero if
* not. * not.
*/ */
int decodeInstruction(struct InternalInstruction* insn, int llvm::X86Disassembler::decodeInstruction(
byteReader_t reader, struct InternalInstruction *insn, byteReader_t reader,
const void* readerArg, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg,
dlog_t logger, uint64_t startLoc, DisassemblerMode mode) {
void* loggerArg,
const void* miiArg,
uint64_t startLoc,
DisassemblerMode mode) {
memset(insn, 0, sizeof(struct InternalInstruction)); memset(insn, 0, sizeof(struct InternalInstruction));
insn->reader = reader; insn->reader = reader;

View File

@ -1,25 +1,21 @@
/*===-- X86DisassemblerDecoderInternal.h - Disassembler decoder ---*- C -*-===* //===-- X86DisassemblerDecoderInternal.h - Disassembler decoder -*- C++ -*-===//
* //
* The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
* //
* This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
* //
*===----------------------------------------------------------------------===* //===----------------------------------------------------------------------===//
* //
* This file is part of the X86 Disassembler. // This file is part of the X86 Disassembler.
* It contains the public interface of the instruction decoder. // It contains the public interface of the instruction decoder.
* Documentation for the disassembler can be found in X86Disassembler.h. // Documentation for the disassembler can be found in X86Disassembler.h.
* //
*===----------------------------------------------------------------------===*/ //===----------------------------------------------------------------------===//
#ifndef X86DISASSEMBLERDECODER_H #ifndef X86DISASSEMBLERDECODER_H
#define X86DISASSEMBLERDECODER_H #define X86DISASSEMBLERDECODER_H
#ifdef __cplusplus
extern "C" {
#endif
#define INSTRUCTION_SPECIFIER_FIELDS \ #define INSTRUCTION_SPECIFIER_FIELDS \
uint16_t operands; uint16_t operands;
@ -31,6 +27,9 @@ extern "C" {
#undef INSTRUCTION_SPECIFIER_FIELDS #undef INSTRUCTION_SPECIFIER_FIELDS
#undef INSTRUCTION_IDS #undef INSTRUCTION_IDS
namespace llvm {
namespace X86Disassembler {
/* /*
* Accessor functions for various fields of an Intel instruction * Accessor functions for various fields of an Intel instruction
*/ */
@ -684,21 +683,17 @@ int decodeInstruction(struct InternalInstruction* insn,
uint64_t startLoc, uint64_t startLoc,
DisassemblerMode mode); DisassemblerMode mode);
/* x86DisassemblerDebug - C-accessible function for printing a message to /* \brief Debug - Print a message to debugs()
* debugs()
* @param file - The name of the file printing the debug message. * @param file - The name of the file printing the debug message.
* @param line - The line number that printed the debug message. * @param line - The line number that printed the debug message.
* @param s - The message to print. * @param s - The message to print.
*/ */
void x86DisassemblerDebug(const char *file, void Debug(const char *file, unsigned line, const char *s);
unsigned line,
const char *s);
const char *x86DisassemblerGetInstrName(unsigned Opcode, const void *mii); const char *GetInstrName(unsigned Opcode, const void *mii);
#ifdef __cplusplus } // namespace X86Disassembler
} } // namespace llvm
#endif
#endif #endif

View File

@ -1,29 +1,27 @@
/*===-- X86DisassemblerDecoderCommon.h - Disassembler decoder -----*- C -*-===* //===-- X86DisassemblerDecoderCommon.h - Disassembler decoder ---*- C++ -*-===//
* //
* The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
* //
* This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
* //
*===----------------------------------------------------------------------===* //===----------------------------------------------------------------------===//
* //
* This file is part of the X86 Disassembler. // This file is part of the X86 Disassembler.
* It contains common definitions used by both the disassembler and the table // It contains common definitions used by both the disassembler and the table
* generator. // generator.
* Documentation for the disassembler can be found in X86Disassembler.h. // Documentation for the disassembler can be found in X86Disassembler.h.
* //
*===----------------------------------------------------------------------===*/ //===----------------------------------------------------------------------===//
/*
* This header file provides those definitions that need to be shared between
* the decoder and the table generator in a C-friendly manner.
*/
#ifndef X86DISASSEMBLERDECODERCOMMON_H #ifndef X86DISASSEMBLERDECODERCOMMON_H
#define X86DISASSEMBLERDECODERCOMMON_H #define X86DISASSEMBLERDECODERCOMMON_H
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
namespace llvm {
namespace X86Disassembler {
#define INSTRUCTIONS_SYM x86DisassemblerInstrSpecifiers #define INSTRUCTIONS_SYM x86DisassemblerInstrSpecifiers
#define CONTEXTS_SYM x86DisassemblerContexts #define CONTEXTS_SYM x86DisassemblerContexts
#define ONEBYTE_SYM x86DisassemblerOneByteOpcodes #define ONEBYTE_SYM x86DisassemblerOneByteOpcodes
@ -274,17 +272,17 @@ enum attributeBits {
ENUM_ENTRY(IC_EVEX_L2_W_OPSIZE_KZ, 4, "requires EVEX_KZ, L2, W and OpSize") ENUM_ENTRY(IC_EVEX_L2_W_OPSIZE_KZ, 4, "requires EVEX_KZ, L2, W and OpSize")
#define ENUM_ENTRY(n, r, d) n, #define ENUM_ENTRY(n, r, d) n,
typedef enum { enum InstructionContext {
INSTRUCTION_CONTEXTS INSTRUCTION_CONTEXTS
IC_max IC_max
} InstructionContext; };
#undef ENUM_ENTRY #undef ENUM_ENTRY
/* /*
* Opcode types, which determine which decode table to use, both in the Intel * Opcode types, which determine which decode table to use, both in the Intel
* manual and also for the decoder. * manual and also for the decoder.
*/ */
typedef enum { enum OpcodeType {
ONEBYTE = 0, ONEBYTE = 0,
TWOBYTE = 1, TWOBYTE = 1,
THREEBYTE_38 = 2, THREEBYTE_38 = 2,
@ -292,7 +290,7 @@ typedef enum {
XOP8_MAP = 4, XOP8_MAP = 4,
XOP9_MAP = 5, XOP9_MAP = 5,
XOPA_MAP = 6 XOPA_MAP = 6
} OpcodeType; };
/* /*
* The following structs are used for the hierarchical decode table. After * The following structs are used for the hierarchical decode table. After
@ -333,10 +331,10 @@ typedef uint16_t InstrUID;
ENUM_ENTRY(MODRM_FULL) ENUM_ENTRY(MODRM_FULL)
#define ENUM_ENTRY(n) n, #define ENUM_ENTRY(n) n,
typedef enum { enum ModRMDecisionType {
MODRMTYPES MODRMTYPES
MODRM_max MODRM_max
} ModRMDecisionType; };
#undef ENUM_ENTRY #undef ENUM_ENTRY
/* /*
@ -356,7 +354,7 @@ struct ModRMDecision {
* given a particular opcode. * given a particular opcode.
*/ */
struct OpcodeDecision { struct OpcodeDecision {
struct ModRMDecision modRMDecisions[256]; ModRMDecision modRMDecisions[256];
}; };
/* /*
@ -367,7 +365,7 @@ struct OpcodeDecision {
* entries in this table, rather than 2^(ATTR_max). * entries in this table, rather than 2^(ATTR_max).
*/ */
struct ContextDecision { struct ContextDecision {
struct OpcodeDecision opcodeDecisions[IC_max]; OpcodeDecision opcodeDecisions[IC_max];
}; };
/* /*
@ -408,10 +406,10 @@ struct ContextDecision {
ENUM_ENTRY(ENCODING_DI, "Destination index; encoded in prefixes") ENUM_ENTRY(ENCODING_DI, "Destination index; encoded in prefixes")
#define ENUM_ENTRY(n, d) n, #define ENUM_ENTRY(n, d) n,
typedef enum { enum OperandEncoding {
ENCODINGS ENCODINGS
ENCODING_max ENCODING_max
} OperandEncoding; };
#undef ENUM_ENTRY #undef ENUM_ENTRY
/* /*
@ -508,10 +506,10 @@ struct ContextDecision {
ENUM_ENTRY(TYPE_M512, "512-bit FPU/MMX/XMM/MXCSR state") ENUM_ENTRY(TYPE_M512, "512-bit FPU/MMX/XMM/MXCSR state")
#define ENUM_ENTRY(n, d) n, #define ENUM_ENTRY(n, d) n,
typedef enum { enum OperandType {
TYPES TYPES
TYPE_max TYPE_max
} OperandType; };
#undef ENUM_ENTRY #undef ENUM_ENTRY
/* /*
@ -532,10 +530,10 @@ struct OperandSpecifier {
ENUM_ENTRY(MODIFIER_NONE) ENUM_ENTRY(MODIFIER_NONE)
#define ENUM_ENTRY(n) n, #define ENUM_ENTRY(n) n,
typedef enum { enum ModifierType {
MODIFIER_TYPES MODIFIER_TYPES
MODIFIER_max MODIFIER_max
} ModifierType; };
#undef ENUM_ENTRY #undef ENUM_ENTRY
#define X86_MAX_OPERANDS 5 #define X86_MAX_OPERANDS 5
@ -554,10 +552,13 @@ struct InstructionSpecifier {
* are supported, and represent real mode, IA-32e, and IA-32e in 64-bit mode, * are supported, and represent real mode, IA-32e, and IA-32e in 64-bit mode,
* respectively. * respectively.
*/ */
typedef enum { enum DisassemblerMode {
MODE_16BIT, MODE_16BIT,
MODE_32BIT, MODE_32BIT,
MODE_64BIT MODE_64BIT
} DisassemblerMode; };
} // namespace X86Disassembler
} // namespace llvm
#endif #endif