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
This commit is contained in:
Sean Callanan
2010-04-08 00:48:21 +00:00
parent 6129c37693
commit 8f993b8c24
9 changed files with 682 additions and 289 deletions

View File

@@ -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;
}
else if (operandFlags & kOperandFlagMemory) {
if (operandFlags & kOperandFlagPCRelative) {
numMCOperands = 1;
}
else {
numMCOperands = 5;
}
}
else if (operandFlags & kOperandFlagEffectiveAddress) {
break;
case kOperandTypeX86Memory:
numMCOperands = 5;
break;
case kOperandTypeX86EffectiveAddress:
numMCOperands = 4;
break;
case kOperandTypeX86PCRelative:
numMCOperands = 1;
break;
}
}
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();
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;
result = addr;
return 0;
}
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;
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;
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__