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"
160b57cec5SDimitry Andric #include "PPCInstrInfo.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.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 
printRegName(raw_ostream & OS,unsigned RegNo) const500b57cec5SDimitry Andric void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
510b57cec5SDimitry Andric   const char *RegName = getRegisterName(RegNo);
520b57cec5SDimitry Andric   OS << RegName;
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & O)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 ";
74af732203SDimitry Andric     printOperand(MI, 0, STI, O);
758bcb0991SDimitry Andric     O << ", ";
76af732203SDimitry Andric     printOperand(MI, 2, STI, O);
778bcb0991SDimitry Andric     O << "(";
78af732203SDimitry Andric     printOperand(MI, 1, STI, O);
798bcb0991SDimitry Andric     O << ")";
808bcb0991SDimitry Andric     return;
818bcb0991SDimitry Andric   }
828bcb0991SDimitry Andric 
83af732203SDimitry Andric   // Check if the last operand is an expression with the variant kind
84af732203SDimitry Andric   // VK_PPC_PCREL_OPT. If this is the case then this is a linker optimization
85af732203SDimitry Andric   // relocation and the .reloc directive needs to be added.
86af732203SDimitry Andric   unsigned LastOp = MI->getNumOperands() - 1;
87af732203SDimitry Andric   if (MI->getNumOperands() > 1) {
88af732203SDimitry Andric     const MCOperand &Operand = MI->getOperand(LastOp);
89af732203SDimitry Andric     if (Operand.isExpr()) {
90af732203SDimitry Andric       const MCExpr *Expr = Operand.getExpr();
91af732203SDimitry Andric       const MCSymbolRefExpr *SymExpr =
92af732203SDimitry Andric           static_cast<const MCSymbolRefExpr *>(Expr);
93af732203SDimitry Andric 
94af732203SDimitry Andric       if (SymExpr && SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT) {
95af732203SDimitry Andric         const MCSymbol &Symbol = SymExpr->getSymbol();
96af732203SDimitry Andric         if (MI->getOpcode() == PPC::PLDpc) {
97af732203SDimitry Andric           printInstruction(MI, Address, STI, O);
98af732203SDimitry Andric           O << "\n";
99af732203SDimitry Andric           Symbol.print(O, &MAI);
100af732203SDimitry Andric           O << ":";
101af732203SDimitry Andric           return;
102af732203SDimitry Andric         } else {
103af732203SDimitry Andric           O << "\t.reloc ";
104af732203SDimitry Andric           Symbol.print(O, &MAI);
105af732203SDimitry Andric           O << "-8,R_PPC64_PCREL_OPT,.-(";
106af732203SDimitry Andric           Symbol.print(O, &MAI);
107af732203SDimitry Andric           O << "-8)\n";
108af732203SDimitry Andric         }
109af732203SDimitry Andric       }
110af732203SDimitry Andric     }
111af732203SDimitry Andric   }
112af732203SDimitry 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) {
127af732203SDimitry Andric       printOperand(MI, 0, STI, O);
1280b57cec5SDimitry Andric       O << ", ";
129af732203SDimitry 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 ";
144af732203SDimitry Andric       printOperand(MI, 0, STI, O);
1450b57cec5SDimitry Andric       O << ", ";
146af732203SDimitry 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.
1610b57cec5SDimitry Andric   if (MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) {
1620b57cec5SDimitry Andric     unsigned char TH = MI->getOperand(0).getImm();
1630b57cec5SDimitry Andric     O << "\tdcbt";
1640b57cec5SDimitry Andric     if (MI->getOpcode() == PPC::DCBTST)
1650b57cec5SDimitry Andric       O << "st";
1660b57cec5SDimitry Andric     if (TH == 16)
1670b57cec5SDimitry Andric       O << "t";
1680b57cec5SDimitry Andric     O << " ";
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric     bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE];
1710b57cec5SDimitry Andric     if (IsBookE && TH != 0 && TH != 16)
1720b57cec5SDimitry Andric       O << (unsigned int) TH << ", ";
1730b57cec5SDimitry Andric 
174af732203SDimitry Andric     printOperand(MI, 1, STI, O);
1750b57cec5SDimitry Andric     O << ", ";
176af732203SDimitry Andric     printOperand(MI, 2, STI, O);
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric     if (!IsBookE && TH != 0 && TH != 16)
1790b57cec5SDimitry Andric       O << ", " << (unsigned int) TH;
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric     printAnnotation(O, Annot);
1820b57cec5SDimitry Andric     return;
1830b57cec5SDimitry Andric   }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   if (MI->getOpcode() == PPC::DCBF) {
1860b57cec5SDimitry Andric     unsigned char L = MI->getOperand(0).getImm();
187af732203SDimitry Andric     if (!L || L == 1 || L == 3 || L == 4 || L == 6) {
188af732203SDimitry Andric       O << "\tdcb";
189af732203SDimitry Andric       if (L != 6)
190af732203SDimitry Andric         O << "f";
191af732203SDimitry Andric       if (L == 1)
1920b57cec5SDimitry Andric         O << "l";
1930b57cec5SDimitry Andric       if (L == 3)
194af732203SDimitry Andric         O << "lp";
195af732203SDimitry Andric       if (L == 4)
196af732203SDimitry Andric         O << "ps";
197af732203SDimitry Andric       if (L == 6)
198af732203SDimitry Andric         O << "stps";
1990b57cec5SDimitry Andric       O << " ";
2000b57cec5SDimitry Andric 
201af732203SDimitry Andric       printOperand(MI, 1, STI, O);
2020b57cec5SDimitry Andric       O << ", ";
203af732203SDimitry Andric       printOperand(MI, 2, STI, O);
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric       printAnnotation(O, Annot);
2060b57cec5SDimitry Andric       return;
2070b57cec5SDimitry Andric     }
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric 
210af732203SDimitry Andric   if (!printAliasInstr(MI, Address, STI, O))
211af732203SDimitry Andric     printInstruction(MI, Address, STI, O);
2120b57cec5SDimitry Andric   printAnnotation(O, Annot);
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
printPredicateOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O,const char * Modifier)2150b57cec5SDimitry Andric void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
216af732203SDimitry Andric                                            const MCSubtargetInfo &STI,
2170b57cec5SDimitry Andric                                            raw_ostream &O,
2180b57cec5SDimitry Andric                                            const char *Modifier) {
2190b57cec5SDimitry Andric   unsigned Code = MI->getOperand(OpNo).getImm();
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   if (StringRef(Modifier) == "cc") {
2220b57cec5SDimitry Andric     switch ((PPC::Predicate)Code) {
2230b57cec5SDimitry Andric     case PPC::PRED_LT_MINUS:
2240b57cec5SDimitry Andric     case PPC::PRED_LT_PLUS:
2250b57cec5SDimitry Andric     case PPC::PRED_LT:
2260b57cec5SDimitry Andric       O << "lt";
2270b57cec5SDimitry Andric       return;
2280b57cec5SDimitry Andric     case PPC::PRED_LE_MINUS:
2290b57cec5SDimitry Andric     case PPC::PRED_LE_PLUS:
2300b57cec5SDimitry Andric     case PPC::PRED_LE:
2310b57cec5SDimitry Andric       O << "le";
2320b57cec5SDimitry Andric       return;
2330b57cec5SDimitry Andric     case PPC::PRED_EQ_MINUS:
2340b57cec5SDimitry Andric     case PPC::PRED_EQ_PLUS:
2350b57cec5SDimitry Andric     case PPC::PRED_EQ:
2360b57cec5SDimitry Andric       O << "eq";
2370b57cec5SDimitry Andric       return;
2380b57cec5SDimitry Andric     case PPC::PRED_GE_MINUS:
2390b57cec5SDimitry Andric     case PPC::PRED_GE_PLUS:
2400b57cec5SDimitry Andric     case PPC::PRED_GE:
2410b57cec5SDimitry Andric       O << "ge";
2420b57cec5SDimitry Andric       return;
2430b57cec5SDimitry Andric     case PPC::PRED_GT_MINUS:
2440b57cec5SDimitry Andric     case PPC::PRED_GT_PLUS:
2450b57cec5SDimitry Andric     case PPC::PRED_GT:
2460b57cec5SDimitry Andric       O << "gt";
2470b57cec5SDimitry Andric       return;
2480b57cec5SDimitry Andric     case PPC::PRED_NE_MINUS:
2490b57cec5SDimitry Andric     case PPC::PRED_NE_PLUS:
2500b57cec5SDimitry Andric     case PPC::PRED_NE:
2510b57cec5SDimitry Andric       O << "ne";
2520b57cec5SDimitry Andric       return;
2530b57cec5SDimitry Andric     case PPC::PRED_UN_MINUS:
2540b57cec5SDimitry Andric     case PPC::PRED_UN_PLUS:
2550b57cec5SDimitry Andric     case PPC::PRED_UN:
2560b57cec5SDimitry Andric       O << "un";
2570b57cec5SDimitry Andric       return;
2580b57cec5SDimitry Andric     case PPC::PRED_NU_MINUS:
2590b57cec5SDimitry Andric     case PPC::PRED_NU_PLUS:
2600b57cec5SDimitry Andric     case PPC::PRED_NU:
2610b57cec5SDimitry Andric       O << "nu";
2620b57cec5SDimitry Andric       return;
2630b57cec5SDimitry Andric     case PPC::PRED_BIT_SET:
2640b57cec5SDimitry Andric     case PPC::PRED_BIT_UNSET:
2650b57cec5SDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
2660b57cec5SDimitry Andric     }
2670b57cec5SDimitry Andric     llvm_unreachable("Invalid predicate code");
2680b57cec5SDimitry Andric   }
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   if (StringRef(Modifier) == "pm") {
2710b57cec5SDimitry Andric     switch ((PPC::Predicate)Code) {
2720b57cec5SDimitry Andric     case PPC::PRED_LT:
2730b57cec5SDimitry Andric     case PPC::PRED_LE:
2740b57cec5SDimitry Andric     case PPC::PRED_EQ:
2750b57cec5SDimitry Andric     case PPC::PRED_GE:
2760b57cec5SDimitry Andric     case PPC::PRED_GT:
2770b57cec5SDimitry Andric     case PPC::PRED_NE:
2780b57cec5SDimitry Andric     case PPC::PRED_UN:
2790b57cec5SDimitry Andric     case PPC::PRED_NU:
2800b57cec5SDimitry Andric       return;
2810b57cec5SDimitry Andric     case PPC::PRED_LT_MINUS:
2820b57cec5SDimitry Andric     case PPC::PRED_LE_MINUS:
2830b57cec5SDimitry Andric     case PPC::PRED_EQ_MINUS:
2840b57cec5SDimitry Andric     case PPC::PRED_GE_MINUS:
2850b57cec5SDimitry Andric     case PPC::PRED_GT_MINUS:
2860b57cec5SDimitry Andric     case PPC::PRED_NE_MINUS:
2870b57cec5SDimitry Andric     case PPC::PRED_UN_MINUS:
2880b57cec5SDimitry Andric     case PPC::PRED_NU_MINUS:
2890b57cec5SDimitry Andric       O << "-";
2900b57cec5SDimitry Andric       return;
2910b57cec5SDimitry Andric     case PPC::PRED_LT_PLUS:
2920b57cec5SDimitry Andric     case PPC::PRED_LE_PLUS:
2930b57cec5SDimitry Andric     case PPC::PRED_EQ_PLUS:
2940b57cec5SDimitry Andric     case PPC::PRED_GE_PLUS:
2950b57cec5SDimitry Andric     case PPC::PRED_GT_PLUS:
2960b57cec5SDimitry Andric     case PPC::PRED_NE_PLUS:
2970b57cec5SDimitry Andric     case PPC::PRED_UN_PLUS:
2980b57cec5SDimitry Andric     case PPC::PRED_NU_PLUS:
2990b57cec5SDimitry Andric       O << "+";
3000b57cec5SDimitry Andric       return;
3010b57cec5SDimitry Andric     case PPC::PRED_BIT_SET:
3020b57cec5SDimitry Andric     case PPC::PRED_BIT_UNSET:
3030b57cec5SDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
3040b57cec5SDimitry Andric     }
3050b57cec5SDimitry Andric     llvm_unreachable("Invalid predicate code");
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   assert(StringRef(Modifier) == "reg" &&
3090b57cec5SDimitry Andric          "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
310af732203SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric 
printATBitsAsHint(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3130b57cec5SDimitry Andric void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
314af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3150b57cec5SDimitry Andric                                        raw_ostream &O) {
3160b57cec5SDimitry Andric   unsigned Code = MI->getOperand(OpNo).getImm();
3170b57cec5SDimitry Andric   if (Code == 2)
3180b57cec5SDimitry Andric     O << "-";
3190b57cec5SDimitry Andric   else if (Code == 3)
3200b57cec5SDimitry Andric     O << "+";
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric 
printU1ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3230b57cec5SDimitry Andric void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
324af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3250b57cec5SDimitry Andric                                        raw_ostream &O) {
3260b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3270b57cec5SDimitry Andric   assert(Value <= 1 && "Invalid u1imm argument!");
3280b57cec5SDimitry Andric   O << (unsigned int)Value;
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
printU2ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3310b57cec5SDimitry Andric void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
332af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3330b57cec5SDimitry Andric                                        raw_ostream &O) {
3340b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3350b57cec5SDimitry Andric   assert(Value <= 3 && "Invalid u2imm argument!");
3360b57cec5SDimitry Andric   O << (unsigned int)Value;
3370b57cec5SDimitry Andric }
3380b57cec5SDimitry Andric 
printU3ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3390b57cec5SDimitry Andric void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
340af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3410b57cec5SDimitry Andric                                        raw_ostream &O) {
3420b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3430b57cec5SDimitry Andric   assert(Value <= 8 && "Invalid u3imm argument!");
3440b57cec5SDimitry Andric   O << (unsigned int)Value;
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric 
printU4ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3470b57cec5SDimitry Andric void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
348af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3490b57cec5SDimitry Andric                                        raw_ostream &O) {
3500b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3510b57cec5SDimitry Andric   assert(Value <= 15 && "Invalid u4imm argument!");
3520b57cec5SDimitry Andric   O << (unsigned int)Value;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
printS5ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3550b57cec5SDimitry Andric void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
356af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3570b57cec5SDimitry Andric                                        raw_ostream &O) {
3580b57cec5SDimitry Andric   int Value = MI->getOperand(OpNo).getImm();
3590b57cec5SDimitry Andric   Value = SignExtend32<5>(Value);
3600b57cec5SDimitry Andric   O << (int)Value;
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric 
printImmZeroOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3635ffd83dbSDimitry Andric void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo,
364af732203SDimitry Andric                                          const MCSubtargetInfo &STI,
3655ffd83dbSDimitry Andric                                          raw_ostream &O) {
3665ffd83dbSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3675ffd83dbSDimitry Andric   assert(Value == 0 && "Operand must be zero");
3685ffd83dbSDimitry Andric   O << (unsigned int)Value;
3695ffd83dbSDimitry Andric }
3705ffd83dbSDimitry Andric 
printU5ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3710b57cec5SDimitry Andric void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
372af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3730b57cec5SDimitry Andric                                        raw_ostream &O) {
3740b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3750b57cec5SDimitry Andric   assert(Value <= 31 && "Invalid u5imm argument!");
3760b57cec5SDimitry Andric   O << (unsigned int)Value;
3770b57cec5SDimitry Andric }
3780b57cec5SDimitry Andric 
printU6ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3790b57cec5SDimitry Andric void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
380af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3810b57cec5SDimitry Andric                                        raw_ostream &O) {
3820b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3830b57cec5SDimitry Andric   assert(Value <= 63 && "Invalid u6imm argument!");
3840b57cec5SDimitry Andric   O << (unsigned int)Value;
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric 
printU7ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3870b57cec5SDimitry Andric void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
388af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
3890b57cec5SDimitry Andric                                        raw_ostream &O) {
3900b57cec5SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3910b57cec5SDimitry Andric   assert(Value <= 127 && "Invalid u7imm argument!");
3920b57cec5SDimitry Andric   O << (unsigned int)Value;
3930b57cec5SDimitry Andric }
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric // Operands of BUILD_VECTOR are signed and we use this to print operands
3960b57cec5SDimitry Andric // of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
3970b57cec5SDimitry Andric // print as unsigned.
printU8ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)3980b57cec5SDimitry Andric void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
399af732203SDimitry Andric                                        const MCSubtargetInfo &STI,
4000b57cec5SDimitry Andric                                        raw_ostream &O) {
4010b57cec5SDimitry Andric   unsigned char Value = MI->getOperand(OpNo).getImm();
4020b57cec5SDimitry Andric   O << (unsigned int)Value;
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric 
printU10ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)4050b57cec5SDimitry Andric void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
406af732203SDimitry Andric                                         const MCSubtargetInfo &STI,
4070b57cec5SDimitry Andric                                         raw_ostream &O) {
4080b57cec5SDimitry Andric   unsigned short Value = MI->getOperand(OpNo).getImm();
4090b57cec5SDimitry Andric   assert(Value <= 1023 && "Invalid u10imm argument!");
4100b57cec5SDimitry Andric   O << (unsigned short)Value;
4110b57cec5SDimitry Andric }
4120b57cec5SDimitry Andric 
printU12ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)4130b57cec5SDimitry Andric void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
414af732203SDimitry Andric                                         const MCSubtargetInfo &STI,
4150b57cec5SDimitry Andric                                         raw_ostream &O) {
4160b57cec5SDimitry Andric   unsigned short Value = MI->getOperand(OpNo).getImm();
4170b57cec5SDimitry Andric   assert(Value <= 4095 && "Invalid u12imm argument!");
4180b57cec5SDimitry Andric   O << (unsigned short)Value;
4190b57cec5SDimitry Andric }
4200b57cec5SDimitry Andric 
printS16ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)4210b57cec5SDimitry Andric void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
422af732203SDimitry Andric                                         const MCSubtargetInfo &STI,
4230b57cec5SDimitry Andric                                         raw_ostream &O) {
4240b57cec5SDimitry Andric   if (MI->getOperand(OpNo).isImm())
4250b57cec5SDimitry Andric     O << (short)MI->getOperand(OpNo).getImm();
4260b57cec5SDimitry Andric   else
427af732203SDimitry Andric     printOperand(MI, OpNo, STI, O);
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric 
printS34ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)4305ffd83dbSDimitry Andric void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo,
431af732203SDimitry Andric                                         const MCSubtargetInfo &STI,
4325ffd83dbSDimitry Andric                                         raw_ostream &O) {
4335ffd83dbSDimitry Andric   if (MI->getOperand(OpNo).isImm()) {
4345ffd83dbSDimitry Andric     long long Value = MI->getOperand(OpNo).getImm();
4355ffd83dbSDimitry Andric     assert(isInt<34>(Value) && "Invalid s34imm argument!");
4365ffd83dbSDimitry Andric     O << (long long)Value;
4375ffd83dbSDimitry Andric   }
4385ffd83dbSDimitry Andric   else
439af732203SDimitry Andric     printOperand(MI, OpNo, STI, O);
4405ffd83dbSDimitry Andric }
4415ffd83dbSDimitry Andric 
printU16ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)4420b57cec5SDimitry Andric void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
443af732203SDimitry Andric                                         const MCSubtargetInfo &STI,
4440b57cec5SDimitry Andric                                         raw_ostream &O) {
4450b57cec5SDimitry Andric   if (MI->getOperand(OpNo).isImm())
4460b57cec5SDimitry Andric     O << (unsigned short)MI->getOperand(OpNo).getImm();
4470b57cec5SDimitry Andric   else
448af732203SDimitry Andric     printOperand(MI, OpNo, STI, O);
4490b57cec5SDimitry Andric }
4500b57cec5SDimitry Andric 
printBranchOperand(const MCInst * MI,uint64_t Address,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)4515ffd83dbSDimitry Andric void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
452af732203SDimitry Andric                                         unsigned OpNo,
453af732203SDimitry Andric                                         const MCSubtargetInfo &STI,
454af732203SDimitry Andric                                         raw_ostream &O) {
4550b57cec5SDimitry Andric   if (!MI->getOperand(OpNo).isImm())
456af732203SDimitry Andric     return printOperand(MI, OpNo, STI, O);
4570b57cec5SDimitry Andric   int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
4585ffd83dbSDimitry Andric   if (PrintBranchImmAsAddress) {
4595ffd83dbSDimitry Andric     uint64_t Target = Address + Imm;
4605ffd83dbSDimitry Andric     if (!TT.isPPC64())
4615ffd83dbSDimitry Andric       Target &= 0xffffffff;
4625ffd83dbSDimitry Andric     O << formatHex(Target);
4635ffd83dbSDimitry Andric   } else {
4645ffd83dbSDimitry Andric     // Branches can take an immediate operand. This is used by the branch
4655ffd83dbSDimitry Andric     // selection pass to print, for example `.+8` (for ELF) or `$+8` (for AIX)
4665ffd83dbSDimitry Andric     // to express an eight byte displacement from the program counter.
4675ffd83dbSDimitry Andric     if (!TT.isOSAIX())
4685ffd83dbSDimitry Andric       O << ".";
4695ffd83dbSDimitry Andric     else
4705ffd83dbSDimitry Andric       O << "$";
4715ffd83dbSDimitry Andric 
4720b57cec5SDimitry Andric     if (Imm >= 0)
4730b57cec5SDimitry Andric       O << "+";
4740b57cec5SDimitry Andric     O << Imm;
4750b57cec5SDimitry Andric   }
4765ffd83dbSDimitry Andric }
4770b57cec5SDimitry Andric 
printAbsBranchOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)4780b57cec5SDimitry Andric void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
479af732203SDimitry Andric                                            const MCSubtargetInfo &STI,
4800b57cec5SDimitry Andric                                            raw_ostream &O) {
4810b57cec5SDimitry Andric   if (!MI->getOperand(OpNo).isImm())
482af732203SDimitry Andric     return printOperand(MI, OpNo, STI, O);
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
4850b57cec5SDimitry Andric }
4860b57cec5SDimitry Andric 
printcrbitm(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)4870b57cec5SDimitry Andric void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
488af732203SDimitry Andric                                  const MCSubtargetInfo &STI, raw_ostream &O) {
4890b57cec5SDimitry Andric   unsigned CCReg = MI->getOperand(OpNo).getReg();
4900b57cec5SDimitry Andric   unsigned RegNo;
4910b57cec5SDimitry Andric   switch (CCReg) {
4920b57cec5SDimitry Andric   default: llvm_unreachable("Unknown CR register");
4930b57cec5SDimitry Andric   case PPC::CR0: RegNo = 0; break;
4940b57cec5SDimitry Andric   case PPC::CR1: RegNo = 1; break;
4950b57cec5SDimitry Andric   case PPC::CR2: RegNo = 2; break;
4960b57cec5SDimitry Andric   case PPC::CR3: RegNo = 3; break;
4970b57cec5SDimitry Andric   case PPC::CR4: RegNo = 4; break;
4980b57cec5SDimitry Andric   case PPC::CR5: RegNo = 5; break;
4990b57cec5SDimitry Andric   case PPC::CR6: RegNo = 6; break;
5000b57cec5SDimitry Andric   case PPC::CR7: RegNo = 7; break;
5010b57cec5SDimitry Andric   }
5020b57cec5SDimitry Andric   O << (0x80 >> RegNo);
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric 
printMemRegImm(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)5050b57cec5SDimitry Andric void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
506af732203SDimitry Andric                                     const MCSubtargetInfo &STI,
5070b57cec5SDimitry Andric                                     raw_ostream &O) {
508af732203SDimitry Andric   printS16ImmOperand(MI, OpNo, STI, O);
5090b57cec5SDimitry Andric   O << '(';
5100b57cec5SDimitry Andric   if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
5110b57cec5SDimitry Andric     O << "0";
5120b57cec5SDimitry Andric   else
513af732203SDimitry Andric     printOperand(MI, OpNo + 1, STI, O);
5140b57cec5SDimitry Andric   O << ')';
5150b57cec5SDimitry Andric }
5160b57cec5SDimitry Andric 
printMemRegImmHash(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)517*5f7ddb14SDimitry Andric void PPCInstPrinter::printMemRegImmHash(const MCInst *MI, unsigned OpNo,
518*5f7ddb14SDimitry Andric                                         const MCSubtargetInfo &STI,
519*5f7ddb14SDimitry Andric                                         raw_ostream &O) {
520*5f7ddb14SDimitry Andric   O << MI->getOperand(OpNo).getImm();
521*5f7ddb14SDimitry Andric   O << '(';
522*5f7ddb14SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
523*5f7ddb14SDimitry Andric   O << ')';
524*5f7ddb14SDimitry Andric }
525*5f7ddb14SDimitry Andric 
printMemRegImm34PCRel(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)5265ffd83dbSDimitry Andric void PPCInstPrinter::printMemRegImm34PCRel(const MCInst *MI, unsigned OpNo,
527af732203SDimitry Andric                                            const MCSubtargetInfo &STI,
5285ffd83dbSDimitry Andric                                            raw_ostream &O) {
529af732203SDimitry Andric   printS34ImmOperand(MI, OpNo, STI, O);
5305ffd83dbSDimitry Andric   O << '(';
531af732203SDimitry Andric   printImmZeroOperand(MI, OpNo + 1, STI, O);
5325ffd83dbSDimitry Andric   O << ')';
5335ffd83dbSDimitry Andric }
5345ffd83dbSDimitry Andric 
printMemRegImm34(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)5355ffd83dbSDimitry Andric void PPCInstPrinter::printMemRegImm34(const MCInst *MI, unsigned OpNo,
536af732203SDimitry Andric                                       const MCSubtargetInfo &STI,
5375ffd83dbSDimitry Andric                                       raw_ostream &O) {
538af732203SDimitry Andric   printS34ImmOperand(MI, OpNo, STI, O);
5395ffd83dbSDimitry Andric   O << '(';
540af732203SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
5415ffd83dbSDimitry Andric   O << ')';
5425ffd83dbSDimitry Andric }
5435ffd83dbSDimitry Andric 
printMemRegReg(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)5440b57cec5SDimitry Andric void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
545af732203SDimitry Andric                                     const MCSubtargetInfo &STI,
5460b57cec5SDimitry Andric                                     raw_ostream &O) {
5470b57cec5SDimitry Andric   // When used as the base register, r0 reads constant zero rather than
5480b57cec5SDimitry Andric   // the value contained in the register.  For this reason, the darwin
5490b57cec5SDimitry Andric   // assembler requires that we print r0 as 0 (no r) when used as the base.
5500b57cec5SDimitry Andric   if (MI->getOperand(OpNo).getReg() == PPC::R0)
5510b57cec5SDimitry Andric     O << "0";
5520b57cec5SDimitry Andric   else
553af732203SDimitry Andric     printOperand(MI, OpNo, STI, O);
5540b57cec5SDimitry Andric   O << ", ";
555af732203SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
5560b57cec5SDimitry Andric }
5570b57cec5SDimitry Andric 
printTLSCall(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)5580b57cec5SDimitry Andric void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
559af732203SDimitry Andric                                   const MCSubtargetInfo &STI, raw_ostream &O) {
5600b57cec5SDimitry Andric   // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
5610b57cec5SDimitry Andric   // come at the _end_ of the expression.
5620b57cec5SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
5630b57cec5SDimitry Andric   const MCSymbolRefExpr *RefExp = nullptr;
5640b57cec5SDimitry Andric   const MCConstantExpr *ConstExp = nullptr;
5650b57cec5SDimitry Andric   if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Op.getExpr())) {
5660b57cec5SDimitry Andric     RefExp = cast<MCSymbolRefExpr>(BinExpr->getLHS());
5670b57cec5SDimitry Andric     ConstExp = cast<MCConstantExpr>(BinExpr->getRHS());
5680b57cec5SDimitry Andric   } else
5690b57cec5SDimitry Andric     RefExp = cast<MCSymbolRefExpr>(Op.getExpr());
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric   O << RefExp->getSymbol().getName();
572af732203SDimitry Andric   // The variant kind VK_PPC_NOTOC needs to be handled as a special case
573af732203SDimitry Andric   // because we do not want the assembly to print out the @notoc at the
574af732203SDimitry Andric   // end like __tls_get_addr(x@tlsgd)@notoc. Instead we want it to look
575af732203SDimitry Andric   // like __tls_get_addr@notoc(x@tlsgd).
576af732203SDimitry Andric   if (RefExp->getKind() == MCSymbolRefExpr::VK_PPC_NOTOC)
577af732203SDimitry Andric     O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
5780b57cec5SDimitry Andric   O << '(';
579af732203SDimitry Andric   printOperand(MI, OpNo + 1, STI, O);
5800b57cec5SDimitry Andric   O << ')';
581af732203SDimitry Andric   if (RefExp->getKind() != MCSymbolRefExpr::VK_None &&
582af732203SDimitry Andric       RefExp->getKind() != MCSymbolRefExpr::VK_PPC_NOTOC)
5830b57cec5SDimitry Andric     O << '@' << MCSymbolRefExpr::getVariantKindName(RefExp->getKind());
5840b57cec5SDimitry Andric   if (ConstExp != nullptr)
5850b57cec5SDimitry Andric     O << '+' << ConstExp->getValue();
5860b57cec5SDimitry Andric }
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric /// showRegistersWithPercentPrefix - Check if this register name should be
5890b57cec5SDimitry Andric /// printed with a percentage symbol as prefix.
showRegistersWithPercentPrefix(const char * RegName) const5900b57cec5SDimitry Andric bool PPCInstPrinter::showRegistersWithPercentPrefix(const char *RegName) const {
591af732203SDimitry Andric   if (!FullRegNamesWithPercent || TT.getOS() == Triple::AIX)
5920b57cec5SDimitry Andric     return false;
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   switch (RegName[0]) {
5950b57cec5SDimitry Andric   default:
5960b57cec5SDimitry Andric     return false;
5970b57cec5SDimitry Andric   case 'r':
5980b57cec5SDimitry Andric   case 'f':
5990b57cec5SDimitry Andric   case 'q':
6000b57cec5SDimitry Andric   case 'v':
6010b57cec5SDimitry Andric   case 'c':
6020b57cec5SDimitry Andric     return true;
6030b57cec5SDimitry Andric   }
6040b57cec5SDimitry Andric }
6050b57cec5SDimitry Andric 
6060b57cec5SDimitry Andric /// getVerboseConditionalRegName - This method expands the condition register
6070b57cec5SDimitry Andric /// when requested explicitly or targetting Darwin.
getVerboseConditionRegName(unsigned RegNum,unsigned RegEncoding) const6080b57cec5SDimitry Andric const char *PPCInstPrinter::getVerboseConditionRegName(unsigned RegNum,
6090b57cec5SDimitry Andric                                                        unsigned RegEncoding)
6100b57cec5SDimitry Andric                                                        const {
611af732203SDimitry Andric   if (!FullRegNames)
6120b57cec5SDimitry Andric     return nullptr;
6130b57cec5SDimitry Andric   if (RegNum < PPC::CR0EQ || RegNum > PPC::CR7UN)
6140b57cec5SDimitry Andric     return nullptr;
6150b57cec5SDimitry Andric   const char *CRBits[] = {
6160b57cec5SDimitry Andric     "lt", "gt", "eq", "un",
6170b57cec5SDimitry Andric     "4*cr1+lt", "4*cr1+gt", "4*cr1+eq", "4*cr1+un",
6180b57cec5SDimitry Andric     "4*cr2+lt", "4*cr2+gt", "4*cr2+eq", "4*cr2+un",
6190b57cec5SDimitry Andric     "4*cr3+lt", "4*cr3+gt", "4*cr3+eq", "4*cr3+un",
6200b57cec5SDimitry Andric     "4*cr4+lt", "4*cr4+gt", "4*cr4+eq", "4*cr4+un",
6210b57cec5SDimitry Andric     "4*cr5+lt", "4*cr5+gt", "4*cr5+eq", "4*cr5+un",
6220b57cec5SDimitry Andric     "4*cr6+lt", "4*cr6+gt", "4*cr6+eq", "4*cr6+un",
6230b57cec5SDimitry Andric     "4*cr7+lt", "4*cr7+gt", "4*cr7+eq", "4*cr7+un"
6240b57cec5SDimitry Andric   };
6250b57cec5SDimitry Andric   return CRBits[RegEncoding];
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric // showRegistersWithPrefix - This method determines whether registers
6290b57cec5SDimitry Andric // should be number-only or include the prefix.
showRegistersWithPrefix() const6300b57cec5SDimitry Andric bool PPCInstPrinter::showRegistersWithPrefix() const {
6310b57cec5SDimitry Andric   if (TT.getOS() == Triple::AIX)
6320b57cec5SDimitry Andric     return false;
633af732203SDimitry Andric   return FullRegNamesWithPercent || FullRegNames;
6340b57cec5SDimitry Andric }
6350b57cec5SDimitry Andric 
printOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)6360b57cec5SDimitry Andric void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
637af732203SDimitry Andric                                   const MCSubtargetInfo &STI, raw_ostream &O) {
6380b57cec5SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
6390b57cec5SDimitry Andric   if (Op.isReg()) {
6400b57cec5SDimitry Andric     unsigned Reg = Op.getReg();
6410b57cec5SDimitry Andric     if (!ShowVSRNumsAsVR)
6420b57cec5SDimitry Andric       Reg = PPCInstrInfo::getRegNumForOperand(MII.get(MI->getOpcode()),
6430b57cec5SDimitry Andric                                               Reg, OpNo);
6440b57cec5SDimitry Andric 
6450b57cec5SDimitry Andric     const char *RegName;
6460b57cec5SDimitry Andric     RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg));
6470b57cec5SDimitry Andric     if (RegName == nullptr)
6480b57cec5SDimitry Andric      RegName = getRegisterName(Reg);
6490b57cec5SDimitry Andric     if (showRegistersWithPercentPrefix(RegName))
6500b57cec5SDimitry Andric       O << "%";
6510b57cec5SDimitry Andric     if (!showRegistersWithPrefix())
6520b57cec5SDimitry Andric       RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric     O << RegName;
6550b57cec5SDimitry Andric     return;
6560b57cec5SDimitry Andric   }
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   if (Op.isImm()) {
6590b57cec5SDimitry Andric     O << Op.getImm();
6600b57cec5SDimitry Andric     return;
6610b57cec5SDimitry Andric   }
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric   assert(Op.isExpr() && "unknown operand kind in printOperand");
6640b57cec5SDimitry Andric   Op.getExpr()->print(O, &MAI);
6650b57cec5SDimitry Andric }
666