1 /* 2 * Copyright 2011 Christoph Bumiller 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23 #include "nv50_ir.h" 24 #include "nv50_ir_build_util.h" 25 26 /* On nvc0, surface info is obtained via the surface binding points passed 27 * to the SULD/SUST instructions. 28 * On nve4, surface info is stored in c[] and is used by various special 29 * instructions, e.g. for clamping coordinates or generating an address. 30 * They couldn't just have added an equivalent to TIC now, couldn't they ? 31 */ 32 #define NVC0_SU_INFO_ADDR 0x00 33 #define NVC0_SU_INFO_FMT 0x04 34 #define NVC0_SU_INFO_DIM_X 0x08 35 #define NVC0_SU_INFO_PITCH 0x0c 36 #define NVC0_SU_INFO_DIM_Y 0x10 37 #define NVC0_SU_INFO_ARRAY 0x14 38 #define NVC0_SU_INFO_DIM_Z 0x18 39 #define NVC0_SU_INFO_UNK1C 0x1c 40 #define NVC0_SU_INFO_WIDTH 0x20 41 #define NVC0_SU_INFO_HEIGHT 0x24 42 #define NVC0_SU_INFO_DEPTH 0x28 43 #define NVC0_SU_INFO_TARGET 0x2c 44 #define NVC0_SU_INFO_BSIZE 0x30 45 #define NVC0_SU_INFO_RAW_X 0x34 46 #define NVC0_SU_INFO_MS_X 0x38 47 #define NVC0_SU_INFO_MS_Y 0x3c 48 49 #define NVC0_SU_INFO__STRIDE 0x40 50 51 #define NVC0_SU_INFO_DIM(i) (0x08 + (i) * 8) 52 #define NVC0_SU_INFO_SIZE(i) (0x20 + (i) * 4) 53 #define NVC0_SU_INFO_MS(i) (0x38 + (i) * 4) 54 55 namespace nv50_ir { 56 57 class NVC0LegalizeSSA : public Pass 58 { 59 protected: 60 using Pass::visit; 61 bool visit(BasicBlock *) override; 62 bool visit(Function *) override; 63 64 // we want to insert calls to the builtin library only after optimization 65 void handleDIV(Instruction *); // integer division, modulus 66 void handleRCPRSQLib(Instruction *, Value *[]); 67 void handleRCPRSQ(Instruction *); // double precision float recip/rsqrt 68 void handleSET(CmpInstruction *); 69 void handleTEXLOD(TexInstruction *); 70 void handleShift(Instruction *); 71 void handleBREV(Instruction *); 72 73 void handleFTZ(Instruction *); 74 75 BuildUtil bld; 76 }; 77 78 class NVC0LegalizePostRA : public Pass 79 { 80 public: 81 NVC0LegalizePostRA(const Program *); 82 83 protected: 84 using Pass::visit; 85 bool visit(Function *) override; 86 bool visit(BasicBlock *) override; 87 88 private: 89 void replaceCvt(Instruction *); 90 void replaceZero(Instruction *); 91 bool tryReplaceContWithBra(BasicBlock *); 92 void propagateJoin(BasicBlock *); 93 94 struct TexUse 95 { TexUseTexUse96 TexUse(Instruction *use, const Instruction *tex, bool after) 97 : insn(use), tex(tex), after(after), level(-1) { } 98 Instruction *insn; 99 const Instruction *tex; // or split / mov 100 bool after; 101 int level; 102 }; 103 struct Limits 104 { LimitsLimits105 Limits() : min(0), max(0) { } LimitsLimits106 Limits(int min, int max) : min(min), max(max) { } 107 int min, max; 108 }; 109 bool insertTextureBarriers(Function *); 110 inline bool insnDominatedBy(const Instruction *, const Instruction *) const; 111 void findFirstUses(Instruction *texi, std::list<TexUse> &uses); 112 void findFirstUsesBB(int minGPR, int maxGPR, Instruction *start, 113 const Instruction *texi, std::list<TexUse> &uses, 114 std::unordered_set<const BasicBlock *> &visited); 115 void addTexUse(std::list<TexUse>&, Instruction *, const Instruction *); 116 const Instruction *recurseDef(const Instruction *); 117 118 private: 119 LValue *rZero; 120 LValue *carry; 121 LValue *pOne; 122 const bool needTexBar; 123 }; 124 125 class NVC0LoweringPass : public Pass 126 { 127 public: 128 NVC0LoweringPass(Program *); 129 130 protected: 131 bool handleRDSV(Instruction *); 132 bool handleEXPORT(Instruction *); 133 bool handleOUT(Instruction *); 134 bool handleDIV(Instruction *); 135 bool handleMOD(Instruction *); 136 bool handleSQRT(Instruction *); 137 bool handleTEX(TexInstruction *); 138 bool handleTXD(TexInstruction *); 139 bool handleTXQ(TexInstruction *); 140 virtual bool handleManualTXD(TexInstruction *); 141 bool handleTXLQ(TexInstruction *); 142 bool handleSUQ(TexInstruction *); 143 bool handleATOM(Instruction *); 144 bool handleATOMCctl(Instruction *); 145 bool handleCasExch(Instruction *); 146 void handleSurfaceOpGM107(TexInstruction *); 147 void handleSurfaceOpNVE4(TexInstruction *); 148 void handleSurfaceOpNVC0(TexInstruction *); 149 void handleSharedATOM(Instruction *); 150 void handleSharedATOMNVE4(Instruction *); 151 void handleLDST(Instruction *); 152 bool handleBUFQ(Instruction *); 153 void handlePIXLD(Instruction *); 154 155 void checkPredicate(Instruction *); 156 Value *loadMsAdjInfo32(TexInstruction::Target targ, uint32_t index, int slot, Value *ind, bool bindless); 157 158 bool visit(Instruction *) override; 159 bool visit(Function *) override; 160 bool visit(BasicBlock *) override; 161 162 private: 163 void readTessCoord(LValue *dst, int c); 164 165 Value *loadResInfo32(Value *ptr, uint32_t off, uint16_t base); 166 Value *loadResInfo64(Value *ptr, uint32_t off, uint16_t base); 167 Value *loadResLength32(Value *ptr, uint32_t off, uint16_t base); 168 Value *loadSuInfo32(Value *ptr, int slot, uint32_t off, bool bindless); 169 Value *loadBufInfo64(Value *ptr, uint32_t off); 170 Value *loadBufLength32(Value *ptr, uint32_t off); 171 Value *loadUboInfo64(Value *ptr, uint32_t off); 172 Value *loadUboLength32(Value *ptr, uint32_t off); 173 Value *loadMsInfo32(Value *ptr, uint32_t off); 174 175 void adjustCoordinatesMS(TexInstruction *); 176 TexInstruction *processSurfaceCoordsGM107(TexInstruction *, Instruction *[4]); 177 void processSurfaceCoordsNVE4(TexInstruction *); 178 void processSurfaceCoordsNVC0(TexInstruction *); 179 void convertSurfaceFormat(TexInstruction *, Instruction **); 180 void insertOOBSurfaceOpResult(TexInstruction *); 181 Value *calculateSampleOffset(Value *sampleID); 182 183 protected: 184 Value *loadTexHandle(Value *ptr, unsigned int slot); 185 186 BuildUtil bld; 187 188 private: 189 const Target *const targ; 190 191 LValue *gpEmitAddress; 192 }; 193 194 } // namespace nv50_ir 195