Index: lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h =================================================================== --- lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h +++ lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h @@ -14,29 +14,29 @@ #ifndef LLVM_LIB_TARGET_POWERPC_INSTPRINTER_PPCINSTPRINTER_H #define LLVM_LIB_TARGET_POWERPC_INSTPRINTER_PPCINSTPRINTER_H +#include "llvm/ADT/Triple.h" #include "llvm/MC/MCInstPrinter.h" namespace llvm { class PPCInstPrinter : public MCInstPrinter { - bool IsDarwin; + Triple TT; +private: + bool showRegistersWithPercentPrefix(const char *RegName); + bool showRegistersWithoutPrefix(const char *RegName); public: PPCInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI, bool isDarwin) - : MCInstPrinter(MAI, MII, MRI), IsDarwin(isDarwin) {} - - bool isDarwinSyntax() const { - return IsDarwin; - } - + const MCRegisterInfo &MRI, Triple T) + : MCInstPrinter(MAI, MII, MRI), TT(T) {} + void printRegName(raw_ostream &OS, unsigned RegNo) const override; void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override; - + // Autogenerated by tblgen. void printInstruction(const MCInst *MI, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); - + bool printAliasInstr(const MCInst *MI, raw_ostream &OS); void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx, unsigned PrintMethodIdx, Index: lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp =================================================================== --- lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +++ lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp @@ -39,6 +39,12 @@ ShowVSRNumsAsVR("ppc-vsr-nums-as-vr", cl::Hidden, cl::init(false), cl::desc("Prints full register names with vs{31-63} as v{0-31}")); +// Prints full register names with percent symbol. +static cl::opt +FullRegNamesWithPercent("ppc-reg-with-percent-prefix", + cl::Hidden, cl::init(false), + cl::desc("Prints full register names with percent")); + #define PRINT_ALIAS_INSTR #include "PPCGenAsmWriter.inc" @@ -445,11 +451,26 @@ O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind()); } - /// stripRegisterPrefix - This method strips the character prefix from a /// register name so that only the number is left. Used by for linux asm. -static const char *stripRegisterPrefix(const char *RegName, unsigned RegNum, - unsigned RegEncoding) { +static const char *stripRegisterPrefix(const char *RegName) { + switch (RegName[0]) { + case 'r': + case 'f': + case 'q': // for QPX + case 'v': + if (RegName[1] == 's') + return RegName + 2; + return RegName + 1; + case 'c': if (RegName[1] == 'r') return RegName + 2; + } + + return RegName; +} + +/// Get full register name. +static const char *getFullRegisterName(const char *RegName, + unsigned RegNum, unsigned RegEncoding) { if (FullRegNames) { if (RegNum >= PPC::CR0EQ && RegNum <= PPC::CR7UN) { const char *CRBits[] = @@ -464,21 +485,43 @@ }; return CRBits[RegEncoding]; } - return RegName; } - switch (RegName[0]) { - case 'r': - case 'f': - case 'q': // for QPX - case 'v': - if (RegName[1] == 's') - return RegName + 2; - return RegName + 1; - case 'c': if (RegName[1] == 'r') return RegName + 2; + return RegName; +} + +/// showRegistersWithPercentPrefix - Check if register name accepts percent +/// symbol in its prefix. +bool PPCInstPrinter::showRegistersWithPercentPrefix( + const char *RegName) { + if (FullRegNamesWithPercent && !TT.isOSDarwin()) { + switch (RegName[0]) { + case 'r': + case 'f': + case 'q': + case 'v': + case 'c': + return true; + } } - return RegName; + return false; +} + +/// showRegistersWithoutPrefix - Check if register prefix can be removed. +bool PPCInstPrinter::showRegistersWithoutPrefix(const char *RegName) { + if (!FullRegNames && !TT.isOSDarwin()) { + switch (RegName[0]) { + case 'r': + case 'f': + case 'q': + case 'v': + case 'c': + return true; + } + } + + return false; } void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, @@ -503,9 +546,17 @@ } const char *RegName = getRegisterName(Reg); - // The linux and AIX assembler does not take register prefixes. - if (!isDarwinSyntax()) - RegName = stripRegisterPrefix(RegName, Reg, MRI.getEncodingValue(Reg)); + + if (showRegistersWithPercentPrefix(RegName)) { + // Print register with percent symbol and prefix. + O << "%"; + } else if (showRegistersWithoutPrefix(RegName)) { + // Print register without prefix. + RegName = stripRegisterPrefix(RegName); + } else { + // Print register with full name. + RegName = getFullRegisterName(RegName, Reg, MRI.getEncodingValue(Reg)); + } O << RegName; return; Index: lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -239,7 +239,7 @@ const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) { - return new PPCInstPrinter(MAI, MII, MRI, T.isOSDarwin()); + return new PPCInstPrinter(MAI, MII, MRI, T); } extern "C" void LLVMInitializePowerPCTargetMC() { Index: test/CodeGen/PowerPC/reg-names.ll =================================================================== --- test/CodeGen/PowerPC/reg-names.ll +++ test/CodeGen/PowerPC/reg-names.ll @@ -1,5 +1,6 @@ ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -ppc-asm-full-reg-names < %s | FileCheck -check-prefix=CHECK-FN %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -ppc-reg-with-percent-prefix < %s | FileCheck -check-prefix=CHECK-PN %s define i64 @test1(i64 %a, i64 %b) { ; CHECK-LABEL: @test1 @@ -10,8 +11,10 @@ ; CHECK: mr 3, 4 ; CHECK-FN: mr r3, r4 +; CHECK-PN: mr %r3, %r4 ; CHECK: blr ; CHECK-FN: blr +; CHECK-PN: blr }