PPCInstPrinter.cpp revision 263508
1//===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This class prints an PPC MCInst to a .s file.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "asm-printer"
15#include "PPCInstPrinter.h"
16#include "MCTargetDesc/PPCMCTargetDesc.h"
17#include "MCTargetDesc/PPCPredicates.h"
18#include "llvm/MC/MCExpr.h"
19#include "llvm/MC/MCInst.h"
20#include "llvm/MC/MCInstrInfo.h"
21#include "llvm/Support/CommandLine.h"
22#include "llvm/Support/raw_ostream.h"
23#include "llvm/Target/TargetOpcodes.h"
24using namespace llvm;
25
26// FIXME: Once the integrated assembler supports full register names, tie this
27// to the verbose-asm setting.
28static cl::opt<bool>
29FullRegNames("ppc-asm-full-reg-names", cl::Hidden, cl::init(false),
30             cl::desc("Use full register names when printing assembly"));
31
32#include "PPCGenAsmWriter.inc"
33
34void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
35  OS << getRegisterName(RegNo);
36}
37
38void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
39                               StringRef Annot) {
40  // Check for slwi/srwi mnemonics.
41  if (MI->getOpcode() == PPC::RLWINM) {
42    unsigned char SH = MI->getOperand(2).getImm();
43    unsigned char MB = MI->getOperand(3).getImm();
44    unsigned char ME = MI->getOperand(4).getImm();
45    bool useSubstituteMnemonic = false;
46    if (SH <= 31 && MB == 0 && ME == (31-SH)) {
47      O << "\tslwi "; useSubstituteMnemonic = true;
48    }
49    if (SH <= 31 && MB == (32-SH) && ME == 31) {
50      O << "\tsrwi "; useSubstituteMnemonic = true;
51      SH = 32-SH;
52    }
53    if (useSubstituteMnemonic) {
54      printOperand(MI, 0, O);
55      O << ", ";
56      printOperand(MI, 1, O);
57      O << ", " << (unsigned int)SH;
58
59      printAnnotation(O, Annot);
60      return;
61    }
62  }
63
64  if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) &&
65      MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
66    O << "\tmr ";
67    printOperand(MI, 0, O);
68    O << ", ";
69    printOperand(MI, 1, O);
70    printAnnotation(O, Annot);
71    return;
72  }
73
74  if (MI->getOpcode() == PPC::RLDICR) {
75    unsigned char SH = MI->getOperand(2).getImm();
76    unsigned char ME = MI->getOperand(3).getImm();
77    // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
78    if (63-SH == ME) {
79      O << "\tsldi ";
80      printOperand(MI, 0, O);
81      O << ", ";
82      printOperand(MI, 1, O);
83      O << ", " << (unsigned int)SH;
84      printAnnotation(O, Annot);
85      return;
86    }
87  }
88
89  // For fast-isel, a COPY_TO_REGCLASS may survive this long.  This is
90  // used when converting a 32-bit float to a 64-bit float as part of
91  // conversion to an integer (see PPCFastISel.cpp:SelectFPToI()),
92  // as otherwise we have problems with incorrect register classes
93  // in machine instruction verification.  For now, just avoid trying
94  // to print it as such an instruction has no effect (a 32-bit float
95  // in a register is already in 64-bit form, just with lower
96  // precision).  FIXME: Is there a better solution?
97  if (MI->getOpcode() == TargetOpcode::COPY_TO_REGCLASS)
98    return;
99
100  printInstruction(MI, O);
101  printAnnotation(O, Annot);
102}
103
104
105void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
106                                           raw_ostream &O,
107                                           const char *Modifier) {
108  unsigned Code = MI->getOperand(OpNo).getImm();
109
110  if (StringRef(Modifier) == "cc") {
111    switch ((PPC::Predicate)Code) {
112    case PPC::PRED_LT_MINUS:
113    case PPC::PRED_LT_PLUS:
114    case PPC::PRED_LT:
115      O << "lt";
116      return;
117    case PPC::PRED_LE_MINUS:
118    case PPC::PRED_LE_PLUS:
119    case PPC::PRED_LE:
120      O << "le";
121      return;
122    case PPC::PRED_EQ_MINUS:
123    case PPC::PRED_EQ_PLUS:
124    case PPC::PRED_EQ:
125      O << "eq";
126      return;
127    case PPC::PRED_GE_MINUS:
128    case PPC::PRED_GE_PLUS:
129    case PPC::PRED_GE:
130      O << "ge";
131      return;
132    case PPC::PRED_GT_MINUS:
133    case PPC::PRED_GT_PLUS:
134    case PPC::PRED_GT:
135      O << "gt";
136      return;
137    case PPC::PRED_NE_MINUS:
138    case PPC::PRED_NE_PLUS:
139    case PPC::PRED_NE:
140      O << "ne";
141      return;
142    case PPC::PRED_UN_MINUS:
143    case PPC::PRED_UN_PLUS:
144    case PPC::PRED_UN:
145      O << "un";
146      return;
147    case PPC::PRED_NU_MINUS:
148    case PPC::PRED_NU_PLUS:
149    case PPC::PRED_NU:
150      O << "nu";
151      return;
152    }
153    llvm_unreachable("Invalid predicate code");
154  }
155
156  if (StringRef(Modifier) == "pm") {
157    switch ((PPC::Predicate)Code) {
158    case PPC::PRED_LT:
159    case PPC::PRED_LE:
160    case PPC::PRED_EQ:
161    case PPC::PRED_GE:
162    case PPC::PRED_GT:
163    case PPC::PRED_NE:
164    case PPC::PRED_UN:
165    case PPC::PRED_NU:
166      return;
167    case PPC::PRED_LT_MINUS:
168    case PPC::PRED_LE_MINUS:
169    case PPC::PRED_EQ_MINUS:
170    case PPC::PRED_GE_MINUS:
171    case PPC::PRED_GT_MINUS:
172    case PPC::PRED_NE_MINUS:
173    case PPC::PRED_UN_MINUS:
174    case PPC::PRED_NU_MINUS:
175      O << "-";
176      return;
177    case PPC::PRED_LT_PLUS:
178    case PPC::PRED_LE_PLUS:
179    case PPC::PRED_EQ_PLUS:
180    case PPC::PRED_GE_PLUS:
181    case PPC::PRED_GT_PLUS:
182    case PPC::PRED_NE_PLUS:
183    case PPC::PRED_UN_PLUS:
184    case PPC::PRED_NU_PLUS:
185      O << "+";
186      return;
187    }
188    llvm_unreachable("Invalid predicate code");
189  }
190
191  assert(StringRef(Modifier) == "reg" &&
192         "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
193  printOperand(MI, OpNo+1, O);
194}
195
196void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
197                                       raw_ostream &O) {
198  int Value = MI->getOperand(OpNo).getImm();
199  Value = SignExtend32<5>(Value);
200  O << (int)Value;
201}
202
203void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
204                                       raw_ostream &O) {
205  unsigned int Value = MI->getOperand(OpNo).getImm();
206  assert(Value <= 31 && "Invalid u5imm argument!");
207  O << (unsigned int)Value;
208}
209
210void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
211                                       raw_ostream &O) {
212  unsigned int Value = MI->getOperand(OpNo).getImm();
213  assert(Value <= 63 && "Invalid u6imm argument!");
214  O << (unsigned int)Value;
215}
216
217void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
218                                        raw_ostream &O) {
219  if (MI->getOperand(OpNo).isImm())
220    O << (short)MI->getOperand(OpNo).getImm();
221  else
222    printOperand(MI, OpNo, O);
223}
224
225void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
226                                        raw_ostream &O) {
227  if (MI->getOperand(OpNo).isImm())
228    O << (unsigned short)MI->getOperand(OpNo).getImm();
229  else
230    printOperand(MI, OpNo, O);
231}
232
233void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
234                                        raw_ostream &O) {
235  if (!MI->getOperand(OpNo).isImm())
236    return printOperand(MI, OpNo, O);
237
238  // Branches can take an immediate operand.  This is used by the branch
239  // selection pass to print .+8, an eight byte displacement from the PC.
240  O << ".+";
241  printAbsBranchOperand(MI, OpNo, O);
242}
243
244void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
245                                           raw_ostream &O) {
246  if (!MI->getOperand(OpNo).isImm())
247    return printOperand(MI, OpNo, O);
248
249  O << (int)MI->getOperand(OpNo).getImm()*4;
250}
251
252
253void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
254                                 raw_ostream &O) {
255  unsigned CCReg = MI->getOperand(OpNo).getReg();
256  unsigned RegNo;
257  switch (CCReg) {
258  default: llvm_unreachable("Unknown CR register");
259  case PPC::CR0: RegNo = 0; break;
260  case PPC::CR1: RegNo = 1; break;
261  case PPC::CR2: RegNo = 2; break;
262  case PPC::CR3: RegNo = 3; break;
263  case PPC::CR4: RegNo = 4; break;
264  case PPC::CR5: RegNo = 5; break;
265  case PPC::CR6: RegNo = 6; break;
266  case PPC::CR7: RegNo = 7; break;
267  }
268  O << (0x80 >> RegNo);
269}
270
271void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
272                                    raw_ostream &O) {
273  printS16ImmOperand(MI, OpNo, O);
274  O << '(';
275  if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
276    O << "0";
277  else
278    printOperand(MI, OpNo+1, O);
279  O << ')';
280}
281
282void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
283                                    raw_ostream &O) {
284  // When used as the base register, r0 reads constant zero rather than
285  // the value contained in the register.  For this reason, the darwin
286  // assembler requires that we print r0 as 0 (no r) when used as the base.
287  if (MI->getOperand(OpNo).getReg() == PPC::R0)
288    O << "0";
289  else
290    printOperand(MI, OpNo, O);
291  O << ", ";
292  printOperand(MI, OpNo+1, O);
293}
294
295void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
296                                  raw_ostream &O) {
297  printBranchOperand(MI, OpNo, O);
298  O << '(';
299  printOperand(MI, OpNo+1, O);
300  O << ')';
301}
302
303
304/// stripRegisterPrefix - This method strips the character prefix from a
305/// register name so that only the number is left.  Used by for linux asm.
306static const char *stripRegisterPrefix(const char *RegName) {
307  if (FullRegNames)
308    return RegName;
309
310  switch (RegName[0]) {
311  case 'r':
312  case 'f':
313  case 'v': return RegName + 1;
314  case 'c': if (RegName[1] == 'r') return RegName + 2;
315  }
316
317  return RegName;
318}
319
320void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
321                                  raw_ostream &O) {
322  const MCOperand &Op = MI->getOperand(OpNo);
323  if (Op.isReg()) {
324    const char *RegName = getRegisterName(Op.getReg());
325    // The linux and AIX assembler does not take register prefixes.
326    if (!isDarwinSyntax())
327      RegName = stripRegisterPrefix(RegName);
328
329    O << RegName;
330    return;
331  }
332
333  if (Op.isImm()) {
334    O << Op.getImm();
335    return;
336  }
337
338  assert(Op.isExpr() && "unknown operand kind in printOperand");
339  O << *Op.getExpr();
340}
341
342