LLVM API Documentation
00001 //===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Print MCInst instructions to .ptx format. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "InstPrinter/NVPTXInstPrinter.h" 00015 #include "MCTargetDesc/NVPTXBaseInfo.h" 00016 #include "NVPTX.h" 00017 #include "llvm/MC/MCExpr.h" 00018 #include "llvm/MC/MCInst.h" 00019 #include "llvm/MC/MCInstrInfo.h" 00020 #include "llvm/MC/MCSubtargetInfo.h" 00021 #include "llvm/MC/MCSymbol.h" 00022 #include "llvm/Support/ErrorHandling.h" 00023 #include "llvm/Support/FormattedStream.h" 00024 #include <cctype> 00025 using namespace llvm; 00026 00027 #define DEBUG_TYPE "asm-printer" 00028 00029 #include "NVPTXGenAsmWriter.inc" 00030 00031 00032 NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, 00033 const MCRegisterInfo &MRI, 00034 const MCSubtargetInfo &STI) 00035 : MCInstPrinter(MAI, MII, MRI) { 00036 setAvailableFeatures(STI.getFeatureBits()); 00037 } 00038 00039 void NVPTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 00040 // Decode the virtual register 00041 // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister 00042 unsigned RCId = (RegNo >> 28); 00043 switch (RCId) { 00044 default: report_fatal_error("Bad virtual register encoding"); 00045 case 0: 00046 // This is actually a physical register, so defer to the autogenerated 00047 // register printer 00048 OS << getRegisterName(RegNo); 00049 return; 00050 case 1: 00051 OS << "%p"; 00052 break; 00053 case 2: 00054 OS << "%rs"; 00055 break; 00056 case 3: 00057 OS << "%r"; 00058 break; 00059 case 4: 00060 OS << "%rd"; 00061 break; 00062 case 5: 00063 OS << "%f"; 00064 break; 00065 case 6: 00066 OS << "%fd"; 00067 break; 00068 } 00069 00070 unsigned VReg = RegNo & 0x0FFFFFFF; 00071 OS << VReg; 00072 } 00073 00074 void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 00075 StringRef Annot) { 00076 printInstruction(MI, OS); 00077 00078 // Next always print the annotation. 00079 printAnnotation(OS, Annot); 00080 } 00081 00082 void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 00083 raw_ostream &O) { 00084 const MCOperand &Op = MI->getOperand(OpNo); 00085 if (Op.isReg()) { 00086 unsigned Reg = Op.getReg(); 00087 printRegName(O, Reg); 00088 } else if (Op.isImm()) { 00089 O << markup("<imm:") << formatImm(Op.getImm()) << markup(">"); 00090 } else { 00091 assert(Op.isExpr() && "Unknown operand kind in printOperand"); 00092 O << *Op.getExpr(); 00093 } 00094 } 00095 00096 void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O, 00097 const char *Modifier) { 00098 const MCOperand &MO = MI->getOperand(OpNum); 00099 int64_t Imm = MO.getImm(); 00100 00101 if (strcmp(Modifier, "ftz") == 0) { 00102 // FTZ flag 00103 if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG) 00104 O << ".ftz"; 00105 } else if (strcmp(Modifier, "sat") == 0) { 00106 // SAT flag 00107 if (Imm & NVPTX::PTXCvtMode::SAT_FLAG) 00108 O << ".sat"; 00109 } else if (strcmp(Modifier, "base") == 0) { 00110 // Default operand 00111 switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) { 00112 default: 00113 return; 00114 case NVPTX::PTXCvtMode::NONE: 00115 break; 00116 case NVPTX::PTXCvtMode::RNI: 00117 O << ".rni"; 00118 break; 00119 case NVPTX::PTXCvtMode::RZI: 00120 O << ".rzi"; 00121 break; 00122 case NVPTX::PTXCvtMode::RMI: 00123 O << ".rmi"; 00124 break; 00125 case NVPTX::PTXCvtMode::RPI: 00126 O << ".rpi"; 00127 break; 00128 case NVPTX::PTXCvtMode::RN: 00129 O << ".rn"; 00130 break; 00131 case NVPTX::PTXCvtMode::RZ: 00132 O << ".rz"; 00133 break; 00134 case NVPTX::PTXCvtMode::RM: 00135 O << ".rm"; 00136 break; 00137 case NVPTX::PTXCvtMode::RP: 00138 O << ".rp"; 00139 break; 00140 } 00141 } else { 00142 llvm_unreachable("Invalid conversion modifier"); 00143 } 00144 } 00145 00146 void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O, 00147 const char *Modifier) { 00148 const MCOperand &MO = MI->getOperand(OpNum); 00149 int64_t Imm = MO.getImm(); 00150 00151 if (strcmp(Modifier, "ftz") == 0) { 00152 // FTZ flag 00153 if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG) 00154 O << ".ftz"; 00155 } else if (strcmp(Modifier, "base") == 0) { 00156 switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) { 00157 default: 00158 return; 00159 case NVPTX::PTXCmpMode::EQ: 00160 O << ".eq"; 00161 break; 00162 case NVPTX::PTXCmpMode::NE: 00163 O << ".ne"; 00164 break; 00165 case NVPTX::PTXCmpMode::LT: 00166 O << ".lt"; 00167 break; 00168 case NVPTX::PTXCmpMode::LE: 00169 O << ".le"; 00170 break; 00171 case NVPTX::PTXCmpMode::GT: 00172 O << ".gt"; 00173 break; 00174 case NVPTX::PTXCmpMode::GE: 00175 O << ".ge"; 00176 break; 00177 case NVPTX::PTXCmpMode::LO: 00178 O << ".lo"; 00179 break; 00180 case NVPTX::PTXCmpMode::LS: 00181 O << ".ls"; 00182 break; 00183 case NVPTX::PTXCmpMode::HI: 00184 O << ".hi"; 00185 break; 00186 case NVPTX::PTXCmpMode::HS: 00187 O << ".hs"; 00188 break; 00189 case NVPTX::PTXCmpMode::EQU: 00190 O << ".equ"; 00191 break; 00192 case NVPTX::PTXCmpMode::NEU: 00193 O << ".neu"; 00194 break; 00195 case NVPTX::PTXCmpMode::LTU: 00196 O << ".ltu"; 00197 break; 00198 case NVPTX::PTXCmpMode::LEU: 00199 O << ".leu"; 00200 break; 00201 case NVPTX::PTXCmpMode::GTU: 00202 O << ".gtu"; 00203 break; 00204 case NVPTX::PTXCmpMode::GEU: 00205 O << ".geu"; 00206 break; 00207 case NVPTX::PTXCmpMode::NUM: 00208 O << ".num"; 00209 break; 00210 case NVPTX::PTXCmpMode::NotANumber: 00211 O << ".nan"; 00212 break; 00213 } 00214 } else { 00215 llvm_unreachable("Empty Modifier"); 00216 } 00217 } 00218 00219 void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum, 00220 raw_ostream &O, const char *Modifier) { 00221 if (Modifier) { 00222 const MCOperand &MO = MI->getOperand(OpNum); 00223 int Imm = (int) MO.getImm(); 00224 if (!strcmp(Modifier, "volatile")) { 00225 if (Imm) 00226 O << ".volatile"; 00227 } else if (!strcmp(Modifier, "addsp")) { 00228 switch (Imm) { 00229 case NVPTX::PTXLdStInstCode::GLOBAL: 00230 O << ".global"; 00231 break; 00232 case NVPTX::PTXLdStInstCode::SHARED: 00233 O << ".shared"; 00234 break; 00235 case NVPTX::PTXLdStInstCode::LOCAL: 00236 O << ".local"; 00237 break; 00238 case NVPTX::PTXLdStInstCode::PARAM: 00239 O << ".param"; 00240 break; 00241 case NVPTX::PTXLdStInstCode::CONSTANT: 00242 O << ".const"; 00243 break; 00244 case NVPTX::PTXLdStInstCode::GENERIC: 00245 break; 00246 default: 00247 llvm_unreachable("Wrong Address Space"); 00248 } 00249 } else if (!strcmp(Modifier, "sign")) { 00250 if (Imm == NVPTX::PTXLdStInstCode::Signed) 00251 O << "s"; 00252 else if (Imm == NVPTX::PTXLdStInstCode::Unsigned) 00253 O << "u"; 00254 else 00255 O << "f"; 00256 } else if (!strcmp(Modifier, "vec")) { 00257 if (Imm == NVPTX::PTXLdStInstCode::V2) 00258 O << ".v2"; 00259 else if (Imm == NVPTX::PTXLdStInstCode::V4) 00260 O << ".v4"; 00261 } else 00262 llvm_unreachable("Unknown Modifier"); 00263 } else 00264 llvm_unreachable("Empty Modifier"); 00265 } 00266 00267 void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum, 00268 raw_ostream &O, const char *Modifier) { 00269 printOperand(MI, OpNum, O); 00270 00271 if (Modifier && !strcmp(Modifier, "add")) { 00272 O << ", "; 00273 printOperand(MI, OpNum + 1, O); 00274 } else { 00275 if (MI->getOperand(OpNum + 1).isImm() && 00276 MI->getOperand(OpNum + 1).getImm() == 0) 00277 return; // don't print ',0' or '+0' 00278 O << "+"; 00279 printOperand(MI, OpNum + 1, O); 00280 } 00281 } 00282 00283 void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum, 00284 raw_ostream &O, const char *Modifier) { 00285 const MCOperand &Op = MI->getOperand(OpNum); 00286 assert(Op.isExpr() && "Call prototype is not an MCExpr?"); 00287 const MCExpr *Expr = Op.getExpr(); 00288 const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol(); 00289 O << Sym.getName(); 00290 }