Remove getInstructionName from MCInstPrinter implementations in favor of using the...
[oota-llvm.git] / lib / Target / PTX / InstPrinter / PTXInstPrinter.cpp
1 //===-- PTXInstPrinter.cpp - Convert PTX 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 a PTX MCInst to a .ptx file.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "asm-printer"
15 #include "PTXInstPrinter.h"
16 #include "MCTargetDesc/PTXBaseInfo.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/ADT/APFloat.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace llvm;
27
28 #include "PTXGenAsmWriter.inc"
29
30 PTXInstPrinter::PTXInstPrinter(const MCAsmInfo &MAI,
31                                const MCInstrInfo &MII,
32                                const MCRegisterInfo &MRI,
33                                const MCSubtargetInfo &STI) :
34   MCInstPrinter(MAI, MII, MRI) {
35   // Initialize the set of available features.
36   setAvailableFeatures(STI.getFeatureBits());
37 }
38
39 StringRef PTXInstPrinter::getOpcodeName(unsigned Opcode) const {
40   return MII.getName(Opcode);
41 }
42
43 void PTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
44   // Decode the register number into type and offset
45   unsigned RegSpace  = RegNo & 0x7;
46   unsigned RegType   = (RegNo >> 3) & 0x7;
47   unsigned RegOffset = RegNo >> 6;
48
49   // Print the register
50   OS << "%";
51
52   switch (RegSpace) {
53   default:
54     llvm_unreachable("Unknown register space!");
55   case PTXRegisterSpace::Reg:
56     switch (RegType) {
57     default:
58       llvm_unreachable("Unknown register type!");
59     case PTXRegisterType::Pred:
60       OS << "p";
61       break;
62     case PTXRegisterType::B16:
63       OS << "rh";
64       break;
65     case PTXRegisterType::B32:
66       OS << "r";
67       break;
68     case PTXRegisterType::B64:
69       OS << "rd";
70       break;
71     case PTXRegisterType::F32:
72       OS << "f";
73       break;
74     case PTXRegisterType::F64:
75       OS << "fd";
76       break;
77     }
78     break;
79   case PTXRegisterSpace::Return:
80     OS << "ret";
81     break;
82   case PTXRegisterSpace::Argument:
83     OS << "arg";
84     break;
85   }
86
87   OS << RegOffset;
88 }
89
90 void PTXInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
91                                StringRef Annot) {
92   printPredicate(MI, O);
93   switch (MI->getOpcode()) {
94   default:
95     printInstruction(MI, O);
96     break;
97   case PTX::CALL:
98     printCall(MI, O);
99   }
100   O << ";";
101   printAnnotation(O, Annot);
102 }
103
104 void PTXInstPrinter::printPredicate(const MCInst *MI, raw_ostream &O) {
105   // The last two operands are the predicate operands
106   int RegIndex;
107   int OpIndex;
108
109   if (MI->getOpcode() == PTX::CALL) {
110     RegIndex = 0;
111     OpIndex  = 1;
112   } else {
113     RegIndex = MI->getNumOperands()-2;
114     OpIndex = MI->getNumOperands()-1;
115   }
116
117   int PredOp = MI->getOperand(OpIndex).getImm();
118   if (PredOp == PTXPredicate::None)
119     return;
120
121   if (PredOp == PTXPredicate::Negate)
122     O << '!';
123   else
124     O << '@';
125
126   printOperand(MI, RegIndex, O);
127 }
128
129 void PTXInstPrinter::printCall(const MCInst *MI, raw_ostream &O) {
130   O << "\tcall.uni\t";
131   // The first two operands are the predicate slot
132   unsigned Index = 2;
133   unsigned NumRets = MI->getOperand(Index++).getImm();
134
135   if (NumRets > 0) {
136     O << "(";
137     printOperand(MI, Index++, O);
138     for (unsigned i = 1; i < NumRets; ++i) {
139       O << ", ";
140       printOperand(MI, Index++, O);
141     }
142     O << "), ";
143   }
144
145   const MCExpr* Expr = MI->getOperand(Index++).getExpr();
146   unsigned NumArgs = MI->getOperand(Index++).getImm();
147   
148   // if the function call is to printf or puts, change to vprintf
149   if (const MCSymbolRefExpr *SymRefExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
150     const MCSymbol &Sym = SymRefExpr->getSymbol();
151     if (Sym.getName() == "printf" || Sym.getName() == "puts") {
152       O << "vprintf";
153     } else {
154       O << Sym.getName();
155     }
156   } else {
157     O << *Expr;
158   }
159   
160   O << ", (";
161
162   if (NumArgs > 0) {
163     printOperand(MI, Index++, O);
164     for (unsigned i = 1; i < NumArgs; ++i) {
165       O << ", ";
166       printOperand(MI, Index++, O);
167     }
168   }
169   O << ")";
170 }
171
172 void PTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
173                                   raw_ostream &O) {
174   const MCOperand &Op = MI->getOperand(OpNo);
175   if (Op.isImm()) {
176     O << Op.getImm();
177   } else if (Op.isFPImm()) {
178     double Imm = Op.getFPImm();
179     APFloat FPImm(Imm);
180     APInt FPIntImm = FPImm.bitcastToAPInt();
181     O << "0D";
182     // PTX requires us to output the full 64 bits, even if the number is zero
183     if (FPIntImm.getZExtValue() > 0) {
184       O << FPIntImm.toString(16, false);
185     } else {
186       O << "0000000000000000";
187     }
188   } else if (Op.isReg()) {
189     printRegName(O, Op.getReg());
190   } else {
191     assert(Op.isExpr() && "unknown operand kind in printOperand");
192     const MCExpr *Expr = Op.getExpr();
193     if (const MCSymbolRefExpr *SymRefExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
194       const MCSymbol &Sym = SymRefExpr->getSymbol();
195       O << Sym.getName();
196     } else {
197       O << *Op.getExpr();
198     }
199   }
200 }
201
202 void PTXInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
203                                      raw_ostream &O) {
204   // By definition, operand OpNo+1 is an i32imm
205   const MCOperand &Op2 = MI->getOperand(OpNo+1);
206   printOperand(MI, OpNo, O);
207   if (Op2.getImm() == 0)
208     return; // don't print "+0"
209   O << "+" << Op2.getImm();
210 }
211
212 void PTXInstPrinter::printRoundingMode(const MCInst *MI, unsigned OpNo,
213                                        raw_ostream &O) {
214   const MCOperand &Op = MI->getOperand(OpNo);
215   assert (Op.isImm() && "Rounding modes must be immediate values");
216   switch (Op.getImm()) {
217   default:
218     llvm_unreachable("Unknown rounding mode!");
219   case PTXRoundingMode::RndDefault:
220     llvm_unreachable("FP rounding-mode pass did not handle instruction!");
221   case PTXRoundingMode::RndNone:
222     // Do not print anything.
223     break;
224   case PTXRoundingMode::RndNearestEven:
225     O << ".rn";
226     break;
227   case PTXRoundingMode::RndTowardsZero:
228     O << ".rz";
229     break;
230   case PTXRoundingMode::RndNegInf:
231     O << ".rm";
232     break;
233   case PTXRoundingMode::RndPosInf:
234     O << ".rp";
235     break;
236   case PTXRoundingMode::RndApprox:
237     O << ".approx";
238     break;
239   case PTXRoundingMode::RndNearestEvenInt:
240     O << ".rni";
241     break;
242   case PTXRoundingMode::RndTowardsZeroInt:
243     O << ".rzi";
244     break;
245   case PTXRoundingMode::RndNegInfInt:
246     O << ".rmi";
247     break;
248   case PTXRoundingMode::RndPosInfInt:
249     O << ".rpi";
250     break;
251   }
252 }
253