]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Target/NVPTX/InstPrinter/NVPTXInstPrinter.cpp
1 //===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
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 // Print MCInst instructions to .ptx format.
12 //===----------------------------------------------------------------------===//
14 #include "InstPrinter/NVPTXInstPrinter.h"
15 #include "MCTargetDesc/NVPTXBaseInfo.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/FormattedStream.h"
27 #define DEBUG_TYPE "asm-printer"
29 #include "NVPTXGenAsmWriter.inc"
32 NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo
&MAI
, const MCInstrInfo
&MII
,
33 const MCRegisterInfo
&MRI
,
34 const MCSubtargetInfo
&STI
)
35 : MCInstPrinter(MAI
, MII
, MRI
) {
36 setAvailableFeatures(STI
.getFeatureBits());
39 void NVPTXInstPrinter::printRegName(raw_ostream
&OS
, unsigned RegNo
) const {
40 // Decode the virtual register
41 // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
42 unsigned RCId
= (RegNo
>> 28);
44 default: report_fatal_error("Bad virtual register encoding");
46 // This is actually a physical register, so defer to the autogenerated
48 OS
<< getRegisterName(RegNo
);
70 unsigned VReg
= RegNo
& 0x0FFFFFFF;
74 void NVPTXInstPrinter::printInst(const MCInst
*MI
, raw_ostream
&OS
,
76 printInstruction(MI
, OS
);
78 // Next always print the annotation.
79 printAnnotation(OS
, Annot
);
82 void NVPTXInstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
84 const MCOperand
&Op
= MI
->getOperand(OpNo
);
86 unsigned Reg
= Op
.getReg();
88 } else if (Op
.isImm()) {
89 O
<< markup("<imm:") << formatImm(Op
.getImm()) << markup(">");
91 assert(Op
.isExpr() && "Unknown operand kind in printOperand");
96 void NVPTXInstPrinter::printCvtMode(const MCInst
*MI
, int OpNum
, raw_ostream
&O
,
97 const char *Modifier
) {
98 const MCOperand
&MO
= MI
->getOperand(OpNum
);
99 int64_t Imm
= MO
.getImm();
101 if (strcmp(Modifier
, "ftz") == 0) {
103 if (Imm
& NVPTX::PTXCvtMode::FTZ_FLAG
)
105 } else if (strcmp(Modifier
, "sat") == 0) {
107 if (Imm
& NVPTX::PTXCvtMode::SAT_FLAG
)
109 } else if (strcmp(Modifier
, "base") == 0) {
111 switch (Imm
& NVPTX::PTXCvtMode::BASE_MASK
) {
114 case NVPTX::PTXCvtMode::NONE
:
116 case NVPTX::PTXCvtMode::RNI
:
119 case NVPTX::PTXCvtMode::RZI
:
122 case NVPTX::PTXCvtMode::RMI
:
125 case NVPTX::PTXCvtMode::RPI
:
128 case NVPTX::PTXCvtMode::RN
:
131 case NVPTX::PTXCvtMode::RZ
:
134 case NVPTX::PTXCvtMode::RM
:
137 case NVPTX::PTXCvtMode::RP
:
142 llvm_unreachable("Invalid conversion modifier");
146 void NVPTXInstPrinter::printCmpMode(const MCInst
*MI
, int OpNum
, raw_ostream
&O
,
147 const char *Modifier
) {
148 const MCOperand
&MO
= MI
->getOperand(OpNum
);
149 int64_t Imm
= MO
.getImm();
151 if (strcmp(Modifier
, "ftz") == 0) {
153 if (Imm
& NVPTX::PTXCmpMode::FTZ_FLAG
)
155 } else if (strcmp(Modifier
, "base") == 0) {
156 switch (Imm
& NVPTX::PTXCmpMode::BASE_MASK
) {
159 case NVPTX::PTXCmpMode::EQ
:
162 case NVPTX::PTXCmpMode::NE
:
165 case NVPTX::PTXCmpMode::LT
:
168 case NVPTX::PTXCmpMode::LE
:
171 case NVPTX::PTXCmpMode::GT
:
174 case NVPTX::PTXCmpMode::GE
:
177 case NVPTX::PTXCmpMode::LO
:
180 case NVPTX::PTXCmpMode::LS
:
183 case NVPTX::PTXCmpMode::HI
:
186 case NVPTX::PTXCmpMode::HS
:
189 case NVPTX::PTXCmpMode::EQU
:
192 case NVPTX::PTXCmpMode::NEU
:
195 case NVPTX::PTXCmpMode::LTU
:
198 case NVPTX::PTXCmpMode::LEU
:
201 case NVPTX::PTXCmpMode::GTU
:
204 case NVPTX::PTXCmpMode::GEU
:
207 case NVPTX::PTXCmpMode::NUM
:
210 case NVPTX::PTXCmpMode::NotANumber
:
215 llvm_unreachable("Empty Modifier");
219 void NVPTXInstPrinter::printLdStCode(const MCInst
*MI
, int OpNum
,
220 raw_ostream
&O
, const char *Modifier
) {
222 const MCOperand
&MO
= MI
->getOperand(OpNum
);
223 int Imm
= (int) MO
.getImm();
224 if (!strcmp(Modifier
, "volatile")) {
227 } else if (!strcmp(Modifier
, "addsp")) {
229 case NVPTX::PTXLdStInstCode::GLOBAL
:
232 case NVPTX::PTXLdStInstCode::SHARED
:
235 case NVPTX::PTXLdStInstCode::LOCAL
:
238 case NVPTX::PTXLdStInstCode::PARAM
:
241 case NVPTX::PTXLdStInstCode::CONSTANT
:
244 case NVPTX::PTXLdStInstCode::GENERIC
:
247 llvm_unreachable("Wrong Address Space");
249 } else if (!strcmp(Modifier
, "sign")) {
250 if (Imm
== NVPTX::PTXLdStInstCode::Signed
)
252 else if (Imm
== NVPTX::PTXLdStInstCode::Unsigned
)
256 } else if (!strcmp(Modifier
, "vec")) {
257 if (Imm
== NVPTX::PTXLdStInstCode::V2
)
259 else if (Imm
== NVPTX::PTXLdStInstCode::V4
)
262 llvm_unreachable("Unknown Modifier");
264 llvm_unreachable("Empty Modifier");
267 void NVPTXInstPrinter::printMemOperand(const MCInst
*MI
, int OpNum
,
268 raw_ostream
&O
, const char *Modifier
) {
269 printOperand(MI
, OpNum
, O
);
271 if (Modifier
&& !strcmp(Modifier
, "add")) {
273 printOperand(MI
, OpNum
+ 1, O
);
275 if (MI
->getOperand(OpNum
+ 1).isImm() &&
276 MI
->getOperand(OpNum
+ 1).getImm() == 0)
277 return; // don't print ',0' or '+0'
279 printOperand(MI
, OpNum
+ 1, O
);
283 void NVPTXInstPrinter::printProtoIdent(const MCInst
*MI
, int OpNum
,
284 raw_ostream
&O
, const char *Modifier
) {
285 const MCOperand
&Op
= MI
->getOperand(OpNum
);
286 assert(Op
.isExpr() && "Call prototype is not an MCExpr?");
287 const MCExpr
*Expr
= Op
.getExpr();
288 const MCSymbol
&Sym
= cast
<MCSymbolRefExpr
>(Expr
)->getSymbol();