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"
17db17bf38SDimitry Andric #include "PPCInstrInfo.h"
182cab237bSDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
192754fe60SDimitry Andric #include "llvm/MC/MCExpr.h"
202754fe60SDimitry Andric #include "llvm/MC/MCInst.h"
21dff0c46cSDimitry Andric #include "llvm/MC/MCInstrInfo.h"
22ff0cc061SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
23ff0cc061SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
2426e25074SRoman Divacky #include "llvm/MC/MCSymbol.h"
25f785676fSDimitry Andric #include "llvm/Support/CommandLine.h"
262754fe60SDimitry Andric #include "llvm/Support/raw_ostream.h"
272754fe60SDimitry Andric using namespace llvm;
282754fe60SDimitry Andric
2991bc56edSDimitry Andric #define DEBUG_TYPE "asm-printer"
3091bc56edSDimitry Andric
31f785676fSDimitry Andric // FIXME: Once the integrated assembler supports full register names, tie this
32f785676fSDimitry Andric // to the verbose-asm setting.
33f785676fSDimitry Andric static cl::opt<bool>
34f785676fSDimitry Andric FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
35f785676fSDimitry Andric cl::desc("Use full register names when printing assembly"));
36f785676fSDimitry Andric
37d88c1a5aSDimitry Andric // Useful for testing purposes. Prints vs{31-63} as v{0-31} respectively.
38d88c1a5aSDimitry Andric static cl::opt<bool>
39d88c1a5aSDimitry Andric ShowVSRNumsAsVR("ppc-vsr-nums-as-vr", cl::Hidden, cl::init(false),
40d88c1a5aSDimitry Andric cl::desc("Prints full register names with vs{31-63} as v{0-31}"));
41d88c1a5aSDimitry Andric
422cab237bSDimitry Andric // Prints full register names with percent symbol.
432cab237bSDimitry Andric static cl::opt<bool>
442cab237bSDimitry Andric FullRegNamesWithPercent("ppc-reg-with-percent-prefix", cl::Hidden,
452cab237bSDimitry Andric cl::init(false),
462cab237bSDimitry Andric cl::desc("Prints full register names with percent"));
472cab237bSDimitry Andric
48ff0cc061SDimitry Andric #define PRINT_ALIAS_INSTR
492754fe60SDimitry Andric #include "PPCGenAsmWriter.inc"
502754fe60SDimitry Andric
printRegName(raw_ostream & OS,unsigned RegNo) const51bd5abe19SDimitry Andric void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
52ff0cc061SDimitry Andric const char *RegName = getRegisterName(RegNo);
53ff0cc061SDimitry Andric if (RegName[0] == 'q' /* QPX */) {
54ff0cc061SDimitry Andric // The system toolchain on the BG/Q does not understand QPX register names
55ff0cc061SDimitry Andric // in .cfi_* directives, so print the name of the floating-point
56ff0cc061SDimitry Andric // subregister instead.
57ff0cc061SDimitry Andric std::string RN(RegName);
58ff0cc061SDimitry Andric
59ff0cc061SDimitry Andric RN[0] = 'f';
60ff0cc061SDimitry Andric OS << RN;
61ff0cc061SDimitry Andric
62ff0cc061SDimitry Andric return;
63ff0cc061SDimitry Andric }
64ff0cc061SDimitry Andric
65ff0cc061SDimitry Andric OS << RegName;
66bd5abe19SDimitry Andric }
672754fe60SDimitry Andric
printInst(const MCInst * MI,raw_ostream & O,StringRef Annot,const MCSubtargetInfo & STI)686122f3e6SDimitry Andric void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
69ff0cc061SDimitry Andric StringRef Annot, const MCSubtargetInfo &STI) {
702754fe60SDimitry Andric // Check for slwi/srwi mnemonics.
712754fe60SDimitry Andric if (MI->getOpcode() == PPC::RLWINM) {
722754fe60SDimitry Andric unsigned char SH = MI->getOperand(2).getImm();
732754fe60SDimitry Andric unsigned char MB = MI->getOperand(3).getImm();
742754fe60SDimitry Andric unsigned char ME = MI->getOperand(4).getImm();
752754fe60SDimitry Andric bool useSubstituteMnemonic = false;
762754fe60SDimitry Andric if (SH <= 31 && MB == 0 && ME == (31-SH)) {
772754fe60SDimitry Andric O << "\tslwi "; useSubstituteMnemonic = true;
782754fe60SDimitry Andric }
792754fe60SDimitry Andric if (SH <= 31 && MB == (32-SH) && ME == 31) {
802754fe60SDimitry Andric O << "\tsrwi "; useSubstituteMnemonic = true;
812754fe60SDimitry Andric SH = 32-SH;
822754fe60SDimitry Andric }
832754fe60SDimitry Andric if (useSubstituteMnemonic) {
842754fe60SDimitry Andric printOperand(MI, 0, O);
852754fe60SDimitry Andric O << ", ";
862754fe60SDimitry Andric printOperand(MI, 1, O);
872754fe60SDimitry Andric O << ", " << (unsigned int)SH;
886122f3e6SDimitry Andric
896122f3e6SDimitry Andric printAnnotation(O, Annot);
902754fe60SDimitry Andric return;
912754fe60SDimitry Andric }
922754fe60SDimitry Andric }
932754fe60SDimitry Andric
942754fe60SDimitry Andric if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
952754fe60SDimitry Andric MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
962754fe60SDimitry Andric O << "\tmr ";
972754fe60SDimitry Andric printOperand(MI, 0, O);
982754fe60SDimitry Andric O << ", ";
992754fe60SDimitry Andric printOperand(MI, 1, O);
1006122f3e6SDimitry Andric printAnnotation(O, Annot);
1012754fe60SDimitry Andric return;
1022754fe60SDimitry Andric }
1032754fe60SDimitry Andric
1045517e702SDimitry Andric if (MI->getOpcode() == PPC::RLDICR ||
1055517e702SDimitry Andric MI->getOpcode() == PPC::RLDICR_32) {
1062754fe60SDimitry Andric unsigned char SH = MI->getOperand(2).getImm();
1072754fe60SDimitry Andric unsigned char ME = MI->getOperand(3).getImm();
1082754fe60SDimitry Andric // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
1092754fe60SDimitry Andric if (63-SH == ME) {
1102754fe60SDimitry Andric O << "\tsldi ";
1112754fe60SDimitry Andric printOperand(MI, 0, O);
1122754fe60SDimitry Andric O << ", ";
1132754fe60SDimitry Andric printOperand(MI, 1, O);
1142754fe60SDimitry Andric O << ", " << (unsigned int)SH;
1156122f3e6SDimitry Andric printAnnotation(O, Annot);
1162754fe60SDimitry Andric return;
1172754fe60SDimitry Andric }
1182754fe60SDimitry Andric }
1192754fe60SDimitry Andric
120ff0cc061SDimitry Andric // dcbt[st] is printed manually here because:
121ff0cc061SDimitry Andric // 1. The assembly syntax is different between embedded and server targets
122ff0cc061SDimitry Andric // 2. We must print the short mnemonics for TH == 0 because the
123ff0cc061SDimitry Andric // embedded/server syntax default will not be stable across assemblers
124ff0cc061SDimitry Andric // The syntax for dcbt is:
125ff0cc061SDimitry Andric // dcbt ra, rb, th [server]
126ff0cc061SDimitry Andric // dcbt th, ra, rb [embedded]
127ff0cc061SDimitry Andric // where th can be omitted when it is 0. dcbtst is the same.
128ff0cc061SDimitry Andric if (MI->getOpcode() == PPC::DCBT || MI->getOpcode() == PPC::DCBTST) {
129ff0cc061SDimitry Andric unsigned char TH = MI->getOperand(0).getImm();
130ff0cc061SDimitry Andric O << "\tdcbt";
131ff0cc061SDimitry Andric if (MI->getOpcode() == PPC::DCBTST)
132ff0cc061SDimitry Andric O << "st";
133ff0cc061SDimitry Andric if (TH == 16)
134ff0cc061SDimitry Andric O << "t";
135ff0cc061SDimitry Andric O << " ";
136ff0cc061SDimitry Andric
137ff0cc061SDimitry Andric bool IsBookE = STI.getFeatureBits()[PPC::FeatureBookE];
138ff0cc061SDimitry Andric if (IsBookE && TH != 0 && TH != 16)
139ff0cc061SDimitry Andric O << (unsigned int) TH << ", ";
140ff0cc061SDimitry Andric
141ff0cc061SDimitry Andric printOperand(MI, 1, O);
142ff0cc061SDimitry Andric O << ", ";
143ff0cc061SDimitry Andric printOperand(MI, 2, O);
144ff0cc061SDimitry Andric
145ff0cc061SDimitry Andric if (!IsBookE && TH != 0 && TH != 16)
146ff0cc061SDimitry Andric O << ", " << (unsigned int) TH;
147ff0cc061SDimitry Andric
148ff0cc061SDimitry Andric printAnnotation(O, Annot);
149ff0cc061SDimitry Andric return;
150ff0cc061SDimitry Andric }
151ff0cc061SDimitry Andric
152d88c1a5aSDimitry Andric if (MI->getOpcode() == PPC::DCBF) {
153d88c1a5aSDimitry Andric unsigned char L = MI->getOperand(0).getImm();
154d88c1a5aSDimitry Andric if (!L || L == 1 || L == 3) {
155d88c1a5aSDimitry Andric O << "\tdcbf";
156d88c1a5aSDimitry Andric if (L == 1 || L == 3)
157d88c1a5aSDimitry Andric O << "l";
158d88c1a5aSDimitry Andric if (L == 3)
159d88c1a5aSDimitry Andric O << "p";
160d88c1a5aSDimitry Andric O << " ";
161d88c1a5aSDimitry Andric
162d88c1a5aSDimitry Andric printOperand(MI, 1, O);
163d88c1a5aSDimitry Andric O << ", ";
164d88c1a5aSDimitry Andric printOperand(MI, 2, O);
165d88c1a5aSDimitry Andric
166d88c1a5aSDimitry Andric printAnnotation(O, Annot);
167d88c1a5aSDimitry Andric return;
168d88c1a5aSDimitry Andric }
169d88c1a5aSDimitry Andric }
170d88c1a5aSDimitry Andric
171ff0cc061SDimitry Andric if (!printAliasInstr(MI, O))
1722754fe60SDimitry Andric printInstruction(MI, O);
1736122f3e6SDimitry Andric printAnnotation(O, Annot);
1742754fe60SDimitry Andric }
1752754fe60SDimitry Andric
1762754fe60SDimitry Andric
printPredicateOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O,const char * Modifier)1772754fe60SDimitry Andric void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
1782754fe60SDimitry Andric raw_ostream &O,
1792754fe60SDimitry Andric const char *Modifier) {
1802754fe60SDimitry Andric unsigned Code = MI->getOperand(OpNo).getImm();
1817ae0e2c9SDimitry Andric
1822754fe60SDimitry Andric if (StringRef(Modifier) == "cc") {
1832754fe60SDimitry Andric switch ((PPC::Predicate)Code) {
184f785676fSDimitry Andric case PPC::PRED_LT_MINUS:
185f785676fSDimitry Andric case PPC::PRED_LT_PLUS:
186f785676fSDimitry Andric case PPC::PRED_LT:
187f785676fSDimitry Andric O << "lt";
188f785676fSDimitry Andric return;
189f785676fSDimitry Andric case PPC::PRED_LE_MINUS:
190f785676fSDimitry Andric case PPC::PRED_LE_PLUS:
191f785676fSDimitry Andric case PPC::PRED_LE:
192f785676fSDimitry Andric O << "le";
193f785676fSDimitry Andric return;
194f785676fSDimitry Andric case PPC::PRED_EQ_MINUS:
195f785676fSDimitry Andric case PPC::PRED_EQ_PLUS:
196f785676fSDimitry Andric case PPC::PRED_EQ:
197f785676fSDimitry Andric O << "eq";
198f785676fSDimitry Andric return;
199f785676fSDimitry Andric case PPC::PRED_GE_MINUS:
200f785676fSDimitry Andric case PPC::PRED_GE_PLUS:
201f785676fSDimitry Andric case PPC::PRED_GE:
202f785676fSDimitry Andric O << "ge";
203f785676fSDimitry Andric return;
204f785676fSDimitry Andric case PPC::PRED_GT_MINUS:
205f785676fSDimitry Andric case PPC::PRED_GT_PLUS:
206f785676fSDimitry Andric case PPC::PRED_GT:
207f785676fSDimitry Andric O << "gt";
208f785676fSDimitry Andric return;
209f785676fSDimitry Andric case PPC::PRED_NE_MINUS:
210f785676fSDimitry Andric case PPC::PRED_NE_PLUS:
211f785676fSDimitry Andric case PPC::PRED_NE:
212f785676fSDimitry Andric O << "ne";
213f785676fSDimitry Andric return;
214f785676fSDimitry Andric case PPC::PRED_UN_MINUS:
215f785676fSDimitry Andric case PPC::PRED_UN_PLUS:
216f785676fSDimitry Andric case PPC::PRED_UN:
217f785676fSDimitry Andric O << "un";
218f785676fSDimitry Andric return;
219f785676fSDimitry Andric case PPC::PRED_NU_MINUS:
220f785676fSDimitry Andric case PPC::PRED_NU_PLUS:
221f785676fSDimitry Andric case PPC::PRED_NU:
222f785676fSDimitry Andric O << "nu";
223f785676fSDimitry Andric return;
22491bc56edSDimitry Andric case PPC::PRED_BIT_SET:
22591bc56edSDimitry Andric case PPC::PRED_BIT_UNSET:
22691bc56edSDimitry Andric llvm_unreachable("Invalid use of bit predicate code");
2272754fe60SDimitry Andric }
228f785676fSDimitry Andric llvm_unreachable("Invalid predicate code");
229f785676fSDimitry Andric }
230f785676fSDimitry Andric
231f785676fSDimitry Andric if (StringRef(Modifier) == "pm") {
232f785676fSDimitry Andric switch ((PPC::Predicate)Code) {
233f785676fSDimitry Andric case PPC::PRED_LT:
234f785676fSDimitry Andric case PPC::PRED_LE:
235f785676fSDimitry Andric case PPC::PRED_EQ:
236f785676fSDimitry Andric case PPC::PRED_GE:
237f785676fSDimitry Andric case PPC::PRED_GT:
238f785676fSDimitry Andric case PPC::PRED_NE:
239f785676fSDimitry Andric case PPC::PRED_UN:
240f785676fSDimitry Andric case PPC::PRED_NU:
241f785676fSDimitry Andric return;
242f785676fSDimitry Andric case PPC::PRED_LT_MINUS:
243f785676fSDimitry Andric case PPC::PRED_LE_MINUS:
244f785676fSDimitry Andric case PPC::PRED_EQ_MINUS:
245f785676fSDimitry Andric case PPC::PRED_GE_MINUS:
246f785676fSDimitry Andric case PPC::PRED_GT_MINUS:
247f785676fSDimitry Andric case PPC::PRED_NE_MINUS:
248f785676fSDimitry Andric case PPC::PRED_UN_MINUS:
249f785676fSDimitry Andric case PPC::PRED_NU_MINUS:
250f785676fSDimitry Andric O << "-";
251f785676fSDimitry Andric return;
252f785676fSDimitry Andric case PPC::PRED_LT_PLUS:
253f785676fSDimitry Andric case PPC::PRED_LE_PLUS:
254f785676fSDimitry Andric case PPC::PRED_EQ_PLUS:
255f785676fSDimitry Andric case PPC::PRED_GE_PLUS:
256f785676fSDimitry Andric case PPC::PRED_GT_PLUS:
257f785676fSDimitry Andric case PPC::PRED_NE_PLUS:
258f785676fSDimitry Andric case PPC::PRED_UN_PLUS:
259f785676fSDimitry Andric case PPC::PRED_NU_PLUS:
260f785676fSDimitry Andric O << "+";
261f785676fSDimitry Andric return;
26291bc56edSDimitry Andric case PPC::PRED_BIT_SET:
26391bc56edSDimitry Andric case PPC::PRED_BIT_UNSET:
26491bc56edSDimitry Andric llvm_unreachable("Invalid use of bit predicate code");
265f785676fSDimitry Andric }
266f785676fSDimitry Andric llvm_unreachable("Invalid predicate code");
2672754fe60SDimitry Andric }
2682754fe60SDimitry Andric
2692754fe60SDimitry Andric assert(StringRef(Modifier) == "reg" &&
270f785676fSDimitry Andric "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
2712754fe60SDimitry Andric printOperand(MI, OpNo+1, O);
2722754fe60SDimitry Andric }
2732754fe60SDimitry Andric
printATBitsAsHint(const MCInst * MI,unsigned OpNo,raw_ostream & O)274d88c1a5aSDimitry Andric void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
275d88c1a5aSDimitry Andric raw_ostream &O) {
276d88c1a5aSDimitry Andric unsigned Code = MI->getOperand(OpNo).getImm();
277d88c1a5aSDimitry Andric if (Code == 2)
278d88c1a5aSDimitry Andric O << "-";
279d88c1a5aSDimitry Andric else if (Code == 3)
280d88c1a5aSDimitry Andric O << "+";
281d88c1a5aSDimitry Andric }
282d88c1a5aSDimitry Andric
printU1ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)283ff0cc061SDimitry Andric void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
284ff0cc061SDimitry Andric raw_ostream &O) {
285ff0cc061SDimitry Andric unsigned int Value = MI->getOperand(OpNo).getImm();
286ff0cc061SDimitry Andric assert(Value <= 1 && "Invalid u1imm argument!");
287ff0cc061SDimitry Andric O << (unsigned int)Value;
288ff0cc061SDimitry Andric }
289ff0cc061SDimitry Andric
printU2ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)29091bc56edSDimitry Andric void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
29191bc56edSDimitry Andric raw_ostream &O) {
29291bc56edSDimitry Andric unsigned int Value = MI->getOperand(OpNo).getImm();
29391bc56edSDimitry Andric assert(Value <= 3 && "Invalid u2imm argument!");
29491bc56edSDimitry Andric O << (unsigned int)Value;
29591bc56edSDimitry Andric }
29691bc56edSDimitry Andric
printU3ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)297ff0cc061SDimitry Andric void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
298ff0cc061SDimitry Andric raw_ostream &O) {
299ff0cc061SDimitry Andric unsigned int Value = MI->getOperand(OpNo).getImm();
300ff0cc061SDimitry Andric assert(Value <= 8 && "Invalid u3imm argument!");
301ff0cc061SDimitry Andric O << (unsigned int)Value;
302ff0cc061SDimitry Andric }
303ff0cc061SDimitry Andric
printU4ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)30439d628a0SDimitry Andric void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
30539d628a0SDimitry Andric raw_ostream &O) {
30639d628a0SDimitry Andric unsigned int Value = MI->getOperand(OpNo).getImm();
30739d628a0SDimitry Andric assert(Value <= 15 && "Invalid u4imm argument!");
30839d628a0SDimitry Andric O << (unsigned int)Value;
30939d628a0SDimitry Andric }
31039d628a0SDimitry Andric
printS5ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3112754fe60SDimitry Andric void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
3122754fe60SDimitry Andric raw_ostream &O) {
3133861d79fSDimitry Andric int Value = MI->getOperand(OpNo).getImm();
3143861d79fSDimitry Andric Value = SignExtend32<5>(Value);
3152754fe60SDimitry Andric O << (int)Value;
3162754fe60SDimitry Andric }
3172754fe60SDimitry Andric
printU5ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3182754fe60SDimitry Andric void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
3192754fe60SDimitry Andric raw_ostream &O) {
3203861d79fSDimitry Andric unsigned int Value = MI->getOperand(OpNo).getImm();
3212754fe60SDimitry Andric assert(Value <= 31 && "Invalid u5imm argument!");
3222754fe60SDimitry Andric O << (unsigned int)Value;
3232754fe60SDimitry Andric }
3242754fe60SDimitry Andric
printU6ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3252754fe60SDimitry Andric void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
3262754fe60SDimitry Andric raw_ostream &O) {
3273861d79fSDimitry Andric unsigned int Value = MI->getOperand(OpNo).getImm();
3282754fe60SDimitry Andric assert(Value <= 63 && "Invalid u6imm argument!");
3292754fe60SDimitry Andric O << (unsigned int)Value;
3302754fe60SDimitry Andric }
3312754fe60SDimitry Andric
printU7ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3323ca95b02SDimitry Andric void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
3333ca95b02SDimitry Andric raw_ostream &O) {
3343ca95b02SDimitry Andric unsigned int Value = MI->getOperand(OpNo).getImm();
3353ca95b02SDimitry Andric assert(Value <= 127 && "Invalid u7imm argument!");
3363ca95b02SDimitry Andric O << (unsigned int)Value;
3373ca95b02SDimitry Andric }
3383ca95b02SDimitry Andric
339d88c1a5aSDimitry Andric // Operands of BUILD_VECTOR are signed and we use this to print operands
340d88c1a5aSDimitry Andric // of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
341d88c1a5aSDimitry Andric // print as unsigned.
printU8ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3423ca95b02SDimitry Andric void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
3433ca95b02SDimitry Andric raw_ostream &O) {
344d88c1a5aSDimitry Andric unsigned char Value = MI->getOperand(OpNo).getImm();
3453ca95b02SDimitry Andric O << (unsigned int)Value;
3463ca95b02SDimitry Andric }
3473ca95b02SDimitry Andric
printU10ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)348ff0cc061SDimitry Andric void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
349ff0cc061SDimitry Andric raw_ostream &O) {
350ff0cc061SDimitry Andric unsigned short Value = MI->getOperand(OpNo).getImm();
351ff0cc061SDimitry Andric assert(Value <= 1023 && "Invalid u10imm argument!");
352ff0cc061SDimitry Andric O << (unsigned short)Value;
353ff0cc061SDimitry Andric }
354ff0cc061SDimitry Andric
printU12ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)355ff0cc061SDimitry Andric void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
356ff0cc061SDimitry Andric raw_ostream &O) {
357ff0cc061SDimitry Andric unsigned short Value = MI->getOperand(OpNo).getImm();
358ff0cc061SDimitry Andric assert(Value <= 4095 && "Invalid u12imm argument!");
359ff0cc061SDimitry Andric O << (unsigned short)Value;
360ff0cc061SDimitry Andric }
361ff0cc061SDimitry Andric
printS16ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3622754fe60SDimitry Andric void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
3632754fe60SDimitry Andric raw_ostream &O) {
364f785676fSDimitry Andric if (MI->getOperand(OpNo).isImm())
3652754fe60SDimitry Andric O << (short)MI->getOperand(OpNo).getImm();
366f785676fSDimitry Andric else
367f785676fSDimitry Andric printOperand(MI, OpNo, O);
3682754fe60SDimitry Andric }
3692754fe60SDimitry Andric
printU16ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3702754fe60SDimitry Andric void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
3712754fe60SDimitry Andric raw_ostream &O) {
3722754fe60SDimitry Andric if (MI->getOperand(OpNo).isImm())
373f785676fSDimitry Andric O << (unsigned short)MI->getOperand(OpNo).getImm();
3742754fe60SDimitry Andric else
3752754fe60SDimitry Andric printOperand(MI, OpNo, O);
3762754fe60SDimitry Andric }
3772754fe60SDimitry Andric
printBranchOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)3782754fe60SDimitry Andric void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
3792754fe60SDimitry Andric raw_ostream &O) {
3802754fe60SDimitry Andric if (!MI->getOperand(OpNo).isImm())
3812754fe60SDimitry Andric return printOperand(MI, OpNo, O);
3822754fe60SDimitry Andric
3832754fe60SDimitry Andric // Branches can take an immediate operand. This is used by the branch
384284c1978SDimitry Andric // selection pass to print .+8, an eight byte displacement from the PC.
385*85573313SDimitry Andric O << ".";
386*85573313SDimitry Andric int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
387*85573313SDimitry Andric if (Imm >= 0)
388*85573313SDimitry Andric O << "+";
389*85573313SDimitry Andric O << Imm;
3902754fe60SDimitry Andric }
3912754fe60SDimitry Andric
printAbsBranchOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)392f785676fSDimitry Andric void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
3932754fe60SDimitry Andric raw_ostream &O) {
394f785676fSDimitry Andric if (!MI->getOperand(OpNo).isImm())
395f785676fSDimitry Andric return printOperand(MI, OpNo, O);
396f785676fSDimitry Andric
3979cac79b3SDimitry Andric O << SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
3982754fe60SDimitry Andric }
3992754fe60SDimitry Andric
4002754fe60SDimitry Andric
printcrbitm(const MCInst * MI,unsigned OpNo,raw_ostream & O)4012754fe60SDimitry Andric void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
4022754fe60SDimitry Andric raw_ostream &O) {
4032754fe60SDimitry Andric unsigned CCReg = MI->getOperand(OpNo).getReg();
4042754fe60SDimitry Andric unsigned RegNo;
4052754fe60SDimitry Andric switch (CCReg) {
406dff0c46cSDimitry Andric default: llvm_unreachable("Unknown CR register");
4072754fe60SDimitry Andric case PPC::CR0: RegNo = 0; break;
4082754fe60SDimitry Andric case PPC::CR1: RegNo = 1; break;
4092754fe60SDimitry Andric case PPC::CR2: RegNo = 2; break;
4102754fe60SDimitry Andric case PPC::CR3: RegNo = 3; break;
4112754fe60SDimitry Andric case PPC::CR4: RegNo = 4; break;
4122754fe60SDimitry Andric case PPC::CR5: RegNo = 5; break;
4132754fe60SDimitry Andric case PPC::CR6: RegNo = 6; break;
4142754fe60SDimitry Andric case PPC::CR7: RegNo = 7; break;
4152754fe60SDimitry Andric }
4162754fe60SDimitry Andric O << (0x80 >> RegNo);
4172754fe60SDimitry Andric }
4182754fe60SDimitry Andric
printMemRegImm(const MCInst * MI,unsigned OpNo,raw_ostream & O)4192754fe60SDimitry Andric void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
4202754fe60SDimitry Andric raw_ostream &O) {
421f785676fSDimitry Andric printS16ImmOperand(MI, OpNo, O);
4222754fe60SDimitry Andric O << '(';
4232754fe60SDimitry Andric if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
4242754fe60SDimitry Andric O << "0";
4252754fe60SDimitry Andric else
4262754fe60SDimitry Andric printOperand(MI, OpNo+1, O);
4272754fe60SDimitry Andric O << ')';
4282754fe60SDimitry Andric }
4292754fe60SDimitry Andric
printMemRegReg(const MCInst * MI,unsigned OpNo,raw_ostream & O)4302754fe60SDimitry Andric void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
4312754fe60SDimitry Andric raw_ostream &O) {
4322754fe60SDimitry Andric // When used as the base register, r0 reads constant zero rather than
4332754fe60SDimitry Andric // the value contained in the register. For this reason, the darwin
4342754fe60SDimitry Andric // assembler requires that we print r0 as 0 (no r) when used as the base.
4352754fe60SDimitry Andric if (MI->getOperand(OpNo).getReg() == PPC::R0)
4362754fe60SDimitry Andric O << "0";
4372754fe60SDimitry Andric else
4382754fe60SDimitry Andric printOperand(MI, OpNo, O);
4392754fe60SDimitry Andric O << ", ";
4402754fe60SDimitry Andric printOperand(MI, OpNo+1, O);
4412754fe60SDimitry Andric }
4422754fe60SDimitry Andric
printTLSCall(const MCInst * MI,unsigned OpNo,raw_ostream & O)443f785676fSDimitry Andric void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
444f785676fSDimitry Andric raw_ostream &O) {
44526e25074SRoman Divacky // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
44626e25074SRoman Divacky // come at the _end_ of the expression.
44726e25074SRoman Divacky const MCOperand &Op = MI->getOperand(OpNo);
44826e25074SRoman Divacky const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*Op.getExpr());
44926e25074SRoman Divacky O << refExp.getSymbol().getName();
450f785676fSDimitry Andric O << '(';
451f785676fSDimitry Andric printOperand(MI, OpNo+1, O);
452f785676fSDimitry Andric O << ')';
45326e25074SRoman Divacky if (refExp.getKind() != MCSymbolRefExpr::VK_None)
45426e25074SRoman Divacky O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind());
455f785676fSDimitry Andric }
4562754fe60SDimitry Andric
4572cab237bSDimitry Andric /// showRegistersWithPercentPrefix - Check if this register name should be
4582cab237bSDimitry Andric /// printed with a percentage symbol as prefix.
showRegistersWithPercentPrefix(const char * RegName) const4592cab237bSDimitry Andric bool PPCInstPrinter::showRegistersWithPercentPrefix(const char *RegName) const {
4602cab237bSDimitry Andric if (!FullRegNamesWithPercent || TT.isOSDarwin() || TT.getOS() == Triple::AIX)
4612cab237bSDimitry Andric return false;
4622cab237bSDimitry Andric
4632cab237bSDimitry Andric switch (RegName[0]) {
4642cab237bSDimitry Andric default:
4652cab237bSDimitry Andric return false;
4662cab237bSDimitry Andric case 'r':
4672cab237bSDimitry Andric case 'f':
4682cab237bSDimitry Andric case 'q':
4692cab237bSDimitry Andric case 'v':
4702cab237bSDimitry Andric case 'c':
4712cab237bSDimitry Andric return true;
4722cab237bSDimitry Andric }
4732cab237bSDimitry Andric }
4742cab237bSDimitry Andric
4752cab237bSDimitry Andric /// getVerboseConditionalRegName - This method expands the condition register
4762cab237bSDimitry Andric /// when requested explicitly or targetting Darwin.
getVerboseConditionRegName(unsigned RegNum,unsigned RegEncoding) const4772cab237bSDimitry Andric const char *PPCInstPrinter::getVerboseConditionRegName(unsigned RegNum,
4782cab237bSDimitry Andric unsigned RegEncoding)
4792cab237bSDimitry Andric const {
4802cab237bSDimitry Andric if (!TT.isOSDarwin() && !FullRegNames)
4812cab237bSDimitry Andric return nullptr;
4822cab237bSDimitry Andric if (RegNum < PPC::CR0EQ || RegNum > PPC::CR7UN)
4832cab237bSDimitry Andric return nullptr;
4842cab237bSDimitry Andric const char *CRBits[] = {
4852cab237bSDimitry Andric "lt", "gt", "eq", "un",
4862cab237bSDimitry Andric "4*cr1+lt", "4*cr1+gt", "4*cr1+eq", "4*cr1+un",
4872cab237bSDimitry Andric "4*cr2+lt", "4*cr2+gt", "4*cr2+eq", "4*cr2+un",
4882cab237bSDimitry Andric "4*cr3+lt", "4*cr3+gt", "4*cr3+eq", "4*cr3+un",
4892cab237bSDimitry Andric "4*cr4+lt", "4*cr4+gt", "4*cr4+eq", "4*cr4+un",
4902cab237bSDimitry Andric "4*cr5+lt", "4*cr5+gt", "4*cr5+eq", "4*cr5+un",
4912cab237bSDimitry Andric "4*cr6+lt", "4*cr6+gt", "4*cr6+eq", "4*cr6+un",
4922cab237bSDimitry Andric "4*cr7+lt", "4*cr7+gt", "4*cr7+eq", "4*cr7+un"
4932cab237bSDimitry Andric };
4942cab237bSDimitry Andric return CRBits[RegEncoding];
4952cab237bSDimitry Andric }
4962cab237bSDimitry Andric
4972cab237bSDimitry Andric // showRegistersWithPrefix - This method determines whether registers
4982cab237bSDimitry Andric // should be number-only or include the prefix.
showRegistersWithPrefix() const4992cab237bSDimitry Andric bool PPCInstPrinter::showRegistersWithPrefix() const {
5002cab237bSDimitry Andric if (TT.getOS() == Triple::AIX)
5012cab237bSDimitry Andric return false;
5022cab237bSDimitry Andric return TT.isOSDarwin() || FullRegNamesWithPercent || FullRegNames;
5032cab237bSDimitry Andric }
5042754fe60SDimitry Andric
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)5052754fe60SDimitry Andric void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
5062754fe60SDimitry Andric raw_ostream &O) {
5072754fe60SDimitry Andric const MCOperand &Op = MI->getOperand(OpNo);
5082754fe60SDimitry Andric if (Op.isReg()) {
509d88c1a5aSDimitry Andric unsigned Reg = Op.getReg();
510b5893f02SDimitry Andric if (!ShowVSRNumsAsVR)
511b5893f02SDimitry Andric Reg = PPCInstrInfo::getRegNumForOperand(MII.get(MI->getOpcode()),
512b5893f02SDimitry Andric Reg, OpNo);
513d88c1a5aSDimitry Andric
5142cab237bSDimitry Andric const char *RegName;
5152cab237bSDimitry Andric RegName = getVerboseConditionRegName(Reg, MRI.getEncodingValue(Reg));
5162cab237bSDimitry Andric if (RegName == nullptr)
5172cab237bSDimitry Andric RegName = getRegisterName(Reg);
5182cab237bSDimitry Andric if (showRegistersWithPercentPrefix(RegName))
5192cab237bSDimitry Andric O << "%";
5202cab237bSDimitry Andric if (!showRegistersWithPrefix())
521b5893f02SDimitry Andric RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
5222754fe60SDimitry Andric
5232754fe60SDimitry Andric O << RegName;
5242754fe60SDimitry Andric return;
5252754fe60SDimitry Andric }
5262754fe60SDimitry Andric
5272754fe60SDimitry Andric if (Op.isImm()) {
5282754fe60SDimitry Andric O << Op.getImm();
5292754fe60SDimitry Andric return;
5302754fe60SDimitry Andric }
5312754fe60SDimitry Andric
5322754fe60SDimitry Andric assert(Op.isExpr() && "unknown operand kind in printOperand");
53397bc6c73SDimitry Andric Op.getExpr()->print(O, &MAI);
5342754fe60SDimitry Andric }
5352754fe60SDimitry Andric
536