12754fe60SDimitry Andric //===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===//
22754fe60SDimitry Andric //
32754fe60SDimitry Andric //                     The LLVM Compiler Infrastructure
42754fe60SDimitry Andric //
52754fe60SDimitry Andric // This file is distributed under the University of Illinois Open Source
62754fe60SDimitry Andric // License. See LICENSE.TXT for details.
72754fe60SDimitry Andric //
82754fe60SDimitry Andric //===----------------------------------------------------------------------===//
92754fe60SDimitry Andric //
102754fe60SDimitry Andric // This class prints an PPC MCInst to a .s file.
112754fe60SDimitry Andric //
122754fe60SDimitry Andric //===----------------------------------------------------------------------===//
132754fe60SDimitry Andric 
142754fe60SDimitry Andric #include "PPCInstPrinter.h"
15139f7f9bSDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
166122f3e6SDimitry Andric #include "MCTargetDesc/PPCPredicates.h"
172754fe60SDimitry Andric #include "llvm/MC/MCExpr.h"
182754fe60SDimitry Andric #include "llvm/MC/MCInst.h"
19dff0c46cSDimitry Andric #include "llvm/MC/MCInstrInfo.h"
20*26e25074SRoman Divacky #include "llvm/MC/MCSymbol.h"
21f785676fSDimitry Andric #include "llvm/Support/CommandLine.h"
222754fe60SDimitry Andric #include "llvm/Support/raw_ostream.h"
23f785676fSDimitry Andric #include "llvm/Target/TargetOpcodes.h"
242754fe60SDimitry Andric using namespace llvm;
252754fe60SDimitry Andric 
2691bc56edSDimitry Andric #define DEBUG_TYPE "asm-printer"
2791bc56edSDimitry Andric 
28f785676fSDimitry Andric // FIXME: Once the integrated assembler supports full register names, tie this
29f785676fSDimitry Andric // to the verbose-asm setting.
30f785676fSDimitry Andric static cl::opt<bool>
31f785676fSDimitry Andric FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
32f785676fSDimitry Andric              cl::desc("Use full register names when printing assembly"));
33f785676fSDimitry Andric 
342754fe60SDimitry Andric #include "PPCGenAsmWriter.inc"
352754fe60SDimitry Andric 
36bd5abe19SDimitry Andric void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
37bd5abe19SDimitry Andric   OS << getRegisterName(RegNo);
38bd5abe19SDimitry Andric }
392754fe60SDimitry Andric 
406122f3e6SDimitry Andric void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
416122f3e6SDimitry Andric                                StringRef Annot) {
422754fe60SDimitry Andric   // Check for slwi/srwi mnemonics.
432754fe60SDimitry Andric   if (MI->getOpcode() == PPC::RLWINM) {
442754fe60SDimitry Andric     unsigned char SH = MI->getOperand(2).getImm();
452754fe60SDimitry Andric     unsigned char MB = MI->getOperand(3).getImm();
462754fe60SDimitry Andric     unsigned char ME = MI->getOperand(4).getImm();
472754fe60SDimitry Andric     bool useSubstituteMnemonic = false;
482754fe60SDimitry Andric     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
492754fe60SDimitry Andric       O << "\tslwi "; useSubstituteMnemonic = true;
502754fe60SDimitry Andric     }
512754fe60SDimitry Andric     if (SH <= 31 && MB == (32-SH) && ME == 31) {
522754fe60SDimitry Andric       O << "\tsrwi "; useSubstituteMnemonic = true;
532754fe60SDimitry Andric       SH = 32-SH;
542754fe60SDimitry Andric     }
552754fe60SDimitry Andric     if (useSubstituteMnemonic) {
562754fe60SDimitry Andric       printOperand(MI, 0, O);
572754fe60SDimitry Andric       O << ", ";
582754fe60SDimitry Andric       printOperand(MI, 1, O);
592754fe60SDimitry Andric       O << ", " << (unsigned int)SH;
606122f3e6SDimitry Andric 
616122f3e6SDimitry Andric       printAnnotation(O, Annot);
622754fe60SDimitry Andric       return;
632754fe60SDimitry Andric     }
642754fe60SDimitry Andric   }
652754fe60SDimitry Andric 
662754fe60SDimitry Andric   if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
672754fe60SDimitry Andric       MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
682754fe60SDimitry Andric     O << "\tmr ";
692754fe60SDimitry Andric     printOperand(MI, 0, O);
702754fe60SDimitry Andric     O << ", ";
712754fe60SDimitry Andric     printOperand(MI, 1, O);
726122f3e6SDimitry Andric     printAnnotation(O, Annot);
732754fe60SDimitry Andric     return;
742754fe60SDimitry Andric   }
752754fe60SDimitry Andric 
762754fe60SDimitry Andric   if (MI->getOpcode() == PPC::RLDICR) {
772754fe60SDimitry Andric     unsigned char SH = MI->getOperand(2).getImm();
782754fe60SDimitry Andric     unsigned char ME = MI->getOperand(3).getImm();
792754fe60SDimitry Andric     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
802754fe60SDimitry Andric     if (63-SH == ME) {
812754fe60SDimitry Andric       O << "\tsldi ";
822754fe60SDimitry Andric       printOperand(MI, 0, O);
832754fe60SDimitry Andric       O << ", ";
842754fe60SDimitry Andric       printOperand(MI, 1, O);
852754fe60SDimitry Andric       O << ", " << (unsigned int)SH;
866122f3e6SDimitry Andric       printAnnotation(O, Annot);
872754fe60SDimitry Andric       return;
882754fe60SDimitry Andric     }
892754fe60SDimitry Andric   }
902754fe60SDimitry Andric 
91f785676fSDimitry Andric   // For fast-isel, a COPY_TO_REGCLASS may survive this long.  This is
92f785676fSDimitry Andric   // used when converting a 32-bit float to a 64-bit float as part of
93f785676fSDimitry Andric   // conversion to an integer (see PPCFastISel.cpp:SelectFPToI()),
94f785676fSDimitry Andric   // as otherwise we have problems with incorrect register classes
95f785676fSDimitry Andric   // in machine instruction verification.  For now, just avoid trying
96f785676fSDimitry Andric   // to print it as such an instruction has no effect (a 32-bit float
97f785676fSDimitry Andric   // in a register is already in 64-bit form, just with lower
98f785676fSDimitry Andric   // precision).  FIXME: Is there a better solution?
99f785676fSDimitry Andric   if (MI->getOpcode() == TargetOpcode::COPY_TO_REGCLASS)
100f785676fSDimitry Andric     return;
101f785676fSDimitry Andric 
1022754fe60SDimitry Andric   printInstruction(MI, O);
1036122f3e6SDimitry Andric   printAnnotation(O, Annot);
1042754fe60SDimitry Andric }
1052754fe60SDimitry Andric 
1062754fe60SDimitry Andric 
1072754fe60SDimitry Andric void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
1082754fe60SDimitry Andric                                            raw_ostream &O,
1092754fe60SDimitry Andric                                            const char *Modifier) {
1102754fe60SDimitry Andric   unsigned Code = MI->getOperand(OpNo).getImm();
1117ae0e2c9SDimitry Andric 
1122754fe60SDimitry Andric   if (StringRef(Modifier) == "cc") {
1132754fe60SDimitry Andric     switch ((PPC::Predicate)Code) {
114f785676fSDimitry Andric     case PPC::PRED_LT_MINUS:
115f785676fSDimitry Andric     case PPC::PRED_LT_PLUS:
116f785676fSDimitry Andric     case PPC::PRED_LT:
117f785676fSDimitry Andric       O << "lt";
118f785676fSDimitry Andric       return;
119f785676fSDimitry Andric     case PPC::PRED_LE_MINUS:
120f785676fSDimitry Andric     case PPC::PRED_LE_PLUS:
121f785676fSDimitry Andric     case PPC::PRED_LE:
122f785676fSDimitry Andric       O << "le";
123f785676fSDimitry Andric       return;
124f785676fSDimitry Andric     case PPC::PRED_EQ_MINUS:
125f785676fSDimitry Andric     case PPC::PRED_EQ_PLUS:
126f785676fSDimitry Andric     case PPC::PRED_EQ:
127f785676fSDimitry Andric       O << "eq";
128f785676fSDimitry Andric       return;
129f785676fSDimitry Andric     case PPC::PRED_GE_MINUS:
130f785676fSDimitry Andric     case PPC::PRED_GE_PLUS:
131f785676fSDimitry Andric     case PPC::PRED_GE:
132f785676fSDimitry Andric       O << "ge";
133f785676fSDimitry Andric       return;
134f785676fSDimitry Andric     case PPC::PRED_GT_MINUS:
135f785676fSDimitry Andric     case PPC::PRED_GT_PLUS:
136f785676fSDimitry Andric     case PPC::PRED_GT:
137f785676fSDimitry Andric       O << "gt";
138f785676fSDimitry Andric       return;
139f785676fSDimitry Andric     case PPC::PRED_NE_MINUS:
140f785676fSDimitry Andric     case PPC::PRED_NE_PLUS:
141f785676fSDimitry Andric     case PPC::PRED_NE:
142f785676fSDimitry Andric       O << "ne";
143f785676fSDimitry Andric       return;
144f785676fSDimitry Andric     case PPC::PRED_UN_MINUS:
145f785676fSDimitry Andric     case PPC::PRED_UN_PLUS:
146f785676fSDimitry Andric     case PPC::PRED_UN:
147f785676fSDimitry Andric       O << "un";
148f785676fSDimitry Andric       return;
149f785676fSDimitry Andric     case PPC::PRED_NU_MINUS:
150f785676fSDimitry Andric     case PPC::PRED_NU_PLUS:
151f785676fSDimitry Andric     case PPC::PRED_NU:
152f785676fSDimitry Andric       O << "nu";
153f785676fSDimitry Andric       return;
15491bc56edSDimitry Andric     case PPC::PRED_BIT_SET:
15591bc56edSDimitry Andric     case PPC::PRED_BIT_UNSET:
15691bc56edSDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
1572754fe60SDimitry Andric     }
158f785676fSDimitry Andric     llvm_unreachable("Invalid predicate code");
159f785676fSDimitry Andric   }
160f785676fSDimitry Andric 
161f785676fSDimitry Andric   if (StringRef(Modifier) == "pm") {
162f785676fSDimitry Andric     switch ((PPC::Predicate)Code) {
163f785676fSDimitry Andric     case PPC::PRED_LT:
164f785676fSDimitry Andric     case PPC::PRED_LE:
165f785676fSDimitry Andric     case PPC::PRED_EQ:
166f785676fSDimitry Andric     case PPC::PRED_GE:
167f785676fSDimitry Andric     case PPC::PRED_GT:
168f785676fSDimitry Andric     case PPC::PRED_NE:
169f785676fSDimitry Andric     case PPC::PRED_UN:
170f785676fSDimitry Andric     case PPC::PRED_NU:
171f785676fSDimitry Andric       return;
172f785676fSDimitry Andric     case PPC::PRED_LT_MINUS:
173f785676fSDimitry Andric     case PPC::PRED_LE_MINUS:
174f785676fSDimitry Andric     case PPC::PRED_EQ_MINUS:
175f785676fSDimitry Andric     case PPC::PRED_GE_MINUS:
176f785676fSDimitry Andric     case PPC::PRED_GT_MINUS:
177f785676fSDimitry Andric     case PPC::PRED_NE_MINUS:
178f785676fSDimitry Andric     case PPC::PRED_UN_MINUS:
179f785676fSDimitry Andric     case PPC::PRED_NU_MINUS:
180f785676fSDimitry Andric       O << "-";
181f785676fSDimitry Andric       return;
182f785676fSDimitry Andric     case PPC::PRED_LT_PLUS:
183f785676fSDimitry Andric     case PPC::PRED_LE_PLUS:
184f785676fSDimitry Andric     case PPC::PRED_EQ_PLUS:
185f785676fSDimitry Andric     case PPC::PRED_GE_PLUS:
186f785676fSDimitry Andric     case PPC::PRED_GT_PLUS:
187f785676fSDimitry Andric     case PPC::PRED_NE_PLUS:
188f785676fSDimitry Andric     case PPC::PRED_UN_PLUS:
189f785676fSDimitry Andric     case PPC::PRED_NU_PLUS:
190f785676fSDimitry Andric       O << "+";
191f785676fSDimitry Andric       return;
19291bc56edSDimitry Andric     case PPC::PRED_BIT_SET:
19391bc56edSDimitry Andric     case PPC::PRED_BIT_UNSET:
19491bc56edSDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
195f785676fSDimitry Andric     }
196f785676fSDimitry Andric     llvm_unreachable("Invalid predicate code");
1972754fe60SDimitry Andric   }
1982754fe60SDimitry Andric 
1992754fe60SDimitry Andric   assert(StringRef(Modifier) == "reg" &&
200f785676fSDimitry Andric          "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
2012754fe60SDimitry Andric   printOperand(MI, OpNo+1, O);
2022754fe60SDimitry Andric }
2032754fe60SDimitry Andric 
20491bc56edSDimitry Andric void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
20591bc56edSDimitry Andric                                        raw_ostream &O) {
20691bc56edSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
20791bc56edSDimitry Andric   assert(Value <= 3 && "Invalid u2imm argument!");
20891bc56edSDimitry Andric   O << (unsigned int)Value;
20991bc56edSDimitry Andric }
21091bc56edSDimitry Andric 
2112754fe60SDimitry Andric void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
2122754fe60SDimitry Andric                                        raw_ostream &O) {
2133861d79fSDimitry Andric   int Value = MI->getOperand(OpNo).getImm();
2143861d79fSDimitry Andric   Value = SignExtend32<5>(Value);
2152754fe60SDimitry Andric   O << (int)Value;
2162754fe60SDimitry Andric }
2172754fe60SDimitry Andric 
2182754fe60SDimitry Andric void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
2192754fe60SDimitry Andric                                        raw_ostream &O) {
2203861d79fSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
2212754fe60SDimitry Andric   assert(Value <= 31 && "Invalid u5imm argument!");
2222754fe60SDimitry Andric   O << (unsigned int)Value;
2232754fe60SDimitry Andric }
2242754fe60SDimitry Andric 
2252754fe60SDimitry Andric void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
2262754fe60SDimitry Andric                                        raw_ostream &O) {
2273861d79fSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
2282754fe60SDimitry Andric   assert(Value <= 63 && "Invalid u6imm argument!");
2292754fe60SDimitry Andric   O << (unsigned int)Value;
2302754fe60SDimitry Andric }
2312754fe60SDimitry Andric 
2322754fe60SDimitry Andric void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
2332754fe60SDimitry Andric                                         raw_ostream &O) {
234f785676fSDimitry Andric   if (MI->getOperand(OpNo).isImm())
2352754fe60SDimitry Andric     O << (short)MI->getOperand(OpNo).getImm();
236f785676fSDimitry Andric   else
237f785676fSDimitry Andric     printOperand(MI, OpNo, O);
2382754fe60SDimitry Andric }
2392754fe60SDimitry Andric 
2402754fe60SDimitry Andric void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
2412754fe60SDimitry Andric                                         raw_ostream &O) {
2422754fe60SDimitry Andric   if (MI->getOperand(OpNo).isImm())
243f785676fSDimitry Andric     O << (unsigned short)MI->getOperand(OpNo).getImm();
2442754fe60SDimitry Andric   else
2452754fe60SDimitry Andric     printOperand(MI, OpNo, O);
2462754fe60SDimitry Andric }
2472754fe60SDimitry Andric 
2482754fe60SDimitry Andric void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
2492754fe60SDimitry Andric                                         raw_ostream &O) {
2502754fe60SDimitry Andric   if (!MI->getOperand(OpNo).isImm())
2512754fe60SDimitry Andric     return printOperand(MI, OpNo, O);
2522754fe60SDimitry Andric 
2532754fe60SDimitry Andric   // Branches can take an immediate operand.  This is used by the branch
254284c1978SDimitry Andric   // selection pass to print .+8, an eight byte displacement from the PC.
255284c1978SDimitry Andric   O << ".+";
256f785676fSDimitry Andric   printAbsBranchOperand(MI, OpNo, O);
2572754fe60SDimitry Andric }
2582754fe60SDimitry Andric 
259f785676fSDimitry Andric void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
2602754fe60SDimitry Andric                                            raw_ostream &O) {
261f785676fSDimitry Andric   if (!MI->getOperand(OpNo).isImm())
262f785676fSDimitry Andric     return printOperand(MI, OpNo, O);
263f785676fSDimitry Andric 
2642754fe60SDimitry Andric   O << (int)MI->getOperand(OpNo).getImm()*4;
2652754fe60SDimitry Andric }
2662754fe60SDimitry Andric 
2672754fe60SDimitry Andric 
2682754fe60SDimitry Andric void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
2692754fe60SDimitry Andric                                  raw_ostream &O) {
2702754fe60SDimitry Andric   unsigned CCReg = MI->getOperand(OpNo).getReg();
2712754fe60SDimitry Andric   unsigned RegNo;
2722754fe60SDimitry Andric   switch (CCReg) {
273dff0c46cSDimitry Andric   default: llvm_unreachable("Unknown CR register");
2742754fe60SDimitry Andric   case PPC::CR0: RegNo = 0; break;
2752754fe60SDimitry Andric   case PPC::CR1: RegNo = 1; break;
2762754fe60SDimitry Andric   case PPC::CR2: RegNo = 2; break;
2772754fe60SDimitry Andric   case PPC::CR3: RegNo = 3; break;
2782754fe60SDimitry Andric   case PPC::CR4: RegNo = 4; break;
2792754fe60SDimitry Andric   case PPC::CR5: RegNo = 5; break;
2802754fe60SDimitry Andric   case PPC::CR6: RegNo = 6; break;
2812754fe60SDimitry Andric   case PPC::CR7: RegNo = 7; break;
2822754fe60SDimitry Andric   }
2832754fe60SDimitry Andric   O << (0x80 >> RegNo);
2842754fe60SDimitry Andric }
2852754fe60SDimitry Andric 
2862754fe60SDimitry Andric void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
2872754fe60SDimitry Andric                                     raw_ostream &O) {
288f785676fSDimitry Andric   printS16ImmOperand(MI, OpNo, O);
2892754fe60SDimitry Andric   O << '(';
2902754fe60SDimitry Andric   if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
2912754fe60SDimitry Andric     O << "0";
2922754fe60SDimitry Andric   else
2932754fe60SDimitry Andric     printOperand(MI, OpNo+1, O);
2942754fe60SDimitry Andric   O << ')';
2952754fe60SDimitry Andric }
2962754fe60SDimitry Andric 
2972754fe60SDimitry Andric void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
2982754fe60SDimitry Andric                                     raw_ostream &O) {
2992754fe60SDimitry Andric   // When used as the base register, r0 reads constant zero rather than
3002754fe60SDimitry Andric   // the value contained in the register.  For this reason, the darwin
3012754fe60SDimitry Andric   // assembler requires that we print r0 as 0 (no r) when used as the base.
3022754fe60SDimitry Andric   if (MI->getOperand(OpNo).getReg() == PPC::R0)
3032754fe60SDimitry Andric     O << "0";
3042754fe60SDimitry Andric   else
3052754fe60SDimitry Andric     printOperand(MI, OpNo, O);
3062754fe60SDimitry Andric   O << ", ";
3072754fe60SDimitry Andric   printOperand(MI, OpNo+1, O);
3082754fe60SDimitry Andric }
3092754fe60SDimitry Andric 
310f785676fSDimitry Andric void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
311f785676fSDimitry Andric                                   raw_ostream &O) {
312*26e25074SRoman Divacky   // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
313*26e25074SRoman Divacky   // come at the _end_ of the expression.
314*26e25074SRoman Divacky   const MCOperand &Op = MI->getOperand(OpNo);
315*26e25074SRoman Divacky   const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*Op.getExpr());
316*26e25074SRoman Divacky   O << refExp.getSymbol().getName();
317f785676fSDimitry Andric   O << '(';
318f785676fSDimitry Andric   printOperand(MI, OpNo+1, O);
319f785676fSDimitry Andric   O << ')';
320*26e25074SRoman Divacky   if (refExp.getKind() != MCSymbolRefExpr::VK_None)
321*26e25074SRoman Divacky     O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind());
322f785676fSDimitry Andric }
3232754fe60SDimitry Andric 
3242754fe60SDimitry Andric 
3252754fe60SDimitry Andric /// stripRegisterPrefix - This method strips the character prefix from a
3262754fe60SDimitry Andric /// register name so that only the number is left.  Used by for linux asm.
3272754fe60SDimitry Andric static const char *stripRegisterPrefix(const char *RegName) {
328f785676fSDimitry Andric   if (FullRegNames)
329f785676fSDimitry Andric     return RegName;
330f785676fSDimitry Andric 
3312754fe60SDimitry Andric   switch (RegName[0]) {
3322754fe60SDimitry Andric   case 'r':
3332754fe60SDimitry Andric   case 'f':
33491bc56edSDimitry Andric   case 'v':
33591bc56edSDimitry Andric     if (RegName[1] == 's')
33691bc56edSDimitry Andric       return RegName + 2;
33791bc56edSDimitry Andric     return RegName + 1;
3382754fe60SDimitry Andric   case 'c': if (RegName[1] == 'r') return RegName + 2;
3392754fe60SDimitry Andric   }
3402754fe60SDimitry Andric 
3412754fe60SDimitry Andric   return RegName;
3422754fe60SDimitry Andric }
3432754fe60SDimitry Andric 
3442754fe60SDimitry Andric void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
3452754fe60SDimitry Andric                                   raw_ostream &O) {
3462754fe60SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
3472754fe60SDimitry Andric   if (Op.isReg()) {
3482754fe60SDimitry Andric     const char *RegName = getRegisterName(Op.getReg());
3492754fe60SDimitry Andric     // The linux and AIX assembler does not take register prefixes.
3502754fe60SDimitry Andric     if (!isDarwinSyntax())
3512754fe60SDimitry Andric       RegName = stripRegisterPrefix(RegName);
3522754fe60SDimitry Andric 
3532754fe60SDimitry Andric     O << RegName;
3542754fe60SDimitry Andric     return;
3552754fe60SDimitry Andric   }
3562754fe60SDimitry Andric 
3572754fe60SDimitry Andric   if (Op.isImm()) {
3582754fe60SDimitry Andric     O << Op.getImm();
3592754fe60SDimitry Andric     return;
3602754fe60SDimitry Andric   }
3612754fe60SDimitry Andric 
3622754fe60SDimitry Andric   assert(Op.isExpr() && "unknown operand kind in printOperand");
3632754fe60SDimitry Andric   O << *Op.getExpr();
3642754fe60SDimitry Andric }
3652754fe60SDimitry Andric 
366