/* 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.
#ifndef LLVM_MC_MCINSTPRINTER_H
#define LLVM_MC_MCINSTPRINTER_H
+#include "llvm/Support/Format.h"
+
namespace llvm {
class MCInst;
class raw_ostream;
/// 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();
/// 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
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);
}
#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;
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);
+}
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");
O << *MO1.getExpr();
else if (MO1.isImm()) {
O << markup("<mem:") << "[pc, "
- << markup("<imm:") << "#" << MO1.getImm()
+ << markup("<imm:") << "#" << formatImm(MO1.getImm())
<< markup(">]>", "]");
}
else
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(">");
}
raw_ostream &O) {
unsigned Imm = MI->getOperand(OpNum).getImm();
O << markup("<imm:")
- << "#" << (Imm == 0 ? 32 : Imm)
+ << "#" << formatImm((Imm == 0 ? 32 : Imm))
<< markup(">");
}
if (unsigned ImmOffs = MO2.getImm()) {
O << ", "
<< markup("<imm:")
- << "#" << ImmOffs * Scale
+ << "#" << formatImm(ImmOffs * Scale)
<< markup(">");
}
O << "]" << markup(">");
if (MO2.getImm()) {
O << ", "
<< markup("<imm:")
- << "#" << MO2.getImm() * 4
+ << "#" << formatImm(MO2.getImm() * 4)
<< markup(">");
}
O << "]" << markup(">");
raw_ostream &O) {
unsigned Imm = MI->getOperand(OpNum).getImm();
O << markup("<imm:")
- << "#" << Imm + 1
+ << "#" << formatImm(Imm + 1)
<< markup(">");
}
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
} 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))
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();
if (ScaleVal != 1) {
O << ','
<< markup("<imm:")
- << ScaleVal
+ << ScaleVal // never printed in hex.
<< markup(">");
}
}
--- /dev/null
+# 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
--- /dev/null
+# 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
AC_Assemble,
AC_Disassemble,
AC_EDisassemble,
- AC_MDisassemble
+ AC_MDisassemble,
+ AC_HDisassemble
};
static cl::opt<ActionType>
"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) {
}
int Res = 1;
+ bool disassemble = false;
switch (Action) {
case AC_AsLex:
Res = AsLexInput(SrcMgr, *MAI, Out.get());
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();