1*9880d681SAndroid Build Coastguard Worker //===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Print MCInst instructions to .ptx format.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/NVPTXInstPrinter.h"
15*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/NVPTXBaseInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "NVPTX.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FormattedStream.h"
24*9880d681SAndroid Build Coastguard Worker #include <cctype>
25*9880d681SAndroid Build Coastguard Worker using namespace llvm;
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "asm-printer"
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker #include "NVPTXGenAsmWriter.inc"
30*9880d681SAndroid Build Coastguard Worker
NVPTXInstPrinter(const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)31*9880d681SAndroid Build Coastguard Worker NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
32*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo &MRI)
33*9880d681SAndroid Build Coastguard Worker : MCInstPrinter(MAI, MII, MRI) {}
34*9880d681SAndroid Build Coastguard Worker
printRegName(raw_ostream & OS,unsigned RegNo) const35*9880d681SAndroid Build Coastguard Worker void NVPTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
36*9880d681SAndroid Build Coastguard Worker // Decode the virtual register
37*9880d681SAndroid Build Coastguard Worker // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
38*9880d681SAndroid Build Coastguard Worker unsigned RCId = (RegNo >> 28);
39*9880d681SAndroid Build Coastguard Worker switch (RCId) {
40*9880d681SAndroid Build Coastguard Worker default: report_fatal_error("Bad virtual register encoding");
41*9880d681SAndroid Build Coastguard Worker case 0:
42*9880d681SAndroid Build Coastguard Worker // This is actually a physical register, so defer to the autogenerated
43*9880d681SAndroid Build Coastguard Worker // register printer
44*9880d681SAndroid Build Coastguard Worker OS << getRegisterName(RegNo);
45*9880d681SAndroid Build Coastguard Worker return;
46*9880d681SAndroid Build Coastguard Worker case 1:
47*9880d681SAndroid Build Coastguard Worker OS << "%p";
48*9880d681SAndroid Build Coastguard Worker break;
49*9880d681SAndroid Build Coastguard Worker case 2:
50*9880d681SAndroid Build Coastguard Worker OS << "%rs";
51*9880d681SAndroid Build Coastguard Worker break;
52*9880d681SAndroid Build Coastguard Worker case 3:
53*9880d681SAndroid Build Coastguard Worker OS << "%r";
54*9880d681SAndroid Build Coastguard Worker break;
55*9880d681SAndroid Build Coastguard Worker case 4:
56*9880d681SAndroid Build Coastguard Worker OS << "%rd";
57*9880d681SAndroid Build Coastguard Worker break;
58*9880d681SAndroid Build Coastguard Worker case 5:
59*9880d681SAndroid Build Coastguard Worker OS << "%f";
60*9880d681SAndroid Build Coastguard Worker break;
61*9880d681SAndroid Build Coastguard Worker case 6:
62*9880d681SAndroid Build Coastguard Worker OS << "%fd";
63*9880d681SAndroid Build Coastguard Worker break;
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker unsigned VReg = RegNo & 0x0FFFFFFF;
67*9880d681SAndroid Build Coastguard Worker OS << VReg;
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker
printInst(const MCInst * MI,raw_ostream & OS,StringRef Annot,const MCSubtargetInfo & STI)70*9880d681SAndroid Build Coastguard Worker void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
71*9880d681SAndroid Build Coastguard Worker StringRef Annot, const MCSubtargetInfo &STI) {
72*9880d681SAndroid Build Coastguard Worker printInstruction(MI, OS);
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker // Next always print the annotation.
75*9880d681SAndroid Build Coastguard Worker printAnnotation(OS, Annot);
76*9880d681SAndroid Build Coastguard Worker }
77*9880d681SAndroid Build Coastguard Worker
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)78*9880d681SAndroid Build Coastguard Worker void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
79*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
80*9880d681SAndroid Build Coastguard Worker const MCOperand &Op = MI->getOperand(OpNo);
81*9880d681SAndroid Build Coastguard Worker if (Op.isReg()) {
82*9880d681SAndroid Build Coastguard Worker unsigned Reg = Op.getReg();
83*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg);
84*9880d681SAndroid Build Coastguard Worker } else if (Op.isImm()) {
85*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
86*9880d681SAndroid Build Coastguard Worker } else {
87*9880d681SAndroid Build Coastguard Worker assert(Op.isExpr() && "Unknown operand kind in printOperand");
88*9880d681SAndroid Build Coastguard Worker Op.getExpr()->print(O, &MAI);
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker
printCvtMode(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)92*9880d681SAndroid Build Coastguard Worker void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,
93*9880d681SAndroid Build Coastguard Worker const char *Modifier) {
94*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
95*9880d681SAndroid Build Coastguard Worker int64_t Imm = MO.getImm();
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker if (strcmp(Modifier, "ftz") == 0) {
98*9880d681SAndroid Build Coastguard Worker // FTZ flag
99*9880d681SAndroid Build Coastguard Worker if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
100*9880d681SAndroid Build Coastguard Worker O << ".ftz";
101*9880d681SAndroid Build Coastguard Worker } else if (strcmp(Modifier, "sat") == 0) {
102*9880d681SAndroid Build Coastguard Worker // SAT flag
103*9880d681SAndroid Build Coastguard Worker if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
104*9880d681SAndroid Build Coastguard Worker O << ".sat";
105*9880d681SAndroid Build Coastguard Worker } else if (strcmp(Modifier, "base") == 0) {
106*9880d681SAndroid Build Coastguard Worker // Default operand
107*9880d681SAndroid Build Coastguard Worker switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
108*9880d681SAndroid Build Coastguard Worker default:
109*9880d681SAndroid Build Coastguard Worker return;
110*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::NONE:
111*9880d681SAndroid Build Coastguard Worker break;
112*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::RNI:
113*9880d681SAndroid Build Coastguard Worker O << ".rni";
114*9880d681SAndroid Build Coastguard Worker break;
115*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::RZI:
116*9880d681SAndroid Build Coastguard Worker O << ".rzi";
117*9880d681SAndroid Build Coastguard Worker break;
118*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::RMI:
119*9880d681SAndroid Build Coastguard Worker O << ".rmi";
120*9880d681SAndroid Build Coastguard Worker break;
121*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::RPI:
122*9880d681SAndroid Build Coastguard Worker O << ".rpi";
123*9880d681SAndroid Build Coastguard Worker break;
124*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::RN:
125*9880d681SAndroid Build Coastguard Worker O << ".rn";
126*9880d681SAndroid Build Coastguard Worker break;
127*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::RZ:
128*9880d681SAndroid Build Coastguard Worker O << ".rz";
129*9880d681SAndroid Build Coastguard Worker break;
130*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::RM:
131*9880d681SAndroid Build Coastguard Worker O << ".rm";
132*9880d681SAndroid Build Coastguard Worker break;
133*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCvtMode::RP:
134*9880d681SAndroid Build Coastguard Worker O << ".rp";
135*9880d681SAndroid Build Coastguard Worker break;
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker } else {
138*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid conversion modifier");
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker
printCmpMode(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)142*9880d681SAndroid Build Coastguard Worker void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
143*9880d681SAndroid Build Coastguard Worker const char *Modifier) {
144*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
145*9880d681SAndroid Build Coastguard Worker int64_t Imm = MO.getImm();
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker if (strcmp(Modifier, "ftz") == 0) {
148*9880d681SAndroid Build Coastguard Worker // FTZ flag
149*9880d681SAndroid Build Coastguard Worker if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
150*9880d681SAndroid Build Coastguard Worker O << ".ftz";
151*9880d681SAndroid Build Coastguard Worker } else if (strcmp(Modifier, "base") == 0) {
152*9880d681SAndroid Build Coastguard Worker switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
153*9880d681SAndroid Build Coastguard Worker default:
154*9880d681SAndroid Build Coastguard Worker return;
155*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::EQ:
156*9880d681SAndroid Build Coastguard Worker O << ".eq";
157*9880d681SAndroid Build Coastguard Worker break;
158*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::NE:
159*9880d681SAndroid Build Coastguard Worker O << ".ne";
160*9880d681SAndroid Build Coastguard Worker break;
161*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::LT:
162*9880d681SAndroid Build Coastguard Worker O << ".lt";
163*9880d681SAndroid Build Coastguard Worker break;
164*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::LE:
165*9880d681SAndroid Build Coastguard Worker O << ".le";
166*9880d681SAndroid Build Coastguard Worker break;
167*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::GT:
168*9880d681SAndroid Build Coastguard Worker O << ".gt";
169*9880d681SAndroid Build Coastguard Worker break;
170*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::GE:
171*9880d681SAndroid Build Coastguard Worker O << ".ge";
172*9880d681SAndroid Build Coastguard Worker break;
173*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::LO:
174*9880d681SAndroid Build Coastguard Worker O << ".lo";
175*9880d681SAndroid Build Coastguard Worker break;
176*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::LS:
177*9880d681SAndroid Build Coastguard Worker O << ".ls";
178*9880d681SAndroid Build Coastguard Worker break;
179*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::HI:
180*9880d681SAndroid Build Coastguard Worker O << ".hi";
181*9880d681SAndroid Build Coastguard Worker break;
182*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::HS:
183*9880d681SAndroid Build Coastguard Worker O << ".hs";
184*9880d681SAndroid Build Coastguard Worker break;
185*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::EQU:
186*9880d681SAndroid Build Coastguard Worker O << ".equ";
187*9880d681SAndroid Build Coastguard Worker break;
188*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::NEU:
189*9880d681SAndroid Build Coastguard Worker O << ".neu";
190*9880d681SAndroid Build Coastguard Worker break;
191*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::LTU:
192*9880d681SAndroid Build Coastguard Worker O << ".ltu";
193*9880d681SAndroid Build Coastguard Worker break;
194*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::LEU:
195*9880d681SAndroid Build Coastguard Worker O << ".leu";
196*9880d681SAndroid Build Coastguard Worker break;
197*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::GTU:
198*9880d681SAndroid Build Coastguard Worker O << ".gtu";
199*9880d681SAndroid Build Coastguard Worker break;
200*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::GEU:
201*9880d681SAndroid Build Coastguard Worker O << ".geu";
202*9880d681SAndroid Build Coastguard Worker break;
203*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::NUM:
204*9880d681SAndroid Build Coastguard Worker O << ".num";
205*9880d681SAndroid Build Coastguard Worker break;
206*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXCmpMode::NotANumber:
207*9880d681SAndroid Build Coastguard Worker O << ".nan";
208*9880d681SAndroid Build Coastguard Worker break;
209*9880d681SAndroid Build Coastguard Worker }
210*9880d681SAndroid Build Coastguard Worker } else {
211*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Empty Modifier");
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker
printLdStCode(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)215*9880d681SAndroid Build Coastguard Worker void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
216*9880d681SAndroid Build Coastguard Worker raw_ostream &O, const char *Modifier) {
217*9880d681SAndroid Build Coastguard Worker if (Modifier) {
218*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
219*9880d681SAndroid Build Coastguard Worker int Imm = (int) MO.getImm();
220*9880d681SAndroid Build Coastguard Worker if (!strcmp(Modifier, "volatile")) {
221*9880d681SAndroid Build Coastguard Worker if (Imm)
222*9880d681SAndroid Build Coastguard Worker O << ".volatile";
223*9880d681SAndroid Build Coastguard Worker } else if (!strcmp(Modifier, "addsp")) {
224*9880d681SAndroid Build Coastguard Worker switch (Imm) {
225*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXLdStInstCode::GLOBAL:
226*9880d681SAndroid Build Coastguard Worker O << ".global";
227*9880d681SAndroid Build Coastguard Worker break;
228*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXLdStInstCode::SHARED:
229*9880d681SAndroid Build Coastguard Worker O << ".shared";
230*9880d681SAndroid Build Coastguard Worker break;
231*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXLdStInstCode::LOCAL:
232*9880d681SAndroid Build Coastguard Worker O << ".local";
233*9880d681SAndroid Build Coastguard Worker break;
234*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXLdStInstCode::PARAM:
235*9880d681SAndroid Build Coastguard Worker O << ".param";
236*9880d681SAndroid Build Coastguard Worker break;
237*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXLdStInstCode::CONSTANT:
238*9880d681SAndroid Build Coastguard Worker O << ".const";
239*9880d681SAndroid Build Coastguard Worker break;
240*9880d681SAndroid Build Coastguard Worker case NVPTX::PTXLdStInstCode::GENERIC:
241*9880d681SAndroid Build Coastguard Worker break;
242*9880d681SAndroid Build Coastguard Worker default:
243*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Wrong Address Space");
244*9880d681SAndroid Build Coastguard Worker }
245*9880d681SAndroid Build Coastguard Worker } else if (!strcmp(Modifier, "sign")) {
246*9880d681SAndroid Build Coastguard Worker if (Imm == NVPTX::PTXLdStInstCode::Signed)
247*9880d681SAndroid Build Coastguard Worker O << "s";
248*9880d681SAndroid Build Coastguard Worker else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
249*9880d681SAndroid Build Coastguard Worker O << "u";
250*9880d681SAndroid Build Coastguard Worker else
251*9880d681SAndroid Build Coastguard Worker O << "f";
252*9880d681SAndroid Build Coastguard Worker } else if (!strcmp(Modifier, "vec")) {
253*9880d681SAndroid Build Coastguard Worker if (Imm == NVPTX::PTXLdStInstCode::V2)
254*9880d681SAndroid Build Coastguard Worker O << ".v2";
255*9880d681SAndroid Build Coastguard Worker else if (Imm == NVPTX::PTXLdStInstCode::V4)
256*9880d681SAndroid Build Coastguard Worker O << ".v4";
257*9880d681SAndroid Build Coastguard Worker } else
258*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown Modifier");
259*9880d681SAndroid Build Coastguard Worker } else
260*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Empty Modifier");
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker
printMemOperand(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)263*9880d681SAndroid Build Coastguard Worker void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
264*9880d681SAndroid Build Coastguard Worker raw_ostream &O, const char *Modifier) {
265*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNum, O);
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker if (Modifier && !strcmp(Modifier, "add")) {
268*9880d681SAndroid Build Coastguard Worker O << ", ";
269*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNum + 1, O);
270*9880d681SAndroid Build Coastguard Worker } else {
271*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(OpNum + 1).isImm() &&
272*9880d681SAndroid Build Coastguard Worker MI->getOperand(OpNum + 1).getImm() == 0)
273*9880d681SAndroid Build Coastguard Worker return; // don't print ',0' or '+0'
274*9880d681SAndroid Build Coastguard Worker O << "+";
275*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNum + 1, O);
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker }
278*9880d681SAndroid Build Coastguard Worker
printProtoIdent(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)279*9880d681SAndroid Build Coastguard Worker void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum,
280*9880d681SAndroid Build Coastguard Worker raw_ostream &O, const char *Modifier) {
281*9880d681SAndroid Build Coastguard Worker const MCOperand &Op = MI->getOperand(OpNum);
282*9880d681SAndroid Build Coastguard Worker assert(Op.isExpr() && "Call prototype is not an MCExpr?");
283*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr = Op.getExpr();
284*9880d681SAndroid Build Coastguard Worker const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
285*9880d681SAndroid Build Coastguard Worker O << Sym.getName();
286*9880d681SAndroid Build Coastguard Worker }
287