PPCInstPrinter.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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    case PPC::PRED_BIT_SET:
153    case PPC::PRED_BIT_UNSET:
154      llvm_unreachable("Invalid use of bit predicate code");
155    }
156    llvm_unreachable("Invalid predicate code");
157  }
158
159  if (StringRef(Modifier) == "pm") {
160    switch ((PPC::Predicate)Code) {
161    case PPC::PRED_LT:
162    case PPC::PRED_LE:
163    case PPC::PRED_EQ:
164    case PPC::PRED_GE:
165    case PPC::PRED_GT:
166    case PPC::PRED_NE:
167    case PPC::PRED_UN:
168    case PPC::PRED_NU:
169      return;
170    case PPC::PRED_LT_MINUS:
171    case PPC::PRED_LE_MINUS:
172    case PPC::PRED_EQ_MINUS:
173    case PPC::PRED_GE_MINUS:
174    case PPC::PRED_GT_MINUS:
175    case PPC::PRED_NE_MINUS:
176    case PPC::PRED_UN_MINUS:
177    case PPC::PRED_NU_MINUS:
178      O << "-";
179      return;
180    case PPC::PRED_LT_PLUS:
181    case PPC::PRED_LE_PLUS:
182    case PPC::PRED_EQ_PLUS:
183    case PPC::PRED_GE_PLUS:
184    case PPC::PRED_GT_PLUS:
185    case PPC::PRED_NE_PLUS:
186    case PPC::PRED_UN_PLUS:
187    case PPC::PRED_NU_PLUS:
188      O << "+";
189      return;
190    case PPC::PRED_BIT_SET:
191    case PPC::PRED_BIT_UNSET:
192      llvm_unreachable("Invalid use of bit predicate code");
193    }
194    llvm_unreachable("Invalid predicate code");
195  }
196
197  assert(StringRef(Modifier) == "reg" &&
198         "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
199  printOperand(MI, OpNo+1, O);
200}
201
202void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
203                                       raw_ostream &O) {
204  unsigned int Value = MI->getOperand(OpNo).getImm();
205  assert(Value <= 3 && "Invalid u2imm argument!");
206  O << (unsigned int)Value;
207}
208
209void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
210                                       raw_ostream &O) {
211  int Value = MI->getOperand(OpNo).getImm();
212  Value = SignExtend32<5>(Value);
213  O << (int)Value;
214}
215
216void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
217                                       raw_ostream &O) {
218  unsigned int Value = MI->getOperand(OpNo).getImm();
219  assert(Value <= 31 && "Invalid u5imm argument!");
220  O << (unsigned int)Value;
221}
222
223void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
224                                       raw_ostream &O) {
225  unsigned int Value = MI->getOperand(OpNo).getImm();
226  assert(Value <= 63 && "Invalid u6imm argument!");
227  O << (unsigned int)Value;
228}
229
230void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
231                                        raw_ostream &O) {
232  if (MI->getOperand(OpNo).isImm())
233    O << (short)MI->getOperand(OpNo).getImm();
234  else
235    printOperand(MI, OpNo, O);
236}
237
238void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
239                                        raw_ostream &O) {
240  if (MI->getOperand(OpNo).isImm())
241    O << (unsigned short)MI->getOperand(OpNo).getImm();
242  else
243    printOperand(MI, OpNo, O);
244}
245
246void PPCInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
247                                        raw_ostream &O) {
248  if (!MI->getOperand(OpNo).isImm())
249    return printOperand(MI, OpNo, O);
250
251  // Branches can take an immediate operand.  This is used by the branch
252  // selection pass to print .+8, an eight byte displacement from the PC.
253  O << ".+";
254  printAbsBranchOperand(MI, OpNo, O);
255}
256
257void PPCInstPrinter::printAbsBranchOperand(const MCInst *MI, unsigned OpNo,
258                                           raw_ostream &O) {
259  if (!MI->getOperand(OpNo).isImm())
260    return printOperand(MI, OpNo, O);
261
262  O << (int)MI->getOperand(OpNo).getImm()*4;
263}
264
265
266void PPCInstPrinter::printcrbitm(const MCInst *MI, unsigned OpNo,
267                                 raw_ostream &O) {
268  unsigned CCReg = MI->getOperand(OpNo).getReg();
269  unsigned RegNo;
270  switch (CCReg) {
271  default: llvm_unreachable("Unknown CR register");
272  case PPC::CR0: RegNo = 0; break;
273  case PPC::CR1: RegNo = 1; break;
274  case PPC::CR2: RegNo = 2; break;
275  case PPC::CR3: RegNo = 3; break;
276  case PPC::CR4: RegNo = 4; break;
277  case PPC::CR5: RegNo = 5; break;
278  case PPC::CR6: RegNo = 6; break;
279  case PPC::CR7: RegNo = 7; break;
280  }
281  O << (0x80 >> RegNo);
282}
283
284void PPCInstPrinter::printMemRegImm(const MCInst *MI, unsigned OpNo,
285                                    raw_ostream &O) {
286  printS16ImmOperand(MI, OpNo, O);
287  O << '(';
288  if (MI->getOperand(OpNo+1).getReg() == PPC::R0)
289    O << "0";
290  else
291    printOperand(MI, OpNo+1, O);
292  O << ')';
293}
294
295void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
296                                    raw_ostream &O) {
297  // When used as the base register, r0 reads constant zero rather than
298  // the value contained in the register.  For this reason, the darwin
299  // assembler requires that we print r0 as 0 (no r) when used as the base.
300  if (MI->getOperand(OpNo).getReg() == PPC::R0)
301    O << "0";
302  else
303    printOperand(MI, OpNo, O);
304  O << ", ";
305  printOperand(MI, OpNo+1, O);
306}
307
308void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
309                                  raw_ostream &O) {
310  printBranchOperand(MI, OpNo, O);
311  O << '(';
312  printOperand(MI, OpNo+1, O);
313  O << ')';
314}
315
316
317/// stripRegisterPrefix - This method strips the character prefix from a
318/// register name so that only the number is left.  Used by for linux asm.
319static const char *stripRegisterPrefix(const char *RegName) {
320  if (FullRegNames)
321    return RegName;
322
323  switch (RegName[0]) {
324  case 'r':
325  case 'f':
326  case 'v':
327    if (RegName[1] == 's')
328      return RegName + 2;
329    return RegName + 1;
330  case 'c': if (RegName[1] == 'r') return RegName + 2;
331  }
332
333  return RegName;
334}
335
336void PPCInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
337                                  raw_ostream &O) {
338  const MCOperand &Op = MI->getOperand(OpNo);
339  if (Op.isReg()) {
340    const char *RegName = getRegisterName(Op.getReg());
341    // The linux and AIX assembler does not take register prefixes.
342    if (!isDarwinSyntax())
343      RegName = stripRegisterPrefix(RegName);
344
345    O << RegName;
346    return;
347  }
348
349  if (Op.isImm()) {
350    O << Op.getImm();
351    return;
352  }
353
354  assert(Op.isExpr() && "unknown operand kind in printOperand");
355  O << *Op.getExpr();
356}
357
358