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/ADT/StringExtras.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
24 using namespace llvm;
25
26 #define GET_INSTRUCTION_NAME
27 #include "PTXGenAsmWriter.inc"
28
PTXInstPrinter(const MCAsmInfo & MAI,const MCSubtargetInfo & STI)29 PTXInstPrinter::PTXInstPrinter(const MCAsmInfo &MAI,
30 const MCSubtargetInfo &STI) :
31 MCInstPrinter(MAI) {
32 // Initialize the set of available features.
33 setAvailableFeatures(STI.getFeatureBits());
34 }
35
getOpcodeName(unsigned Opcode) const36 StringRef PTXInstPrinter::getOpcodeName(unsigned Opcode) const {
37 return getInstructionName(Opcode);
38 }
39
printRegName(raw_ostream & OS,unsigned RegNo) const40 void PTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
41 OS << getRegisterName(RegNo);
42 }
43
printInst(const MCInst * MI,raw_ostream & O,StringRef Annot)44 void PTXInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
45 StringRef Annot) {
46 printPredicate(MI, O);
47 switch (MI->getOpcode()) {
48 default:
49 printInstruction(MI, O);
50 break;
51 case PTX::CALL:
52 printCall(MI, O);
53 }
54 O << ";";
55 printAnnotation(O, Annot);
56 }
57
printPredicate(const MCInst * MI,raw_ostream & O)58 void PTXInstPrinter::printPredicate(const MCInst *MI, raw_ostream &O) {
59 // The last two operands are the predicate operands
60 int RegIndex;
61 int OpIndex;
62
63 if (MI->getOpcode() == PTX::CALL) {
64 RegIndex = 0;
65 OpIndex = 1;
66 } else {
67 RegIndex = MI->getNumOperands()-2;
68 OpIndex = MI->getNumOperands()-1;
69 }
70
71 int PredOp = MI->getOperand(OpIndex).getImm();
72 if (PredOp == PTXPredicate::None)
73 return;
74
75 if (PredOp == PTXPredicate::Negate)
76 O << '!';
77 else
78 O << '@';
79
80 printOperand(MI, RegIndex, O);
81 }
82
printCall(const MCInst * MI,raw_ostream & O)83 void PTXInstPrinter::printCall(const MCInst *MI, raw_ostream &O) {
84 O << "\tcall.uni\t";
85 // The first two operands are the predicate slot
86 unsigned Index = 2;
87 unsigned NumRets = MI->getOperand(Index++).getImm();
88
89 if (NumRets > 0) {
90 O << "(";
91 printOperand(MI, Index++, O);
92 for (unsigned i = 1; i < NumRets; ++i) {
93 O << ", ";
94 printOperand(MI, Index++, O);
95 }
96 O << "), ";
97 }
98
99 O << *(MI->getOperand(Index++).getExpr()) << ", (";
100
101 unsigned NumArgs = MI->getOperand(Index++).getImm();
102 if (NumArgs > 0) {
103 printOperand(MI, Index++, O);
104 for (unsigned i = 1; i < NumArgs; ++i) {
105 O << ", ";
106 printOperand(MI, Index++, O);
107 }
108 }
109 O << ")";
110 }
111
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)112 void PTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
113 raw_ostream &O) {
114 const MCOperand &Op = MI->getOperand(OpNo);
115 if (Op.isImm()) {
116 O << Op.getImm();
117 } else if (Op.isFPImm()) {
118 double Imm = Op.getFPImm();
119 APFloat FPImm(Imm);
120 APInt FPIntImm = FPImm.bitcastToAPInt();
121 O << "0D";
122 // PTX requires us to output the full 64 bits, even if the number is zero
123 if (FPIntImm.getZExtValue() > 0) {
124 O << FPIntImm.toString(16, false);
125 } else {
126 O << "0000000000000000";
127 }
128 } else {
129 assert(Op.isExpr() && "unknown operand kind in printOperand");
130 const MCExpr *Expr = Op.getExpr();
131 if (const MCSymbolRefExpr *SymRefExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
132 const MCSymbol &Sym = SymRefExpr->getSymbol();
133 O << Sym.getName();
134 } else {
135 O << *Op.getExpr();
136 }
137 }
138 }
139
printMemOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)140 void PTXInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
141 raw_ostream &O) {
142 // By definition, operand OpNo+1 is an i32imm
143 const MCOperand &Op2 = MI->getOperand(OpNo+1);
144 printOperand(MI, OpNo, O);
145 if (Op2.getImm() == 0)
146 return; // don't print "+0"
147 O << "+" << Op2.getImm();
148 }
149
printRoundingMode(const MCInst * MI,unsigned OpNo,raw_ostream & O)150 void PTXInstPrinter::printRoundingMode(const MCInst *MI, unsigned OpNo,
151 raw_ostream &O) {
152 const MCOperand &Op = MI->getOperand(OpNo);
153 assert (Op.isImm() && "Rounding modes must be immediate values");
154 switch (Op.getImm()) {
155 default:
156 llvm_unreachable("Unknown rounding mode!");
157 case PTXRoundingMode::RndDefault:
158 llvm_unreachable("FP rounding-mode pass did not handle instruction!");
159 break;
160 case PTXRoundingMode::RndNone:
161 // Do not print anything.
162 break;
163 case PTXRoundingMode::RndNearestEven:
164 O << ".rn";
165 break;
166 case PTXRoundingMode::RndTowardsZero:
167 O << ".rz";
168 break;
169 case PTXRoundingMode::RndNegInf:
170 O << ".rm";
171 break;
172 case PTXRoundingMode::RndPosInf:
173 O << ".rp";
174 break;
175 case PTXRoundingMode::RndApprox:
176 O << ".approx";
177 break;
178 case PTXRoundingMode::RndNearestEvenInt:
179 O << ".rni";
180 break;
181 case PTXRoundingMode::RndTowardsZeroInt:
182 O << ".rzi";
183 break;
184 case PTXRoundingMode::RndNegInfInt:
185 O << ".rmi";
186 break;
187 case PTXRoundingMode::RndPosInfInt:
188 O << ".rpi";
189 break;
190 }
191 }
192
193