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/ADT/StringExtras.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
26 #define GET_INSTRUCTION_NAME
27 #include "PTXGenAsmWriter.inc"
29 PTXInstPrinter::PTXInstPrinter(const MCAsmInfo &MAI,
30 const MCSubtargetInfo &STI) :
32 // Initialize the set of available features.
33 setAvailableFeatures(STI.getFeatureBits());
36 StringRef PTXInstPrinter::getOpcodeName(unsigned Opcode) const {
37 return getInstructionName(Opcode);
40 void PTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
41 OS << getRegisterName(RegNo);
44 void PTXInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
46 printPredicate(MI, O);
47 switch (MI->getOpcode()) {
49 printInstruction(MI, O);
55 printAnnotation(O, Annot);
58 void PTXInstPrinter::printPredicate(const MCInst *MI, raw_ostream &O) {
59 // The last two operands are the predicate operands
63 if (MI->getOpcode() == PTX::CALL) {
67 RegIndex = MI->getNumOperands()-2;
68 OpIndex = MI->getNumOperands()-1;
71 int PredOp = MI->getOperand(OpIndex).getImm();
72 if (PredOp != PTX::PRED_NONE) {
73 if (PredOp == PTX::PRED_NEGATE) {
78 printOperand(MI, RegIndex, O);
82 void PTXInstPrinter::printCall(const MCInst *MI, raw_ostream &O) {
84 // The first two operands are the predicate slot
86 unsigned NumRets = MI->getOperand(Index++).getImm();
87 for (unsigned i = 0; i < NumRets; ++i) {
93 printOperand(MI, Index++, O);
100 O << *(MI->getOperand(Index++).getExpr()) << ", (";
102 unsigned NumArgs = MI->getOperand(Index++).getImm();
103 for (unsigned i = 0; i < NumArgs; ++i) {
104 printOperand(MI, Index++, O);
113 void PTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
115 const MCOperand &Op = MI->getOperand(OpNo);
118 } else if (Op.isFPImm()) {
119 double Imm = Op.getFPImm();
121 APInt FPIntImm = FPImm.bitcastToAPInt();
123 // PTX requires us to output the full 64 bits, even if the number is zero
124 if (FPIntImm.getZExtValue() > 0) {
125 O << FPIntImm.toString(16, false);
127 O << "0000000000000000";
130 assert(Op.isExpr() && "unknown operand kind in printOperand");
131 const MCExpr *Expr = Op.getExpr();
132 if (const MCSymbolRefExpr *SymRefExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
133 const MCSymbol &Sym = SymRefExpr->getSymbol();
141 void PTXInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
143 printOperand(MI, OpNo, O);
144 if (MI->getOperand(OpNo+1).isImm() && MI->getOperand(OpNo+1).getImm() == 0)
145 return; // don't print "+0"
147 printOperand(MI, OpNo+1, O);
150 void PTXInstPrinter::printRoundingMode(const MCInst *MI, unsigned OpNo,
152 const MCOperand &Op = MI->getOperand(OpNo);
153 assert (Op.isImm() && "Rounding modes must be immediate values");
154 switch (Op.getImm()) {
156 llvm_unreachable("Unknown rounding mode!");
157 case PTXRoundingMode::RndDefault:
158 llvm_unreachable("FP rounding-mode pass did not handle instruction!");
160 case PTXRoundingMode::RndNone:
161 // Do not print anything.
163 case PTXRoundingMode::RndNearestEven:
166 case PTXRoundingMode::RndTowardsZero:
169 case PTXRoundingMode::RndNegInf:
172 case PTXRoundingMode::RndPosInf:
175 case PTXRoundingMode::RndApprox:
178 case PTXRoundingMode::RndNearestEvenInt:
181 case PTXRoundingMode::RndTowardsZeroInt:
184 case PTXRoundingMode::RndNegInfInt:
187 case PTXRoundingMode::RndPosInfInt: