Index: llvm/include/llvm/MC/MCInstPrinter.h =================================================================== --- llvm/include/llvm/MC/MCInstPrinter.h +++ llvm/include/llvm/MC/MCInstPrinter.h @@ -37,6 +37,17 @@ } // end namespace HexStyle +namespace HighlightStyle { + +enum Style { + Immediate, + Register, + Address, + None, +}; + +} // namespace HighlightStyle + struct AliasMatchingData; /// This is an instance of a target assembly language printer that @@ -55,6 +66,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; @@ -119,6 +133,12 @@ /// Utility functions to make adding mark ups simpler. StringRef markup(StringRef s) const; + bool getUseColor() const { return UseColor; } + void setUseColor(bool Value) { UseColor = Value; } + + /// Utility functions to make color highlighting simpler. + void highlight(raw_ostream &OS, HighlightStyle::Style Style) const; + bool getPrintImmHex() const { return PrintImmHex; } void setPrintImmHex(bool Value) { PrintImmHex = Value; } Index: llvm/lib/MC/MCInstPrinter.cpp =================================================================== --- llvm/lib/MC/MCInstPrinter.cpp +++ llvm/lib/MC/MCInstPrinter.cpp @@ -178,6 +178,26 @@ return ""; } +void MCInstPrinter::highlight(raw_ostream &OS, + HighlightStyle::Style Style) const { + if (!getUseColor()) + return; + switch (Style) { + case HighlightStyle::Immediate: + OS.changeColor(raw_ostream::RED); + break; + case HighlightStyle::Register: + OS.changeColor(raw_ostream::CYAN); + break; + case HighlightStyle::Address: + OS.changeColor(raw_ostream::YELLOW); + break; + case HighlightStyle::None: + OS.resetColor(); + break; + } +} + // For asm-style hex (e.g. 0ffh) the first digit always has to be a number. static bool needsLeadingZero(uint64_t Value) { Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h =================================================================== --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -92,6 +92,9 @@ 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,16 @@ } void AArch64InstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const { + highlight(OS, HighlightStyle::Register); OS << markup(""); + highlight(OS, HighlightStyle::None); } void AArch64InstPrinter::printRegName(raw_ostream &OS, MCRegister Reg, unsigned AltIdx) const { + highlight(OS, HighlightStyle::Register); OS << markup(""); + highlight(OS, HighlightStyle::None); } StringRef AArch64InstPrinter::getRegName(MCRegister Reg) const { @@ -175,7 +179,10 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op1.getReg()); - O << ", " << markup(""); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); printAnnotation(O, Annot); return; } @@ -187,9 +194,15 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op1.getReg()); - O << ", " << markup("") << ", " << markup(""); + highlight(O, HighlightStyle::None); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); printAnnotation(O, Annot); return; } @@ -199,9 +212,16 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op1.getReg()); - O << ", " << markup("") << ", " - << markup(""); + highlight(O, HighlightStyle::None); + + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); printAnnotation(O, Annot); return; } @@ -221,8 +241,14 @@ O << "\tbfc\t"; printRegName(O, Op0.getReg()); - O << ", " << markup("") << ", " - << markup(""); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); printAnnotation(O, Annot); return; } else if (ImmS < ImmR) { @@ -235,8 +261,14 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op2.getReg()); - O << ", " << markup("") << ", " - << markup(""); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); printAnnotation(O, Annot); return; } @@ -248,8 +280,14 @@ printRegName(O, Op0.getReg()); O << ", "; printRegName(O, Op2.getReg()); - O << ", " << markup("") << ", " - << markup(""); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); printAnnotation(O, Annot); return; } @@ -266,7 +304,10 @@ O << "\tmovn\t"; printRegName(O, MI->getOperand(0).getReg()); - O << ", " << markup("getOperand(1).getExpr()->print(O, &MAI); O << markup(">"); return; @@ -276,9 +317,12 @@ MI->getOperand(2).isExpr()) { O << "\tmovk\t"; printRegName(O, MI->getOperand(0).getReg()); - O << ", " << markup("getOperand(2).getExpr()->print(O, &MAI); O << markup(">"); + highlight(O, HighlightStyle::None); return; } @@ -286,8 +330,10 @@ int64_t SExtVal = SignExtend64(Value, RegWidth); O << "\tmov\t"; printRegName(O, MI->getOperand(0).getReg()); - O << ", " << markup(""); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); if (CommentStream) { // Do the opposite to that used for instruction operands. if (getPrintImmHex()) @@ -813,8 +859,10 @@ printRegName(O, Reg); } else { assert(LdStDesc->NaturalOffset && "no offset on post-inc instruction?"); - O << ", " << markup("NaturalOffset - << markup(">"); + O << ", "; + highlight(O, HighlightStyle::Immediate); + O << markup("NaturalOffset << markup(">"); + highlight(O, HighlightStyle::None); } } @@ -1142,14 +1190,18 @@ const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); } void AArch64InstPrinter::printImmHex(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); } template @@ -1157,6 +1209,7 @@ const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); + highlight(O, HighlightStyle::Immediate); if (Size == 8) O << markup(""); @@ -1165,6 +1218,7 @@ << markup(">"); else O << markup(""); + highlight(O, HighlightStyle::None); } void AArch64InstPrinter::printPostIncOperand(const MCInst *MI, unsigned OpNo, @@ -1172,9 +1226,11 @@ const MCOperand &Op = MI->getOperand(OpNo); if (Op.isReg()) { unsigned Reg = Op.getReg(); - if (Reg == AArch64::XZR) + if (Reg == AArch64::XZR) { + highlight(O, HighlightStyle::Immediate); O << markup(""); - else + highlight(O, HighlightStyle::None); + } else printRegName(O, Reg); } else llvm_unreachable("unknown operand kind in printPostIncOperand64"); @@ -1206,7 +1262,9 @@ assert(Val == MO.getImm() && "Add/sub immediate out of range!"); unsigned Shift = AArch64_AM::getShiftValue(MI->getOperand(OpNum + 1).getImm()); + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); if (Shift != 0) { printShifter(MI, OpNum + 1, STI, O); if (CommentStream) @@ -1224,9 +1282,12 @@ const MCSubtargetInfo &STI, raw_ostream &O) { uint64_t Val = MI->getOperand(OpNum).getImm(); + + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); } void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum, @@ -1238,8 +1299,11 @@ AArch64_AM::getShiftValue(Val) == 0) return; O << ", " << AArch64_AM::getShiftExtendName(AArch64_AM::getShiftType(Val)) - << " " << markup(""); + << " "; + + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); } void AArch64InstPrinter::printShiftedRegister(const MCInst *MI, unsigned OpNum, @@ -1273,19 +1337,26 @@ 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 "; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); + } return; } } O << ", " << AArch64_AM::getShiftExtendName(ExtType); - if (ShiftVal != 0) + if (ShiftVal != 0) { + highlight(O, HighlightStyle::Immediate); O << " " << markup(""); + highlight(O, HighlightStyle::None); + } } -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 +1366,9 @@ if (DoShift || IsLSL) { O << " "; - if (UseMarkup) - O << ""; + highlight(O, HighlightStyle::Immediate); + O << markup(""); + highlight(O, HighlightStyle::None); } } @@ -1308,7 +1377,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 +1394,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 +1453,11 @@ void AArch64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { + + highlight(O, HighlightStyle::Immediate); O << markup("getOperand(OpNum).getImm()) << markup(">"); + highlight(O, HighlightStyle::None); } template @@ -1401,8 +1473,11 @@ unsigned Scale, raw_ostream &O) { const MCOperand MO = MI->getOperand(OpNum); if (MO.isImm()) { + + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); } else { assert(MO.isExpr() && "Unexpected operand type!"); MO.getExpr()->print(O, &MAI); @@ -1415,8 +1490,11 @@ O << '['; printRegName(O, MI->getOperand(OpNum).getReg()); if (MO1.isImm()) { - O << ", " << markup(""); + highlight(O, HighlightStyle::None); } else { assert(MO1.isExpr() && "Unexpected operand type!"); O << ", "; @@ -1465,8 +1543,13 @@ auto PSB = AArch64PSBHint::lookupPSBByEncoding(psbhintop); if (PSB) O << PSB->Name; - else + else { + + highlight(O, HighlightStyle::Immediate); O << markup(""); + + highlight(O, HighlightStyle::None); + } } void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum, @@ -1476,8 +1559,11 @@ auto BTI = AArch64BTIHint::lookupBTIByEncoding(btihintop); if (BTI) O << BTI->Name; - else + else { + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); + } } void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, @@ -1488,7 +1574,9 @@ : AArch64_AM::getFPImmFloat(MO.getImm()); // 8 decimal places are enough to perfectly represent permitted floats. + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); } static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1) { @@ -1758,6 +1846,8 @@ // 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()) { + + highlight(O, HighlightStyle::Immediate); O << markup(""); + + highlight(O, HighlightStyle::None); return; } @@ -1773,7 +1865,9 @@ dyn_cast(MI->getOperand(OpNum).getExpr()); int64_t TargetAddress; if (BranchTarget && BranchTarget->evaluateAsAbsolute(TargetAddress)) { + highlight(O, HighlightStyle::Address); O << formatHex((uint64_t)TargetAddress); + highlight(O, HighlightStyle::None); } else { // Otherwise, just print the expression. MI->getOperand(OpNum).getExpr()->print(O, &MAI); @@ -1794,12 +1888,15 @@ Offset = Offset * 4096; Address = Address & -4096; } + + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); return; } @@ -1842,8 +1939,11 @@ if (!Name.empty()) O << Name; - else + else { + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); + } } static bool isValidSysReg(const AArch64SysReg::SysReg *Reg, bool Read, @@ -1942,7 +2042,9 @@ raw_ostream &O) { unsigned RawVal = MI->getOperand(OpNo).getImm(); uint64_t Val = AArch64_AM::decodeAdvSIMDModImmType10(RawVal); + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); } template @@ -1950,7 +2052,10 @@ const MCSubtargetInfo &STI, raw_ostream &O) { unsigned Val = MI->getOperand(OpNo).getImm(); + + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); } void AArch64InstPrinter::printSVEPattern(const MCInst *MI, unsigned OpNum, @@ -1959,8 +2064,11 @@ unsigned Val = MI->getOperand(OpNum).getImm(); if (auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByEncoding(Val)) O << Pat->Name; - else + else { + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); + } } void AArch64InstPrinter::printSVEVecLenSpecifier(const MCInst *MI, @@ -2003,10 +2111,12 @@ void AArch64InstPrinter::printImmSVE(T Value, raw_ostream &O) { std::make_unsigned_t HexValue = Value; + highlight(O, HighlightStyle::Immediate); if (getPrintImmHex()) O << markup(""); else O << markup(""); + highlight(O, HighlightStyle::None); if (CommentStream) { // Do the opposite to that used for instruction operands. @@ -2028,7 +2138,9 @@ // #0 lsl #8 is never pretty printed if ((UnscaledVal == 0) && (AArch64_AM::getShiftValue(Shift) != 0)) { + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); printShifter(MI, OpNum + 1, STI, O); return; } @@ -2057,8 +2169,11 @@ printImmSVE((T)PrintVal, O); else if ((uint16_t)PrintVal == PrintVal) printImmSVE(PrintVal, O); - else + else { + highlight(O, HighlightStyle::Immediate); O << markup(""); + highlight(O, HighlightStyle::None); + } } template @@ -2086,8 +2201,11 @@ auto *Imm0Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmIs0); auto *Imm1Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmIs1); unsigned Val = MI->getOperand(OpNum).getImm(); + + highlight(O, HighlightStyle::Immediate); O << markup("Repr : Imm0Desc->Repr) << markup(">"); + highlight(O, HighlightStyle::None); } 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);