1*9880d681SAndroid Build Coastguard Worker //===-- NVPTXAsmPrinter.h - NVPTX LLVM assembly writer --------------------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file contains a printer that converts from our internal representation 11*9880d681SAndroid Build Coastguard Worker // of machine-dependent LLVM code to NVPTX assembly language. 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_NVPTX_NVPTXASMPRINTER_H 16*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_NVPTX_NVPTXASMPRINTER_H 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #include "NVPTX.h" 19*9880d681SAndroid Build Coastguard Worker #include "NVPTXSubtarget.h" 20*9880d681SAndroid Build Coastguard Worker #include "NVPTXTargetMachine.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/AsmPrinter.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h" 24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h" 25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h" 26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h" 27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h" 28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h" 29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FormattedStream.h" 30*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h" 31*9880d681SAndroid Build Coastguard Worker #include <fstream> 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker // The ptx syntax and format is very different from that usually seem in a .s 34*9880d681SAndroid Build Coastguard Worker // file, 35*9880d681SAndroid Build Coastguard Worker // therefore we are not able to use the MCAsmStreamer interface here. 36*9880d681SAndroid Build Coastguard Worker // 37*9880d681SAndroid Build Coastguard Worker // We are handcrafting the output method here. 38*9880d681SAndroid Build Coastguard Worker // 39*9880d681SAndroid Build Coastguard Worker // A better approach is to clone the MCAsmStreamer to a MCPTXAsmStreamer 40*9880d681SAndroid Build Coastguard Worker // (subclass of MCStreamer). 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Worker namespace llvm { 43*9880d681SAndroid Build Coastguard Worker class MCOperand; 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker class LineReader { 46*9880d681SAndroid Build Coastguard Worker private: 47*9880d681SAndroid Build Coastguard Worker unsigned theCurLine; 48*9880d681SAndroid Build Coastguard Worker std::ifstream fstr; 49*9880d681SAndroid Build Coastguard Worker char buff[512]; 50*9880d681SAndroid Build Coastguard Worker std::string theFileName; 51*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 32> lineOffset; 52*9880d681SAndroid Build Coastguard Worker public: LineReader(std::string filename)53*9880d681SAndroid Build Coastguard Worker LineReader(std::string filename) { 54*9880d681SAndroid Build Coastguard Worker theCurLine = 0; 55*9880d681SAndroid Build Coastguard Worker fstr.open(filename.c_str()); 56*9880d681SAndroid Build Coastguard Worker theFileName = filename; 57*9880d681SAndroid Build Coastguard Worker } fileName()58*9880d681SAndroid Build Coastguard Worker std::string fileName() { return theFileName; } ~LineReader()59*9880d681SAndroid Build Coastguard Worker ~LineReader() { fstr.close(); } 60*9880d681SAndroid Build Coastguard Worker std::string readLine(unsigned line); 61*9880d681SAndroid Build Coastguard Worker }; 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker class LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter { 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker class AggBuffer { 66*9880d681SAndroid Build Coastguard Worker // Used to buffer the emitted string for initializing global 67*9880d681SAndroid Build Coastguard Worker // aggregates. 68*9880d681SAndroid Build Coastguard Worker // 69*9880d681SAndroid Build Coastguard Worker // Normally an aggregate (array, vector or structure) is emitted 70*9880d681SAndroid Build Coastguard Worker // as a u8[]. However, if one element/field of the aggregate 71*9880d681SAndroid Build Coastguard Worker // is a non-NULL address, then the aggregate is emitted as u32[] 72*9880d681SAndroid Build Coastguard Worker // or u64[]. 73*9880d681SAndroid Build Coastguard Worker // 74*9880d681SAndroid Build Coastguard Worker // We first layout the aggregate in 'buffer' in bytes, except for 75*9880d681SAndroid Build Coastguard Worker // those symbol addresses. For the i-th symbol address in the 76*9880d681SAndroid Build Coastguard Worker //aggregate, its corresponding 4-byte or 8-byte elements in 'buffer' 77*9880d681SAndroid Build Coastguard Worker // are filled with 0s. symbolPosInBuffer[i-1] records its position 78*9880d681SAndroid Build Coastguard Worker // in 'buffer', and Symbols[i-1] records the Value*. 79*9880d681SAndroid Build Coastguard Worker // 80*9880d681SAndroid Build Coastguard Worker // Once we have this AggBuffer setup, we can choose how to print 81*9880d681SAndroid Build Coastguard Worker // it out. 82*9880d681SAndroid Build Coastguard Worker public: 83*9880d681SAndroid Build Coastguard Worker unsigned numSymbols; // number of symbol addresses 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker private: 86*9880d681SAndroid Build Coastguard Worker const unsigned size; // size of the buffer in bytes 87*9880d681SAndroid Build Coastguard Worker std::vector<unsigned char> buffer; // the buffer 88*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 4> symbolPosInBuffer; 89*9880d681SAndroid Build Coastguard Worker SmallVector<const Value *, 4> Symbols; 90*9880d681SAndroid Build Coastguard Worker // SymbolsBeforeStripping[i] is the original form of Symbols[i] before 91*9880d681SAndroid Build Coastguard Worker // stripping pointer casts, i.e., 92*9880d681SAndroid Build Coastguard Worker // Symbols[i] == SymbolsBeforeStripping[i]->stripPointerCasts(). 93*9880d681SAndroid Build Coastguard Worker // 94*9880d681SAndroid Build Coastguard Worker // We need to keep these values because AggBuffer::print decides whether to 95*9880d681SAndroid Build Coastguard Worker // emit a "generic()" cast for Symbols[i] depending on the address space of 96*9880d681SAndroid Build Coastguard Worker // SymbolsBeforeStripping[i]. 97*9880d681SAndroid Build Coastguard Worker SmallVector<const Value *, 4> SymbolsBeforeStripping; 98*9880d681SAndroid Build Coastguard Worker unsigned curpos; 99*9880d681SAndroid Build Coastguard Worker raw_ostream &O; 100*9880d681SAndroid Build Coastguard Worker NVPTXAsmPrinter &AP; 101*9880d681SAndroid Build Coastguard Worker bool EmitGeneric; 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker public: AggBuffer(unsigned size,raw_ostream & O,NVPTXAsmPrinter & AP)104*9880d681SAndroid Build Coastguard Worker AggBuffer(unsigned size, raw_ostream &O, NVPTXAsmPrinter &AP) 105*9880d681SAndroid Build Coastguard Worker : size(size), buffer(size), O(O), AP(AP) { 106*9880d681SAndroid Build Coastguard Worker curpos = 0; 107*9880d681SAndroid Build Coastguard Worker numSymbols = 0; 108*9880d681SAndroid Build Coastguard Worker EmitGeneric = AP.EmitGeneric; 109*9880d681SAndroid Build Coastguard Worker } addBytes(unsigned char * Ptr,int Num,int Bytes)110*9880d681SAndroid Build Coastguard Worker unsigned addBytes(unsigned char *Ptr, int Num, int Bytes) { 111*9880d681SAndroid Build Coastguard Worker assert((curpos + Num) <= size); 112*9880d681SAndroid Build Coastguard Worker assert((curpos + Bytes) <= size); 113*9880d681SAndroid Build Coastguard Worker for (int i = 0; i < Num; ++i) { 114*9880d681SAndroid Build Coastguard Worker buffer[curpos] = Ptr[i]; 115*9880d681SAndroid Build Coastguard Worker curpos++; 116*9880d681SAndroid Build Coastguard Worker } 117*9880d681SAndroid Build Coastguard Worker for (int i = Num; i < Bytes; ++i) { 118*9880d681SAndroid Build Coastguard Worker buffer[curpos] = 0; 119*9880d681SAndroid Build Coastguard Worker curpos++; 120*9880d681SAndroid Build Coastguard Worker } 121*9880d681SAndroid Build Coastguard Worker return curpos; 122*9880d681SAndroid Build Coastguard Worker } addZeros(int Num)123*9880d681SAndroid Build Coastguard Worker unsigned addZeros(int Num) { 124*9880d681SAndroid Build Coastguard Worker assert((curpos + Num) <= size); 125*9880d681SAndroid Build Coastguard Worker for (int i = 0; i < Num; ++i) { 126*9880d681SAndroid Build Coastguard Worker buffer[curpos] = 0; 127*9880d681SAndroid Build Coastguard Worker curpos++; 128*9880d681SAndroid Build Coastguard Worker } 129*9880d681SAndroid Build Coastguard Worker return curpos; 130*9880d681SAndroid Build Coastguard Worker } addSymbol(const Value * GVar,const Value * GVarBeforeStripping)131*9880d681SAndroid Build Coastguard Worker void addSymbol(const Value *GVar, const Value *GVarBeforeStripping) { 132*9880d681SAndroid Build Coastguard Worker symbolPosInBuffer.push_back(curpos); 133*9880d681SAndroid Build Coastguard Worker Symbols.push_back(GVar); 134*9880d681SAndroid Build Coastguard Worker SymbolsBeforeStripping.push_back(GVarBeforeStripping); 135*9880d681SAndroid Build Coastguard Worker numSymbols++; 136*9880d681SAndroid Build Coastguard Worker } print()137*9880d681SAndroid Build Coastguard Worker void print() { 138*9880d681SAndroid Build Coastguard Worker if (numSymbols == 0) { 139*9880d681SAndroid Build Coastguard Worker // print out in bytes 140*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < size; i++) { 141*9880d681SAndroid Build Coastguard Worker if (i) 142*9880d681SAndroid Build Coastguard Worker O << ", "; 143*9880d681SAndroid Build Coastguard Worker O << (unsigned int) buffer[i]; 144*9880d681SAndroid Build Coastguard Worker } 145*9880d681SAndroid Build Coastguard Worker } else { 146*9880d681SAndroid Build Coastguard Worker // print out in 4-bytes or 8-bytes 147*9880d681SAndroid Build Coastguard Worker unsigned int pos = 0; 148*9880d681SAndroid Build Coastguard Worker unsigned int nSym = 0; 149*9880d681SAndroid Build Coastguard Worker unsigned int nextSymbolPos = symbolPosInBuffer[nSym]; 150*9880d681SAndroid Build Coastguard Worker unsigned int nBytes = 4; 151*9880d681SAndroid Build Coastguard Worker if (static_cast<const NVPTXTargetMachine &>(AP.TM).is64Bit()) 152*9880d681SAndroid Build Coastguard Worker nBytes = 8; 153*9880d681SAndroid Build Coastguard Worker for (pos = 0; pos < size; pos += nBytes) { 154*9880d681SAndroid Build Coastguard Worker if (pos) 155*9880d681SAndroid Build Coastguard Worker O << ", "; 156*9880d681SAndroid Build Coastguard Worker if (pos == nextSymbolPos) { 157*9880d681SAndroid Build Coastguard Worker const Value *v = Symbols[nSym]; 158*9880d681SAndroid Build Coastguard Worker const Value *v0 = SymbolsBeforeStripping[nSym]; 159*9880d681SAndroid Build Coastguard Worker if (const GlobalValue *GVar = dyn_cast<GlobalValue>(v)) { 160*9880d681SAndroid Build Coastguard Worker MCSymbol *Name = AP.getSymbol(GVar); 161*9880d681SAndroid Build Coastguard Worker PointerType *PTy = dyn_cast<PointerType>(v0->getType()); 162*9880d681SAndroid Build Coastguard Worker bool IsNonGenericPointer = false; // Is v0 a non-generic pointer? 163*9880d681SAndroid Build Coastguard Worker if (PTy && PTy->getAddressSpace() != 0) { 164*9880d681SAndroid Build Coastguard Worker IsNonGenericPointer = true; 165*9880d681SAndroid Build Coastguard Worker } 166*9880d681SAndroid Build Coastguard Worker if (EmitGeneric && !isa<Function>(v) && !IsNonGenericPointer) { 167*9880d681SAndroid Build Coastguard Worker O << "generic("; 168*9880d681SAndroid Build Coastguard Worker Name->print(O, AP.MAI); 169*9880d681SAndroid Build Coastguard Worker O << ")"; 170*9880d681SAndroid Build Coastguard Worker } else { 171*9880d681SAndroid Build Coastguard Worker Name->print(O, AP.MAI); 172*9880d681SAndroid Build Coastguard Worker } 173*9880d681SAndroid Build Coastguard Worker } else if (const ConstantExpr *CExpr = dyn_cast<ConstantExpr>(v0)) { 174*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr = 175*9880d681SAndroid Build Coastguard Worker AP.lowerConstantForGV(cast<Constant>(CExpr), false); 176*9880d681SAndroid Build Coastguard Worker AP.printMCExpr(*Expr, O); 177*9880d681SAndroid Build Coastguard Worker } else 178*9880d681SAndroid Build Coastguard Worker llvm_unreachable("symbol type unknown"); 179*9880d681SAndroid Build Coastguard Worker nSym++; 180*9880d681SAndroid Build Coastguard Worker if (nSym >= numSymbols) 181*9880d681SAndroid Build Coastguard Worker nextSymbolPos = size + 1; 182*9880d681SAndroid Build Coastguard Worker else 183*9880d681SAndroid Build Coastguard Worker nextSymbolPos = symbolPosInBuffer[nSym]; 184*9880d681SAndroid Build Coastguard Worker } else if (nBytes == 4) 185*9880d681SAndroid Build Coastguard Worker O << *(unsigned int *)(&buffer[pos]); 186*9880d681SAndroid Build Coastguard Worker else 187*9880d681SAndroid Build Coastguard Worker O << *(unsigned long long *)(&buffer[pos]); 188*9880d681SAndroid Build Coastguard Worker } 189*9880d681SAndroid Build Coastguard Worker } 190*9880d681SAndroid Build Coastguard Worker } 191*9880d681SAndroid Build Coastguard Worker }; 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker friend class AggBuffer; 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Worker void emitSrcInText(StringRef filename, unsigned line); 196*9880d681SAndroid Build Coastguard Worker 197*9880d681SAndroid Build Coastguard Worker private: getPassName()198*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override { return "NVPTX Assembly Printer"; } 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker const Function *F; 201*9880d681SAndroid Build Coastguard Worker std::string CurrentFnName; 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Worker void EmitBasicBlockStart(const MachineBasicBlock &MBB) const override; 204*9880d681SAndroid Build Coastguard Worker void EmitFunctionEntryLabel() override; 205*9880d681SAndroid Build Coastguard Worker void EmitFunctionBodyStart() override; 206*9880d681SAndroid Build Coastguard Worker void EmitFunctionBodyEnd() override; 207*9880d681SAndroid Build Coastguard Worker void emitImplicitDef(const MachineInstr *MI) const override; 208*9880d681SAndroid Build Coastguard Worker 209*9880d681SAndroid Build Coastguard Worker void EmitInstruction(const MachineInstr *) override; 210*9880d681SAndroid Build Coastguard Worker void lowerToMCInst(const MachineInstr *MI, MCInst &OutMI); 211*9880d681SAndroid Build Coastguard Worker bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); 212*9880d681SAndroid Build Coastguard Worker MCOperand GetSymbolRef(const MCSymbol *Symbol); 213*9880d681SAndroid Build Coastguard Worker unsigned encodeVirtualRegister(unsigned Reg); 214*9880d681SAndroid Build Coastguard Worker 215*9880d681SAndroid Build Coastguard Worker void printVecModifiedImmediate(const MachineOperand &MO, const char *Modifier, 216*9880d681SAndroid Build Coastguard Worker raw_ostream &O); 217*9880d681SAndroid Build Coastguard Worker void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 218*9880d681SAndroid Build Coastguard Worker const char *Modifier = nullptr); 219*9880d681SAndroid Build Coastguard Worker void printModuleLevelGV(const GlobalVariable *GVar, raw_ostream &O, 220*9880d681SAndroid Build Coastguard Worker bool = false); 221*9880d681SAndroid Build Coastguard Worker void printParamName(Function::const_arg_iterator I, int paramIndex, 222*9880d681SAndroid Build Coastguard Worker raw_ostream &O); 223*9880d681SAndroid Build Coastguard Worker void emitGlobals(const Module &M); 224*9880d681SAndroid Build Coastguard Worker void emitHeader(Module &M, raw_ostream &O, const NVPTXSubtarget &STI); 225*9880d681SAndroid Build Coastguard Worker void emitKernelFunctionDirectives(const Function &F, raw_ostream &O) const; 226*9880d681SAndroid Build Coastguard Worker void emitVirtualRegister(unsigned int vr, raw_ostream &); 227*9880d681SAndroid Build Coastguard Worker void emitFunctionParamList(const Function *, raw_ostream &O); 228*9880d681SAndroid Build Coastguard Worker void emitFunctionParamList(const MachineFunction &MF, raw_ostream &O); 229*9880d681SAndroid Build Coastguard Worker void setAndEmitFunctionVirtualRegisters(const MachineFunction &MF); 230*9880d681SAndroid Build Coastguard Worker void printReturnValStr(const Function *, raw_ostream &O); 231*9880d681SAndroid Build Coastguard Worker void printReturnValStr(const MachineFunction &MF, raw_ostream &O); 232*9880d681SAndroid Build Coastguard Worker bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 233*9880d681SAndroid Build Coastguard Worker unsigned AsmVariant, const char *ExtraCode, 234*9880d681SAndroid Build Coastguard Worker raw_ostream &) override; 235*9880d681SAndroid Build Coastguard Worker void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 236*9880d681SAndroid Build Coastguard Worker const char *Modifier = nullptr); 237*9880d681SAndroid Build Coastguard Worker bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 238*9880d681SAndroid Build Coastguard Worker unsigned AsmVariant, const char *ExtraCode, 239*9880d681SAndroid Build Coastguard Worker raw_ostream &) override; 240*9880d681SAndroid Build Coastguard Worker 241*9880d681SAndroid Build Coastguard Worker const MCExpr *lowerConstantForGV(const Constant *CV, bool ProcessingGeneric); 242*9880d681SAndroid Build Coastguard Worker void printMCExpr(const MCExpr &Expr, raw_ostream &OS); 243*9880d681SAndroid Build Coastguard Worker 244*9880d681SAndroid Build Coastguard Worker protected: 245*9880d681SAndroid Build Coastguard Worker bool doInitialization(Module &M) override; 246*9880d681SAndroid Build Coastguard Worker bool doFinalization(Module &M) override; 247*9880d681SAndroid Build Coastguard Worker 248*9880d681SAndroid Build Coastguard Worker private: 249*9880d681SAndroid Build Coastguard Worker std::string CurrentBankselLabelInBasicBlock; 250*9880d681SAndroid Build Coastguard Worker 251*9880d681SAndroid Build Coastguard Worker bool GlobalsEmitted; 252*9880d681SAndroid Build Coastguard Worker 253*9880d681SAndroid Build Coastguard Worker // This is specific per MachineFunction. 254*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo *MRI; 255*9880d681SAndroid Build Coastguard Worker // The contents are specific for each 256*9880d681SAndroid Build Coastguard Worker // MachineFunction. But the size of the 257*9880d681SAndroid Build Coastguard Worker // array is not. 258*9880d681SAndroid Build Coastguard Worker typedef DenseMap<unsigned, unsigned> VRegMap; 259*9880d681SAndroid Build Coastguard Worker typedef DenseMap<const TargetRegisterClass *, VRegMap> VRegRCMap; 260*9880d681SAndroid Build Coastguard Worker VRegRCMap VRegMapping; 261*9880d681SAndroid Build Coastguard Worker 262*9880d681SAndroid Build Coastguard Worker // Cache the subtarget here. 263*9880d681SAndroid Build Coastguard Worker const NVPTXSubtarget *nvptxSubtarget; 264*9880d681SAndroid Build Coastguard Worker 265*9880d681SAndroid Build Coastguard Worker // Build the map between type name and ID based on module's type 266*9880d681SAndroid Build Coastguard Worker // symbol table. 267*9880d681SAndroid Build Coastguard Worker std::map<Type *, std::string> TypeNameMap; 268*9880d681SAndroid Build Coastguard Worker 269*9880d681SAndroid Build Coastguard Worker // List of variables demoted to a function scope. 270*9880d681SAndroid Build Coastguard Worker std::map<const Function *, std::vector<const GlobalVariable *> > localDecls; 271*9880d681SAndroid Build Coastguard Worker 272*9880d681SAndroid Build Coastguard Worker // To record filename to ID mapping 273*9880d681SAndroid Build Coastguard Worker std::map<std::string, unsigned> filenameMap; 274*9880d681SAndroid Build Coastguard Worker void recordAndEmitFilenames(Module &); 275*9880d681SAndroid Build Coastguard Worker 276*9880d681SAndroid Build Coastguard Worker void emitPTXGlobalVariable(const GlobalVariable *GVar, raw_ostream &O); 277*9880d681SAndroid Build Coastguard Worker void emitPTXAddressSpace(unsigned int AddressSpace, raw_ostream &O) const; 278*9880d681SAndroid Build Coastguard Worker std::string getPTXFundamentalTypeStr(Type *Ty, bool = true) const; 279*9880d681SAndroid Build Coastguard Worker void printScalarConstant(const Constant *CPV, raw_ostream &O); 280*9880d681SAndroid Build Coastguard Worker void printFPConstant(const ConstantFP *Fp, raw_ostream &O); 281*9880d681SAndroid Build Coastguard Worker void bufferLEByte(const Constant *CPV, int Bytes, AggBuffer *aggBuffer); 282*9880d681SAndroid Build Coastguard Worker void bufferAggregateConstant(const Constant *CV, AggBuffer *aggBuffer); 283*9880d681SAndroid Build Coastguard Worker 284*9880d681SAndroid Build Coastguard Worker void emitLinkageDirective(const GlobalValue *V, raw_ostream &O); 285*9880d681SAndroid Build Coastguard Worker void emitDeclarations(const Module &, raw_ostream &O); 286*9880d681SAndroid Build Coastguard Worker void emitDeclaration(const Function *, raw_ostream &O); 287*9880d681SAndroid Build Coastguard Worker void emitDemotedVars(const Function *, raw_ostream &); 288*9880d681SAndroid Build Coastguard Worker 289*9880d681SAndroid Build Coastguard Worker bool lowerImageHandleOperand(const MachineInstr *MI, unsigned OpNo, 290*9880d681SAndroid Build Coastguard Worker MCOperand &MCOp); 291*9880d681SAndroid Build Coastguard Worker void lowerImageHandleSymbol(unsigned Index, MCOperand &MCOp); 292*9880d681SAndroid Build Coastguard Worker 293*9880d681SAndroid Build Coastguard Worker bool isLoopHeaderOfNoUnroll(const MachineBasicBlock &MBB) const; 294*9880d681SAndroid Build Coastguard Worker 295*9880d681SAndroid Build Coastguard Worker LineReader *reader; 296*9880d681SAndroid Build Coastguard Worker LineReader *getReader(const std::string &); 297*9880d681SAndroid Build Coastguard Worker 298*9880d681SAndroid Build Coastguard Worker // Used to control the need to emit .generic() in the initializer of 299*9880d681SAndroid Build Coastguard Worker // module scope variables. 300*9880d681SAndroid Build Coastguard Worker // Although ptx supports the hybrid mode like the following, 301*9880d681SAndroid Build Coastguard Worker // .global .u32 a; 302*9880d681SAndroid Build Coastguard Worker // .global .u32 b; 303*9880d681SAndroid Build Coastguard Worker // .global .u32 addr[] = {a, generic(b)} 304*9880d681SAndroid Build Coastguard Worker // we have difficulty representing the difference in the NVVM IR. 305*9880d681SAndroid Build Coastguard Worker // 306*9880d681SAndroid Build Coastguard Worker // Since the address value should always be generic in CUDA C and always 307*9880d681SAndroid Build Coastguard Worker // be specific in OpenCL, we use this simple control here. 308*9880d681SAndroid Build Coastguard Worker // 309*9880d681SAndroid Build Coastguard Worker bool EmitGeneric; 310*9880d681SAndroid Build Coastguard Worker 311*9880d681SAndroid Build Coastguard Worker public: NVPTXAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)312*9880d681SAndroid Build Coastguard Worker NVPTXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) 313*9880d681SAndroid Build Coastguard Worker : AsmPrinter(TM, std::move(Streamer)), 314*9880d681SAndroid Build Coastguard Worker EmitGeneric(static_cast<NVPTXTargetMachine &>(TM).getDrvInterface() == 315*9880d681SAndroid Build Coastguard Worker NVPTX::CUDA) { 316*9880d681SAndroid Build Coastguard Worker CurrentBankselLabelInBasicBlock = ""; 317*9880d681SAndroid Build Coastguard Worker reader = nullptr; 318*9880d681SAndroid Build Coastguard Worker } 319*9880d681SAndroid Build Coastguard Worker ~NVPTXAsmPrinter()320*9880d681SAndroid Build Coastguard Worker ~NVPTXAsmPrinter() { 321*9880d681SAndroid Build Coastguard Worker if (!reader) 322*9880d681SAndroid Build Coastguard Worker delete reader; 323*9880d681SAndroid Build Coastguard Worker } 324*9880d681SAndroid Build Coastguard Worker runOnMachineFunction(MachineFunction & F)325*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &F) override { 326*9880d681SAndroid Build Coastguard Worker nvptxSubtarget = &F.getSubtarget<NVPTXSubtarget>(); 327*9880d681SAndroid Build Coastguard Worker return AsmPrinter::runOnMachineFunction(F); 328*9880d681SAndroid Build Coastguard Worker } getAnalysisUsage(AnalysisUsage & AU)329*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override { 330*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineLoopInfo>(); 331*9880d681SAndroid Build Coastguard Worker AsmPrinter::getAnalysisUsage(AU); 332*9880d681SAndroid Build Coastguard Worker } 333*9880d681SAndroid Build Coastguard Worker 334*9880d681SAndroid Build Coastguard Worker bool ignoreLoc(const MachineInstr &); 335*9880d681SAndroid Build Coastguard Worker 336*9880d681SAndroid Build Coastguard Worker std::string getVirtualRegisterName(unsigned) const; 337*9880d681SAndroid Build Coastguard Worker 338*9880d681SAndroid Build Coastguard Worker DebugLoc prevDebugLoc; 339*9880d681SAndroid Build Coastguard Worker void emitLineNumberAsDotLoc(const MachineInstr &); 340*9880d681SAndroid Build Coastguard Worker }; 341*9880d681SAndroid Build Coastguard Worker } // end of namespace 342*9880d681SAndroid Build Coastguard Worker 343*9880d681SAndroid Build Coastguard Worker #endif 344