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