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"
15d88c1a5aSDimitry Andric #include "PPCInstrInfo.h"
16139f7f9bSDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
176122f3e6SDimitry Andric #include "MCTargetDesc/PPCPredicates.h"
182754fe60SDimitry Andric #include "llvm/MC/MCExpr.h"
192754fe60SDimitry Andric #include "llvm/MC/MCInst.h"
20dff0c46cSDimitry Andric #include "llvm/MC/MCInstrInfo.h"
21ff0cc061SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
22ff0cc061SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
23*26e25074SRoman Divacky #include "llvm/MC/MCSymbol.h"
24f785676fSDimitry Andric #include "llvm/Support/CommandLine.h"
252754fe60SDimitry Andric #include "llvm/Support/raw_ostream.h"
26f785676fSDimitry Andric #include "llvm/Target/TargetOpcodes.h"
272754fe60SDimitry Andric using namespace llvm;
282754fe60SDimitry Andric 
2991bc56edSDimitry Andric #define DEBUG_TYPE "asm-printer"
3091bc56edSDimitry Andric 
31f785676fSDimitry Andric // FIXME: Once the integrated assembler supports full register names, tie this
32f785676fSDimitry Andric // to the verbose-asm setting.
33f785676fSDimitry Andric static cl::opt<bool>
34f785676fSDimitry Andric FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
35f785676fSDimitry Andric              cl::desc("Use full register names when printing assembly"));
36f785676fSDimitry Andric 
37d88c1a5aSDimitry Andric // Useful for testing purposes. Prints vs{31-63} as v{0-31} respectively.
38d88c1a5aSDimitry Andric static cl::opt<bool>
39d88c1a5aSDimitry Andric ShowVSRNumsAsVR("ppc-vsr-nums-as-vr", cl::Hidden, cl::init(false),
40d88c1a5aSDimitry Andric              cl::desc("Prints full register names with vs{31-63} as v{0-31}"));
41d88c1a5aSDimitry Andric 
42ff0cc061SDimitry Andric #define PRINT_ALIAS_INSTR
432754fe60SDimitry Andric #include "PPCGenAsmWriter.inc"
442754fe60SDimitry Andric 
45bd5abe19SDimitry Andric void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
46ff0cc061SDimitry Andric   const char *RegName = getRegisterName(RegNo);
47ff0cc061SDimitry Andric   if (RegName[0] == 'q' /* QPX */) {
48ff0cc061SDimitry Andric     // The system toolchain on the BG/Q does not understand QPX register names
49ff0cc061SDimitry Andric     // in .cfi_* directives, so print the name of the floating-point
50ff0cc061SDimitry Andric     // subregister instead.
51ff0cc061SDimitry Andric     std::string RN(RegName);
52ff0cc061SDimitry Andric 
53ff0cc061SDimitry Andric     RN[0] = 'f';
54ff0cc061SDimitry Andric     OS << RN;
55ff0cc061SDimitry Andric 
56ff0cc061SDimitry Andric     return;
57ff0cc061SDimitry Andric   }
58ff0cc061SDimitry Andric 
59ff0cc061SDimitry Andric   OS << RegName;
60bd5abe19SDimitry Andric }
612754fe60SDimitry Andric 
626122f3e6SDimitry Andric void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
63ff0cc061SDimitry Andric                                StringRef Annot, const MCSubtargetInfo &STI) {
642754fe60SDimitry Andric   // Check for slwi/srwi mnemonics.
652754fe60SDimitry Andric   if (MI->getOpcode() == PPC::RLWINM) {
662754fe60SDimitry Andric     unsigned char SH = MI->getOperand(2).getImm();
672754fe60SDimitry Andric     unsigned char MB = MI->getOperand(3).getImm();
682754fe60SDimitry Andric     unsigned char ME = MI->getOperand(4).getImm();
692754fe60SDimitry Andric     bool useSubstituteMnemonic = false;
702754fe60SDimitry Andric     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
712754fe60SDimitry Andric       O << "\tslwi "; useSubstituteMnemonic = true;
722754fe60SDimitry Andric     }
732754fe60SDimitry Andric     if (SH <= 31 && MB == (32-SH) && ME == 31) {
742754fe60SDimitry Andric       O << "\tsrwi "; useSubstituteMnemonic = true;
752754fe60SDimitry Andric       SH = 32-SH;
762754fe60SDimitry Andric     }
772754fe60SDimitry Andric     if (useSubstituteMnemonic) {
782754fe60SDimitry Andric       printOperand(MI, 0, O);
792754fe60SDimitry Andric       O << ", ";
802754fe60SDimitry Andric       printOperand(MI, 1, O);
812754fe60SDimitry Andric       O << ", " << (unsigned int)SH;
826122f3e6SDimitry Andric 
836122f3e6SDimitry Andric       printAnnotation(O, Annot);
842754fe60SDimitry Andric       return;
852754fe60SDimitry Andric     }
862754fe60SDimitry Andric   }
872754fe60SDimitry Andric 
882754fe60SDimitry Andric   if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
892754fe60SDimitry Andric       MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
902754fe60SDimitry Andric     O << "\tmr ";
912754fe60SDimitry Andric     printOperand(MI, 0, O);
922754fe60SDimitry Andric     O << ", ";
932754fe60SDimitry Andric     printOperand(MI, 1, O);
946122f3e6SDimitry Andric     printAnnotation(O, Annot);
952754fe60SDimitry Andric     return;
962754fe60SDimitry Andric   }
972754fe60SDimitry Andric 
985517e702SDimitry Andric   if (MI->getOpcode() == PPC::RLDICR ||
995517e702SDimitry Andric       MI->getOpcode() == PPC::RLDICR_32) {
1002754fe60SDimitry Andric     unsigned char SH = MI->getOperand(2).getImm();
1012754fe60SDimitry Andric     unsigned char ME = MI->getOperand(3).getImm();
1022754fe60SDimitry Andric     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
1032754fe60SDimitry Andric     if (63-SH == ME) {
1042754fe60SDimitry Andric       O << "\tsldi ";
1052754fe60SDimitry Andric       printOperand(MI, 0, O);
1062754fe60SDimitry Andric       O << ", ";
1072754fe60SDimitry Andric       printOperand(MI, 1, O);
1082754fe60SDimitry Andric       O << ", " << (unsigned int)SH;
1096122f3e6SDimitry Andric       printAnnotation(O, Annot);
1102754fe60SDimitry Andric       return;
1112754fe60SDimitry Andric     }
1122754fe60SDimitry Andric   }
1132754fe60SDimitry Andric 
114ff0cc061SDimitry Andric   // dcbt[st] is printed manually here because:
115ff0cc061SDimitry Andric   //  1. The assembly syntax is different between embedded and server targets
116ff0cc061SDimitry Andric   //  2. We must print the short mnemonics for TH == 0 because the
117ff0cc061SDimitry Andric   //     embedded/server syntax default will not be stable across assemblers
118ff0cc061SDimitry Andric   //  The syntax for dcbt is:
119ff0cc061SDimitry Andric   //    dcbt ra, rb, th [server]
120ff0cc061SDimitry Andric   //    dcbt th, ra, rb [embedded]
121ff0cc061SDimitry Andric   //  where th can be omitted when it is 0. dcbtst is the same.
122ff0cc061SDimitry Andric   if (MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) {
123ff0cc061SDimitry Andric     unsigned char TH = MI->getOperand(0).getImm();
124ff0cc061SDimitry Andric     O << "\tdcbt";
125ff0cc061SDimitry Andric     if (MI->getOpcode() == PPC::DCBTST)
126ff0cc061SDimitry Andric       O << "st";
127ff0cc061SDimitry Andric     if (TH == 16)
128ff0cc061SDimitry Andric       O << "t";
129ff0cc061SDimitry Andric     O << " ";
130ff0cc061SDimitry Andric 
131ff0cc061SDimitry Andric     bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE];
132ff0cc061SDimitry Andric     if (IsBookE && TH != 0 && TH != 16)
133ff0cc061SDimitry Andric       O << (unsigned int) TH << ", ";
134ff0cc061SDimitry Andric 
135ff0cc061SDimitry Andric     printOperand(MI, 1, O);
136ff0cc061SDimitry Andric     O << ", ";
137ff0cc061SDimitry Andric     printOperand(MI, 2, O);
138ff0cc061SDimitry Andric 
139ff0cc061SDimitry Andric     if (!IsBookE && TH != 0 && TH != 16)
140ff0cc061SDimitry Andric       O << ", " << (unsigned int) TH;
141ff0cc061SDimitry Andric 
142ff0cc061SDimitry Andric     printAnnotation(O, Annot);
143ff0cc061SDimitry Andric     return;
144ff0cc061SDimitry Andric   }
145ff0cc061SDimitry Andric 
146d88c1a5aSDimitry Andric   if (MI->getOpcode() == PPC::DCBF) {
147d88c1a5aSDimitry Andric     unsigned char L = MI->getOperand(0).getImm();
148d88c1a5aSDimitry Andric     if (!L || L == 1 || L == 3) {
149d88c1a5aSDimitry Andric       O << "\tdcbf";
150d88c1a5aSDimitry Andric       if (L == 1 || L == 3)
151d88c1a5aSDimitry Andric         O << "l";
152d88c1a5aSDimitry Andric       if (L == 3)
153d88c1a5aSDimitry Andric         O << "p";
154d88c1a5aSDimitry Andric       O << " ";
155d88c1a5aSDimitry Andric 
156d88c1a5aSDimitry Andric       printOperand(MI, 1, O);
157d88c1a5aSDimitry Andric       O << ", ";
158d88c1a5aSDimitry Andric       printOperand(MI, 2, O);
159d88c1a5aSDimitry Andric 
160d88c1a5aSDimitry Andric       printAnnotation(O, Annot);
161d88c1a5aSDimitry Andric       return;
162d88c1a5aSDimitry Andric     }
163d88c1a5aSDimitry Andric   }
164d88c1a5aSDimitry Andric 
165ff0cc061SDimitry Andric   if (!printAliasInstr(MI, O))
1662754fe60SDimitry Andric     printInstruction(MI, O);
1676122f3e6SDimitry Andric   printAnnotation(O, Annot);
1682754fe60SDimitry Andric }
1692754fe60SDimitry Andric 
1702754fe60SDimitry Andric 
1712754fe60SDimitry Andric void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
1722754fe60SDimitry Andric                                            raw_ostream &O,
1732754fe60SDimitry Andric                                            const char *Modifier) {
1742754fe60SDimitry Andric   unsigned Code = MI->getOperand(OpNo).getImm();
1757ae0e2c9SDimitry Andric 
1762754fe60SDimitry Andric   if (StringRef(Modifier) == "cc") {
1772754fe60SDimitry Andric     switch ((PPC::Predicate)Code) {
178f785676fSDimitry Andric     case PPC::PRED_LT_MINUS:
179f785676fSDimitry Andric     case PPC::PRED_LT_PLUS:
180f785676fSDimitry Andric     case PPC::PRED_LT:
181f785676fSDimitry Andric       O << "lt";
182f785676fSDimitry Andric       return;
183f785676fSDimitry Andric     case PPC::PRED_LE_MINUS:
184f785676fSDimitry Andric     case PPC::PRED_LE_PLUS:
185f785676fSDimitry Andric     case PPC::PRED_LE:
186f785676fSDimitry Andric       O << "le";
187f785676fSDimitry Andric       return;
188f785676fSDimitry Andric     case PPC::PRED_EQ_MINUS:
189f785676fSDimitry Andric     case PPC::PRED_EQ_PLUS:
190f785676fSDimitry Andric     case PPC::PRED_EQ:
191f785676fSDimitry Andric       O << "eq";
192f785676fSDimitry Andric       return;
193f785676fSDimitry Andric     case PPC::PRED_GE_MINUS:
194f785676fSDimitry Andric     case PPC::PRED_GE_PLUS:
195f785676fSDimitry Andric     case PPC::PRED_GE:
196f785676fSDimitry Andric       O << "ge";
197f785676fSDimitry Andric       return;
198f785676fSDimitry Andric     case PPC::PRED_GT_MINUS:
199f785676fSDimitry Andric     case PPC::PRED_GT_PLUS:
200f785676fSDimitry Andric     case PPC::PRED_GT:
201f785676fSDimitry Andric       O << "gt";
202f785676fSDimitry Andric       return;
203f785676fSDimitry Andric     case PPC::PRED_NE_MINUS:
204f785676fSDimitry Andric     case PPC::PRED_NE_PLUS:
205f785676fSDimitry Andric     case PPC::PRED_NE:
206f785676fSDimitry Andric       O << "ne";
207f785676fSDimitry Andric       return;
208f785676fSDimitry Andric     case PPC::PRED_UN_MINUS:
209f785676fSDimitry Andric     case PPC::PRED_UN_PLUS:
210f785676fSDimitry Andric     case PPC::PRED_UN:
211f785676fSDimitry Andric       O << "un";
212f785676fSDimitry Andric       return;
213f785676fSDimitry Andric     case PPC::PRED_NU_MINUS:
214f785676fSDimitry Andric     case PPC::PRED_NU_PLUS:
215f785676fSDimitry Andric     case PPC::PRED_NU:
216f785676fSDimitry Andric       O << "nu";
217f785676fSDimitry Andric       return;
21891bc56edSDimitry Andric     case PPC::PRED_BIT_SET:
21991bc56edSDimitry Andric     case PPC::PRED_BIT_UNSET:
22091bc56edSDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
2212754fe60SDimitry Andric     }
222f785676fSDimitry Andric     llvm_unreachable("Invalid predicate code");
223f785676fSDimitry Andric   }
224f785676fSDimitry Andric 
225f785676fSDimitry Andric   if (StringRef(Modifier) == "pm") {
226f785676fSDimitry Andric     switch ((PPC::Predicate)Code) {
227f785676fSDimitry Andric     case PPC::PRED_LT:
228f785676fSDimitry Andric     case PPC::PRED_LE:
229f785676fSDimitry Andric     case PPC::PRED_EQ:
230f785676fSDimitry Andric     case PPC::PRED_GE:
231f785676fSDimitry Andric     case PPC::PRED_GT:
232f785676fSDimitry Andric     case PPC::PRED_NE:
233f785676fSDimitry Andric     case PPC::PRED_UN:
234f785676fSDimitry Andric     case PPC::PRED_NU:
235f785676fSDimitry Andric       return;
236f785676fSDimitry Andric     case PPC::PRED_LT_MINUS:
237f785676fSDimitry Andric     case PPC::PRED_LE_MINUS:
238f785676fSDimitry Andric     case PPC::PRED_EQ_MINUS:
239f785676fSDimitry Andric     case PPC::PRED_GE_MINUS:
240f785676fSDimitry Andric     case PPC::PRED_GT_MINUS:
241f785676fSDimitry Andric     case PPC::PRED_NE_MINUS:
242f785676fSDimitry Andric     case PPC::PRED_UN_MINUS:
243f785676fSDimitry Andric     case PPC::PRED_NU_MINUS:
244f785676fSDimitry Andric       O << "-";
245f785676fSDimitry Andric       return;
246f785676fSDimitry Andric     case PPC::PRED_LT_PLUS:
247f785676fSDimitry Andric     case PPC::PRED_LE_PLUS:
248f785676fSDimitry Andric     case PPC::PRED_EQ_PLUS:
249f785676fSDimitry Andric     case PPC::PRED_GE_PLUS:
250f785676fSDimitry Andric     case PPC::PRED_GT_PLUS:
251f785676fSDimitry Andric     case PPC::PRED_NE_PLUS:
252f785676fSDimitry Andric     case PPC::PRED_UN_PLUS:
253f785676fSDimitry Andric     case PPC::PRED_NU_PLUS:
254f785676fSDimitry Andric       O << "+";
255f785676fSDimitry Andric       return;
25691bc56edSDimitry Andric     case PPC::PRED_BIT_SET:
25791bc56edSDimitry Andric     case PPC::PRED_BIT_UNSET:
25891bc56edSDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
259f785676fSDimitry Andric     }
260f785676fSDimitry Andric     llvm_unreachable("Invalid predicate code");
2612754fe60SDimitry Andric   }
2622754fe60SDimitry Andric 
2632754fe60SDimitry Andric   assert(StringRef(Modifier) == "reg" &&
264f785676fSDimitry Andric          "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
2652754fe60SDimitry Andric   printOperand(MI, OpNo+1, O);
2662754fe60SDimitry Andric }
2672754fe60SDimitry Andric 
268d88c1a5aSDimitry Andric void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
269d88c1a5aSDimitry Andric                                        raw_ostream &O) {
270d88c1a5aSDimitry Andric   unsigned Code = MI->getOperand(OpNo).getImm();
271d88c1a5aSDimitry Andric   if (Code == 2)
272d88c1a5aSDimitry Andric     O << "-";
273d88c1a5aSDimitry Andric   else if (Code == 3)
274d88c1a5aSDimitry Andric     O << "+";
275d88c1a5aSDimitry Andric }
276d88c1a5aSDimitry Andric 
277ff0cc061SDimitry Andric void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
278ff0cc061SDimitry Andric                                        raw_ostream &O) {
279ff0cc061SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
280ff0cc061SDimitry Andric   assert(Value <= 1 && "Invalid u1imm argument!");
281ff0cc061SDimitry Andric   O << (unsigned int)Value;
282ff0cc061SDimitry Andric }
283ff0cc061SDimitry Andric 
28491bc56edSDimitry Andric void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
28591bc56edSDimitry Andric                                        raw_ostream &O) {
28691bc56edSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
28791bc56edSDimitry Andric   assert(Value <= 3 && "Invalid u2imm argument!");
28891bc56edSDimitry Andric   O << (unsigned int)Value;
28991bc56edSDimitry Andric }
29091bc56edSDimitry Andric 
291ff0cc061SDimitry Andric void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
292ff0cc061SDimitry Andric                                        raw_ostream &O) {
293ff0cc061SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
294ff0cc061SDimitry Andric   assert(Value <= 8 && "Invalid u3imm argument!");
295ff0cc061SDimitry Andric   O << (unsigned int)Value;
296ff0cc061SDimitry Andric }
297ff0cc061SDimitry Andric 
29839d628a0SDimitry Andric void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
29939d628a0SDimitry Andric                                        raw_ostream &O) {
30039d628a0SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
30139d628a0SDimitry Andric   assert(Value <= 15 && "Invalid u4imm argument!");
30239d628a0SDimitry Andric   O << (unsigned int)Value;
30339d628a0SDimitry Andric }
30439d628a0SDimitry Andric 
3052754fe60SDimitry Andric void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
3062754fe60SDimitry Andric                                        raw_ostream &O) {
3073861d79fSDimitry Andric   int Value = MI->getOperand(OpNo).getImm();
3083861d79fSDimitry Andric   Value = SignExtend32<5>(Value);
3092754fe60SDimitry Andric   O << (int)Value;
3102754fe60SDimitry Andric }
3112754fe60SDimitry Andric 
3122754fe60SDimitry Andric void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
3132754fe60SDimitry Andric                                        raw_ostream &O) {
3143861d79fSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3152754fe60SDimitry Andric   assert(Value <= 31 && "Invalid u5imm argument!");
3162754fe60SDimitry Andric   O << (unsigned int)Value;
3172754fe60SDimitry Andric }
3182754fe60SDimitry Andric 
3192754fe60SDimitry Andric void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
3202754fe60SDimitry Andric                                        raw_ostream &O) {
3213861d79fSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3222754fe60SDimitry Andric   assert(Value <= 63 && "Invalid u6imm argument!");
3232754fe60SDimitry Andric   O << (unsigned int)Value;
3242754fe60SDimitry Andric }
3252754fe60SDimitry Andric 
3263ca95b02SDimitry Andric void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
3273ca95b02SDimitry Andric                                        raw_ostream &O) {
3283ca95b02SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3293ca95b02SDimitry Andric   assert(Value <= 127 && "Invalid u7imm argument!");
3303ca95b02SDimitry Andric   O << (unsigned int)Value;
3313ca95b02SDimitry Andric }
3323ca95b02SDimitry Andric 
333d88c1a5aSDimitry Andric // Operands of BUILD_VECTOR are signed and we use this to print operands
334d88c1a5aSDimitry Andric // of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
335d88c1a5aSDimitry Andric // print as unsigned.
3363ca95b02SDimitry Andric void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
3373ca95b02SDimitry Andric                                        raw_ostream &O) {
338d88c1a5aSDimitry Andric   unsigned char Value = MI->getOperand(OpNo).getImm();
3393ca95b02SDimitry Andric   O << (unsigned int)Value;
3403ca95b02SDimitry Andric }
3413ca95b02SDimitry Andric 
342ff0cc061SDimitry Andric void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
343ff0cc061SDimitry Andric                                         raw_ostream &O) {
344ff0cc061SDimitry Andric   unsigned short Value = MI->getOperand(OpNo).getImm();
345ff0cc061SDimitry Andric   assert(Value <= 1023 && "Invalid u10imm argument!");
346ff0cc061SDimitry Andric   O << (unsigned short)Value;
347ff0cc061SDimitry Andric }
348ff0cc061SDimitry Andric 
349ff0cc061SDimitry Andric void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
350ff0cc061SDimitry Andric                                         raw_ostream &O) {
351ff0cc061SDimitry Andric   unsigned short Value = MI->getOperand(OpNo).getImm();
352ff0cc061SDimitry Andric   assert(Value <= 4095 && "Invalid u12imm argument!");
353ff0cc061SDimitry Andric   O << (unsigned short)Value;
354ff0cc061SDimitry Andric }
355ff0cc061SDimitry Andric 
3562754fe60SDimitry Andric void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
3572754fe60SDimitry Andric                                         raw_ostream &O) {
358f785676fSDimitry Andric   if (MI->getOperand(OpNo).isImm())
3592754fe60SDimitry Andric     O << (short)MI->getOperand(OpNo).getImm();
360f785676fSDimitry Andric   else
361f785676fSDimitry Andric     printOperand(MI, OpNo, O);
3622754fe60SDimitry Andric }
3632754fe60SDimitry Andric 
3642754fe60SDimitry Andric void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
3652754fe60SDimitry Andric                                         raw_ostream &O) {
3662754fe60SDimitry Andric   if (MI->getOperand(OpNo).isImm())
367f785676fSDimitry Andric     O << (unsigned short)MI->getOperand(OpNo).getImm();
3682754fe60SDimitry Andric   else
3692754fe60SDimitry Andric     printOperand(MI, OpNo, O);
3702754fe60SDimitry Andric }
3712754fe60SDimitry Andric 
3722754fe60SDimitry Andric void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
3732754fe60SDimitry Andric                                         raw_ostream &O) {
3742754fe60SDimitry Andric   if (!MI->getOperand(OpNo).isImm())
3752754fe60SDimitry Andric     return printOperand(MI, OpNo, O);
3762754fe60SDimitry Andric 
3772754fe60SDimitry Andric   // Branches can take an immediate operand.  This is used by the branch
378284c1978SDimitry Andric   // selection pass to print .+8, an eight byte displacement from the PC.
379284c1978SDimitry Andric   O << ".+";
380f785676fSDimitry Andric   printAbsBranchOperand(MI, OpNo, O);
3812754fe60SDimitry Andric }
3822754fe60SDimitry Andric 
383f785676fSDimitry Andric void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
3842754fe60SDimitry Andric                                            raw_ostream &O) {
385f785676fSDimitry Andric   if (!MI->getOperand(OpNo).isImm())
386f785676fSDimitry Andric     return printOperand(MI, OpNo, O);
387f785676fSDimitry Andric 
3889cac79b3SDimitry Andric   O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
3892754fe60SDimitry Andric }
3902754fe60SDimitry Andric 
3912754fe60SDimitry Andric 
3922754fe60SDimitry Andric void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
3932754fe60SDimitry Andric                                  raw_ostream &O) {
3942754fe60SDimitry Andric   unsigned CCReg = MI->getOperand(OpNo).getReg();
3952754fe60SDimitry Andric   unsigned RegNo;
3962754fe60SDimitry Andric   switch (CCReg) {
397dff0c46cSDimitry Andric   default: llvm_unreachable("Unknown CR register");
3982754fe60SDimitry Andric   case PPC::CR0: RegNo = 0; break;
3992754fe60SDimitry Andric   case PPC::CR1: RegNo = 1; break;
4002754fe60SDimitry Andric   case PPC::CR2: RegNo = 2; break;
4012754fe60SDimitry Andric   case PPC::CR3: RegNo = 3; break;
4022754fe60SDimitry Andric   case PPC::CR4: RegNo = 4; break;
4032754fe60SDimitry Andric   case PPC::CR5: RegNo = 5; break;
4042754fe60SDimitry Andric   case PPC::CR6: RegNo = 6; break;
4052754fe60SDimitry Andric   case PPC::CR7: RegNo = 7; break;
4062754fe60SDimitry Andric   }
4072754fe60SDimitry Andric   O << (0x80 >> RegNo);
4082754fe60SDimitry Andric }
4092754fe60SDimitry Andric 
4102754fe60SDimitry Andric void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
4112754fe60SDimitry Andric                                     raw_ostream &O) {
412f785676fSDimitry Andric   printS16ImmOperand(MI, OpNo, O);
4132754fe60SDimitry Andric   O << '(';
4142754fe60SDimitry Andric   if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
4152754fe60SDimitry Andric     O << "0";
4162754fe60SDimitry Andric   else
4172754fe60SDimitry Andric     printOperand(MI, OpNo+1, O);
4182754fe60SDimitry Andric   O << ')';
4192754fe60SDimitry Andric }
4202754fe60SDimitry Andric 
4212754fe60SDimitry Andric void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
4222754fe60SDimitry Andric                                     raw_ostream &O) {
4232754fe60SDimitry Andric   // When used as the base register, r0 reads constant zero rather than
4242754fe60SDimitry Andric   // the value contained in the register.  For this reason, the darwin
4252754fe60SDimitry Andric   // assembler requires that we print r0 as 0 (no r) when used as the base.
4262754fe60SDimitry Andric   if (MI->getOperand(OpNo).getReg() == PPC::R0)
4272754fe60SDimitry Andric     O << "0";
4282754fe60SDimitry Andric   else
4292754fe60SDimitry Andric     printOperand(MI, OpNo, O);
4302754fe60SDimitry Andric   O << ", ";
4312754fe60SDimitry Andric   printOperand(MI, OpNo+1, O);
4322754fe60SDimitry Andric }
4332754fe60SDimitry Andric 
434f785676fSDimitry Andric void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
435f785676fSDimitry Andric                                   raw_ostream &O) {
436*26e25074SRoman Divacky   // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
437*26e25074SRoman Divacky   // come at the _end_ of the expression.
438*26e25074SRoman Divacky   const MCOperand &Op = MI->getOperand(OpNo);
439*26e25074SRoman Divacky   const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*Op.getExpr());
440*26e25074SRoman Divacky   O << refExp.getSymbol().getName();
441f785676fSDimitry Andric   O << '(';
442f785676fSDimitry Andric   printOperand(MI, OpNo+1, O);
443f785676fSDimitry Andric   O << ')';
444*26e25074SRoman Divacky   if (refExp.getKind() != MCSymbolRefExpr::VK_None)
445*26e25074SRoman Divacky     O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind());
446f785676fSDimitry Andric }
4472754fe60SDimitry Andric 
4482754fe60SDimitry Andric 
4492754fe60SDimitry Andric /// stripRegisterPrefix - This method strips the character prefix from a
4502754fe60SDimitry Andric /// register name so that only the number is left.  Used by for linux asm.
4512754fe60SDimitry Andric static const char *stripRegisterPrefix(const char *RegName) {
452d88c1a5aSDimitry Andric   if (FullRegNames || ShowVSRNumsAsVR)
453f785676fSDimitry Andric     return RegName;
454f785676fSDimitry Andric 
4552754fe60SDimitry Andric   switch (RegName[0]) {
4562754fe60SDimitry Andric   case 'r':
4572754fe60SDimitry Andric   case 'f':
458ff0cc061SDimitry Andric   case 'q': // for QPX
45991bc56edSDimitry Andric   case 'v':
46091bc56edSDimitry Andric     if (RegName[1] == 's')
46191bc56edSDimitry Andric       return RegName + 2;
46291bc56edSDimitry Andric     return RegName + 1;
4632754fe60SDimitry Andric   case 'c': if (RegName[1] == 'r') return RegName + 2;
4642754fe60SDimitry Andric   }
4652754fe60SDimitry Andric 
4662754fe60SDimitry Andric   return RegName;
4672754fe60SDimitry Andric }
4682754fe60SDimitry Andric 
4692754fe60SDimitry Andric void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
4702754fe60SDimitry Andric                                   raw_ostream &O) {
4712754fe60SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
4722754fe60SDimitry Andric   if (Op.isReg()) {
473d88c1a5aSDimitry Andric     unsigned Reg = Op.getReg();
474d88c1a5aSDimitry Andric 
475d88c1a5aSDimitry Andric     // There are VSX instructions that use VSX register numbering (vs0 - vs63)
476d88c1a5aSDimitry Andric     // as well as those that use VMX register numbering (v0 - v31 which
477d88c1a5aSDimitry Andric     // correspond to vs32 - vs63). If we have an instruction that uses VSX
478d88c1a5aSDimitry Andric     // numbering, we need to convert the VMX registers to VSX registers.
479d88c1a5aSDimitry Andric     // Namely, we print 32-63 when the instruction operates on one of the
480d88c1a5aSDimitry Andric     // VMX registers.
481d88c1a5aSDimitry Andric     // (Please synchronize with PPCAsmPrinter::printOperand)
482d88c1a5aSDimitry Andric     if ((MII.get(MI->getOpcode()).TSFlags & PPCII::UseVSXReg) &&
483d88c1a5aSDimitry Andric         !ShowVSRNumsAsVR) {
484d88c1a5aSDimitry Andric       if (PPCInstrInfo::isVRRegister(Reg))
485d88c1a5aSDimitry Andric         Reg = PPC::VSX32 + (Reg - PPC::V0);
486d88c1a5aSDimitry Andric       else if (PPCInstrInfo::isVFRegister(Reg))
487d88c1a5aSDimitry Andric         Reg = PPC::VSX32 + (Reg - PPC::VF0);
488d88c1a5aSDimitry Andric     }
489d88c1a5aSDimitry Andric 
490d88c1a5aSDimitry Andric     const char *RegName = getRegisterName(Reg);
4912754fe60SDimitry Andric     // The linux and AIX assembler does not take register prefixes.
4922754fe60SDimitry Andric     if (!isDarwinSyntax())
4932754fe60SDimitry Andric       RegName = stripRegisterPrefix(RegName);
4942754fe60SDimitry Andric 
4952754fe60SDimitry Andric     O << RegName;
4962754fe60SDimitry Andric     return;
4972754fe60SDimitry Andric   }
4982754fe60SDimitry Andric 
4992754fe60SDimitry Andric   if (Op.isImm()) {
5002754fe60SDimitry Andric     O << Op.getImm();
5012754fe60SDimitry Andric     return;
5022754fe60SDimitry Andric   }
5032754fe60SDimitry Andric 
5042754fe60SDimitry Andric   assert(Op.isExpr() && "unknown operand kind in printOperand");
50597bc6c73SDimitry Andric   Op.getExpr()->print(O, &MAI);
5062754fe60SDimitry Andric }
5072754fe60SDimitry Andric 
508