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