Fixed the Intel-syntax X86 disassembler to respect the (existing) option for hexadecimal immediates, to match AT&T syntax. This also brings a new option for C-vs-MASM-style hex.

Patch by Richard Mitton
Reviewed: http://llvm-reviews.chandlerc.com/D1243



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187614 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Malea 2013-08-01 21:18:16 +00:00
parent b1fa7d4d26
commit 44c8e346c7
4 changed files with 74 additions and 15 deletions

View File

@ -21,6 +21,13 @@ class MCInstrInfo;
class MCRegisterInfo;
class StringRef;
namespace HexStyle {
enum Style {
C, ///< 0xff
Asm ///< 0ffh
};
}
/// MCInstPrinter - This is an instance of a target assembly language printer
/// that converts an MCInst to valid target assembly syntax.
class MCInstPrinter {
@ -42,13 +49,16 @@ protected:
/// True if we are printing immediates as hex.
bool PrintImmHex;
/// Which style to use for printing hexadecimal values.
HexStyle::Style PrintHexStyle;
/// 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), PrintImmHex(0) {}
UseMarkup(0), PrintImmHex(0), PrintHexStyle(HexStyle::C) {}
virtual ~MCInstPrinter();
@ -80,8 +90,16 @@ public:
bool getPrintImmHex() const { return PrintImmHex; }
void setPrintImmHex(bool Value) { PrintImmHex = Value; }
HexStyle::Style getPrintHexStyleHex() const { return PrintHexStyle; }
void setPrintImmHex(HexStyle::Style Value) { PrintHexStyle = Value; }
/// Utility function to print immediates in decimal or hex.
format_object1<int64_t> formatImm(const int64_t Value) const;
format_object1<int64_t> formatImm(const int64_t Value) const { return PrintImmHex ? formatHex(Value) : formatDec(Value); }
/// Utility functions to print decimal/hexadecimal values.
format_object1<int64_t> formatDec(const int64_t Value) const;
format_object1<int64_t> formatHex(const int64_t Value) const;
format_object1<uint64_t> formatHex(const uint64_t Value) const;
};
} // namespace llvm

View File

@ -52,10 +52,53 @@ StringRef MCInstPrinter::markup(StringRef a, StringRef b) const {
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%" PRIx64, Value);
else
return format("%" PRId64, Value);
// For asm-style hex (e.g. 0ffh) the first digit always has to be a number.
static bool needsLeadingZero(uint64_t Value)
{
while(Value)
{
uint64_t digit = (Value >> 60) & 0xf;
if (digit != 0)
return (digit >= 0xa);
Value <<= 4;
}
return false;
}
format_object1<int64_t> MCInstPrinter::formatDec(const int64_t Value) const {
return format("%" PRId64, Value);
}
format_object1<int64_t> MCInstPrinter::formatHex(const int64_t Value) const {
switch(PrintHexStyle) {
case HexStyle::C:
if (Value < 0)
return format("-0x%" PRIx64, -Value);
else
return format("0x%" PRIx64, Value);
case HexStyle::Asm:
if (Value < 0) {
if (needsLeadingZero((uint64_t)(-Value)))
return format("-0%" PRIx64 "h", -Value);
else
return format("-%" PRIx64 "h", -Value);
} else {
if (needsLeadingZero((uint64_t)(Value)))
return format("0%" PRIx64 "h", Value);
else
return format("%" PRIx64 "h", Value);
}
}
}
format_object1<uint64_t> MCInstPrinter::formatHex(const uint64_t Value) const {
switch(PrintHexStyle) {
case HexStyle::C:
return format("0x%" PRIx64, Value);
case HexStyle::Asm:
if (needsLeadingZero(Value))
return format("0%" PRIx64 "h", Value);
else
return format("%" PRIx64 "h", Value);
}
}

View File

@ -139,8 +139,7 @@ void X86ATTInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
int64_t Address;
if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
O << "0x";
O.write_hex(Address);
O << formatHex((uint64_t)Address);
}
else {
// Otherwise, just print the expression.

View File

@ -119,7 +119,7 @@ void X86IntelInstPrinter::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
@ -127,8 +127,7 @@ void X86IntelInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr());
int64_t Address;
if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
O << "0x";
O.write_hex(Address);
O << formatHex((uint64_t)Address);
}
else {
// Otherwise, just print the expression.
@ -143,7 +142,7 @@ void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
if (Op.isReg()) {
printRegName(O, Op.getReg());
} else if (Op.isImm()) {
O << Op.getImm();
O << formatImm((int64_t)Op.getImm());
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
O << *Op.getExpr();
@ -195,7 +194,7 @@ void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
DispVal = -DispVal;
}
}
O << DispVal;
O << formatImm(DispVal);
}
}