1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

Add support for annotated disassembly output for X86 and arm.

Per the October 12, 2012 Proposal for annotated disassembly output sent out by
Jim Grosbach this set of changes implements this for X86 and arm.  The llvm-mc
tool now has a -mdis option to produced the marked up disassembly and a couple
of small example test cases have been added.

rdar://11764962

llvm-svn: 166445
This commit is contained in:
Kevin Enderby 2012-10-22 22:31:46 +00:00
parent f906b0e674
commit 0f6b703b72
9 changed files with 570 additions and 133 deletions

View File

@ -145,6 +145,15 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp);
/**
* Set the disassembler's options. Returns 1 if it can set the Options and 0
* otherwise.
*/
int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
/* The option to produce marked up assembly. */
#define LLVMDisassembler_Option_UseMarkup 1
/**
* Dispose of a disassembler context.
*/

View File

@ -33,12 +33,16 @@ protected:
/// The current set of available features.
unsigned AvailableFeatures;
/// True if we are printing marked up assembly.
bool UseMarkup;
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
const MCRegisterInfo &mri)
: CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0) {}
: CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0),
UseMarkup(0) {}
virtual ~MCInstPrinter();
@ -59,6 +63,9 @@ public:
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
bool getUseMarkup() const { return UseMarkup; }
void setUseMarkup(bool Value) { UseMarkup = Value; }
};
} // namespace llvm

View File

@ -184,3 +184,17 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
}
llvm_unreachable("Invalid DecodeStatus!");
}
//
// LLVMSetDisasmOptions() sets the disassembler's options. It returns 1 if it
// can set all the Options and 0 otherwise.
//
int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
if (Options & LLVMDisassembler_Option_UseMarkup){
LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
MCInstPrinter *IP = DC->getIP();
IP->setUseMarkup(1);
Options &= ~LLVMDisassembler_Option_UseMarkup;
}
return (Options == 0);
}

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,11 @@ using namespace llvm;
void X86ATTInstPrinter::printRegName(raw_ostream &OS,
unsigned RegNo) const {
if (UseMarkup)
OS << "<reg:";
OS << '%' << getRegisterName(RegNo);
if (UseMarkup)
OS << ">";
}
void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
@ -151,17 +155,29 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
if (UseMarkup)
O << "<reg:";
O << '%' << getRegisterName(Op.getReg());
if (UseMarkup)
O << ">";
} else if (Op.isImm()) {
if (UseMarkup)
O << "<imm:";
// Print X86 immediates as signed values.
O << '$' << (int64_t)Op.getImm();
if (UseMarkup)
O << ">";
if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
*CommentStream << format("imm = 0x%" PRIX64 "\n", (uint64_t)Op.getImm());
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
if (UseMarkup)
O << "<imm:";
O << '$' << *Op.getExpr();
if (UseMarkup)
O << ">";
}
}
@ -172,6 +188,9 @@ void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
const MCOperand &DispSpec = MI->getOperand(Op+3);
const MCOperand &SegReg = MI->getOperand(Op+4);
if (UseMarkup)
O << "<mem:";
// If this has a segment register, print it.
if (SegReg.getReg()) {
printOperand(MI, Op+4, O);
@ -196,9 +215,18 @@ void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
O << ',';
printOperand(MI, Op+2, O);
unsigned ScaleVal = MI->getOperand(Op+1).getImm();
if (ScaleVal != 1)
O << ',' << ScaleVal;
if (ScaleVal != 1) {
O << ',';
if (UseMarkup)
O << "<imm:";
O << ScaleVal;
if (UseMarkup)
O << ">";
}
}
O << ')';
}
if (UseMarkup)
O << ">";
}

View File

@ -0,0 +1,7 @@
# RUN: llvm-mc -triple=thumbv7-apple-darwin -mcpu=cortex-a8 -mdis < %s | FileCheck %s
# CHECK: ldr <reg:r4>, <imm:#32>
0x08 0x4c
# CHECK: push {<reg:r1>, <reg:r2>, <reg:r7>}
0x86 0xb4
# CHECK: sub <reg:sp>, <imm:#132>
0xa1 0xb0

View File

@ -0,0 +1,6 @@
# RUN: llvm-mc --mdis %s -triple=x86_64-apple-darwin9 2>&1 | FileCheck %s
# CHECK: movq <mem:<reg:%gs>:8>, <reg:%rcx>
0x65 0x48 0x8b 0x0c 0x25 0x08 0x00 0x00 0x00
# CHECK: xorps <reg:%xmm1>, <reg:%xmm2>
0x0f 0x57 0xd1

View File

@ -158,7 +158,8 @@ enum ActionType {
AC_AsLex,
AC_Assemble,
AC_Disassemble,
AC_EDisassemble
AC_EDisassemble,
AC_MDisassemble
};
static cl::opt<ActionType>
@ -172,6 +173,8 @@ Action(cl::desc("Action to perform:"),
"Disassemble strings of hex bytes"),
clEnumValN(AC_EDisassemble, "edis",
"Enhanced disassembly of strings of hex bytes"),
clEnumValN(AC_MDisassemble, "mdis",
"Marked up disassembly of strings of hex bytes"),
clEnumValEnd));
static const Target *GetTarget(const char *ProgName) {
@ -402,8 +405,9 @@ int main(int argc, char **argv) {
OwningPtr<MCSubtargetInfo>
STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
MCInstPrinter *IP;
if (FileType == OFT_AssemblyFile) {
MCInstPrinter *IP =
IP =
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
MCCodeEmitter *CE = 0;
MCAsmBackend *MAB = 0;
@ -436,6 +440,9 @@ int main(int argc, char **argv) {
case AC_Assemble:
Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI);
break;
case AC_MDisassemble:
IP->setUseMarkup(1);
// Fall through to do disassembly.
case AC_Disassemble:
Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
*Buffer, SrcMgr, Out->os());

View File

@ -30,3 +30,4 @@ lto_codegen_compile_to_file
LLVMCreateDisasm
LLVMDisasmDispose
LLVMDisasmInstruction
LLVMSetDisasmOptions