Index: llvm/include/llvm/MC/MCInstPrinter.h =================================================================== --- llvm/include/llvm/MC/MCInstPrinter.h +++ llvm/include/llvm/MC/MCInstPrinter.h @@ -55,6 +55,9 @@ /// True if we are printing marked up assembly. bool UseMarkup = false; + /// True if we are printing colored assembly. + bool UseColor = false; + /// True if we prefer aliases (e.g. nop) to raw mnemonics. bool PrintAliases = true; @@ -85,6 +88,33 @@ virtual ~MCInstPrinter(); + enum class Markup { + Immediate, + Register, + Address, + }; + + class WithMarkup { + public: + WithMarkup(raw_ostream &OS, Markup M, bool EnableMarkup, bool EnableColor); + ~WithMarkup(); + + template WithMarkup &operator<<(T &O) { + OS << O; + return *this; + } + + template WithMarkup &operator<<(const T &O) { + OS << O; + return *this; + } + + private: + raw_ostream &OS; + bool EnableMarkup; + bool EnableColor; + }; + /// Customize the printer according to a command line option. /// @return true if the option is recognized and applied. virtual bool applyTargetSpecificCLOption(StringRef Opt) { return false; } @@ -116,6 +146,11 @@ bool getUseMarkup() const { return UseMarkup; } void setUseMarkup(bool Value) { UseMarkup = Value; } + bool getUseColor() const { return UseColor; } + void setUseColor(bool Value) { UseColor = Value; } + + WithMarkup markup(raw_ostream &OS, Markup M) const; + /// Utility functions to make adding mark ups simpler. StringRef markup(StringRef s) const; Index: llvm/lib/MC/MCInstPrinter.cpp =================================================================== --- llvm/lib/MC/MCInstPrinter.cpp +++ llvm/lib/MC/MCInstPrinter.cpp @@ -231,3 +231,47 @@ } llvm_unreachable("unsupported print style"); } + +MCInstPrinter::WithMarkup MCInstPrinter::markup(raw_ostream &OS, + Markup S) const { + return WithMarkup(OS, S, getUseMarkup(), getUseColor()); +} + +MCInstPrinter::WithMarkup::WithMarkup(raw_ostream &OS, Markup M, + bool EnableMarkup, bool EnableColor) + : OS(OS), EnableMarkup(EnableMarkup), EnableColor(EnableColor) { + if (EnableColor) { + switch (M) { + case Markup::Immediate: + OS.changeColor(raw_ostream::RED); + break; + case Markup::Register: + OS.changeColor(raw_ostream::CYAN); + break; + case Markup::Address: + OS.changeColor(raw_ostream::YELLOW); + break; + } + } + + if (EnableMarkup) { + switch (M) { + case Markup::Immediate: + OS << "'; + if (EnableColor) + OS.resetColor(); +} Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h =================================================================== --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -91,7 +91,8 @@ const MCSubtargetInfo &STI, raw_ostream &O); void printArithExtend(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); - + void printMemExtendImpl(bool SignExtend, bool DoShift, unsigned Width, + char SrcRegKind, raw_ostream &O); void printMemExtend(const MCInst *MI, unsigned OpNum, raw_ostream &O, char SrcRegKind, unsigned Width); template Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp =================================================================== --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -60,12 +60,12 @@ } void AArch64InstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const { - OS << markup(""); + markup(OS, Markup::Register) << getRegisterName(Reg); } void AArch64InstPrinter::printRegName(raw_ostream &OS, MCRegister Reg, unsigned AltIdx) const { - OS << markup(""); + markup(OS, Markup::Register) << getRegisterName(Reg, AltIdx); } StringRef AArch64InstPrinter::getRegName(MCRegister Reg) const { @@ -175,7 +175,8 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op1.getReg()); - O << ", " << markup(""); + O << ", "; + markup(O, Markup::Immediate) << "#" << shift; printAnnotation(O, Annot); return; } @@ -187,9 +188,10 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op1.getReg()); - O << ", " << markup("") << ", " << markup(""); + O << ", "; + markup(O, Markup::Immediate) << "#" << (Is64Bit ? 64 : 32) - Op2.getImm(); + O << ", "; + markup(O, Markup::Immediate) << "#" << Op3.getImm() + 1; printAnnotation(O, Annot); return; } @@ -199,9 +201,10 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op1.getReg()); - O << ", " << markup("") << ", " - << markup(""); + O << ", "; + markup(O, Markup::Immediate) << "#" << Op2.getImm(); + O << ", "; + markup(O, Markup::Immediate) << "#" << Op3.getImm() - Op2.getImm() + 1; printAnnotation(O, Annot); return; } @@ -221,8 +224,10 @@ O << "\tbfc\t"; printRegName(O, Op0.getReg()); - O << ", " << markup("") << ", " - << markup(""); + O << ", "; + markup(O, Markup::Immediate) << "#" << LSB; + O << ", "; + markup(O, Markup::Immediate) << "#" << Width; printAnnotation(O, Annot); return; } else if (ImmS < ImmR) { @@ -235,8 +240,10 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op2.getReg()); - O << ", " << markup("") << ", " - << markup(""); + O << ", "; + markup(O, Markup::Immediate) << "#" << LSB; + O << ", "; + markup(O, Markup::Immediate) << "#" << Width; printAnnotation(O, Annot); return; } @@ -248,8 +255,10 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op2.getReg()); - O << ", " << markup("") << ", " - << markup(""); + O << ", "; + markup(O, Markup::Immediate) << "#" << LSB; + O << ", "; + markup(O, Markup::Immediate) << "#" << Width; printAnnotation(O, Annot); return; } @@ -266,9 +275,12 @@ O << "\tmovn\t"; printRegName(O, MI->getOperand(0).getReg()); - O << ", " << markup("getOperand(1).getExpr()->print(O, &MAI); - O << markup(">"); + O << ", "; + { + WithMarkup M = markup(O, Markup::Immediate); + O << "#"; + MI->getOperand(1).getExpr()->print(O, &MAI); + } return; } @@ -276,9 +288,12 @@ MI->getOperand(2).isExpr()) { O << "\tmovk\t"; printRegName(O, MI->getOperand(0).getReg()); - O << ", " << markup("getOperand(2).getExpr()->print(O, &MAI); - O << markup(">"); + O << ", "; + { + WithMarkup M = markup(O, Markup::Immediate); + O << "#"; + MI->getOperand(2).getExpr()->print(O, &MAI); + } return; } @@ -286,8 +301,8 @@ int64_t SExtVal = SignExtend64(Value, RegWidth); O << "\tmov\t"; printRegName(O, MI->getOperand(0).getReg()); - O << ", " << markup(""); + O << ", "; + markup(O, Markup::Immediate) << "#" << formatImm(SExtVal); if (CommentStream) { // Do the opposite to that used for instruction operands. if (getPrintImmHex()) @@ -813,8 +828,8 @@ printRegName(O, Reg); } else { assert(LdStDesc->NaturalOffset && "no offset on post-inc instruction?"); - O << ", " << markup("NaturalOffset - << markup(">"); + O << ", "; + markup(O, Markup::Immediate) << "#" << LdStDesc->NaturalOffset; } } @@ -1142,14 +1157,14 @@ const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); - O << markup(""); + markup(O, Markup::Immediate) << "#" << formatImm(Op.getImm()); } void AArch64InstPrinter::printImmHex(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); - O << markup(""); + markup(O, Markup::Immediate) << format("#%#llx", Op.getImm()); } template @@ -1158,13 +1173,11 @@ raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); if (Size == 8) - O << markup(""); + markup(O, Markup::Immediate) << "#" << formatImm((signed char)Op.getImm()); else if (Size == 16) - O << markup(""); + markup(O, Markup::Immediate) << "#" << formatImm((signed short)Op.getImm()); else - O << markup(""); + markup(O, Markup::Immediate) << "#" << formatImm(Op.getImm()); } void AArch64InstPrinter::printPostIncOperand(const MCInst *MI, unsigned OpNo, @@ -1173,7 +1186,7 @@ if (Op.isReg()) { unsigned Reg = Op.getReg(); if (Reg == AArch64::XZR) - O << markup(""); + markup(O, Markup::Immediate) << "#" << Imm; else printRegName(O, Reg); } else @@ -1206,7 +1219,7 @@ assert(Val == MO.getImm() && "Add/sub immediate out of range!"); unsigned Shift = AArch64_AM::getShiftValue(MI->getOperand(OpNum + 1).getImm()); - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatImm(Val); if (Shift != 0) { printShifter(MI, OpNum + 1, STI, O); if (CommentStream) @@ -1224,9 +1237,9 @@ const MCSubtargetInfo &STI, raw_ostream &O) { uint64_t Val = MI->getOperand(OpNum).getImm(); - O << markup(""); } void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum, @@ -1238,8 +1251,8 @@ AArch64_AM::getShiftValue(Val) == 0) return; O << ", " << AArch64_AM::getShiftExtendName(AArch64_AM::getShiftType(Val)) - << " " << markup(""); + << " "; + markup(O, Markup::Immediate) << "#" << AArch64_AM::getShiftValue(Val); } void AArch64InstPrinter::printShiftedRegister(const MCInst *MI, unsigned OpNum, @@ -1273,19 +1286,21 @@ ExtType == AArch64_AM::UXTX) || ((Dest == AArch64::WSP || Src1 == AArch64::WSP) && ExtType == AArch64_AM::UXTW) ) { - if (ShiftVal != 0) - O << ", lsl " << markup(""); + if (ShiftVal != 0) { + O << ", lsl "; + markup(O, Markup::Immediate) << "#" << ShiftVal; + } return; } } O << ", " << AArch64_AM::getShiftExtendName(ExtType); if (ShiftVal != 0) - O << " " << markup(""); + markup(O, Markup::Immediate) << "#" << ShiftVal; } -static void printMemExtendImpl(bool SignExtend, bool DoShift, unsigned Width, - char SrcRegKind, raw_ostream &O, - bool UseMarkup) { +void AArch64InstPrinter::printMemExtendImpl(bool SignExtend, bool DoShift, + unsigned Width, char SrcRegKind, + raw_ostream &O) { // sxtw, sxtx, uxtw or lsl (== uxtx) bool IsLSL = !SignExtend && SrcRegKind == 'x'; if (IsLSL) @@ -1295,11 +1310,7 @@ if (DoShift || IsLSL) { O << " "; - if (UseMarkup) - O << ""; + markup(O, Markup::Immediate) << "#" << Log2_32(Width / 8); } } @@ -1308,7 +1319,7 @@ unsigned Width) { bool SignExtend = MI->getOperand(OpNum).getImm(); bool DoShift = MI->getOperand(OpNum + 1).getImm(); - printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O, UseMarkup); + printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O); } template @@ -1325,7 +1336,7 @@ bool DoShift = ExtWidth != 8; if (SignExtend || DoShift || SrcRegKind == 'w') { O << ", "; - printMemExtendImpl(SignExtend, DoShift, ExtWidth, SrcRegKind, O, UseMarkup); + printMemExtendImpl(SignExtend, DoShift, ExtWidth, SrcRegKind, O); } } @@ -1384,8 +1395,8 @@ void AArch64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { - O << markup("getOperand(OpNum).getImm()) << markup(">"); + markup(O, Markup::Immediate) + << '#' << formatImm(Scale * MI->getOperand(OpNum).getImm()); } template @@ -1401,8 +1412,7 @@ unsigned Scale, raw_ostream &O) { const MCOperand MO = MI->getOperand(OpNum); if (MO.isImm()) { - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatImm(MO.getImm() * Scale); } else { assert(MO.isExpr() && "Unexpected operand type!"); MO.getExpr()->print(O, &MAI); @@ -1415,8 +1425,8 @@ O << '['; printRegName(O, MI->getOperand(OpNum).getReg()); if (MO1.isImm()) { - O << ", " << markup(""); + O << ", "; + markup(O, Markup::Immediate) << "#" << formatImm(MO1.getImm() * Scale); } else { assert(MO1.isExpr() && "Unexpected operand type!"); O << ", "; @@ -1455,7 +1465,7 @@ } } - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatImm(prfop); } void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum, @@ -1466,7 +1476,7 @@ if (PSB) O << PSB->Name; else - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatImm(psbhintop); } void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum, @@ -1477,7 +1487,7 @@ if (BTI) O << BTI->Name; else - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatImm(btihintop); } void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, @@ -1488,7 +1498,7 @@ : AArch64_AM::getFPImmFloat(MO.getImm()); // 8 decimal places are enough to perfectly represent permitted floats. - O << markup(""); + markup(O, Markup::Immediate) << format("#%.8f", FPImm); } static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1) { @@ -1758,13 +1768,11 @@ // If the label has already been resolved to an immediate offset (say, when // we're running the disassembler), just print the immediate. if (Op.isImm()) { - O << markup(""); + markup(O, Markup::Immediate) << "#" << formatImm(Offset); return; } @@ -1773,7 +1781,7 @@ dyn_cast(MI->getOperand(OpNum).getExpr()); int64_t TargetAddress; if (BranchTarget && BranchTarget->evaluateAsAbsolute(TargetAddress)) { - O << formatHex((uint64_t)TargetAddress); + markup(O, Markup::Address) << formatHex((uint64_t)TargetAddress); } else { // Otherwise, just print the expression. MI->getOperand(OpNum).getExpr()->print(O, &MAI); @@ -1794,12 +1802,11 @@ Offset = Offset * 4096; Address = Address & -4096; } - O << markup(""); + markup(O, Markup::Immediate) << "#" << Offset; return; } @@ -1827,7 +1834,7 @@ if (!Name.empty()) O << Name; else - O << markup(""); + markup(O, Markup::Immediate) << "#" << Val; } void AArch64InstPrinter::printBarriernXSOption(const MCInst *MI, unsigned OpNo, @@ -1843,7 +1850,7 @@ if (!Name.empty()) O << Name; else - O << markup(""); + markup(O, Markup::Immediate) << "#" << Val; } static bool isValidSysReg(const AArch64SysReg::SysReg *Reg, bool Read, @@ -1942,7 +1949,7 @@ raw_ostream &O) { unsigned RawVal = MI->getOperand(OpNo).getImm(); uint64_t Val = AArch64_AM::decodeAdvSIMDModImmType10(RawVal); - O << markup(""); + markup(O, Markup::Immediate) << format("#%#016llx", Val); } template @@ -1950,7 +1957,7 @@ const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Val = MI->getOperand(OpNo).getImm(); - O << markup(""); + markup(O, Markup::Immediate) << "#" << (Val * Angle) + Remainder; } void AArch64InstPrinter::printSVEPattern(const MCInst *MI, unsigned OpNum, @@ -1960,7 +1967,7 @@ if (auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByEncoding(Val)) O << Pat->Name; else - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatImm(Val); } void AArch64InstPrinter::printSVEVecLenSpecifier(const MCInst *MI, @@ -2004,9 +2011,9 @@ std::make_unsigned_t HexValue = Value; if (getPrintImmHex()) - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatHex((uint64_t)HexValue); else - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatDec(Value); if (CommentStream) { // Do the opposite to that used for instruction operands. @@ -2028,7 +2035,7 @@ // #0 lsl #8 is never pretty printed if ((UnscaledVal == 0) && (AArch64_AM::getShiftValue(Shift) != 0)) { - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatImm(UnscaledVal); printShifter(MI, OpNum + 1, STI, O); return; } @@ -2058,7 +2065,7 @@ else if ((uint16_t)PrintVal == PrintVal) printImmSVE(PrintVal, O); else - O << markup(""); + markup(O, Markup::Immediate) << '#' << formatHex((uint64_t)PrintVal); } template @@ -2086,8 +2093,8 @@ auto *Imm0Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmIs0); auto *Imm1Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmIs1); unsigned Val = MI->getOperand(OpNum).getImm(); - O << markup("Repr : Imm0Desc->Repr) - << markup(">"); + markup(O, Markup::Immediate) + << "#" << (Val ? Imm1Desc->Repr : Imm0Desc->Repr); } void AArch64InstPrinter::printGPR64as32(const MCInst *MI, unsigned OpNum, Index: llvm/tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- llvm/tools/llvm-objdump/llvm-objdump.cpp +++ llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -896,6 +896,7 @@ if (!InstPrinter) reportError(Obj.getFileName(), "no instruction printer for target " + TripleName); + InstPrinter->setUseColor(true); InstPrinter->setPrintImmHex(PrintImmHex); InstPrinter->setPrintBranchImmAsAddress(true); InstPrinter->setSymbolizeOperands(SymbolizeOperands);