xref: /aosp_15_r20/external/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This class prints an PPC MCInst to a .s file.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "PPCInstPrinter.h"
15*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/PPCMCTargetDesc.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/PPCPredicates.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOpcodes.h"
26*9880d681SAndroid Build Coastguard Worker using namespace llvm;
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "asm-printer"
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker // FIXME: Once the integrated assembler supports full register names, tie this
31*9880d681SAndroid Build Coastguard Worker // to the verbose-asm setting.
32*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
33*9880d681SAndroid Build Coastguard Worker FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
34*9880d681SAndroid Build Coastguard Worker              cl::desc("Use full register names when printing assembly"));
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker #define PRINT_ALIAS_INSTR
37*9880d681SAndroid Build Coastguard Worker #include "PPCGenAsmWriter.inc"
38*9880d681SAndroid Build Coastguard Worker 
printRegName(raw_ostream & OS,unsigned RegNo) const39*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
40*9880d681SAndroid Build Coastguard Worker   const char *RegName = getRegisterName(RegNo);
41*9880d681SAndroid Build Coastguard Worker   if (RegName[0] == 'q' /* QPX */) {
42*9880d681SAndroid Build Coastguard Worker     // The system toolchain on the BG/Q does not understand QPX register names
43*9880d681SAndroid Build Coastguard Worker     // in .cfi_* directives, so print the name of the floating-point
44*9880d681SAndroid Build Coastguard Worker     // subregister instead.
45*9880d681SAndroid Build Coastguard Worker     std::string RN(RegName);
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker     RN[0] = 'f';
48*9880d681SAndroid Build Coastguard Worker     OS << RN;
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker     return;
51*9880d681SAndroid Build Coastguard Worker   }
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker   OS << RegName;
54*9880d681SAndroid Build Coastguard Worker }
55*9880d681SAndroid Build Coastguard Worker 
printInst(const MCInst * MI,raw_ostream & O,StringRef Annot,const MCSubtargetInfo & STI)56*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
57*9880d681SAndroid Build Coastguard Worker                                StringRef Annot, const MCSubtargetInfo &STI) {
58*9880d681SAndroid Build Coastguard Worker   // Check for slwi/srwi mnemonics.
59*9880d681SAndroid Build Coastguard Worker   if (MI->getOpcode() == PPC::RLWINM) {
60*9880d681SAndroid Build Coastguard Worker     unsigned char SH = MI->getOperand(2).getImm();
61*9880d681SAndroid Build Coastguard Worker     unsigned char MB = MI->getOperand(3).getImm();
62*9880d681SAndroid Build Coastguard Worker     unsigned char ME = MI->getOperand(4).getImm();
63*9880d681SAndroid Build Coastguard Worker     bool useSubstituteMnemonic = false;
64*9880d681SAndroid Build Coastguard Worker     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
65*9880d681SAndroid Build Coastguard Worker       O << "\tslwi "; useSubstituteMnemonic = true;
66*9880d681SAndroid Build Coastguard Worker     }
67*9880d681SAndroid Build Coastguard Worker     if (SH <= 31 && MB == (32-SH) && ME == 31) {
68*9880d681SAndroid Build Coastguard Worker       O << "\tsrwi "; useSubstituteMnemonic = true;
69*9880d681SAndroid Build Coastguard Worker       SH = 32-SH;
70*9880d681SAndroid Build Coastguard Worker     }
71*9880d681SAndroid Build Coastguard Worker     if (useSubstituteMnemonic) {
72*9880d681SAndroid Build Coastguard Worker       printOperand(MI, 0, O);
73*9880d681SAndroid Build Coastguard Worker       O << ", ";
74*9880d681SAndroid Build Coastguard Worker       printOperand(MI, 1, O);
75*9880d681SAndroid Build Coastguard Worker       O << ", " << (unsigned int)SH;
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker       printAnnotation(O, Annot);
78*9880d681SAndroid Build Coastguard Worker       return;
79*9880d681SAndroid Build Coastguard Worker     }
80*9880d681SAndroid Build Coastguard Worker   }
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker   if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
83*9880d681SAndroid Build Coastguard Worker       MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
84*9880d681SAndroid Build Coastguard Worker     O << "\tmr ";
85*9880d681SAndroid Build Coastguard Worker     printOperand(MI, 0, O);
86*9880d681SAndroid Build Coastguard Worker     O << ", ";
87*9880d681SAndroid Build Coastguard Worker     printOperand(MI, 1, O);
88*9880d681SAndroid Build Coastguard Worker     printAnnotation(O, Annot);
89*9880d681SAndroid Build Coastguard Worker     return;
90*9880d681SAndroid Build Coastguard Worker   }
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker   if (MI->getOpcode() == PPC::RLDICR) {
93*9880d681SAndroid Build Coastguard Worker     unsigned char SH = MI->getOperand(2).getImm();
94*9880d681SAndroid Build Coastguard Worker     unsigned char ME = MI->getOperand(3).getImm();
95*9880d681SAndroid Build Coastguard Worker     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
96*9880d681SAndroid Build Coastguard Worker     if (63-SH == ME) {
97*9880d681SAndroid Build Coastguard Worker       O << "\tsldi ";
98*9880d681SAndroid Build Coastguard Worker       printOperand(MI, 0, O);
99*9880d681SAndroid Build Coastguard Worker       O << ", ";
100*9880d681SAndroid Build Coastguard Worker       printOperand(MI, 1, O);
101*9880d681SAndroid Build Coastguard Worker       O << ", " << (unsigned int)SH;
102*9880d681SAndroid Build Coastguard Worker       printAnnotation(O, Annot);
103*9880d681SAndroid Build Coastguard Worker       return;
104*9880d681SAndroid Build Coastguard Worker     }
105*9880d681SAndroid Build Coastguard Worker   }
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker   // dcbt[st] is printed manually here because:
108*9880d681SAndroid Build Coastguard Worker   //  1. The assembly syntax is different between embedded and server targets
109*9880d681SAndroid Build Coastguard Worker   //  2. We must print the short mnemonics for TH == 0 because the
110*9880d681SAndroid Build Coastguard Worker   //     embedded/server syntax default will not be stable across assemblers
111*9880d681SAndroid Build Coastguard Worker   //  The syntax for dcbt is:
112*9880d681SAndroid Build Coastguard Worker   //    dcbt ra, rb, th [server]
113*9880d681SAndroid Build Coastguard Worker   //    dcbt th, ra, rb [embedded]
114*9880d681SAndroid Build Coastguard Worker   //  where th can be omitted when it is 0. dcbtst is the same.
115*9880d681SAndroid Build Coastguard Worker   if (MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) {
116*9880d681SAndroid Build Coastguard Worker     unsigned char TH = MI->getOperand(0).getImm();
117*9880d681SAndroid Build Coastguard Worker     O << "\tdcbt";
118*9880d681SAndroid Build Coastguard Worker     if (MI->getOpcode() == PPC::DCBTST)
119*9880d681SAndroid Build Coastguard Worker       O << "st";
120*9880d681SAndroid Build Coastguard Worker     if (TH == 16)
121*9880d681SAndroid Build Coastguard Worker       O << "t";
122*9880d681SAndroid Build Coastguard Worker     O << " ";
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker     bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE];
125*9880d681SAndroid Build Coastguard Worker     if (IsBookE && TH != 0 && TH != 16)
126*9880d681SAndroid Build Coastguard Worker       O << (unsigned int) TH << ", ";
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker     printOperand(MI, 1, O);
129*9880d681SAndroid Build Coastguard Worker     O << ", ";
130*9880d681SAndroid Build Coastguard Worker     printOperand(MI, 2, O);
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker     if (!IsBookE && TH != 0 && TH != 16)
133*9880d681SAndroid Build Coastguard Worker       O << ", " << (unsigned int) TH;
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker     printAnnotation(O, Annot);
136*9880d681SAndroid Build Coastguard Worker     return;
137*9880d681SAndroid Build Coastguard Worker   }
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker   if (!printAliasInstr(MI, O))
140*9880d681SAndroid Build Coastguard Worker     printInstruction(MI, O);
141*9880d681SAndroid Build Coastguard Worker   printAnnotation(O, Annot);
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker 
printPredicateOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O,const char * Modifier)145*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
146*9880d681SAndroid Build Coastguard Worker                                            raw_ostream &O,
147*9880d681SAndroid Build Coastguard Worker                                            const char *Modifier) {
148*9880d681SAndroid Build Coastguard Worker   unsigned Code = MI->getOperand(OpNo).getImm();
149*9880d681SAndroid Build Coastguard Worker 
150*9880d681SAndroid Build Coastguard Worker   if (StringRef(Modifier) == "cc") {
151*9880d681SAndroid Build Coastguard Worker     switch ((PPC::Predicate)Code) {
152*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LT_MINUS:
153*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LT_PLUS:
154*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LT:
155*9880d681SAndroid Build Coastguard Worker       O << "lt";
156*9880d681SAndroid Build Coastguard Worker       return;
157*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LE_MINUS:
158*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LE_PLUS:
159*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LE:
160*9880d681SAndroid Build Coastguard Worker       O << "le";
161*9880d681SAndroid Build Coastguard Worker       return;
162*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_EQ_MINUS:
163*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_EQ_PLUS:
164*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_EQ:
165*9880d681SAndroid Build Coastguard Worker       O << "eq";
166*9880d681SAndroid Build Coastguard Worker       return;
167*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GE_MINUS:
168*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GE_PLUS:
169*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GE:
170*9880d681SAndroid Build Coastguard Worker       O << "ge";
171*9880d681SAndroid Build Coastguard Worker       return;
172*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GT_MINUS:
173*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GT_PLUS:
174*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GT:
175*9880d681SAndroid Build Coastguard Worker       O << "gt";
176*9880d681SAndroid Build Coastguard Worker       return;
177*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NE_MINUS:
178*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NE_PLUS:
179*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NE:
180*9880d681SAndroid Build Coastguard Worker       O << "ne";
181*9880d681SAndroid Build Coastguard Worker       return;
182*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_UN_MINUS:
183*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_UN_PLUS:
184*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_UN:
185*9880d681SAndroid Build Coastguard Worker       O << "un";
186*9880d681SAndroid Build Coastguard Worker       return;
187*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NU_MINUS:
188*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NU_PLUS:
189*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NU:
190*9880d681SAndroid Build Coastguard Worker       O << "nu";
191*9880d681SAndroid Build Coastguard Worker       return;
192*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_BIT_SET:
193*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_BIT_UNSET:
194*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Invalid use of bit predicate code");
195*9880d681SAndroid Build Coastguard Worker     }
196*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Invalid predicate code");
197*9880d681SAndroid Build Coastguard Worker   }
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker   if (StringRef(Modifier) == "pm") {
200*9880d681SAndroid Build Coastguard Worker     switch ((PPC::Predicate)Code) {
201*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LT:
202*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LE:
203*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_EQ:
204*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GE:
205*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GT:
206*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NE:
207*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_UN:
208*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NU:
209*9880d681SAndroid Build Coastguard Worker       return;
210*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LT_MINUS:
211*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LE_MINUS:
212*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_EQ_MINUS:
213*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GE_MINUS:
214*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GT_MINUS:
215*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NE_MINUS:
216*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_UN_MINUS:
217*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NU_MINUS:
218*9880d681SAndroid Build Coastguard Worker       O << "-";
219*9880d681SAndroid Build Coastguard Worker       return;
220*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LT_PLUS:
221*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_LE_PLUS:
222*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_EQ_PLUS:
223*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GE_PLUS:
224*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_GT_PLUS:
225*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NE_PLUS:
226*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_UN_PLUS:
227*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_NU_PLUS:
228*9880d681SAndroid Build Coastguard Worker       O << "+";
229*9880d681SAndroid Build Coastguard Worker       return;
230*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_BIT_SET:
231*9880d681SAndroid Build Coastguard Worker     case PPC::PRED_BIT_UNSET:
232*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Invalid use of bit predicate code");
233*9880d681SAndroid Build Coastguard Worker     }
234*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Invalid predicate code");
235*9880d681SAndroid Build Coastguard Worker   }
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker   assert(StringRef(Modifier) == "reg" &&
238*9880d681SAndroid Build Coastguard Worker          "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
239*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNo+1, O);
240*9880d681SAndroid Build Coastguard Worker }
241*9880d681SAndroid Build Coastguard Worker 
printU1ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)242*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
243*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
244*9880d681SAndroid Build Coastguard Worker   unsigned int Value = MI->getOperand(OpNo).getImm();
245*9880d681SAndroid Build Coastguard Worker   assert(Value <= 1 && "Invalid u1imm argument!");
246*9880d681SAndroid Build Coastguard Worker   O << (unsigned int)Value;
247*9880d681SAndroid Build Coastguard Worker }
248*9880d681SAndroid Build Coastguard Worker 
printU2ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)249*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
250*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
251*9880d681SAndroid Build Coastguard Worker   unsigned int Value = MI->getOperand(OpNo).getImm();
252*9880d681SAndroid Build Coastguard Worker   assert(Value <= 3 && "Invalid u2imm argument!");
253*9880d681SAndroid Build Coastguard Worker   O << (unsigned int)Value;
254*9880d681SAndroid Build Coastguard Worker }
255*9880d681SAndroid Build Coastguard Worker 
printU3ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)256*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
257*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
258*9880d681SAndroid Build Coastguard Worker   unsigned int Value = MI->getOperand(OpNo).getImm();
259*9880d681SAndroid Build Coastguard Worker   assert(Value <= 8 && "Invalid u3imm argument!");
260*9880d681SAndroid Build Coastguard Worker   O << (unsigned int)Value;
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker 
printU4ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)263*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
264*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
265*9880d681SAndroid Build Coastguard Worker   unsigned int Value = MI->getOperand(OpNo).getImm();
266*9880d681SAndroid Build Coastguard Worker   assert(Value <= 15 && "Invalid u4imm argument!");
267*9880d681SAndroid Build Coastguard Worker   O << (unsigned int)Value;
268*9880d681SAndroid Build Coastguard Worker }
269*9880d681SAndroid Build Coastguard Worker 
printS5ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)270*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
271*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
272*9880d681SAndroid Build Coastguard Worker   int Value = MI->getOperand(OpNo).getImm();
273*9880d681SAndroid Build Coastguard Worker   Value = SignExtend32<5>(Value);
274*9880d681SAndroid Build Coastguard Worker   O << (int)Value;
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker 
printU5ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)277*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
278*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
279*9880d681SAndroid Build Coastguard Worker   unsigned int Value = MI->getOperand(OpNo).getImm();
280*9880d681SAndroid Build Coastguard Worker   assert(Value <= 31 && "Invalid u5imm argument!");
281*9880d681SAndroid Build Coastguard Worker   O << (unsigned int)Value;
282*9880d681SAndroid Build Coastguard Worker }
283*9880d681SAndroid Build Coastguard Worker 
printU6ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)284*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
285*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
286*9880d681SAndroid Build Coastguard Worker   unsigned int Value = MI->getOperand(OpNo).getImm();
287*9880d681SAndroid Build Coastguard Worker   assert(Value <= 63 && "Invalid u6imm argument!");
288*9880d681SAndroid Build Coastguard Worker   O << (unsigned int)Value;
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker 
printU7ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)291*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
292*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
293*9880d681SAndroid Build Coastguard Worker   unsigned int Value = MI->getOperand(OpNo).getImm();
294*9880d681SAndroid Build Coastguard Worker   assert(Value <= 127 && "Invalid u7imm argument!");
295*9880d681SAndroid Build Coastguard Worker   O << (unsigned int)Value;
296*9880d681SAndroid Build Coastguard Worker }
297*9880d681SAndroid Build Coastguard Worker 
printU8ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)298*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
299*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &O) {
300*9880d681SAndroid Build Coastguard Worker   unsigned int Value = MI->getOperand(OpNo).getImm();
301*9880d681SAndroid Build Coastguard Worker   assert(Value <= 255 && "Invalid u8imm argument!");
302*9880d681SAndroid Build Coastguard Worker   O << (unsigned int)Value;
303*9880d681SAndroid Build Coastguard Worker }
304*9880d681SAndroid Build Coastguard Worker 
printU10ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)305*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
306*9880d681SAndroid Build Coastguard Worker                                         raw_ostream &O) {
307*9880d681SAndroid Build Coastguard Worker   unsigned short Value = MI->getOperand(OpNo).getImm();
308*9880d681SAndroid Build Coastguard Worker   assert(Value <= 1023 && "Invalid u10imm argument!");
309*9880d681SAndroid Build Coastguard Worker   O << (unsigned short)Value;
310*9880d681SAndroid Build Coastguard Worker }
311*9880d681SAndroid Build Coastguard Worker 
printU12ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)312*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
313*9880d681SAndroid Build Coastguard Worker                                         raw_ostream &O) {
314*9880d681SAndroid Build Coastguard Worker   unsigned short Value = MI->getOperand(OpNo).getImm();
315*9880d681SAndroid Build Coastguard Worker   assert(Value <= 4095 && "Invalid u12imm argument!");
316*9880d681SAndroid Build Coastguard Worker   O << (unsigned short)Value;
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker 
printS16ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)319*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
320*9880d681SAndroid Build Coastguard Worker                                         raw_ostream &O) {
321*9880d681SAndroid Build Coastguard Worker   if (MI->getOperand(OpNo).isImm())
322*9880d681SAndroid Build Coastguard Worker     O << (short)MI->getOperand(OpNo).getImm();
323*9880d681SAndroid Build Coastguard Worker   else
324*9880d681SAndroid Build Coastguard Worker     printOperand(MI, OpNo, O);
325*9880d681SAndroid Build Coastguard Worker }
326*9880d681SAndroid Build Coastguard Worker 
printU16ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)327*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
328*9880d681SAndroid Build Coastguard Worker                                         raw_ostream &O) {
329*9880d681SAndroid Build Coastguard Worker   if (MI->getOperand(OpNo).isImm())
330*9880d681SAndroid Build Coastguard Worker     O << (unsigned short)MI->getOperand(OpNo).getImm();
331*9880d681SAndroid Build Coastguard Worker   else
332*9880d681SAndroid Build Coastguard Worker     printOperand(MI, OpNo, O);
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker 
printBranchOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)335*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
336*9880d681SAndroid Build Coastguard Worker                                         raw_ostream &O) {
337*9880d681SAndroid Build Coastguard Worker   if (!MI->getOperand(OpNo).isImm())
338*9880d681SAndroid Build Coastguard Worker     return printOperand(MI, OpNo, O);
339*9880d681SAndroid Build Coastguard Worker 
340*9880d681SAndroid Build Coastguard Worker   // Branches can take an immediate operand.  This is used by the branch
341*9880d681SAndroid Build Coastguard Worker   // selection pass to print .+8, an eight byte displacement from the PC.
342*9880d681SAndroid Build Coastguard Worker   O << ".+";
343*9880d681SAndroid Build Coastguard Worker   printAbsBranchOperand(MI, OpNo, O);
344*9880d681SAndroid Build Coastguard Worker }
345*9880d681SAndroid Build Coastguard Worker 
printAbsBranchOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)346*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
347*9880d681SAndroid Build Coastguard Worker                                            raw_ostream &O) {
348*9880d681SAndroid Build Coastguard Worker   if (!MI->getOperand(OpNo).isImm())
349*9880d681SAndroid Build Coastguard Worker     return printOperand(MI, OpNo, O);
350*9880d681SAndroid Build Coastguard Worker 
351*9880d681SAndroid Build Coastguard Worker   O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
352*9880d681SAndroid Build Coastguard Worker }
353*9880d681SAndroid Build Coastguard Worker 
354*9880d681SAndroid Build Coastguard Worker 
printcrbitm(const MCInst * MI,unsigned OpNo,raw_ostream & O)355*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
356*9880d681SAndroid Build Coastguard Worker                                  raw_ostream &O) {
357*9880d681SAndroid Build Coastguard Worker   unsigned CCReg = MI->getOperand(OpNo).getReg();
358*9880d681SAndroid Build Coastguard Worker   unsigned RegNo;
359*9880d681SAndroid Build Coastguard Worker   switch (CCReg) {
360*9880d681SAndroid Build Coastguard Worker   default: llvm_unreachable("Unknown CR register");
361*9880d681SAndroid Build Coastguard Worker   case PPC::CR0: RegNo = 0; break;
362*9880d681SAndroid Build Coastguard Worker   case PPC::CR1: RegNo = 1; break;
363*9880d681SAndroid Build Coastguard Worker   case PPC::CR2: RegNo = 2; break;
364*9880d681SAndroid Build Coastguard Worker   case PPC::CR3: RegNo = 3; break;
365*9880d681SAndroid Build Coastguard Worker   case PPC::CR4: RegNo = 4; break;
366*9880d681SAndroid Build Coastguard Worker   case PPC::CR5: RegNo = 5; break;
367*9880d681SAndroid Build Coastguard Worker   case PPC::CR6: RegNo = 6; break;
368*9880d681SAndroid Build Coastguard Worker   case PPC::CR7: RegNo = 7; break;
369*9880d681SAndroid Build Coastguard Worker   }
370*9880d681SAndroid Build Coastguard Worker   O << (0x80 >> RegNo);
371*9880d681SAndroid Build Coastguard Worker }
372*9880d681SAndroid Build Coastguard Worker 
printMemRegImm(const MCInst * MI,unsigned OpNo,raw_ostream & O)373*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
374*9880d681SAndroid Build Coastguard Worker                                     raw_ostream &O) {
375*9880d681SAndroid Build Coastguard Worker   printS16ImmOperand(MI, OpNo, O);
376*9880d681SAndroid Build Coastguard Worker   O << '(';
377*9880d681SAndroid Build Coastguard Worker   if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
378*9880d681SAndroid Build Coastguard Worker     O << "0";
379*9880d681SAndroid Build Coastguard Worker   else
380*9880d681SAndroid Build Coastguard Worker     printOperand(MI, OpNo+1, O);
381*9880d681SAndroid Build Coastguard Worker   O << ')';
382*9880d681SAndroid Build Coastguard Worker }
383*9880d681SAndroid Build Coastguard Worker 
printMemRegReg(const MCInst * MI,unsigned OpNo,raw_ostream & O)384*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
385*9880d681SAndroid Build Coastguard Worker                                     raw_ostream &O) {
386*9880d681SAndroid Build Coastguard Worker   // When used as the base register, r0 reads constant zero rather than
387*9880d681SAndroid Build Coastguard Worker   // the value contained in the register.  For this reason, the darwin
388*9880d681SAndroid Build Coastguard Worker   // assembler requires that we print r0 as 0 (no r) when used as the base.
389*9880d681SAndroid Build Coastguard Worker   if (MI->getOperand(OpNo).getReg() == PPC::R0)
390*9880d681SAndroid Build Coastguard Worker     O << "0";
391*9880d681SAndroid Build Coastguard Worker   else
392*9880d681SAndroid Build Coastguard Worker     printOperand(MI, OpNo, O);
393*9880d681SAndroid Build Coastguard Worker   O << ", ";
394*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNo+1, O);
395*9880d681SAndroid Build Coastguard Worker }
396*9880d681SAndroid Build Coastguard Worker 
printTLSCall(const MCInst * MI,unsigned OpNo,raw_ostream & O)397*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
398*9880d681SAndroid Build Coastguard Worker                                   raw_ostream &O) {
399*9880d681SAndroid Build Coastguard Worker   // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
400*9880d681SAndroid Build Coastguard Worker   // come at the _end_ of the expression.
401*9880d681SAndroid Build Coastguard Worker   const MCOperand &Op = MI->getOperand(OpNo);
402*9880d681SAndroid Build Coastguard Worker   const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*Op.getExpr());
403*9880d681SAndroid Build Coastguard Worker   O << refExp.getSymbol().getName();
404*9880d681SAndroid Build Coastguard Worker   O << '(';
405*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNo+1, O);
406*9880d681SAndroid Build Coastguard Worker   O << ')';
407*9880d681SAndroid Build Coastguard Worker   if (refExp.getKind() != MCSymbolRefExpr::VK_None)
408*9880d681SAndroid Build Coastguard Worker     O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind());
409*9880d681SAndroid Build Coastguard Worker }
410*9880d681SAndroid Build Coastguard Worker 
411*9880d681SAndroid Build Coastguard Worker 
412*9880d681SAndroid Build Coastguard Worker /// stripRegisterPrefix - This method strips the character prefix from a
413*9880d681SAndroid Build Coastguard Worker /// register name so that only the number is left.  Used by for linux asm.
stripRegisterPrefix(const char * RegName)414*9880d681SAndroid Build Coastguard Worker static const char *stripRegisterPrefix(const char *RegName) {
415*9880d681SAndroid Build Coastguard Worker   if (FullRegNames)
416*9880d681SAndroid Build Coastguard Worker     return RegName;
417*9880d681SAndroid Build Coastguard Worker 
418*9880d681SAndroid Build Coastguard Worker   switch (RegName[0]) {
419*9880d681SAndroid Build Coastguard Worker   case 'r':
420*9880d681SAndroid Build Coastguard Worker   case 'f':
421*9880d681SAndroid Build Coastguard Worker   case 'q': // for QPX
422*9880d681SAndroid Build Coastguard Worker   case 'v':
423*9880d681SAndroid Build Coastguard Worker     if (RegName[1] == 's')
424*9880d681SAndroid Build Coastguard Worker       return RegName + 2;
425*9880d681SAndroid Build Coastguard Worker     return RegName + 1;
426*9880d681SAndroid Build Coastguard Worker   case 'c': if (RegName[1] == 'r') return RegName + 2;
427*9880d681SAndroid Build Coastguard Worker   }
428*9880d681SAndroid Build Coastguard Worker 
429*9880d681SAndroid Build Coastguard Worker   return RegName;
430*9880d681SAndroid Build Coastguard Worker }
431*9880d681SAndroid Build Coastguard Worker 
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)432*9880d681SAndroid Build Coastguard Worker void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
433*9880d681SAndroid Build Coastguard Worker                                   raw_ostream &O) {
434*9880d681SAndroid Build Coastguard Worker   const MCOperand &Op = MI->getOperand(OpNo);
435*9880d681SAndroid Build Coastguard Worker   if (Op.isReg()) {
436*9880d681SAndroid Build Coastguard Worker     const char *RegName = getRegisterName(Op.getReg());
437*9880d681SAndroid Build Coastguard Worker     // The linux and AIX assembler does not take register prefixes.
438*9880d681SAndroid Build Coastguard Worker     if (!isDarwinSyntax())
439*9880d681SAndroid Build Coastguard Worker       RegName = stripRegisterPrefix(RegName);
440*9880d681SAndroid Build Coastguard Worker 
441*9880d681SAndroid Build Coastguard Worker     O << RegName;
442*9880d681SAndroid Build Coastguard Worker     return;
443*9880d681SAndroid Build Coastguard Worker   }
444*9880d681SAndroid Build Coastguard Worker 
445*9880d681SAndroid Build Coastguard Worker   if (Op.isImm()) {
446*9880d681SAndroid Build Coastguard Worker     O << Op.getImm();
447*9880d681SAndroid Build Coastguard Worker     return;
448*9880d681SAndroid Build Coastguard Worker   }
449*9880d681SAndroid Build Coastguard Worker 
450*9880d681SAndroid Build Coastguard Worker   assert(Op.isExpr() && "unknown operand kind in printOperand");
451*9880d681SAndroid Build Coastguard Worker   Op.getExpr()->print(O, &MAI);
452*9880d681SAndroid Build Coastguard Worker }
453*9880d681SAndroid Build Coastguard Worker 
454