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