149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===-- NVPTXAsmPrinter.h - NVPTX LLVM assembly writer --------------------===// 249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// The LLVM Compiler Infrastructure 449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file is distributed under the University of Illinois Open Source 649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// License. See LICENSE.TXT for details. 749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file contains a printer that converts from our internal representation 1149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// of machine-dependent LLVM code to NVPTX assembly language. 1249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 1449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_LIB_TARGET_NVPTX_NVPTXASMPRINTER_H 1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_LIB_TARGET_NVPTX_NVPTXASMPRINTER_H 1749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTX.h" 1949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXSubtarget.h" 20a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "NVPTXTargetMachine.h" 21a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/ADT/SmallString.h" 22a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/ADT/StringExtras.h" 2349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/AsmPrinter.h" 240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 2549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/MC/MCAsmInfo.h" 2649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/MC/MCExpr.h" 2749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/MC/MCSymbol.h" 28a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/Support/CommandLine.h" 2949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Support/FormattedStream.h" 30a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/Target/TargetMachine.h" 3149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include <fstream> 3249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 3349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// The ptx syntax and format is very different from that usually seem in a .s 3449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// file, 3549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// therefore we are not able to use the MCAsmStreamer interface here. 3649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 3749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// We are handcrafting the output method here. 3849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 3949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// A better approach is to clone the MCAsmStreamer to a MCPTXAsmStreamer 4049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// (subclass of MCStreamer). 4149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 4249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskinamespace llvm { 4349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 4449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiclass LineReader { 4549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiprivate: 463639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski unsigned theCurLine; 4749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::ifstream fstr; 4849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski char buff[512]; 4949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::string theFileName; 5049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SmallVector<unsigned, 32> lineOffset; 5149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskipublic: 5249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski LineReader(std::string filename) { 5349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski theCurLine = 0; 5449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski fstr.open(filename.c_str()); 5549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski theFileName = filename; 5649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 5749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::string fileName() { return theFileName; } 583639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski ~LineReader() { fstr.close(); } 5949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::string readLine(unsigned line); 6049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski}; 6149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiclass LLVM_LIBRARY_VISIBILITY NVPTXAsmPrinter : public AsmPrinter { 6349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski class AggBuffer { 6549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Used to buffer the emitted string for initializing global 6649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // aggregates. 6749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // 6849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Normally an aggregate (array, vector or structure) is emitted 6949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // as a u8[]. However, if one element/field of the aggregate 7049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // is a non-NULL address, then the aggregate is emitted as u32[] 7149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // or u64[]. 7249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // 7349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // We first layout the aggregate in 'buffer' in bytes, except for 7449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // those symbol addresses. For the i-th symbol address in the 7549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski //aggregate, its corresponding 4-byte or 8-byte elements in 'buffer' 7649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // are filled with 0s. symbolPosInBuffer[i-1] records its position 7749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // in 'buffer', and Symbols[i-1] records the Value*. 7849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // 7949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Once we have this AggBuffer setup, we can choose how to print 8049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // it out. 8149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski public: 8249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned numSymbols; // number of symbol addresses 8349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski private: 8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const unsigned size; // size of the buffer in bytes 8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::vector<unsigned char> buffer; // the buffer 8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallVector<unsigned, 4> symbolPosInBuffer; 8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallVector<const Value *, 4> Symbols; 8949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned curpos; 9049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski raw_ostream &O; 9149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXAsmPrinter &AP; 92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool EmitGeneric; 9349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski public: 954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AggBuffer(unsigned size, raw_ostream &O, NVPTXAsmPrinter &AP) 964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : size(size), buffer(size), O(O), AP(AP) { 9749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski curpos = 0; 9849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski numSymbols = 0; 99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines EmitGeneric = AP.EmitGeneric; 10049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 10149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned addBytes(unsigned char *Ptr, int Num, int Bytes) { 1023639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski assert((curpos + Num) <= size); 1033639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski assert((curpos + Bytes) <= size); 1043639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski for (int i = 0; i < Num; ++i) { 10549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski buffer[curpos] = Ptr[i]; 1063639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski curpos++; 10749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 1083639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski for (int i = Num; i < Bytes; ++i) { 10949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski buffer[curpos] = 0; 1103639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski curpos++; 11149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 11249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return curpos; 11349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 11449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned addZeros(int Num) { 1153639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski assert((curpos + Num) <= size); 1163639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski for (int i = 0; i < Num; ++i) { 11749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski buffer[curpos] = 0; 1183639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski curpos++; 11949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 12049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return curpos; 12149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 1227536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski void addSymbol(const Value *GVar) { 12349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski symbolPosInBuffer.push_back(curpos); 12449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Symbols.push_back(GVar); 12549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski numSymbols++; 12649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 12749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void print() { 12849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (numSymbols == 0) { 12949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // print out in bytes 1303639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski for (unsigned i = 0; i < size; i++) { 13149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (i) 13249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski O << ", "; 1333639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski O << (unsigned int) buffer[i]; 13449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 1356366361998599a63a74ee7cc5f4ba900711c7e7aCraig Topper } else { 13649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // print out in 4-bytes or 8-bytes 13749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int pos = 0; 13849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int nSym = 0; 13949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int nextSymbolPos = symbolPosInBuffer[nSym]; 14049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int nBytes = 4; 141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (static_cast<const NVPTXTargetMachine &>(AP.TM).is64Bit()) 14249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski nBytes = 8; 1433639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski for (pos = 0; pos < size; pos += nBytes) { 14449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (pos) 14549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski O << ", "; 14649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (pos == nextSymbolPos) { 1477536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski const Value *v = Symbols[nSym]; 1487536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski if (const GlobalValue *GVar = dyn_cast<GlobalValue>(v)) { 149ffc7dca885151ed42642c2d6733e8db75d276621Rafael Espindola MCSymbol *Name = AP.getSymbol(GVar); 150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines PointerType *PTy = dyn_cast<PointerType>(GVar->getType()); 151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsNonGenericPointer = false; 152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (PTy && PTy->getAddressSpace() != 0) { 153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IsNonGenericPointer = true; 154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (EmitGeneric && !isa<Function>(v) && !IsNonGenericPointer) { 156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines O << "generic("; 157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines O << *Name; 158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines O << ")"; 159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines O << *Name; 161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1627536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski } else if (const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(v)) { 163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines O << *AP.lowerConstant(Cexpr); 1646366361998599a63a74ee7cc5f4ba900711c7e7aCraig Topper } else 1656366361998599a63a74ee7cc5f4ba900711c7e7aCraig Topper llvm_unreachable("symbol type unknown"); 16649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski nSym++; 16749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (nSym >= numSymbols) 1683639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski nextSymbolPos = size + 1; 16949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else 17049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski nextSymbolPos = symbolPosInBuffer[nSym]; 1713639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski } else if (nBytes == 4) 17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines O << *(unsigned int *)(&buffer[pos]); 1733639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski else 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines O << *(unsigned long long *)(&buffer[pos]); 17549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 17649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 17749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 17849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski }; 17949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 18049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski friend class AggBuffer; 18149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitSrcInText(StringRef filename, unsigned line); 18349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1843639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinskiprivate: 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *getPassName() const override { return "NVPTX Assembly Printer"; } 18649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 18749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Function *F; 18849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::string CurrentFnName; 18949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void EmitBasicBlockStart(const MachineBasicBlock &MBB) const override; 191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitFunctionEntryLabel() override; 192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitFunctionBodyStart() override; 193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitFunctionBodyEnd() override; 194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitImplicitDef(const MachineInstr *MI) const override; 19549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitInstruction(const MachineInstr *) override; 19782767327c59ede1f8663ec9b9a64a668993d501fJustin Holewinski void lowerToMCInst(const MachineInstr *MI, MCInst &OutMI); 19882767327c59ede1f8663ec9b9a64a668993d501fJustin Holewinski bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp); 199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOperand GetSymbolRef(const MCSymbol *Symbol); 20082767327c59ede1f8663ec9b9a64a668993d501fJustin Holewinski unsigned encodeVirtualRegister(unsigned Reg); 20149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitAlignment(unsigned NumBits, const GlobalValue *GV = nullptr) const {} 20349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2043639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski void printVecModifiedImmediate(const MachineOperand &MO, const char *Modifier, 2053639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski raw_ostream &O); 20649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *Modifier = nullptr); 20849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void printImplicitDef(const MachineInstr *MI, raw_ostream &O) const; 2097536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski void printModuleLevelGV(const GlobalVariable *GVar, raw_ostream &O, 2107536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski bool = false); 21149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void printParamName(int paramIndex, raw_ostream &O); 21249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void printParamName(Function::const_arg_iterator I, int paramIndex, 21349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski raw_ostream &O); 2147536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski void emitGlobals(const Module &M); 215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void emitHeader(Module &M, raw_ostream &O, const NVPTXSubtarget &STI); 2163639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski void emitKernelFunctionDirectives(const Function &F, raw_ostream &O) const; 21743777c3150c1dd12c661f62d5d7c95bf9b04c16aJustin Holewinski void emitVirtualRegister(unsigned int vr, raw_ostream &); 21849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void emitFunctionExternParamList(const MachineFunction &MF); 21949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void emitFunctionParamList(const Function *, raw_ostream &O); 22049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void emitFunctionParamList(const MachineFunction &MF, raw_ostream &O); 22149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void setAndEmitFunctionVirtualRegisters(const MachineFunction &MF); 2223639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski void emitFunctionTempData(const MachineFunction &MF, unsigned &FrameSize); 22349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool isImageType(const Type *Ty); 22449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void printReturnValStr(const Function *, raw_ostream &O); 22549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void printReturnValStr(const MachineFunction &MF, raw_ostream &O); 22630632d2fbb3c46e552a68aa7961b12eb44cece01Justin Holewinski bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 22730632d2fbb3c46e552a68aa7961b12eb44cece01Justin Holewinski unsigned AsmVariant, const char *ExtraCode, 228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines raw_ostream &) override; 22930632d2fbb3c46e552a68aa7961b12eb44cece01Justin Holewinski void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *Modifier = nullptr); 23130632d2fbb3c46e552a68aa7961b12eb44cece01Justin Holewinski bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 23230632d2fbb3c46e552a68aa7961b12eb44cece01Justin Holewinski unsigned AsmVariant, const char *ExtraCode, 233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines raw_ostream &) override; 23449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiprotected: 235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool doInitialization(Module &M) override; 236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool doFinalization(Module &M) override; 23749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 23849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiprivate: 23949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::string CurrentBankselLabelInBasicBlock; 24049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2417536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski bool GlobalsEmitted; 2427536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 24349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // This is specific per MachineFunction. 24449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const MachineRegisterInfo *MRI; 24549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // The contents are specific for each 24649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // MachineFunction. But the size of the 24749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // array is not. 2485443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski typedef DenseMap<unsigned, unsigned> VRegMap; 2495443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski typedef DenseMap<const TargetRegisterClass *, VRegMap> VRegRCMap; 2505443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski VRegRCMap VRegMapping; 251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 252ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Cache the subtarget here. 253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const NVPTXSubtarget *nvptxSubtarget; 254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 25549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Build the map between type name and ID based on module's type 25649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // symbol table. 25749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::map<const Type *, std::string> TypeNameMap; 25849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 25949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // List of variables demoted to a function scope. 2607536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski std::map<const Function *, std::vector<const GlobalVariable *> > localDecls; 26149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 26249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // To record filename to ID mapping 26349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::map<std::string, unsigned> filenameMap; 26449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void recordAndEmitFilenames(Module &); 26549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 26649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void emitPTXGlobalVariable(const GlobalVariable *GVar, raw_ostream &O); 2673639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski void emitPTXAddressSpace(unsigned int AddressSpace, raw_ostream &O) const; 2683639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski std::string getPTXFundamentalTypeStr(const Type *Ty, bool = true) const; 2697536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski void printScalarConstant(const Constant *CPV, raw_ostream &O); 2703639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski void printFPConstant(const ConstantFP *Fp, raw_ostream &O); 2717536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski void bufferLEByte(const Constant *CPV, int Bytes, AggBuffer *aggBuffer); 2727536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski void bufferAggregateConstant(const Constant *CV, AggBuffer *aggBuffer); 27349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 27449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void printOperandProper(const MachineOperand &MO); 27549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2763639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski void emitLinkageDirective(const GlobalValue *V, raw_ostream &O); 2777536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski void emitDeclarations(const Module &, raw_ostream &O); 27849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void emitDeclaration(const Function *, raw_ostream &O); 27949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 28049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski static const char *getRegisterName(unsigned RegNo); 28149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void emitDemotedVars(const Function *, raw_ostream &); 28249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool lowerImageHandleOperand(const MachineInstr *MI, unsigned OpNo, 284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOperand &MCOp); 285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void lowerImageHandleSymbol(unsigned Index, MCOperand &MCOp); 286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool isLoopHeaderOfNoUnroll(const MachineBasicBlock &MBB) const; 288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 28949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski LineReader *reader; 29049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski LineReader *getReader(std::string); 291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Used to control the need to emit .generic() in the initializer of 293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // module scope variables. 294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Although ptx supports the hybrid mode like the following, 295dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // .global .u32 a; 296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // .global .u32 b; 297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // .global .u32 addr[] = {a, generic(b)} 298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // we have difficulty representing the difference in the NVVM IR. 299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // 300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Since the address value should always be generic in CUDA C and always 301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // be specific in OpenCL, we use this simple control here. 302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // 303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool EmitGeneric; 304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 30549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskipublic: 306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NVPTXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) 307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : AsmPrinter(TM, std::move(Streamer)), 308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EmitGeneric(static_cast<NVPTXTargetMachine &>(TM).getDrvInterface() == 309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NVPTX::CUDA) { 31049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski CurrentBankselLabelInBasicBlock = ""; 311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines reader = nullptr; 31249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 31349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 31449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski ~NVPTXAsmPrinter() { 31549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (!reader) 31649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski delete reader; 31749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 31849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool runOnMachineFunction(MachineFunction &F) override { 320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines nvptxSubtarget = &F.getSubtarget<NVPTXSubtarget>(); 321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return AsmPrinter::runOnMachineFunction(F); 322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addRequired<MachineLoopInfo>(); 325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AsmPrinter::getAnalysisUsage(AU); 326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 32849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool ignoreLoc(const MachineInstr &); 32949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 33043777c3150c1dd12c661f62d5d7c95bf9b04c16aJustin Holewinski std::string getVirtualRegisterName(unsigned) const; 33149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 33249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski DebugLoc prevDebugLoc; 33349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski void emitLineNumberAsDotLoc(const MachineInstr &); 33449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski}; 33549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} // end of namespace 33649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 33749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#endif 338