1 //===-- PTXInstPrinter.cpp - Convert PTX MCInst to assembly syntax --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This class prints a PTX MCInst to a .ptx file.
12 //===----------------------------------------------------------------------===//
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"
28 #include "PTXGenAsmWriter.inc"
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());
39 StringRef PTXInstPrinter::getOpcodeName(unsigned Opcode) const {
40 return MII.getName(Opcode);
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;
54 llvm_unreachable("Unknown register space!");
55 case PTXRegisterSpace::Reg:
58 llvm_unreachable("Unknown register type!");
59 case PTXRegisterType::Pred:
62 case PTXRegisterType::B16:
65 case PTXRegisterType::B32:
68 case PTXRegisterType::B64:
71 case PTXRegisterType::F32:
74 case PTXRegisterType::F64:
79 case PTXRegisterSpace::Return:
82 case PTXRegisterSpace::Argument:
90 void PTXInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
92 printPredicate(MI, O);
93 switch (MI->getOpcode()) {
95 printInstruction(MI, O);
101 printAnnotation(O, Annot);
104 void PTXInstPrinter::printPredicate(const MCInst *MI, raw_ostream &O) {
105 // The last two operands are the predicate operands
109 if (MI->getOpcode() == PTX::CALL) {
113 RegIndex = MI->getNumOperands()-2;
114 OpIndex = MI->getNumOperands()-1;
117 int PredOp = MI->getOperand(OpIndex).getImm();
118 if (PredOp == PTXPredicate::None)
121 if (PredOp == PTXPredicate::Negate)
126 printOperand(MI, RegIndex, O);
129 void PTXInstPrinter::printCall(const MCInst *MI, raw_ostream &O) {
131 // The first two operands are the predicate slot
133 unsigned NumRets = MI->getOperand(Index++).getImm();
137 printOperand(MI, Index++, O);
138 for (unsigned i = 1; i < NumRets; ++i) {
140 printOperand(MI, Index++, O);
145 const MCExpr* Expr = MI->getOperand(Index++).getExpr();
146 unsigned NumArgs = MI->getOperand(Index++).getImm();
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") {
163 printOperand(MI, Index++, O);
164 for (unsigned i = 1; i < NumArgs; ++i) {
166 printOperand(MI, Index++, O);
172 void PTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
174 const MCOperand &Op = MI->getOperand(OpNo);
177 } else if (Op.isFPImm()) {
178 double Imm = Op.getFPImm();
180 APInt FPIntImm = FPImm.bitcastToAPInt();
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);
186 O << "0000000000000000";
188 } else if (Op.isReg()) {
189 printRegName(O, Op.getReg());
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();
202 void PTXInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
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();
212 void PTXInstPrinter::printRoundingMode(const MCInst *MI, unsigned OpNo,
214 const MCOperand &Op = MI->getOperand(OpNo);
215 assert (Op.isImm() && "Rounding modes must be immediate values");
216 switch (Op.getImm()) {
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.
224 case PTXRoundingMode::RndNearestEven:
227 case PTXRoundingMode::RndTowardsZero:
230 case PTXRoundingMode::RndNegInf:
233 case PTXRoundingMode::RndPosInf:
236 case PTXRoundingMode::RndApprox:
239 case PTXRoundingMode::RndNearestEvenInt:
242 case PTXRoundingMode::RndTowardsZeroInt:
245 case PTXRoundingMode::RndNegInfInt:
248 case PTXRoundingMode::RndPosInfInt: