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