Skip to content

Commit

Permalink
Added a option to the disassembler to print immediates as hex.
Browse files Browse the repository at this point in the history
This is for the lldb team so most of but not all of the values are
to be printed as hex with this option.  Some small values like the
scale in an X86 address were requested to printed in decimal
without the leading 0x.

There may be some tweaks need to places that may still be in
decimal that they want in hex.  Specially for arm.  I made my best
guess.  Any tweaks from here should be simple.

I also did the best I know now with help from the C++ gurus
creating the cleanest formatImm() utility function and containing
the changes.  But if someone has a better idea to make something
cleaner I'm all ears and game for changing the implementation.

rdar://8109283



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169393 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
enderby committed Dec 5, 2012
1 parent d1abec3 commit 14ccc90
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 16 deletions.
2 changes: 2 additions & 0 deletions include/llvm-c/Disassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);

/* The option to produce marked up assembly. */
#define LLVMDisassembler_Option_UseMarkup 1
/* The option to print immediates as hex. */
#define LLVMDisassembler_Option_PrintImmHex 2

/**
* Dispose of a disassembler context.
Expand Down
13 changes: 12 additions & 1 deletion include/llvm/MC/MCInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#ifndef LLVM_MC_MCINSTPRINTER_H
#define LLVM_MC_MCINSTPRINTER_H

#include "llvm/Support/Format.h"

namespace llvm {
class MCInst;
class raw_ostream;
Expand All @@ -36,13 +38,16 @@ class MCInstPrinter {
/// True if we are printing marked up assembly.
bool UseMarkup;

/// True if we are printing immediates as hex.
bool PrintImmHex;

/// 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),
UseMarkup(0) {}
UseMarkup(0), PrintImmHex(0) {}

virtual ~MCInstPrinter();

Expand Down Expand Up @@ -70,6 +75,12 @@ class MCInstPrinter {
/// Utility functions to make adding mark ups simpler.
StringRef markup(StringRef s) const;
StringRef markup(StringRef a, StringRef b) const;

bool getPrintImmHex() const { return PrintImmHex; }
void setPrintImmHex(bool Value) { PrintImmHex = Value; }

/// Utility function to print immediates in decimal or hex.
format_object1<int64_t> formatImm(const int64_t Value) const;
};

} // namespace llvm
Expand Down
6 changes: 6 additions & 0 deletions lib/MC/MCDisassembler/Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,5 +182,11 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
IP->setUseMarkup(1);
Options &= ~LLVMDisassembler_Option_UseMarkup;
}
if (Options & LLVMDisassembler_Option_PrintImmHex){
LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
MCInstPrinter *IP = DC->getIP();
IP->setPrintImmHex(1);
Options &= ~LLVMDisassembler_Option_PrintImmHex;
}
return (Options == 0);
}
9 changes: 9 additions & 0 deletions lib/MC/MCInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

Expand Down Expand Up @@ -50,3 +51,11 @@ StringRef MCInstPrinter::markup(StringRef a, StringRef b) const {
else
return b;
}

/// Utility function to print immediates in decimal or hex.
format_object1<int64_t> MCInstPrinter::formatImm(const int64_t Value) const {
if (getPrintImmHex())
return format("0x%llx", Value);
else
return format("%lld", Value);
}
14 changes: 7 additions & 7 deletions lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
printRegName(O, Reg);
} else if (Op.isImm()) {
O << markup("<imm:")
<< '#' << Op.getImm()
<< '#' << formatImm(Op.getImm())
<< markup(">");
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
Expand All @@ -319,7 +319,7 @@ void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
O << *MO1.getExpr();
else if (MO1.isImm()) {
O << markup("<mem:") << "[pc, "
<< markup("<imm:") << "#" << MO1.getImm()
<< markup("<imm:") << "#" << formatImm(MO1.getImm())
<< markup(">]>", "]");
}
else
Expand Down Expand Up @@ -911,15 +911,15 @@ void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O) {
O << markup("<imm:")
<< "#" << MI->getOperand(OpNum).getImm() * 4
<< "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
<< markup(">");
}

void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
raw_ostream &O) {
unsigned Imm = MI->getOperand(OpNum).getImm();
O << markup("<imm:")
<< "#" << (Imm == 0 ? 32 : Imm)
<< "#" << formatImm((Imm == 0 ? 32 : Imm))
<< markup(">");
}

Expand Down Expand Up @@ -976,7 +976,7 @@ void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
if (unsigned ImmOffs = MO2.getImm()) {
O << ", "
<< markup("<imm:")
<< "#" << ImmOffs * Scale
<< "#" << formatImm(ImmOffs * Scale)
<< markup(">");
}
O << "]" << markup(">");
Expand Down Expand Up @@ -1127,7 +1127,7 @@ void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(const MCInst *MI,
if (MO2.getImm()) {
O << ", "
<< markup("<imm:")
<< "#" << MO2.getImm() * 4
<< "#" << formatImm(MO2.getImm() * 4)
<< markup(">");
}
O << "]" << markup(">");
Expand Down Expand Up @@ -1217,7 +1217,7 @@ void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O) {
unsigned Imm = MI->getOperand(OpNum).getImm();
O << markup("<imm:")
<< "#" << Imm + 1
<< "#" << formatImm(Imm + 1)
<< markup(">");
}

Expand Down
8 changes: 4 additions & 4 deletions lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void X86ATTInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isImm())
O << Op.getImm();
O << formatImm(Op.getImm());
else {
assert(Op.isExpr() && "unknown pcrel immediate operand");
// If a symbolic branch target was added as a constant expression then print
Expand All @@ -157,7 +157,7 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
} else if (Op.isImm()) {
// Print X86 immediates as signed values.
O << markup("<imm:")
<< '$' << (int64_t)Op.getImm()
<< '$' << formatImm((int64_t)Op.getImm())
<< markup(">");

if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256))
Expand Down Expand Up @@ -189,7 +189,7 @@ void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
if (DispSpec.isImm()) {
int64_t DispVal = DispSpec.getImm();
if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
O << DispVal;
O << formatImm(DispVal);
} else {
assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
O << *DispSpec.getExpr();
Expand All @@ -207,7 +207,7 @@ void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
if (ScaleVal != 1) {
O << ','
<< markup("<imm:")
<< ScaleVal
<< ScaleVal // never printed in hex.
<< markup(">");
}
}
Expand Down
5 changes: 5 additions & 0 deletions test/MC/Disassembler/ARM/hex-immediates.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# RUN: llvm-mc -triple=thumbv7-apple-darwin -mcpu=cortex-a8 -hdis < %s | FileCheck %s
# CHECK: ldr r4, [pc, #0x20]
0x08 0x4c
# CHECK: sub sp, #0x84
0xa1 0xb0
10 changes: 10 additions & 0 deletions test/MC/Disassembler/X86/hex-immediates.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# RUN: llvm-mc --hdis %s -triple=x86_64-apple-darwin9 2>&1 | FileCheck %s

# CHECK: movabsq $0x7fffffffffffffff, %rcx
0x48 0xb9 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x7f
# CHECK: leaq 0x3e2(%rip), %rdi
0x48 0x8d 0x3d 0xe2 0x03 0x00 0x00
# CHECK: subq $0x40, %rsp
0x48 0x83 0xec 0x40
# CHECK: leal (,%r14,4), %eax
0x42 0x8d 0x04 0xb5 0x00 0x00 0x00 0x00
20 changes: 16 additions & 4 deletions tools/llvm-mc/llvm-mc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ enum ActionType {
AC_Assemble,
AC_Disassemble,
AC_EDisassemble,
AC_MDisassemble
AC_MDisassemble,
AC_HDisassemble
};

static cl::opt<ActionType>
Expand All @@ -178,6 +179,9 @@ Action(cl::desc("Action to perform:"),
"Enhanced disassembly of strings of hex bytes"),
clEnumValN(AC_MDisassemble, "mdis",
"Marked up disassembly of strings of hex bytes"),
clEnumValN(AC_HDisassemble, "hdis",
"Disassemble strings of hex bytes printing "
"immediates as hex"),
clEnumValEnd));

static const Target *GetTarget(const char *ProgName) {
Expand Down Expand Up @@ -437,6 +441,7 @@ int main(int argc, char **argv) {
}

int Res = 1;
bool disassemble = false;
switch (Action) {
case AC_AsLex:
Res = AsLexInput(SrcMgr, *MAI, Out.get());
Expand All @@ -446,15 +451,22 @@ int main(int argc, char **argv) {
break;
case AC_MDisassemble:
IP->setUseMarkup(1);
// Fall through to do disassembly.
disassemble = true;
break;
case AC_HDisassemble:
IP->setPrintImmHex(1);
disassemble = true;
break;
case AC_Disassemble:
Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
*Buffer, SrcMgr, Out->os());
disassemble = true;
break;
case AC_EDisassemble:
Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, SrcMgr, Out->os());
break;
}
if (disassemble)
Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
*Buffer, SrcMgr, Out->os());

// Keep output if no errors.
if (Res == 0) Out->keep();
Expand Down

0 comments on commit 14ccc90

Please sign in to comment.