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 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 36 StringRef PTXInstPrinter::getOpcodeName(unsigned Opcode) const { 37 return getInstructionName(Opcode); 38 } 39 40 void PTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 41 OS << getRegisterName(RegNo); 42 } 43 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 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 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 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 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 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