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"
20ff0cc061SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
21ff0cc061SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
22*26e25074SRoman Divacky #include "llvm/MC/MCSymbol.h"
23f785676fSDimitry Andric #include "llvm/Support/CommandLine.h"
242754fe60SDimitry Andric #include "llvm/Support/raw_ostream.h"
25f785676fSDimitry Andric #include "llvm/Target/TargetOpcodes.h"
262754fe60SDimitry Andric using namespace llvm;
272754fe60SDimitry Andric 
2891bc56edSDimitry Andric #define DEBUG_TYPE "asm-printer"
2991bc56edSDimitry Andric 
30f785676fSDimitry Andric // FIXME: Once the integrated assembler supports full register names, tie this
31f785676fSDimitry Andric // to the verbose-asm setting.
32f785676fSDimitry Andric static cl::opt<bool>
33f785676fSDimitry Andric FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
34f785676fSDimitry Andric              cl::desc("Use full register names when printing assembly"));
35f785676fSDimitry Andric 
36ff0cc061SDimitry Andric #define PRINT_ALIAS_INSTR
372754fe60SDimitry Andric #include "PPCGenAsmWriter.inc"
382754fe60SDimitry Andric 
39bd5abe19SDimitry Andric void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
40ff0cc061SDimitry Andric   const char *RegName = getRegisterName(RegNo);
41ff0cc061SDimitry Andric   if (RegName[0] == 'q' /* QPX */) {
42ff0cc061SDimitry Andric     // The system toolchain on the BG/Q does not understand QPX register names
43ff0cc061SDimitry Andric     // in .cfi_* directives, so print the name of the floating-point
44ff0cc061SDimitry Andric     // subregister instead.
45ff0cc061SDimitry Andric     std::string RN(RegName);
46ff0cc061SDimitry Andric 
47ff0cc061SDimitry Andric     RN[0] = 'f';
48ff0cc061SDimitry Andric     OS << RN;
49ff0cc061SDimitry Andric 
50ff0cc061SDimitry Andric     return;
51ff0cc061SDimitry Andric   }
52ff0cc061SDimitry Andric 
53ff0cc061SDimitry Andric   OS << RegName;
54bd5abe19SDimitry Andric }
552754fe60SDimitry Andric 
566122f3e6SDimitry Andric void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
57ff0cc061SDimitry Andric                                StringRef Annot, const MCSubtargetInfo &STI) {
582754fe60SDimitry Andric   // Check for slwi/srwi mnemonics.
592754fe60SDimitry Andric   if (MI->getOpcode() == PPC::RLWINM) {
602754fe60SDimitry Andric     unsigned char SH = MI->getOperand(2).getImm();
612754fe60SDimitry Andric     unsigned char MB = MI->getOperand(3).getImm();
622754fe60SDimitry Andric     unsigned char ME = MI->getOperand(4).getImm();
632754fe60SDimitry Andric     bool useSubstituteMnemonic = false;
642754fe60SDimitry Andric     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
652754fe60SDimitry Andric       O << "\tslwi "; useSubstituteMnemonic = true;
662754fe60SDimitry Andric     }
672754fe60SDimitry Andric     if (SH <= 31 && MB == (32-SH) && ME == 31) {
682754fe60SDimitry Andric       O << "\tsrwi "; useSubstituteMnemonic = true;
692754fe60SDimitry Andric       SH = 32-SH;
702754fe60SDimitry Andric     }
712754fe60SDimitry Andric     if (useSubstituteMnemonic) {
722754fe60SDimitry Andric       printOperand(MI, 0, O);
732754fe60SDimitry Andric       O << ", ";
742754fe60SDimitry Andric       printOperand(MI, 1, O);
752754fe60SDimitry Andric       O << ", " << (unsigned int)SH;
766122f3e6SDimitry Andric 
776122f3e6SDimitry Andric       printAnnotation(O, Annot);
782754fe60SDimitry Andric       return;
792754fe60SDimitry Andric     }
802754fe60SDimitry Andric   }
812754fe60SDimitry Andric 
822754fe60SDimitry Andric   if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
832754fe60SDimitry Andric       MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
842754fe60SDimitry Andric     O << "\tmr ";
852754fe60SDimitry Andric     printOperand(MI, 0, O);
862754fe60SDimitry Andric     O << ", ";
872754fe60SDimitry Andric     printOperand(MI, 1, O);
886122f3e6SDimitry Andric     printAnnotation(O, Annot);
892754fe60SDimitry Andric     return;
902754fe60SDimitry Andric   }
912754fe60SDimitry Andric 
922754fe60SDimitry Andric   if (MI->getOpcode() == PPC::RLDICR) {
932754fe60SDimitry Andric     unsigned char SH = MI->getOperand(2).getImm();
942754fe60SDimitry Andric     unsigned char ME = MI->getOperand(3).getImm();
952754fe60SDimitry Andric     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
962754fe60SDimitry Andric     if (63-SH == ME) {
972754fe60SDimitry Andric       O << "\tsldi ";
982754fe60SDimitry Andric       printOperand(MI, 0, O);
992754fe60SDimitry Andric       O << ", ";
1002754fe60SDimitry Andric       printOperand(MI, 1, O);
1012754fe60SDimitry Andric       O << ", " << (unsigned int)SH;
1026122f3e6SDimitry Andric       printAnnotation(O, Annot);
1032754fe60SDimitry Andric       return;
1042754fe60SDimitry Andric     }
1052754fe60SDimitry Andric   }
1062754fe60SDimitry Andric 
107ff0cc061SDimitry Andric   // dcbt[st] is printed manually here because:
108ff0cc061SDimitry Andric   //  1. The assembly syntax is different between embedded and server targets
109ff0cc061SDimitry Andric   //  2. We must print the short mnemonics for TH == 0 because the
110ff0cc061SDimitry Andric   //     embedded/server syntax default will not be stable across assemblers
111ff0cc061SDimitry Andric   //  The syntax for dcbt is:
112ff0cc061SDimitry Andric   //    dcbt ra, rb, th [server]
113ff0cc061SDimitry Andric   //    dcbt th, ra, rb [embedded]
114ff0cc061SDimitry Andric   //  where th can be omitted when it is 0. dcbtst is the same.
115ff0cc061SDimitry Andric   if (MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) {
116ff0cc061SDimitry Andric     unsigned char TH = MI->getOperand(0).getImm();
117ff0cc061SDimitry Andric     O << "\tdcbt";
118ff0cc061SDimitry Andric     if (MI->getOpcode() == PPC::DCBTST)
119ff0cc061SDimitry Andric       O << "st";
120ff0cc061SDimitry Andric     if (TH == 16)
121ff0cc061SDimitry Andric       O << "t";
122ff0cc061SDimitry Andric     O << " ";
123ff0cc061SDimitry Andric 
124ff0cc061SDimitry Andric     bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE];
125ff0cc061SDimitry Andric     if (IsBookE && TH != 0 && TH != 16)
126ff0cc061SDimitry Andric       O << (unsigned int) TH << ", ";
127ff0cc061SDimitry Andric 
128ff0cc061SDimitry Andric     printOperand(MI, 1, O);
129ff0cc061SDimitry Andric     O << ", ";
130ff0cc061SDimitry Andric     printOperand(MI, 2, O);
131ff0cc061SDimitry Andric 
132ff0cc061SDimitry Andric     if (!IsBookE && TH != 0 && TH != 16)
133ff0cc061SDimitry Andric       O << ", " << (unsigned int) TH;
134ff0cc061SDimitry Andric 
135ff0cc061SDimitry Andric     printAnnotation(O, Annot);
136ff0cc061SDimitry Andric     return;
137ff0cc061SDimitry Andric   }
138ff0cc061SDimitry Andric 
139ff0cc061SDimitry Andric   if (!printAliasInstr(MI, O))
1402754fe60SDimitry Andric     printInstruction(MI, O);
1416122f3e6SDimitry Andric   printAnnotation(O, Annot);
1422754fe60SDimitry Andric }
1432754fe60SDimitry Andric 
1442754fe60SDimitry Andric 
1452754fe60SDimitry Andric void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
1462754fe60SDimitry Andric                                            raw_ostream &O,
1472754fe60SDimitry Andric                                            const char *Modifier) {
1482754fe60SDimitry Andric   unsigned Code = MI->getOperand(OpNo).getImm();
1497ae0e2c9SDimitry Andric 
1502754fe60SDimitry Andric   if (StringRef(Modifier) == "cc") {
1512754fe60SDimitry Andric     switch ((PPC::Predicate)Code) {
152f785676fSDimitry Andric     case PPC::PRED_LT_MINUS:
153f785676fSDimitry Andric     case PPC::PRED_LT_PLUS:
154f785676fSDimitry Andric     case PPC::PRED_LT:
155f785676fSDimitry Andric       O << "lt";
156f785676fSDimitry Andric       return;
157f785676fSDimitry Andric     case PPC::PRED_LE_MINUS:
158f785676fSDimitry Andric     case PPC::PRED_LE_PLUS:
159f785676fSDimitry Andric     case PPC::PRED_LE:
160f785676fSDimitry Andric       O << "le";
161f785676fSDimitry Andric       return;
162f785676fSDimitry Andric     case PPC::PRED_EQ_MINUS:
163f785676fSDimitry Andric     case PPC::PRED_EQ_PLUS:
164f785676fSDimitry Andric     case PPC::PRED_EQ:
165f785676fSDimitry Andric       O << "eq";
166f785676fSDimitry Andric       return;
167f785676fSDimitry Andric     case PPC::PRED_GE_MINUS:
168f785676fSDimitry Andric     case PPC::PRED_GE_PLUS:
169f785676fSDimitry Andric     case PPC::PRED_GE:
170f785676fSDimitry Andric       O << "ge";
171f785676fSDimitry Andric       return;
172f785676fSDimitry Andric     case PPC::PRED_GT_MINUS:
173f785676fSDimitry Andric     case PPC::PRED_GT_PLUS:
174f785676fSDimitry Andric     case PPC::PRED_GT:
175f785676fSDimitry Andric       O << "gt";
176f785676fSDimitry Andric       return;
177f785676fSDimitry Andric     case PPC::PRED_NE_MINUS:
178f785676fSDimitry Andric     case PPC::PRED_NE_PLUS:
179f785676fSDimitry Andric     case PPC::PRED_NE:
180f785676fSDimitry Andric       O << "ne";
181f785676fSDimitry Andric       return;
182f785676fSDimitry Andric     case PPC::PRED_UN_MINUS:
183f785676fSDimitry Andric     case PPC::PRED_UN_PLUS:
184f785676fSDimitry Andric     case PPC::PRED_UN:
185f785676fSDimitry Andric       O << "un";
186f785676fSDimitry Andric       return;
187f785676fSDimitry Andric     case PPC::PRED_NU_MINUS:
188f785676fSDimitry Andric     case PPC::PRED_NU_PLUS:
189f785676fSDimitry Andric     case PPC::PRED_NU:
190f785676fSDimitry Andric       O << "nu";
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");
1952754fe60SDimitry Andric     }
196f785676fSDimitry Andric     llvm_unreachable("Invalid predicate code");
197f785676fSDimitry Andric   }
198f785676fSDimitry Andric 
199f785676fSDimitry Andric   if (StringRef(Modifier) == "pm") {
200f785676fSDimitry Andric     switch ((PPC::Predicate)Code) {
201f785676fSDimitry Andric     case PPC::PRED_LT:
202f785676fSDimitry Andric     case PPC::PRED_LE:
203f785676fSDimitry Andric     case PPC::PRED_EQ:
204f785676fSDimitry Andric     case PPC::PRED_GE:
205f785676fSDimitry Andric     case PPC::PRED_GT:
206f785676fSDimitry Andric     case PPC::PRED_NE:
207f785676fSDimitry Andric     case PPC::PRED_UN:
208f785676fSDimitry Andric     case PPC::PRED_NU:
209f785676fSDimitry Andric       return;
210f785676fSDimitry Andric     case PPC::PRED_LT_MINUS:
211f785676fSDimitry Andric     case PPC::PRED_LE_MINUS:
212f785676fSDimitry Andric     case PPC::PRED_EQ_MINUS:
213f785676fSDimitry Andric     case PPC::PRED_GE_MINUS:
214f785676fSDimitry Andric     case PPC::PRED_GT_MINUS:
215f785676fSDimitry Andric     case PPC::PRED_NE_MINUS:
216f785676fSDimitry Andric     case PPC::PRED_UN_MINUS:
217f785676fSDimitry Andric     case PPC::PRED_NU_MINUS:
218f785676fSDimitry Andric       O << "-";
219f785676fSDimitry Andric       return;
220f785676fSDimitry Andric     case PPC::PRED_LT_PLUS:
221f785676fSDimitry Andric     case PPC::PRED_LE_PLUS:
222f785676fSDimitry Andric     case PPC::PRED_EQ_PLUS:
223f785676fSDimitry Andric     case PPC::PRED_GE_PLUS:
224f785676fSDimitry Andric     case PPC::PRED_GT_PLUS:
225f785676fSDimitry Andric     case PPC::PRED_NE_PLUS:
226f785676fSDimitry Andric     case PPC::PRED_UN_PLUS:
227f785676fSDimitry Andric     case PPC::PRED_NU_PLUS:
228f785676fSDimitry Andric       O << "+";
229f785676fSDimitry Andric       return;
23091bc56edSDimitry Andric     case PPC::PRED_BIT_SET:
23191bc56edSDimitry Andric     case PPC::PRED_BIT_UNSET:
23291bc56edSDimitry Andric       llvm_unreachable("Invalid use of bit predicate code");
233f785676fSDimitry Andric     }
234f785676fSDimitry Andric     llvm_unreachable("Invalid predicate code");
2352754fe60SDimitry Andric   }
2362754fe60SDimitry Andric 
2372754fe60SDimitry Andric   assert(StringRef(Modifier) == "reg" &&
238f785676fSDimitry Andric          "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
2392754fe60SDimitry Andric   printOperand(MI, OpNo+1, O);
2402754fe60SDimitry Andric }
2412754fe60SDimitry Andric 
242ff0cc061SDimitry Andric void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
243ff0cc061SDimitry Andric                                        raw_ostream &O) {
244ff0cc061SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
245ff0cc061SDimitry Andric   assert(Value <= 1 && "Invalid u1imm argument!");
246ff0cc061SDimitry Andric   O << (unsigned int)Value;
247ff0cc061SDimitry Andric }
248ff0cc061SDimitry Andric 
24991bc56edSDimitry Andric void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
25091bc56edSDimitry Andric                                        raw_ostream &O) {
25191bc56edSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
25291bc56edSDimitry Andric   assert(Value <= 3 && "Invalid u2imm argument!");
25391bc56edSDimitry Andric   O << (unsigned int)Value;
25491bc56edSDimitry Andric }
25591bc56edSDimitry Andric 
256ff0cc061SDimitry Andric void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
257ff0cc061SDimitry Andric                                        raw_ostream &O) {
258ff0cc061SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
259ff0cc061SDimitry Andric   assert(Value <= 8 && "Invalid u3imm argument!");
260ff0cc061SDimitry Andric   O << (unsigned int)Value;
261ff0cc061SDimitry Andric }
262ff0cc061SDimitry Andric 
26339d628a0SDimitry Andric void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
26439d628a0SDimitry Andric                                        raw_ostream &O) {
26539d628a0SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
26639d628a0SDimitry Andric   assert(Value <= 15 && "Invalid u4imm argument!");
26739d628a0SDimitry Andric   O << (unsigned int)Value;
26839d628a0SDimitry Andric }
26939d628a0SDimitry Andric 
2702754fe60SDimitry Andric void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
2712754fe60SDimitry Andric                                        raw_ostream &O) {
2723861d79fSDimitry Andric   int Value = MI->getOperand(OpNo).getImm();
2733861d79fSDimitry Andric   Value = SignExtend32<5>(Value);
2742754fe60SDimitry Andric   O << (int)Value;
2752754fe60SDimitry Andric }
2762754fe60SDimitry Andric 
2772754fe60SDimitry Andric void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
2782754fe60SDimitry Andric                                        raw_ostream &O) {
2793861d79fSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
2802754fe60SDimitry Andric   assert(Value <= 31 && "Invalid u5imm argument!");
2812754fe60SDimitry Andric   O << (unsigned int)Value;
2822754fe60SDimitry Andric }
2832754fe60SDimitry Andric 
2842754fe60SDimitry Andric void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
2852754fe60SDimitry Andric                                        raw_ostream &O) {
2863861d79fSDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
2872754fe60SDimitry Andric   assert(Value <= 63 && "Invalid u6imm argument!");
2882754fe60SDimitry Andric   O << (unsigned int)Value;
2892754fe60SDimitry Andric }
2902754fe60SDimitry Andric 
2913ca95b02SDimitry Andric void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
2923ca95b02SDimitry Andric                                        raw_ostream &O) {
2933ca95b02SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
2943ca95b02SDimitry Andric   assert(Value <= 127 && "Invalid u7imm argument!");
2953ca95b02SDimitry Andric   O << (unsigned int)Value;
2963ca95b02SDimitry Andric }
2973ca95b02SDimitry Andric 
2983ca95b02SDimitry Andric void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
2993ca95b02SDimitry Andric                                        raw_ostream &O) {
3003ca95b02SDimitry Andric   unsigned int Value = MI->getOperand(OpNo).getImm();
3013ca95b02SDimitry Andric   assert(Value <= 255 && "Invalid u8imm argument!");
3023ca95b02SDimitry Andric   O << (unsigned int)Value;
3033ca95b02SDimitry Andric }
3043ca95b02SDimitry Andric 
305ff0cc061SDimitry Andric void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
306ff0cc061SDimitry Andric                                         raw_ostream &O) {
307ff0cc061SDimitry Andric   unsigned short Value = MI->getOperand(OpNo).getImm();
308ff0cc061SDimitry Andric   assert(Value <= 1023 && "Invalid u10imm argument!");
309ff0cc061SDimitry Andric   O << (unsigned short)Value;
310ff0cc061SDimitry Andric }
311ff0cc061SDimitry Andric 
312ff0cc061SDimitry Andric void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
313ff0cc061SDimitry Andric                                         raw_ostream &O) {
314ff0cc061SDimitry Andric   unsigned short Value = MI->getOperand(OpNo).getImm();
315ff0cc061SDimitry Andric   assert(Value <= 4095 && "Invalid u12imm argument!");
316ff0cc061SDimitry Andric   O << (unsigned short)Value;
317ff0cc061SDimitry Andric }
318ff0cc061SDimitry Andric 
3192754fe60SDimitry Andric void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
3202754fe60SDimitry Andric                                         raw_ostream &O) {
321f785676fSDimitry Andric   if (MI->getOperand(OpNo).isImm())
3222754fe60SDimitry Andric     O << (short)MI->getOperand(OpNo).getImm();
323f785676fSDimitry Andric   else
324f785676fSDimitry Andric     printOperand(MI, OpNo, O);
3252754fe60SDimitry Andric }
3262754fe60SDimitry Andric 
3272754fe60SDimitry Andric void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
3282754fe60SDimitry Andric                                         raw_ostream &O) {
3292754fe60SDimitry Andric   if (MI->getOperand(OpNo).isImm())
330f785676fSDimitry Andric     O << (unsigned short)MI->getOperand(OpNo).getImm();
3312754fe60SDimitry Andric   else
3322754fe60SDimitry Andric     printOperand(MI, OpNo, O);
3332754fe60SDimitry Andric }
3342754fe60SDimitry Andric 
3352754fe60SDimitry Andric void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
3362754fe60SDimitry Andric                                         raw_ostream &O) {
3372754fe60SDimitry Andric   if (!MI->getOperand(OpNo).isImm())
3382754fe60SDimitry Andric     return printOperand(MI, OpNo, O);
3392754fe60SDimitry Andric 
3402754fe60SDimitry Andric   // Branches can take an immediate operand.  This is used by the branch
341284c1978SDimitry Andric   // selection pass to print .+8, an eight byte displacement from the PC.
342284c1978SDimitry Andric   O << ".+";
343f785676fSDimitry Andric   printAbsBranchOperand(MI, OpNo, O);
3442754fe60SDimitry Andric }
3452754fe60SDimitry Andric 
346f785676fSDimitry Andric void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
3472754fe60SDimitry Andric                                            raw_ostream &O) {
348f785676fSDimitry Andric   if (!MI->getOperand(OpNo).isImm())
349f785676fSDimitry Andric     return printOperand(MI, OpNo, O);
350f785676fSDimitry Andric 
3519cac79b3SDimitry Andric   O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
3522754fe60SDimitry Andric }
3532754fe60SDimitry Andric 
3542754fe60SDimitry Andric 
3552754fe60SDimitry Andric void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
3562754fe60SDimitry Andric                                  raw_ostream &O) {
3572754fe60SDimitry Andric   unsigned CCReg = MI->getOperand(OpNo).getReg();
3582754fe60SDimitry Andric   unsigned RegNo;
3592754fe60SDimitry Andric   switch (CCReg) {
360dff0c46cSDimitry Andric   default: llvm_unreachable("Unknown CR register");
3612754fe60SDimitry Andric   case PPC::CR0: RegNo = 0; break;
3622754fe60SDimitry Andric   case PPC::CR1: RegNo = 1; break;
3632754fe60SDimitry Andric   case PPC::CR2: RegNo = 2; break;
3642754fe60SDimitry Andric   case PPC::CR3: RegNo = 3; break;
3652754fe60SDimitry Andric   case PPC::CR4: RegNo = 4; break;
3662754fe60SDimitry Andric   case PPC::CR5: RegNo = 5; break;
3672754fe60SDimitry Andric   case PPC::CR6: RegNo = 6; break;
3682754fe60SDimitry Andric   case PPC::CR7: RegNo = 7; break;
3692754fe60SDimitry Andric   }
3702754fe60SDimitry Andric   O << (0x80 >> RegNo);
3712754fe60SDimitry Andric }
3722754fe60SDimitry Andric 
3732754fe60SDimitry Andric void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
3742754fe60SDimitry Andric                                     raw_ostream &O) {
375f785676fSDimitry Andric   printS16ImmOperand(MI, OpNo, O);
3762754fe60SDimitry Andric   O << '(';
3772754fe60SDimitry Andric   if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
3782754fe60SDimitry Andric     O << "0";
3792754fe60SDimitry Andric   else
3802754fe60SDimitry Andric     printOperand(MI, OpNo+1, O);
3812754fe60SDimitry Andric   O << ')';
3822754fe60SDimitry Andric }
3832754fe60SDimitry Andric 
3842754fe60SDimitry Andric void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
3852754fe60SDimitry Andric                                     raw_ostream &O) {
3862754fe60SDimitry Andric   // When used as the base register, r0 reads constant zero rather than
3872754fe60SDimitry Andric   // the value contained in the register.  For this reason, the darwin
3882754fe60SDimitry Andric   // assembler requires that we print r0 as 0 (no r) when used as the base.
3892754fe60SDimitry Andric   if (MI->getOperand(OpNo).getReg() == PPC::R0)
3902754fe60SDimitry Andric     O << "0";
3912754fe60SDimitry Andric   else
3922754fe60SDimitry Andric     printOperand(MI, OpNo, O);
3932754fe60SDimitry Andric   O << ", ";
3942754fe60SDimitry Andric   printOperand(MI, OpNo+1, O);
3952754fe60SDimitry Andric }
3962754fe60SDimitry Andric 
397f785676fSDimitry Andric void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
398f785676fSDimitry Andric                                   raw_ostream &O) {
399*26e25074SRoman Divacky   // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
400*26e25074SRoman Divacky   // come at the _end_ of the expression.
401*26e25074SRoman Divacky   const MCOperand &Op = MI->getOperand(OpNo);
402*26e25074SRoman Divacky   const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*Op.getExpr());
403*26e25074SRoman Divacky   O << refExp.getSymbol().getName();
404f785676fSDimitry Andric   O << '(';
405f785676fSDimitry Andric   printOperand(MI, OpNo+1, O);
406f785676fSDimitry Andric   O << ')';
407*26e25074SRoman Divacky   if (refExp.getKind() != MCSymbolRefExpr::VK_None)
408*26e25074SRoman Divacky     O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind());
409f785676fSDimitry Andric }
4102754fe60SDimitry Andric 
4112754fe60SDimitry Andric 
4122754fe60SDimitry Andric /// stripRegisterPrefix - This method strips the character prefix from a
4132754fe60SDimitry Andric /// register name so that only the number is left.  Used by for linux asm.
4142754fe60SDimitry Andric static const char *stripRegisterPrefix(const char *RegName) {
415f785676fSDimitry Andric   if (FullRegNames)
416f785676fSDimitry Andric     return RegName;
417f785676fSDimitry Andric 
4182754fe60SDimitry Andric   switch (RegName[0]) {
4192754fe60SDimitry Andric   case 'r':
4202754fe60SDimitry Andric   case 'f':
421ff0cc061SDimitry Andric   case 'q': // for QPX
42291bc56edSDimitry Andric   case 'v':
42391bc56edSDimitry Andric     if (RegName[1] == 's')
42491bc56edSDimitry Andric       return RegName + 2;
42591bc56edSDimitry Andric     return RegName + 1;
4262754fe60SDimitry Andric   case 'c': if (RegName[1] == 'r') return RegName + 2;
4272754fe60SDimitry Andric   }
4282754fe60SDimitry Andric 
4292754fe60SDimitry Andric   return RegName;
4302754fe60SDimitry Andric }
4312754fe60SDimitry Andric 
4322754fe60SDimitry Andric void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
4332754fe60SDimitry Andric                                   raw_ostream &O) {
4342754fe60SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
4352754fe60SDimitry Andric   if (Op.isReg()) {
4362754fe60SDimitry Andric     const char *RegName = getRegisterName(Op.getReg());
4372754fe60SDimitry Andric     // The linux and AIX assembler does not take register prefixes.
4382754fe60SDimitry Andric     if (!isDarwinSyntax())
4392754fe60SDimitry Andric       RegName = stripRegisterPrefix(RegName);
4402754fe60SDimitry Andric 
4412754fe60SDimitry Andric     O << RegName;
4422754fe60SDimitry Andric     return;
4432754fe60SDimitry Andric   }
4442754fe60SDimitry Andric 
4452754fe60SDimitry Andric   if (Op.isImm()) {
4462754fe60SDimitry Andric     O << Op.getImm();
4472754fe60SDimitry Andric     return;
4482754fe60SDimitry Andric   }
4492754fe60SDimitry Andric 
4502754fe60SDimitry Andric   assert(Op.isExpr() && "unknown operand kind in printOperand");
45197bc6c73SDimitry Andric   Op.getExpr()->print(O, &MAI);
4522754fe60SDimitry Andric }
4532754fe60SDimitry Andric 
454