xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This class prints an PPC MCInst to a .s file.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "MCTargetDesc/PPCInstPrinter.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/PPCPredicates.h"
16*5f757f3fSDimitry Andric #include "llvm/MC/MCAsmInfo.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
23*5f757f3fSDimitry Andric #include "llvm/Support/Casting.h"
240b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric #define DEBUG_TYPE "asm-printer"
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric // FIXME: Once the integrated assembler supports full register names, tie this
310b57cec5SDimitry Andric // to the verbose-asm setting.
320b57cec5SDimitry Andric static cl::opt<bool>
330b57cec5SDimitry Andric FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
340b57cec5SDimitry Andric              cl::desc("Use full register names when printing assembly"));
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric // Useful for testing purposes. Prints vs{31-63} as v{0-31} respectively.
370b57cec5SDimitry Andric static cl::opt<bool>
380b57cec5SDimitry Andric ShowVSRNumsAsVR("ppc-vsr-nums-as-vr", cl::Hidden, cl::init(false),
390b57cec5SDimitry Andric              cl::desc("Prints full register names with vs{31-63} as v{0-31}"));
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric // Prints full register names with percent symbol.
420b57cec5SDimitry Andric static cl::opt<bool>
430b57cec5SDimitry Andric FullRegNamesWithPercent("ppc-reg-with-percent-prefix", cl::Hidden,
440b57cec5SDimitry Andric                         cl::init(false),
450b57cec5SDimitry Andric                         cl::desc("Prints full register names with percent"));
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric #define PRINT_ALIAS_INSTR
480b57cec5SDimitry Andric #include "PPCGenAsmWriter.inc"
490b57cec5SDimitry Andric 
50bdd1243dSDimitry Andric void PPCInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
51bdd1243dSDimitry Andric   const char *RegName = getRegisterName(Reg);
520b57cec5SDimitry Andric   OS << RegName;
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
55480093f4SDimitry Andric void PPCInstPrinter::printInst(const MCInst *MI, uint64_t Address,
56480093f4SDimitry Andric                                StringRef Annot, const MCSubtargetInfo &STI,
57480093f4SDimitry Andric                                raw_ostream &O) {
588bcb0991SDimitry Andric   // Customize printing of the addis instruction on AIX. When an operand is a
598bcb0991SDimitry Andric   // symbol reference, the instruction syntax is changed to look like a load
608bcb0991SDimitry Andric   // operation, i.e:
618bcb0991SDimitry Andric   //     Transform:  addis $rD, $rA, $src --> addis $rD, $src($rA).
628bcb0991SDimitry Andric   if (TT.isOSAIX() &&
638bcb0991SDimitry Andric       (MI->getOpcode() == PPC::ADDIS8 || MI->getOpcode() == PPC::ADDIS) &&
648bcb0991SDimitry Andric       MI->getOperand(2).isExpr()) {
658bcb0991SDimitry Andric     assert((MI->getOperand(0).isReg() && MI->getOperand(1).isReg()) &&
668bcb0991SDimitry Andric            "The first and the second operand of an addis instruction"
678bcb0991SDimitry Andric            " should be registers.");
688bcb0991SDimitry Andric 
698bcb0991SDimitry Andric     assert(isa<MCSymbolRefExpr>(MI->getOperand(2).getExpr()) &&
708bcb0991SDimitry Andric            "The third operand of an addis instruction should be a symbol "
718bcb0991SDimitry Andric            "reference expression if it is an expression at all.");
728bcb0991SDimitry Andric 
738bcb0991SDimitry Andric     O << "\taddis ";
74e8d8bef9SDimitry Andric     printOperand(MI, 0, STI, O);
758bcb0991SDimitry Andric     O << ", ";
76e8d8bef9SDimitry Andric     printOperand(MI, 2, STI, O);
778bcb0991SDimitry Andric     O << "(";
78e8d8bef9SDimitry Andric     printOperand(MI, 1, STI, O);
798bcb0991SDimitry Andric     O << ")";
808bcb0991SDimitry Andric     return;
818bcb0991SDimitry Andric   }
828bcb0991SDimitry Andric 
83e8d8bef9SDimitry Andric   // Check if the last operand is an expression with the variant kind
84e8d8bef9SDimitry Andric   // VK_PPC_PCREL_OPT. If this is the case then this is a linker optimization
85e8d8bef9SDimitry Andric   // relocation and the .reloc directive needs to be added.
86e8d8bef9SDimitry Andric   unsigned LastOp = MI->getNumOperands() - 1;
87e8d8bef9SDimitry Andric   if (MI->getNumOperands() > 1) {
88e8d8bef9SDimitry Andric     const MCOperand &Operand = MI->getOperand(LastOp);
89e8d8bef9SDimitry Andric     if (Operand.isExpr()) {
90e8d8bef9SDimitry Andric       const MCExpr *Expr = Operand.getExpr();
91e8d8bef9SDimitry Andric       const MCSymbolRefExpr *SymExpr =
92e8d8bef9SDimitry Andric           static_cast<const MCSymbolRefExpr *>(Expr);
93e8d8bef9SDimitry Andric 
94e8d8bef9SDimitry Andric       if (SymExpr && SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT) {
95e8d8bef9SDimitry Andric         const MCSymbol &Symbol = SymExpr->getSymbol();
96e8d8bef9SDimitry Andric         if (MI->getOpcode() == PPC::PLDpc) {
97e8d8bef9SDimitry Andric           printInstruction(MI, Address, STI, O);
98e8d8bef9SDimitry Andric           O << "\n";
99e8d8bef9SDimitry Andric           Symbol.print(O, &MAI);
100e8d8bef9SDimitry Andric           O << ":";
101e8d8bef9SDimitry Andric           return;
102e8d8bef9SDimitry Andric         } else {
103e8d8bef9SDimitry Andric           O << "\t.reloc ";
104e8d8bef9SDimitry Andric           Symbol.print(O, &MAI);
105e8d8bef9SDimitry Andric           O << "-8,R_PPC64_PCREL_OPT,.-(";
106e8d8bef9SDimitry Andric           Symbol.print(O, &MAI);
107e8d8bef9SDimitry Andric           O << "-8)\n";
108e8d8bef9SDimitry Andric         }
109e8d8bef9SDimitry Andric       }
110e8d8bef9SDimitry Andric     }
111e8d8bef9SDimitry Andric   }
112e8d8bef9SDimitry Andric 
1130b57cec5SDimitry Andric   // Check for slwi/srwi mnemonics.
1140b57cec5SDimitry Andric   if (MI->getOpcode() == PPC::RLWINM) {
1150b57cec5SDimitry Andric     unsigned char SH = MI->getOperand(2).getImm();
1160b57cec5SDimitry Andric     unsigned char MB = MI->getOperand(3).getImm();
1170b57cec5SDimitry Andric     unsigned char ME = MI->getOperand(4).getImm();
1180b57cec5SDimitry Andric     bool useSubstituteMnemonic = false;
1190b57cec5SDimitry Andric     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
1200b57cec5SDimitry Andric       O << "\tslwi "; useSubstituteMnemonic = true;
1210b57cec5SDimitry Andric     }
1220b57cec5SDimitry Andric     if (SH <= 31 && MB == (32-SH) && ME == 31) {
1230b57cec5SDimitry Andric       O << "\tsrwi "; useSubstituteMnemonic = true;
1240b57cec5SDimitry Andric       SH = 32-SH;
1250b57cec5SDimitry Andric     }
1260b57cec5SDimitry Andric     if (useSubstituteMnemonic) {
127e8d8bef9SDimitry Andric       printOperand(MI, 0, STI, O);
1280b57cec5SDimitry Andric       O << ", ";
129e8d8bef9SDimitry Andric       printOperand(MI, 1, STI, O);
1300b57cec5SDimitry Andric       O << ", " << (unsigned int)SH;
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric       printAnnotation(O, Annot);
1330b57cec5SDimitry Andric       return;
1340b57cec5SDimitry Andric     }
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   if (MI->getOpcode() == PPC::RLDICR ||
1380b57cec5SDimitry Andric       MI->getOpcode() == PPC::RLDICR_32) {
1390b57cec5SDimitry Andric     unsigned char SH = MI->getOperand(2).getImm();
1400b57cec5SDimitry Andric     unsigned char ME = MI->getOperand(3).getImm();
1410b57cec5SDimitry Andric     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
1420b57cec5SDimitry Andric     if (63-SH == ME) {
1430b57cec5SDimitry Andric       O << "\tsldi ";
144e8d8bef9SDimitry Andric       printOperand(MI, 0, STI, O);
1450b57cec5SDimitry Andric       O << ", ";
146e8d8bef9SDimitry Andric       printOperand(MI, 1, STI, O);
1470b57cec5SDimitry Andric       O << ", " << (unsigned int)SH;
1480b57cec5SDimitry Andric       printAnnotation(O, Annot);
1490b57cec5SDimitry Andric       return;
1500b57cec5SDimitry Andric     }
1510b57cec5SDimitry Andric   }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   // dcbt[st] is printed manually here because:
1540b57cec5SDimitry Andric   //  1. The assembly syntax is different between embedded and server targets
1550b57cec5SDimitry Andric   //  2. We must print the short mnemonics for TH == 0 because the
1560b57cec5SDimitry Andric   //     embedded/server syntax default will not be stable across assemblers
1570b57cec5SDimitry Andric   //  The syntax for dcbt is:
1580b57cec5SDimitry Andric   //    dcbt ra, rb, th [server]
1590b57cec5SDimitry Andric   //    dcbt th, ra, rb [embedded]
1600b57cec5SDimitry Andric   //  where th can be omitted when it is 0. dcbtst is the same.
161349cc55cSDimitry Andric   // On AIX, only emit the extended mnemonics for dcbt and dcbtst if
162349cc55cSDimitry Andric   // the "modern assembler" is available.
163349cc55cSDimitry Andric   if ((MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) &&
16406c3fb27SDimitry Andric       (!TT.isOSAIX() || STI.hasFeature(PPC::FeatureModernAIXAs))) {
1650b57cec5SDimitry Andric     unsigned char TH = MI->getOperand(0).getImm();
1660b57cec5SDimitry Andric     O << "\tdcbt";
1670b57cec5SDimitry Andric     if (MI->getOpcode() == PPC::DCBTST)
1680b57cec5SDimitry Andric       O << "st";
1690b57cec5SDimitry Andric     if (TH == 16)
1700b57cec5SDimitry Andric       O << "t";
1710b57cec5SDimitry Andric     O << " ";
1720b57cec5SDimitry Andric 
17306c3fb27SDimitry Andric     bool IsBookE = STI.hasFeature(PPC::FeatureBookE);
1740b57cec5SDimitry Andric     if (IsBookE && TH != 0 && TH != 16)
1750b57cec5SDimitry Andric       O << (unsigned int) TH << ", ";
1760b57cec5SDimitry Andric 
177e8d8bef9SDimitry Andric     printOperand(MI, 1, STI, O);
1780b57cec5SDimitry Andric     O << ", ";
179e8d8bef9SDimitry Andric     printOperand(MI, 2, STI, O);
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric     if (!IsBookE && TH != 0 && TH != 16)
1820b57cec5SDimitry Andric       O << ", " << (unsigned int) TH;
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric     printAnnotation(O, Annot);
1850b57cec5SDimitry Andric     return;
1860b57cec5SDimitry Andric   }
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   if (MI->getOpcode() == PPC::DCBF) {
1890b57cec5SDimitry Andric     unsigned char L = MI->getOperand(0).getImm();
190e8d8bef9SDimitry Andric     if (!L || L == 1 || L == 3 || L == 4 || L == 6) {
191e8d8bef9SDimitry Andric       O << "\tdcb";
192e8d8bef9SDimitry Andric       if (L != 6)
193e8d8bef9SDimitry Andric         O << "f";
194e8d8bef9SDimitry Andric       if (L == 1)
1950b57cec5SDimitry Andric         O << "l";
1960b57cec5SDimitry Andric       if (L == 3)
197e8d8bef9SDimitry Andric         O << "lp";
198e8d8bef9SDimitry Andric       if (L == 4)
199e8d8bef9SDimitry Andric         O << "ps";
200e8d8bef9SDimitry Andric       if (L == 6)
201e8d8bef9SDimitry Andric         O << "stps";
2020b57cec5SDimitry Andric       O << " ";
2030b57cec5SDimitry Andric 
204e8d8bef9SDimitry Andric       printOperand(MI, 1, STI, O);
2050b57cec5SDimitry Andric       O << ", ";
206e8d8bef9SDimitry Andric       printOperand(MI, 2, STI, O);
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric       printAnnotation(O, Annot);
2090b57cec5SDimitry Andric       return;
2100b57cec5SDimitry Andric     }
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric 
213e8d8bef9SDimitry Andric   if (!printAliasInstr(MI, Address, STI, O))
214e8d8bef9SDimitry Andric     printInstruction(MI, Address, STI, O);
2150b57cec5SDimitry Andric   printAnnotation(O, Annot);
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
219e8d8bef9SDimitry Andric                                            const MCSubtargetInfo &STI,
2200b57cec5SDimitry Andric                                            raw_ostream &O,
2210b57cec5SDimitry Andric                                            const char *Modifier) {
2220b57cec5SDimitry Andric   unsigned Code = MI->getOperand(OpNo).getImm();
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   if (StringRef(Modifier) == "cc") {
2250b57cec5SDimitry Andric     switch ((PPC::Predicate)Code) {
2260b57cec5SDimitry Andric     case PPC::PRED_LT_MINUS:
2270b57cec5SDimitry Andric     case PPC::PRED_LT_PLUS:
2280b57cec5SDimitry Andric     case PPC::PRED_LT:
2290b57cec5SDimitry Andric       O << "lt";
2300b57cec5SDimitry Andric       return;
2310b57cec5SDimitry Andric     case PPC::PRED_LE_MINUS:
2320b57cec5SDimitry Andric     case PPC::PRED_LE_PLUS:
2330b57cec5SDimitry Andric     case PPC::PRED_LE:
2340b57cec5SDimitry Andric       O << "le";
2350b57cec5SDimitry Andric       return;
2360b57cec5SDimitry Andric     case PPC::PRED_EQ_MINUS:
2370b57cec5SDimitry Andric     case PPC::PRED_EQ_PLUS:
2380b57cec5SDimitry Andric     case PPC::PRED_EQ:
2390b57cec5SDimitry Andric       O << "eq";
2400b57cec5SDimitry Andric       return;
2410b57cec5SDimitry Andric     case PPC::PRED_GE_MINUS:
2420b57cec5SDimitry Andric     case PPC::PRED_GE_PLUS:
2430b57cec5SDimitry Andric     case PPC::PRED_GE:
2440b57cec5SDimitry Andric       O << "ge";
2450b57cec5SDimitry Andric       return;
2460b57cec5SDimitry Andric     case PPC::PRED_GT_MINUS:
2470b57cec5SDimitry Andric     case PPC::PRED_GT_PLUS:
2480b57cec5SDimitry Andric     case PPC::PRED_GT:
2490b57cec5SDimitry Andric       O << "gt";
2500b57cec5SDimitry Andric       return;
2510b57cec5SDimitry Andric     case PPC::PRED_NE_MINUS:
2520b57cec5SDimitry Andric     case PPC::PRED_NE_PLUS:
2530b57cec5SDimitry Andric     case PPC::PRED_NE:
2540b57cec5SDimitry Andric       O << "ne";
2550b57cec5SDimitry Andric       return;
2560b57cec5SDimitry Andric     case PPC::PRED_UN_MINUS:
2570b57cec5SDimitry Andric     case PPC::PRED_UN_PLUS:
2580b57cec5SDimitry Andric     case PPC::PRED_UN:
2590b57cec5SDimitry Andric       O << "un";
2600b57cec5SDimitry Andric       return;
2610b57cec5SDimitry Andric     case PPC::PRED_NU_MINUS:
2620b57cec5SDimitry Andric     case PPC::PRED_NU_PLUS:
2630b57cec5SDimitry Andric     case PPC::PRED_NU:
2640b57cec5SDimitry Andric       O << "nu";
2650b57cec5SDimitry Andric       return;
2660b57cec5SDimitry Andric     case PPC::PRED_BIT_SET:
2670b57cec5SDimitry Andric     case PPC::PRED_BIT_UNSET:
2680b57cec5SDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
2690b57cec5SDimitry Andric     }
2700b57cec5SDimitry Andric     llvm_unreachable("Invalid predicate code");
2710b57cec5SDimitry Andric   }
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   if (StringRef(Modifier) == "pm") {
2740b57cec5SDimitry Andric     switch ((PPC::Predicate)Code) {
2750b57cec5SDimitry Andric     case PPC::PRED_LT:
2760b57cec5SDimitry Andric     case PPC::PRED_LE:
2770b57cec5SDimitry Andric     case PPC::PRED_EQ:
2780b57cec5SDimitry Andric     case PPC::PRED_GE:
2790b57cec5SDimitry Andric     case PPC::PRED_GT:
2800b57cec5SDimitry Andric     case PPC::PRED_NE:
2810b57cec5SDimitry Andric     case PPC::PRED_UN:
2820b57cec5SDimitry Andric     case PPC::PRED_NU:
2830b57cec5SDimitry Andric       return;
2840b57cec5SDimitry Andric     case PPC::PRED_LT_MINUS:
2850b57cec5SDimitry Andric     case PPC::PRED_LE_MINUS:
2860b57cec5SDimitry Andric     case PPC::PRED_EQ_MINUS:
2870b57cec5SDimitry Andric     case PPC::PRED_GE_MINUS:
2880b57cec5SDimitry Andric     case PPC::PRED_GT_MINUS:
2890b57cec5SDimitry Andric     case PPC::PRED_NE_MINUS:
2900b57cec5SDimitry Andric     case PPC::PRED_UN_MINUS:
2910b57cec5SDimitry Andric     case PPC::PRED_NU_MINUS:
2920b57cec5SDimitry Andric       O << "-";
2930b57cec5SDimitry Andric       return;
2940b57cec5SDimitry Andric     case PPC::PRED_LT_PLUS:
2950b57cec5SDimitry Andric     case PPC::PRED_LE_PLUS:
2960b57cec5SDimitry Andric     case PPC::PRED_EQ_PLUS:
2970b57cec5SDimitry Andric     case PPC::PRED_GE_PLUS:
2980b57cec5SDimitry Andric     case PPC::PRED_GT_PLUS:
2990b57cec5SDimitry Andric     case PPC::PRED_NE_PLUS:
3000b57cec5SDimitry Andric     case PPC::PRED_UN_PLUS:
3010b57cec5SDimitry Andric     case PPC::PRED_NU_PLUS:
3020b57cec5SDimitry Andric       O << "+";
3030b57cec5SDimitry Andric       return;
3040b57cec5SDimitry Andric     case PPC::PRED_BIT_SET:
3050b57cec5SDimitry Andric     case PPC::PRED_BIT_UNSET:
3060b57cec5SDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
3070b57cec5SDimitry Andric     }
3080b57cec5SDimitry Andric     llvm_unreachable("Invalid predicate code");
3090b57cec5SDimitry Andric   }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   assert(StringRef(Modifier) == "reg" &&
3120b57cec5SDimitry Andric          "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
313e8d8bef9SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
317e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3180b57cec5SDimitry Andric                                        raw_ostream &O) {
3190b57cec5SDimitry Andric   unsigned Code = MI->getOperand(OpNo).getImm();
3200b57cec5SDimitry Andric   if (Code == 2)
3210b57cec5SDimitry Andric     O << "-";
3220b57cec5SDimitry Andric   else if (Code == 3)
3230b57cec5SDimitry Andric     O << "+";
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
327e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3280b57cec5SDimitry Andric                                        raw_ostream &O) {
3290b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3300b57cec5SDimitry Andric   assert(Value <= 1 && "Invalid u1imm argument!");
3310b57cec5SDimitry Andric   O << (unsigned int)Value;
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
335e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3360b57cec5SDimitry Andric                                        raw_ostream &O) {
3370b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3380b57cec5SDimitry Andric   assert(Value <= 3 && "Invalid u2imm argument!");
3390b57cec5SDimitry Andric   O << (unsigned int)Value;
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
343e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3440b57cec5SDimitry Andric                                        raw_ostream &O) {
3450b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3460b57cec5SDimitry Andric   assert(Value <= 8 && "Invalid u3imm argument!");
3470b57cec5SDimitry Andric   O << (unsigned int)Value;
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
351e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3520b57cec5SDimitry Andric                                        raw_ostream &O) {
3530b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3540b57cec5SDimitry Andric   assert(Value <= 15 && "Invalid u4imm argument!");
3550b57cec5SDimitry Andric   O << (unsigned int)Value;
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
359e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3600b57cec5SDimitry Andric                                        raw_ostream &O) {
3610b57cec5SDimitry Andric   int Value = MI->getOperand(OpNo).getImm();
3620b57cec5SDimitry Andric   Value = SignExtend32<5>(Value);
3630b57cec5SDimitry Andric   O << (int)Value;
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
3665ffd83dbSDimitry Andric void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo,
367e8d8bef9SDimitry Andric                                          const MCSubtargetInfo &STI,
3685ffd83dbSDimitry Andric                                          raw_ostream &O) {
3695ffd83dbSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3705ffd83dbSDimitry Andric   assert(Value == 0 && "Operand must be zero");
3715ffd83dbSDimitry Andric   O << (unsigned int)Value;
3725ffd83dbSDimitry Andric }
3735ffd83dbSDimitry Andric 
3740b57cec5SDimitry Andric void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
375e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3760b57cec5SDimitry Andric                                        raw_ostream &O) {
3770b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3780b57cec5SDimitry Andric   assert(Value <= 31 && "Invalid u5imm argument!");
3790b57cec5SDimitry Andric   O << (unsigned int)Value;
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
383e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3840b57cec5SDimitry Andric                                        raw_ostream &O) {
3850b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3860b57cec5SDimitry Andric   assert(Value <= 63 && "Invalid u6imm argument!");
3870b57cec5SDimitry Andric   O << (unsigned int)Value;
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
391e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
3920b57cec5SDimitry Andric                                        raw_ostream &O) {
3930b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3940b57cec5SDimitry Andric   assert(Value <= 127 && "Invalid u7imm argument!");
3950b57cec5SDimitry Andric   O << (unsigned int)Value;
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric // Operands of BUILD_VECTOR are signed and we use this to print operands
3990b57cec5SDimitry Andric // of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
4000b57cec5SDimitry Andric // print as unsigned.
4010b57cec5SDimitry Andric void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
402e8d8bef9SDimitry Andric                                        const MCSubtargetInfo &STI,
4030b57cec5SDimitry Andric                                        raw_ostream &O) {
4040b57cec5SDimitry Andric   unsigned char Value = MI->getOperand(OpNo).getImm();
4050b57cec5SDimitry Andric   O << (unsigned int)Value;
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
409e8d8bef9SDimitry Andric                                         const MCSubtargetInfo &STI,
4100b57cec5SDimitry Andric                                         raw_ostream &O) {
4110b57cec5SDimitry Andric   unsigned short Value = MI->getOperand(OpNo).getImm();
4120b57cec5SDimitry Andric   assert(Value <= 1023 && "Invalid u10imm argument!");
4130b57cec5SDimitry Andric   O << (unsigned short)Value;
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
417e8d8bef9SDimitry Andric                                         const MCSubtargetInfo &STI,
4180b57cec5SDimitry Andric                                         raw_ostream &O) {
4190b57cec5SDimitry Andric   unsigned short Value = MI->getOperand(OpNo).getImm();
4200b57cec5SDimitry Andric   assert(Value <= 4095 && "Invalid u12imm argument!");
4210b57cec5SDimitry Andric   O << (unsigned short)Value;
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
425e8d8bef9SDimitry Andric                                         const MCSubtargetInfo &STI,
4260b57cec5SDimitry Andric                                         raw_ostream &O) {
4270b57cec5SDimitry Andric   if (MI->getOperand(OpNo).isImm())
4280b57cec5SDimitry Andric     O << (short)MI->getOperand(OpNo).getImm();
4290b57cec5SDimitry Andric   else
430e8d8bef9SDimitry Andric     printOperand(MI, OpNo, STI, O);
4310b57cec5SDimitry Andric }
4320b57cec5SDimitry Andric 
4335ffd83dbSDimitry Andric void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo,
434e8d8bef9SDimitry Andric                                         const MCSubtargetInfo &STI,
4355ffd83dbSDimitry Andric                                         raw_ostream &O) {
4365ffd83dbSDimitry Andric   if (MI->getOperand(OpNo).isImm()) {
4375ffd83dbSDimitry Andric     long long Value = MI->getOperand(OpNo).getImm();
4385ffd83dbSDimitry Andric     assert(isInt<34>(Value) && "Invalid s34imm argument!");
4395ffd83dbSDimitry Andric     O << (long long)Value;
4405ffd83dbSDimitry Andric   }
4415ffd83dbSDimitry Andric   else
442e8d8bef9SDimitry Andric     printOperand(MI, OpNo, STI, O);
4435ffd83dbSDimitry Andric }
4445ffd83dbSDimitry Andric 
4450b57cec5SDimitry Andric void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
446e8d8bef9SDimitry Andric                                         const MCSubtargetInfo &STI,
4470b57cec5SDimitry Andric                                         raw_ostream &O) {
4480b57cec5SDimitry Andric   if (MI->getOperand(OpNo).isImm())
4490b57cec5SDimitry Andric     O << (unsigned short)MI->getOperand(OpNo).getImm();
4500b57cec5SDimitry Andric   else
451e8d8bef9SDimitry Andric     printOperand(MI, OpNo, STI, O);
4520b57cec5SDimitry Andric }
4530b57cec5SDimitry Andric 
4545ffd83dbSDimitry Andric void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
455e8d8bef9SDimitry Andric                                         unsigned OpNo,
456e8d8bef9SDimitry Andric                                         const MCSubtargetInfo &STI,
457e8d8bef9SDimitry Andric                                         raw_ostream &O) {
4580b57cec5SDimitry Andric   if (!MI->getOperand(OpNo).isImm())
459e8d8bef9SDimitry Andric     return printOperand(MI, OpNo, STI, O);
4600b57cec5SDimitry Andric   int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
4615ffd83dbSDimitry Andric   if (PrintBranchImmAsAddress) {
4625ffd83dbSDimitry Andric     uint64_t Target = Address + Imm;
4635ffd83dbSDimitry Andric     if (!TT.isPPC64())
4645ffd83dbSDimitry Andric       Target &= 0xffffffff;
4655ffd83dbSDimitry Andric     O << formatHex(Target);
4665ffd83dbSDimitry Andric   } else {
4675ffd83dbSDimitry Andric     // Branches can take an immediate operand. This is used by the branch
4685ffd83dbSDimitry Andric     // selection pass to print, for example `.+8` (for ELF) or `$+8` (for AIX)
4695ffd83dbSDimitry Andric     // to express an eight byte displacement from the program counter.
4705ffd83dbSDimitry Andric     if (!TT.isOSAIX())
4715ffd83dbSDimitry Andric       O << ".";
4725ffd83dbSDimitry Andric     else
4735ffd83dbSDimitry Andric       O << "$";
4745ffd83dbSDimitry Andric 
4750b57cec5SDimitry Andric     if (Imm >= 0)
4760b57cec5SDimitry Andric       O << "+";
4770b57cec5SDimitry Andric     O << Imm;
4780b57cec5SDimitry Andric   }
4795ffd83dbSDimitry Andric }
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
482e8d8bef9SDimitry Andric                                            const MCSubtargetInfo &STI,
4830b57cec5SDimitry Andric                                            raw_ostream &O) {
4840b57cec5SDimitry Andric   if (!MI->getOperand(OpNo).isImm())
485e8d8bef9SDimitry Andric     return printOperand(MI, OpNo, STI, O);
4860b57cec5SDimitry Andric 
487*5f757f3fSDimitry Andric   uint64_t Imm = static_cast<uint64_t>(MI->getOperand(OpNo).getImm()) << 2;
488*5f757f3fSDimitry Andric   if (!TT.isPPC64())
489*5f757f3fSDimitry Andric     Imm = static_cast<uint32_t>(Imm);
490*5f757f3fSDimitry Andric   O << formatHex(Imm);
4910b57cec5SDimitry Andric }
4920b57cec5SDimitry Andric 
4930b57cec5SDimitry Andric void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
494e8d8bef9SDimitry Andric                                  const MCSubtargetInfo &STI, raw_ostream &O) {
4950b57cec5SDimitry Andric   unsigned CCReg = MI->getOperand(OpNo).getReg();
4960b57cec5SDimitry Andric   unsigned RegNo;
4970b57cec5SDimitry Andric   switch (CCReg) {
4980b57cec5SDimitry Andric   default: llvm_unreachable("Unknown CR register");
4990b57cec5SDimitry Andric   case PPC::CR0: RegNo = 0; break;
5000b57cec5SDimitry Andric   case PPC::CR1: RegNo = 1; break;
5010b57cec5SDimitry Andric   case PPC::CR2: RegNo = 2; break;
5020b57cec5SDimitry Andric   case PPC::CR3: RegNo = 3; break;
5030b57cec5SDimitry Andric   case PPC::CR4: RegNo = 4; break;
5040b57cec5SDimitry Andric   case PPC::CR5: RegNo = 5; break;
5050b57cec5SDimitry Andric   case PPC::CR6: RegNo = 6; break;
5060b57cec5SDimitry Andric   case PPC::CR7: RegNo = 7; break;
5070b57cec5SDimitry Andric   }
5080b57cec5SDimitry Andric   O << (0x80 >> RegNo);
5090b57cec5SDimitry Andric }
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
512e8d8bef9SDimitry Andric                                     const MCSubtargetInfo &STI,
5130b57cec5SDimitry Andric                                     raw_ostream &O) {
514e8d8bef9SDimitry Andric   printS16ImmOperand(MI, OpNo, STI, O);
5150b57cec5SDimitry Andric   O << '(';
5160b57cec5SDimitry Andric   if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
5170b57cec5SDimitry Andric     O << "0";
5180b57cec5SDimitry Andric   else
519e8d8bef9SDimitry Andric     printOperand(MI, OpNo + 1, STI, O);
5200b57cec5SDimitry Andric   O << ')';
5210b57cec5SDimitry Andric }
5220b57cec5SDimitry Andric 
523fe6060f1SDimitry Andric void PPCInstPrinter::printMemRegImmHash(const MCInst *MI, unsigned OpNo,
524fe6060f1SDimitry Andric                                         const MCSubtargetInfo &STI,
525fe6060f1SDimitry Andric                                         raw_ostream &O) {
526fe6060f1SDimitry Andric   O << MI->getOperand(OpNo).getImm();
527fe6060f1SDimitry Andric   O << '(';
528fe6060f1SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
529fe6060f1SDimitry Andric   O << ')';
530fe6060f1SDimitry Andric }
531fe6060f1SDimitry Andric 
5325ffd83dbSDimitry Andric void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
533e8d8bef9SDimitry Andric                                            const MCSubtargetInfo &STI,
5345ffd83dbSDimitry Andric                                            raw_ostream &O) {
535e8d8bef9SDimitry Andric   printS34ImmOperand(MI, OpNo, STI, O);
5365ffd83dbSDimitry Andric   O << '(';
537e8d8bef9SDimitry Andric   printImmZeroOperand(MI, OpNo + 1, STI, O);
5385ffd83dbSDimitry Andric   O << ')';
5395ffd83dbSDimitry Andric }
5405ffd83dbSDimitry Andric 
5415ffd83dbSDimitry Andric void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo,
542e8d8bef9SDimitry Andric                                       const MCSubtargetInfo &STI,
5435ffd83dbSDimitry Andric                                       raw_ostream &O) {
544e8d8bef9SDimitry Andric   printS34ImmOperand(MI, OpNo, STI, O);
5455ffd83dbSDimitry Andric   O << '(';
546e8d8bef9SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
5475ffd83dbSDimitry Andric   O << ')';
5485ffd83dbSDimitry Andric }
5495ffd83dbSDimitry Andric 
5500b57cec5SDimitry Andric void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
551e8d8bef9SDimitry Andric                                     const MCSubtargetInfo &STI,
5520b57cec5SDimitry Andric                                     raw_ostream &O) {
5530b57cec5SDimitry Andric   // When used as the base register, r0 reads constant zero rather than
5540b57cec5SDimitry Andric   // the value contained in the register.  For this reason, the darwin
5550b57cec5SDimitry Andric   // assembler requires that we print r0 as 0 (no r) when used as the base.
5560b57cec5SDimitry Andric   if (MI->getOperand(OpNo).getReg() == PPC::R0)
5570b57cec5SDimitry Andric     O << "0";
5580b57cec5SDimitry Andric   else
559e8d8bef9SDimitry Andric     printOperand(MI, OpNo, STI, O);
5600b57cec5SDimitry Andric   O << ", ";
561e8d8bef9SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
565e8d8bef9SDimitry Andric                                   const MCSubtargetInfo &STI, raw_ostream &O) {
5660b57cec5SDimitry Andric   // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
5670b57cec5SDimitry Andric   // come at the _end_ of the expression.
5680b57cec5SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
5690b57cec5SDimitry Andric   const MCSymbolRefExpr *RefExp = nullptr;
5708a4dda33SDimitry Andric   const MCExpr *Rhs = nullptr;
5710b57cec5SDimitry Andric   if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Op.getExpr())) {
5720b57cec5SDimitry Andric     RefExp = cast<MCSymbolRefExpr>(BinExpr->getLHS());
5738a4dda33SDimitry Andric     Rhs = BinExpr->getRHS();
5740b57cec5SDimitry Andric   } else
5750b57cec5SDimitry Andric     RefExp = cast<MCSymbolRefExpr>(Op.getExpr());
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric   O << RefExp->getSymbol().getName();
578e8d8bef9SDimitry Andric   // The variant kind VK_PPC_NOTOC needs to be handled as a special case
579e8d8bef9SDimitry Andric   // because we do not want the assembly to print out the @notoc at the
580e8d8bef9SDimitry Andric   // end like __tls_get_addr(x@tlsgd)@notoc. Instead we want it to look
581e8d8bef9SDimitry Andric   // like __tls_get_addr@notoc(x@tlsgd).
582e8d8bef9SDimitry Andric   if (RefExp->getKind() == MCSymbolRefExpr::VK_PPC_NOTOC)
583e8d8bef9SDimitry Andric     O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
5840b57cec5SDimitry Andric   O << '(';
585e8d8bef9SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
5860b57cec5SDimitry Andric   O << ')';
587e8d8bef9SDimitry Andric   if (RefExp->getKind() != MCSymbolRefExpr::VK_None &&
588e8d8bef9SDimitry Andric       RefExp->getKind() != MCSymbolRefExpr::VK_PPC_NOTOC)
5890b57cec5SDimitry Andric     O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
5908a4dda33SDimitry Andric   if (Rhs) {
5918a4dda33SDimitry Andric     SmallString<0> Buf;
5928a4dda33SDimitry Andric     raw_svector_ostream Tmp(Buf);
5938a4dda33SDimitry Andric     Rhs->print(Tmp, &MAI);
5948a4dda33SDimitry Andric     if (isdigit(Buf[0]))
5958a4dda33SDimitry Andric       O << '+';
5968a4dda33SDimitry Andric     O << Buf;
5978a4dda33SDimitry Andric   }
5980b57cec5SDimitry Andric }
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric /// showRegistersWithPercentPrefix - Check if this register name should be
6010b57cec5SDimitry Andric /// printed with a percentage symbol as prefix.
6020b57cec5SDimitry Andric bool PPCInstPrinter::showRegistersWithPercentPrefix(const char *RegName) const {
603*5f757f3fSDimitry Andric   if ((!FullRegNamesWithPercent && !MAI.useFullRegisterNames()) ||
604*5f757f3fSDimitry Andric       TT.getOS() == Triple::AIX)
6050b57cec5SDimitry Andric     return false;
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric   switch (RegName[0]) {
6080b57cec5SDimitry Andric   default:
6090b57cec5SDimitry Andric     return false;
6100b57cec5SDimitry Andric   case 'r':
6110b57cec5SDimitry Andric   case 'f':
6120b57cec5SDimitry Andric   case 'q':
6130b57cec5SDimitry Andric   case 'v':
6140b57cec5SDimitry Andric   case 'c':
6150b57cec5SDimitry Andric     return true;
6160b57cec5SDimitry Andric   }
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric /// getVerboseConditionalRegName - This method expands the condition register
6200b57cec5SDimitry Andric /// when requested explicitly or targetting Darwin.
621*5f757f3fSDimitry Andric const char *
622*5f757f3fSDimitry Andric PPCInstPrinter::getVerboseConditionRegName(unsigned RegNum,
623*5f757f3fSDimitry Andric                                            unsigned RegEncoding) const {
624*5f757f3fSDimitry Andric   if (!FullRegNames && !MAI.useFullRegisterNames())
6250b57cec5SDimitry Andric     return nullptr;
6260b57cec5SDimitry Andric   if (RegNum < PPC::CR0EQ || RegNum > PPC::CR7UN)
6270b57cec5SDimitry Andric     return nullptr;
6280b57cec5SDimitry Andric   const char *CRBits[] = {
6290b57cec5SDimitry Andric     "lt", "gt", "eq", "un",
6300b57cec5SDimitry Andric     "4*cr1+lt", "4*cr1+gt", "4*cr1+eq", "4*cr1+un",
6310b57cec5SDimitry Andric     "4*cr2+lt", "4*cr2+gt", "4*cr2+eq", "4*cr2+un",
6320b57cec5SDimitry Andric     "4*cr3+lt", "4*cr3+gt", "4*cr3+eq", "4*cr3+un",
6330b57cec5SDimitry Andric     "4*cr4+lt", "4*cr4+gt", "4*cr4+eq", "4*cr4+un",
6340b57cec5SDimitry Andric     "4*cr5+lt", "4*cr5+gt", "4*cr5+eq", "4*cr5+un",
6350b57cec5SDimitry Andric     "4*cr6+lt", "4*cr6+gt", "4*cr6+eq", "4*cr6+un",
6360b57cec5SDimitry Andric     "4*cr7+lt", "4*cr7+gt", "4*cr7+eq", "4*cr7+un"
6370b57cec5SDimitry Andric   };
6380b57cec5SDimitry Andric   return CRBits[RegEncoding];
6390b57cec5SDimitry Andric }
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric // showRegistersWithPrefix - This method determines whether registers
6420b57cec5SDimitry Andric // should be number-only or include the prefix.
6430b57cec5SDimitry Andric bool PPCInstPrinter::showRegistersWithPrefix() const {
644*5f757f3fSDimitry Andric   return FullRegNamesWithPercent || FullRegNames || MAI.useFullRegisterNames();
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
648e8d8bef9SDimitry Andric                                   const MCSubtargetInfo &STI, raw_ostream &O) {
6490b57cec5SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
6500b57cec5SDimitry Andric   if (Op.isReg()) {
6510b57cec5SDimitry Andric     unsigned Reg = Op.getReg();
6520b57cec5SDimitry Andric     if (!ShowVSRNumsAsVR)
653*5f757f3fSDimitry Andric       Reg = PPC::getRegNumForOperand(MII.get(MI->getOpcode()), Reg, OpNo);
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric     const char *RegName;
6560b57cec5SDimitry Andric     RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg));
6570b57cec5SDimitry Andric     if (RegName == nullptr)
6580b57cec5SDimitry Andric      RegName = getRegisterName(Reg);
6590b57cec5SDimitry Andric     if (showRegistersWithPercentPrefix(RegName))
6600b57cec5SDimitry Andric       O << "%";
6610b57cec5SDimitry Andric     if (!showRegistersWithPrefix())
662*5f757f3fSDimitry Andric       RegName = PPC::stripRegisterPrefix(RegName);
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric     O << RegName;
6650b57cec5SDimitry Andric     return;
6660b57cec5SDimitry Andric   }
6670b57cec5SDimitry Andric 
6680b57cec5SDimitry Andric   if (Op.isImm()) {
6690b57cec5SDimitry Andric     O << Op.getImm();
6700b57cec5SDimitry Andric     return;
6710b57cec5SDimitry Andric   }
6720b57cec5SDimitry Andric 
6730b57cec5SDimitry Andric   assert(Op.isExpr() && "unknown operand kind in printOperand");
6740b57cec5SDimitry Andric   Op.getExpr()->print(O, &MAI);
6750b57cec5SDimitry Andric }
676