aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2010-04-08 00:48:21 +0000
committerSean Callanan <scallanan@apple.com>2010-04-08 00:48:21 +0000
commit8f993b8c244bb5ec19d004a070eb9f32c5a29b1a (patch)
tree552595597d80db505ac9ad4dc9c6b4cf15dddfc3
parent6129c376935db12dc79f6d515a1d96632adb480c (diff)
Added support for ARM disassembly to edis.
I also added a rule to the ARM target's Makefile to build the ARM-specific instruction information table for the enhanced disassembler. I will add the test harness for all this stuff in a separate commit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100735 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm-c/EnhancedDisassembly.h5
-rw-r--r--lib/Target/ARM/Makefile2
-rw-r--r--tools/edis/EDDisassembler.cpp74
-rw-r--r--tools/edis/EDDisassembler.h16
-rw-r--r--tools/edis/EDInst.cpp6
-rw-r--r--tools/edis/EDMain.cpp29
-rw-r--r--tools/edis/EDOperand.cpp232
-rw-r--r--tools/edis/EDToken.cpp18
-rw-r--r--utils/TableGen/EDEmitter.cpp579
9 files changed, 677 insertions, 284 deletions
diff --git a/include/llvm-c/EnhancedDisassembly.h b/include/llvm-c/EnhancedDisassembly.h
index 9cd1e1f5f3..5ed6043f66 100644
--- a/include/llvm-c/EnhancedDisassembly.h
+++ b/include/llvm-c/EnhancedDisassembly.h
@@ -19,7 +19,7 @@
#ifndef LLVM_C_ENHANCEDDISASSEMBLY_H
#define LLVM_C_ENHANCEDDISASSEMBLY_H
-#include "llvm/System/DataTypes.h"
+#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
@@ -55,7 +55,8 @@ typedef enum {
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
kEDAssemblySyntaxX86Intel = 0,
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
- kEDAssemblySyntaxX86ATT = 1
+ kEDAssemblySyntaxX86ATT = 1,
+ kEDAssemblySyntaxARMUAL = 2
} EDAssemblySyntax_t;
/*!
diff --git a/lib/Target/ARM/Makefile b/lib/Target/ARM/Makefile
index 47922436f5..9e3ff29e07 100644
--- a/lib/Target/ARM/Makefile
+++ b/lib/Target/ARM/Makefile
@@ -17,7 +17,7 @@ BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \
ARMGenInstrInfo.inc ARMGenAsmWriter.inc \
ARMGenDAGISel.inc ARMGenSubtarget.inc \
ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
- ARMGenDecoderTables.inc
+ ARMGenDecoderTables.inc ARMGenEDInfo.inc
DIRS = AsmPrinter AsmParser Disassembler TargetInfo
diff --git a/tools/edis/EDDisassembler.cpp b/tools/edis/EDDisassembler.cpp
index 8729b4998f..072df822bf 100644
--- a/tools/edis/EDDisassembler.cpp
+++ b/tools/edis/EDDisassembler.cpp
@@ -13,6 +13,9 @@
//
//===----------------------------------------------------------------------===//
+#include "EDDisassembler.h"
+#include "EDInst.h"
+
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -36,10 +39,8 @@
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSelect.h"
-#include "EDDisassembler.h"
-#include "EDInst.h"
-
#include "../../lib/Target/X86/X86GenEDInfo.inc"
+#include "../../lib/Target/ARM/ARMGenEDInfo.inc"
using namespace llvm;
@@ -55,6 +56,8 @@ struct InfoMap {
static struct InfoMap infomap[] = {
{ Triple::x86, "i386-unknown-unknown", instInfoX86 },
{ Triple::x86_64, "x86_64-unknown-unknown", instInfoX86 },
+ { Triple::arm, "arm-unknown-unknown", instInfoARM },
+ { Triple::thumb, "thumb-unknown-unknown", instInfoARM },
{ Triple::InvalidArch, NULL, NULL }
};
@@ -66,7 +69,7 @@ static const InfoMap *infoFromArch(Triple::ArchType arch) {
unsigned int infoIndex;
for (infoIndex = 0; infomap[infoIndex].String != NULL; ++infoIndex) {
- if(arch == infomap[infoIndex].Arch)
+ if (arch == infomap[infoIndex].Arch)
return &infomap[infoIndex];
}
@@ -95,6 +98,11 @@ static int getLLVMSyntaxVariant(Triple::ArchType arch,
return 1;
else
return -1;
+ case kEDAssemblySyntaxARMUAL:
+ if (arch == Triple::arm || arch == Triple::thumb)
+ return 0;
+ else
+ return -1;
}
}
@@ -112,6 +120,7 @@ void EDDisassembler::initialize() {
sInitialized = true;
BRINGUP_TARGET(X86)
+ BRINGUP_TARGET(ARM)
}
#undef BRINGUP_TARGET
@@ -126,10 +135,9 @@ EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
if (i != sDisassemblers.end()) {
return i->second;
- }
- else {
+ } else {
EDDisassembler* sdd = new EDDisassembler(key);
- if(!sdd->valid()) {
+ if (!sdd->valid()) {
delete sdd;
return NULL;
}
@@ -150,11 +158,16 @@ EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
}
EDDisassembler::EDDisassembler(CPUKey &key) :
- Valid(false), ErrorString(), ErrorStream(ErrorString), Key(key) {
+ Valid(false),
+ HasSemantics(false),
+ ErrorStream(nulls()),
+ Key(key) {
const InfoMap *infoMap = infoFromArch(key.Arch);
if (!infoMap)
return;
+
+ InstInfos = infoMap->Info;
const char *triple = infoMap->String;
@@ -182,6 +195,8 @@ EDDisassembler::EDDisassembler(CPUKey &key) :
if (!registerInfo)
return;
+
+ initMaps(*registerInfo);
AsmInfo.reset(Tgt->createAsmInfo(tripleString));
@@ -212,7 +227,7 @@ EDDisassembler::EDDisassembler(CPUKey &key) :
}
EDDisassembler::~EDDisassembler() {
- if(!valid())
+ if (!valid())
return;
}
@@ -230,10 +245,10 @@ namespace {
uint64_t getBase() const { return 0x0; }
uint64_t getExtent() const { return (uint64_t)-1; }
int readByte(uint64_t address, uint8_t *ptr) const {
- if(!Callback)
+ if (!Callback)
return -1;
- if(Callback(ptr, address, Arg))
+ if (Callback(ptr, address, Arg))
return -1;
return 0;
@@ -256,9 +271,10 @@ EDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader,
ErrorStream)) {
delete inst;
return NULL;
- }
- else {
- const InstInfo *thisInstInfo = &InstInfos[inst->getOpcode()];
+ } else {
+ const InstInfo *thisInstInfo;
+
+ thisInstInfo = &InstInfos[inst->getOpcode()];
EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
return sdInst;
@@ -276,8 +292,11 @@ void EDDisassembler::initMaps(const TargetRegisterInfo &registerInfo) {
RegRMap[registerName] = registerIndex;
}
- if (Key.Arch == Triple::x86 ||
- Key.Arch == Triple::x86_64) {
+ switch (Key.Arch) {
+ default:
+ break;
+ case Triple::x86:
+ case Triple::x86_64:
stackPointers.insert(registerIDWithName("SP"));
stackPointers.insert(registerIDWithName("ESP"));
stackPointers.insert(registerIDWithName("RSP"));
@@ -285,6 +304,13 @@ void EDDisassembler::initMaps(const TargetRegisterInfo &registerInfo) {
programCounters.insert(registerIDWithName("IP"));
programCounters.insert(registerIDWithName("EIP"));
programCounters.insert(registerIDWithName("RIP"));
+ break;
+ case Triple::arm:
+ case Triple::thumb:
+ stackPointers.insert(registerIDWithName("SP"));
+
+ programCounters.insert(registerIDWithName("PC"));
+ break;
}
}
@@ -329,6 +355,16 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
const std::string &str) {
int ret = 0;
+ switch (Key.Arch) {
+ default:
+ return -1;
+ case Triple::x86:
+ case Triple::x86_64:
+ case Triple::arm:
+ case Triple::thumb:
+ break;
+ }
+
const char *cStr = str.c_str();
MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
@@ -343,14 +379,14 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
OwningPtr<TargetAsmParser> TargetParser(Tgt->createAsmParser(genericParser));
AsmToken OpcodeToken = genericParser.Lex();
+ genericParser.Lex(); // consume next token, because specificParser expects us to
- if(OpcodeToken.is(AsmToken::Identifier)) {
+ if (OpcodeToken.is(AsmToken::Identifier)) {
instName = OpcodeToken.getString();
instLoc = OpcodeToken.getLoc();
if (TargetParser->ParseInstruction(instName, instLoc, operands))
ret = -1;
- }
- else {
+ } else {
ret = -1;
}
diff --git a/tools/edis/EDDisassembler.h b/tools/edis/EDDisassembler.h
index 6be9152fac..9b27fe8170 100644
--- a/tools/edis/EDDisassembler.h
+++ b/tools/edis/EDDisassembler.h
@@ -113,13 +113,13 @@ struct EDDisassembler {
// Per-object members //
////////////////////////
- /// True only if the object has been fully and successfully initialized
+ /// True only if the object has been successfully initialized
bool Valid;
+ /// True if the disassembler can provide semantic information
+ bool HasSemantics;
- /// The string that stores disassembler errors from the backend
- std::string ErrorString;
- /// The stream that wraps the ErrorString
- llvm::raw_string_ostream ErrorStream;
+ /// The stream to write errors to
+ llvm::raw_ostream &ErrorStream;
/// The architecture/syntax pair for the current architecture
CPUKey Key;
@@ -180,6 +180,12 @@ struct EDDisassembler {
return Valid;
}
+ /// hasSemantics - reports whether the disassembler can provide operands and
+ /// tokens.
+ bool hasSemantics() {
+ return HasSemantics;
+ }
+
~EDDisassembler();
/// createInst - creates and returns an instruction given a callback and
diff --git a/tools/edis/EDInst.cpp b/tools/edis/EDInst.cpp
index 9ed27002ad..1b6a3607ba 100644
--- a/tools/edis/EDInst.cpp
+++ b/tools/edis/EDInst.cpp
@@ -81,21 +81,21 @@ unsigned EDInst::instID() {
bool EDInst::isBranch() {
if (ThisInstInfo)
- return ThisInstInfo->instructionFlags & kInstructionFlagBranch;
+ return ThisInstInfo->instructionType == kInstructionTypeBranch;
else
return false;
}
bool EDInst::isMove() {
if (ThisInstInfo)
- return ThisInstInfo->instructionFlags & kInstructionFlagMove;
+ return ThisInstInfo->instructionType == kInstructionTypeMove;
else
return false;
}
int EDInst::parseOperands() {
if (ParseResult.valid())
- return ParseResult.result();
+ return ParseResult.result();
if (!ThisInstInfo)
return ParseResult.setResult(-1);
diff --git a/tools/edis/EDMain.cpp b/tools/edis/EDMain.cpp
index 3585657ca6..b6ca32f2db 100644
--- a/tools/edis/EDMain.cpp
+++ b/tools/edis/EDMain.cpp
@@ -29,8 +29,7 @@ int EDGetDisassembler(EDDisassemblerRef *disassembler,
if (ret) {
*disassembler = ret;
return 0;
- }
- else {
+ } else {
return -1;
}
}
@@ -39,7 +38,7 @@ int EDGetRegisterName(const char** regName,
EDDisassemblerRef disassembler,
unsigned regID) {
const char* name = disassembler->nameWithRegisterID(regID);
- if(!name)
+ if (!name)
return -1;
*regName = name;
return 0;
@@ -63,10 +62,10 @@ unsigned int EDCreateInsts(EDInstRef *insts,
void *arg) {
unsigned int index;
- for (index = 0; index < count; index++) {
+ for (index = 0; index < count; ++index) {
EDInst *inst = disassembler->createInst(byteReader, address, arg);
- if(!inst)
+ if (!inst)
return index;
insts[index] = inst;
@@ -134,42 +133,42 @@ int EDOperandIndexForToken(EDTokenRef token) {
}
int EDTokenIsWhitespace(EDTokenRef token) {
- if(token->type() == EDToken::kTokenWhitespace)
+ if (token->type() == EDToken::kTokenWhitespace)
return 1;
else
return 0;
}
int EDTokenIsPunctuation(EDTokenRef token) {
- if(token->type() == EDToken::kTokenPunctuation)
+ if (token->type() == EDToken::kTokenPunctuation)
return 1;
else
return 0;
}
int EDTokenIsOpcode(EDTokenRef token) {
- if(token->type() == EDToken::kTokenOpcode)
+ if (token->type() == EDToken::kTokenOpcode)
return 1;
else
return 0;
}
int EDTokenIsLiteral(EDTokenRef token) {
- if(token->type() == EDToken::kTokenLiteral)
+ if (token->type() == EDToken::kTokenLiteral)
return 1;
else
return 0;
}
int EDTokenIsRegister(EDTokenRef token) {
- if(token->type() == EDToken::kTokenRegister)
+ if (token->type() == EDToken::kTokenRegister)
return 1;
else
return 0;
}
int EDTokenIsNegativeLiteral(EDTokenRef token) {
- if(token->type() != EDToken::kTokenLiteral)
+ if (token->type() != EDToken::kTokenLiteral)
return -1;
return token->literalSign();
@@ -177,7 +176,7 @@ int EDTokenIsNegativeLiteral(EDTokenRef token) {
int EDLiteralTokenAbsoluteValue(uint64_t *value,
EDTokenRef token) {
- if(token->type() != EDToken::kTokenLiteral)
+ if (token->type() != EDToken::kTokenLiteral)
return -1;
return token->literalAbsoluteValue(*value);
@@ -185,7 +184,7 @@ int EDLiteralTokenAbsoluteValue(uint64_t *value,
int EDRegisterTokenValue(unsigned *registerID,
EDTokenRef token) {
- if(token->type() != EDToken::kTokenRegister)
+ if (token->type() != EDToken::kTokenRegister)
return -1;
return token->registerID(*registerID);
@@ -215,7 +214,7 @@ int EDOperandIsMemory(EDOperandRef operand) {
int EDRegisterOperandValue(unsigned *value,
EDOperandRef operand) {
- if(!operand->isRegister())
+ if (!operand->isRegister())
return -1;
*value = operand->regVal();
return 0;
@@ -223,7 +222,7 @@ int EDRegisterOperandValue(unsigned *value,
int EDImmediateOperandValue(uint64_t *value,
EDOperandRef operand) {
- if(!operand->isImmediate())
+ if (!operand->isImmediate())
return -1;
*value = operand->immediateVal();
return 0;
diff --git a/tools/edis/EDOperand.cpp b/tools/edis/EDOperand.cpp
index da6797e035..93efd47094 100644
--- a/tools/edis/EDOperand.cpp
+++ b/tools/edis/EDOperand.cpp
@@ -31,26 +31,77 @@ EDOperand::EDOperand(const EDDisassembler &disassembler,
MCOpIndex(mcOpIndex) {
unsigned int numMCOperands = 0;
- if(Disassembler.Key.Arch == Triple::x86 ||
- Disassembler.Key.Arch == Triple::x86_64) {
- uint8_t operandFlags = inst.ThisInstInfo->operandFlags[opIndex];
+ if (Disassembler.Key.Arch == Triple::x86 ||
+ Disassembler.Key.Arch == Triple::x86_64) {
+ uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
- if (operandFlags & kOperandFlagImmediate) {
+ switch (operandType) {
+ default:
+ break;
+ case kOperandTypeImmediate:
numMCOperands = 1;
- }
- else if (operandFlags & kOperandFlagRegister) {
+ break;
+ case kOperandTypeRegister:
numMCOperands = 1;
+ break;
+ case kOperandTypeX86Memory:
+ numMCOperands = 5;
+ break;
+ case kOperandTypeX86EffectiveAddress:
+ numMCOperands = 4;
+ break;
+ case kOperandTypeX86PCRelative:
+ numMCOperands = 1;
+ break;
}
- else if (operandFlags & kOperandFlagMemory) {
- if (operandFlags & kOperandFlagPCRelative) {
- numMCOperands = 1;
- }
- else {
- numMCOperands = 5;
- }
- }
- else if (operandFlags & kOperandFlagEffectiveAddress) {
+ }
+ else if (Disassembler.Key.Arch == Triple::arm ||
+ Disassembler.Key.Arch == Triple::thumb) {
+ uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
+
+ switch (operandType) {
+ default:
+ case kOperandTypeARMRegisterList:
+ break;
+ case kOperandTypeImmediate:
+ case kOperandTypeRegister:
+ case kOperandTypeARMBranchTarget:
+ case kOperandTypeARMSoImm:
+ case kOperandTypeThumb2SoImm:
+ case kOperandTypeARMSoImm2Part:
+ case kOperandTypeARMPredicate:
+ case kOperandTypeThumbITMask:
+ case kOperandTypeThumb2AddrModeImm8Offset:
+ case kOperandTypeARMTBAddrMode:
+ case kOperandTypeThumb2AddrModeImm8s4Offset:
+ numMCOperands = 1;
+ break;
+ case kOperandTypeThumb2SoReg:
+ case kOperandTypeARMAddrMode2Offset:
+ case kOperandTypeARMAddrMode3Offset:
+ case kOperandTypeARMAddrMode4:
+ case kOperandTypeARMAddrMode5:
+ case kOperandTypeARMAddrModePC:
+ case kOperandTypeThumb2AddrModeImm8:
+ case kOperandTypeThumb2AddrModeImm12:
+ case kOperandTypeThumb2AddrModeImm8s4:
+ case kOperandTypeThumbAddrModeRR:
+ case kOperandTypeThumbAddrModeSP:
+ numMCOperands = 2;
+ break;
+ case kOperandTypeARMSoReg:
+ case kOperandTypeARMAddrMode2:
+ case kOperandTypeARMAddrMode3:
+ case kOperandTypeThumb2AddrModeSoReg:
+ case kOperandTypeThumbAddrModeS1:
+ case kOperandTypeThumbAddrModeS2:
+ case kOperandTypeThumbAddrModeS4:
+ case kOperandTypeARMAddrMode6Offset:
+ numMCOperands = 3;
+ break;
+ case kOperandTypeARMAddrMode6:
numMCOperands = 4;
+ break;
}
}
@@ -63,70 +114,103 @@ EDOperand::~EDOperand() {
int EDOperand::evaluate(uint64_t &result,
EDRegisterReaderCallback callback,
void *arg) {
- if (Disassembler.Key.Arch == Triple::x86 ||
- Disassembler.Key.Arch == Triple::x86_64) {
- uint8_t operandFlags = Inst.ThisInstInfo->operandFlags[OpIndex];
-
- if (operandFlags & kOperandFlagImmediate) {
+ uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
+
+ switch (Disassembler.Key.Arch) {
+ default:
+ return -1;
+ case Triple::x86:
+ case Triple::x86_64:
+ switch (operandType) {
+ default:
+ return -1;
+ case kOperandTypeImmediate:
result = Inst.Inst->getOperand(MCOpIndex).getImm();
return 0;
- }
- if (operandFlags & kOperandFlagRegister) {
+ case kOperandTypeRegister:
+ {
unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
return callback(&result, reg, arg);
}
- if (operandFlags & kOperandFlagMemory ||
- operandFlags & kOperandFlagEffectiveAddress){
- if(operandFlags & kOperandFlagPCRelative) {
- int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
+ case kOperandTypeX86PCRelative:
+ {
+ int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
- uint64_t ripVal;
+ uint64_t ripVal;
- // TODO fix how we do this
+ // TODO fix how we do this
- if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
- return -1;
+ if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
+ return -1;
- result = ripVal + displacement;
- return 0;
- }
- else {
- unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
- uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
- unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
- int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
- //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
+ result = ripVal + displacement;
+ return 0;
+ }
+ case kOperandTypeX86Memory:
+ case kOperandTypeX86EffectiveAddress:
+ {
+ unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
+ uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
+ unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
+ int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
+ //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
- uint64_t addr = 0;
+ uint64_t addr = 0;
- if(baseReg) {
- uint64_t baseVal;
- if (callback(&baseVal, baseReg, arg))
- return -1;
- addr += baseVal;
- }
-
- if(indexReg) {
- uint64_t indexVal;
- if (callback(&indexVal, indexReg, arg))
- return -1;
- addr += (scaleAmount * indexVal);
- }
-
- addr += displacement;
+ if (baseReg) {
+ uint64_t baseVal;
+ if (callback(&baseVal, baseReg, arg))
+ return -1;
+ addr += baseVal;
+ }
- result = addr;
- return 0;
+ if (indexReg) {
+ uint64_t indexVal;
+ if (callback(&indexVal, indexReg, arg))
+ return -1;
+ addr += (scaleAmount * indexVal);
}
+
+ addr += displacement;
+
+ result = addr;
+ return 0;
+ }
+ }
+ break;
+ case Triple::arm:
+ case Triple::thumb:
+ switch (operandType) {
+ default:
+ return -1;
+ case kOperandTypeImmediate:
+ result = Inst.Inst->getOperand(MCOpIndex).getImm();
+ return 0;
+ case kOperandTypeRegister:
+ {
+ unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
+ return callback(&result, reg, arg);
+ }
+ case kOperandTypeARMBranchTarget:
+ {
+ int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
+
+ uint64_t pcVal;
+
+ if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
+ return -1;
+
+ result = pcVal + displacement;
+ return 0;
+ }
}
- return -1;
}
return -1;
}
int EDOperand::isRegister() {
- return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagRegister);
+ return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
}
unsigned EDOperand::regVal() {
@@ -134,7 +218,7 @@ unsigned EDOperand::regVal() {
}
int EDOperand::isImmediate() {
- return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagImmediate);
+ return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
}
uint64_t EDOperand::immediateVal() {
@@ -142,7 +226,33 @@ uint64_t EDOperand::immediateVal() {
}
int EDOperand::isMemory() {
- return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagMemory);
+ switch (Inst.ThisInstInfo->operandFlags[OpIndex]) {
+ default:
+ return 0;
+ case kOperandTypeX86Memory:
+ case kOperandTypeARMSoReg:
+ case kOperandTypeARMSoImm:
+ case kOperandTypeARMAddrMode2:
+ case kOperandTypeARMAddrMode2Offset:
+ case kOperandTypeARMAddrMode3:
+ case kOperandTypeARMAddrMode3Offset:
+ case kOperandTypeARMAddrMode4:
+ case kOperandTypeARMAddrMode5:
+ case kOperandTypeARMAddrMode6:
+ case kOperandTypeARMAddrModePC:
+ case kOperandTypeThumbAddrModeS1:
+ case kOperandTypeThumbAddrModeS2:
+ case kOperandTypeThumbAddrModeS4:
+ case kOperandTypeThumbAddrModeRR:
+ case kOperandTypeThumbAddrModeSP:
+ case kOperandTypeThumb2SoImm:
+ case kOperandTypeThumb2AddrModeImm8:
+ case kOperandTypeThumb2AddrModeImm8Offset:
+ case kOperandTypeThumb2AddrModeImm12:
+ case kOperandTypeThumb2AddrModeSoReg:
+ case kOperandTypeThumb2AddrModeImm8s4:
+ return 1;
+ }
}
#ifdef __BLOCKS__
diff --git a/tools/edis/EDToken.cpp b/tools/edis/EDToken.cpp
index cd79152e35..3bcb0a14b8 100644
--- a/tools/edis/EDToken.cpp
+++ b/tools/edis/EDToken.cpp
@@ -68,20 +68,20 @@ int EDToken::operandID() const {
}
int EDToken::literalSign() const {
- if(Type != kTokenLiteral)
+ if (Type != kTokenLiteral)
return -1;
return (LiteralSign ? 1 : 0);
}
int EDToken::literalAbsoluteValue(uint64_t &value) const {
- if(Type != kTokenLiteral)
+ if (Type != kTokenLiteral)
return -1;
value = LiteralAbsoluteValue;
return 0;
}
int EDToken::registerID(unsigned &registerID) const {
- if(Type != kTokenRegister)
+ if (Type != kTokenRegister)
return -1;
registerID = RegisterID;
return 0;
@@ -94,7 +94,7 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
SmallVector<AsmToken, 10> asmTokens;
- if(disassembler.parseInst(parsedOperands, asmTokens, str))
+ if (disassembler.parseInst(parsedOperands, asmTokens, str))
return -1;
SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
@@ -115,7 +115,7 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
const char *tokenPointer = tokenLoc.getPointer();
- if(tokenPointer > wsPointer) {
+ if (tokenPointer > wsPointer) {
unsigned long wsLength = tokenPointer - wsPointer;
EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
@@ -164,7 +164,7 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
int64_t intVal = tokenIterator->getIntVal();
- if(intVal < 0)
+ if (intVal < 0)
token->makeLiteral(true, -intVal);
else
token->makeLiteral(false, intVal);
@@ -182,14 +182,14 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
}
}
- if(operandIterator != parsedOperands.end() &&
+ if (operandIterator != parsedOperands.end() &&
tokenLoc.getPointer() >=
(*operandIterator)->getStartLoc().getPointer()) {
/// operandIndex == 0 means the operand is the instruction (which the
/// AsmParser treats as an operand but edis does not). We therefore skip
/// operandIndex == 0 and subtract 1 from all other operand indices.
- if(operandIndex > 0)
+ if (operandIndex > 0)
token->setOperandID(operandOrder[operandIndex - 1]);
}
@@ -200,7 +200,7 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
}
int EDToken::getString(const char*& buf) {
- if(PermStr.length() == 0) {
+ if (PermStr.length() == 0) {
PermStr = Str.str();
}
buf = PermStr.c_str();
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index f83ab48682..c10d680296 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -23,10 +23,11 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
-#include <vector>
+#include <map>
#include <string>
+#include <vector>
-#define MAX_OPERANDS 5
+#define MAX_OPERANDS 13
#define MAX_SYNTAXES 2
using namespace llvm;
@@ -54,9 +55,9 @@ namespace {
unsigned int index = 0;
unsigned int numEntries = Entries.size();
- for(index = 0; index < numEntries; ++index) {
+ for (index = 0; index < numEntries; ++index) {
o.indent(i) << Entries[index];
- if(index < (numEntries - 1))
+ if (index < (numEntries - 1))
o << ",";
o << "\n";
}
@@ -88,24 +89,24 @@ namespace {
class StructEmitter {
private:
std::string Name;
- std::vector<std::string> MemberTypes;
- std::vector<std::string> MemberNames;
+ typedef std::pair<const char*, const char*> member;
+ std::vector< member > Members;
public:
StructEmitter(const char *N) : Name(N) {
}
void addMember(const char *t, const char *n) {
- MemberTypes.push_back(std::string(t));
- MemberNames.push_back(std::string(n));
+ member m(t, n);
+ Members.push_back(m);
}
void emit(raw_ostream &o, unsigned int &i) {
o.indent(i) << "struct " << Name.c_str() << " {" << "\n";
i += 2;
unsigned int index = 0;
- unsigned int numMembers = MemberTypes.size();
+ unsigned int numMembers = Members.size();
for (index = 0; index < numMembers; ++index) {
- o.indent(i) << MemberTypes[index] << " " << MemberNames[index] << ";";
- o << "\n";
+ o.indent(i) << Members[index].first << " ";
+ o.indent(i) << Members[index].second << ";" << "\n";
}
i -= 2;
@@ -121,47 +122,87 @@ namespace {
class LiteralConstantEmitter : public ConstantEmitter {
private:
- std::string Literal;
+ bool IsNumber;
+ union {
+ int Number;
+ const char* String;
+ };
public:
- LiteralConstantEmitter(const char *literal) : Literal(literal) {
+ LiteralConstantEmitter(const char *string) :
+ IsNumber(false),
+ String(string) {
}
- LiteralConstantEmitter(int literal) {
- char buf[256];
- snprintf(buf, 256, "%d", literal);
- Literal = buf;
+ LiteralConstantEmitter(int number = 0) :
+ IsNumber(true),
+ Number(number) {
+ }
+ void set(const char *string) {
+ IsNumber = false;
+ Number = 0;
+ String = string;
+ }
+ void set(int number) {
+ IsNumber = true;
+ String = NULL;
+ Number = number;
+ }
+ bool is(const char *string) {
+ return !strcmp(String, string);
}
void emit(raw_ostream &o, unsigned int &i) {
- o << Literal;
+ if (IsNumber)
+ o << Number;
+ else
+ o << String;
}
};
class CompoundConstantEmitter : public ConstantEmitter {
private:
- std::vector<ConstantEmitter*> Entries;
+ unsigned int Padding;
+ std::vector<ConstantEmitter *> Entries;
public:
- CompoundConstantEmitter() {
- }
- ~CompoundConstantEmitter() {
- unsigned int index;
- unsigned int numEntries = Entries.size();
- for (index = 0; index < numEntries; ++index) {
- delete Entries[index];
- }
+ CompoundConstantEmitter(unsigned int padding = 0) : Padding(padding) {
}
CompoundConstantEmitter &addEntry(ConstantEmitter *e) {
Entries.push_back(e);
+
return *this;
}
+ ~CompoundConstantEmitter() {
+ while (Entries.size()) {
+ ConstantEmitter *entry = Entries.back();
+ Entries.pop_back();
+ delete entry;
+ }
+ }
void emit(raw_ostream &o, unsigned int &i) {
o << "{" << "\n";
i += 2;
unsigned int index;
unsigned int numEntries = Entries.size();
- for (index = 0; index < numEntries; ++index) {
+
+ unsigned int numToPrint;
+
+ if (Padding) {
+ if (numEntries > Padding) {
+ fprintf(stderr, "%u entries but %u padding\n", numEntries, Padding);
+ llvm_unreachable("More entries than padding");
+ }
+ numToPrint = Padding;
+ } else {
+ numToPrint = numEntries;
+ }
+
+ for (index = 0; index < numToPrint; ++index) {
o.indent(i);
- Entries[index]->emit(o, i);
- if (index < (numEntries - 1))
+ if (index < numEntries)
+ Entries[index]->emit(o, i);
+ else
+ o << "-1";
+
+ if (index < (numToPrint - 1))
o << ",";
o << "\n";
}
@@ -226,40 +267,31 @@ void populateOperandOrder(CompoundConstantEmitter *operandOrder,
++operandIterator) {
if (operandIterator->OperandType ==
AsmWriterOperand::isMachineInstrOperand) {
- char buf[2];
- snprintf(buf, sizeof(buf), "%u", operandIterator->CGIOpNo);
- operandOrder->addEntry(new LiteralConstantEmitter(buf));
+ operandOrder->addEntry(
+ new LiteralConstantEmitter(operandIterator->CGIOpNo));
numArgs++;
}
}
-
- for(; numArgs < MAX_OPERANDS; numArgs++) {
- operandOrder->addEntry(new LiteralConstantEmitter("-1"));
- }
}
/////////////////////////////////////////////////////
// Support functions for handling X86 instructions //
/////////////////////////////////////////////////////
-#define ADDFLAG(flag) flags->addEntry(flag)
+#define SET(flag) { type->set(flag); return 0; }
-#define REG(str) if (name == str) { ADDFLAG("kOperandFlagRegister"); return 0; }
-#define MEM(str) if (name == str) { ADDFLAG("kOperandFlagMemory"); return 0; }
-#define LEA(str) if (name == str) { ADDFLAG("kOperandFlagEffectiveAddress"); \
- return 0; }
-#define IMM(str) if (name == str) { ADDFLAG("kOperandFlagImmediate"); \
- return 0; }
-#define PCR(str) if (name == str) { ADDFLAG("kOperandFlagMemory"); \
- ADDFLAG("kOperandFlagPCRelative"); \
- return 0; }
+#define REG(str) if (name == str) SET("kOperandTypeRegister");
+#define MEM(str) if (name