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:
parent
f906b0e674
commit
0f6b703b72
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
@ -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 << ">";
|
||||
}
|
||||
|
7
test/MC/Disassembler/ARM/marked-up-thumb.txt
Normal file
7
test/MC/Disassembler/ARM/marked-up-thumb.txt
Normal 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
|
6
test/MC/Disassembler/X86/marked-up.txt
Normal file
6
test/MC/Disassembler/X86/marked-up.txt
Normal 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
|
@ -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());
|
||||
|
@ -30,3 +30,4 @@ lto_codegen_compile_to_file
|
||||
LLVMCreateDisasm
|
||||
LLVMDisasmDispose
|
||||
LLVMDisasmInstruction
|
||||
LLVMSetDisasmOptions
|
||||
|
Loading…
Reference in New Issue
Block a user