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 private: 60 virtual bool visit(BasicBlock *); 61 virtual bool visit(Function *); 62 63 // we want to insert calls to the builtin library only after optimization 64 void handleDIV(Instruction *); // integer division, modulus 65 void handleRCPRSQLib(Instruction *, Value *[]); 66 void handleRCPRSQ(Instruction *); // double precision float recip/rsqrt 67 void handleSET(CmpInstruction *); 68 void handleTEXLOD(TexInstruction *); 69 void handleShift(Instruction *); 70 void handleBREV(Instruction *); 71 72 protected: 73 void handleFTZ(Instruction *); 74 75 BuildUtil bld; 76 }; 77 78 class NVC0LegalizePostRA : public Pass 79 { 80 public: 81 NVC0LegalizePostRA(const Program *); 82 83 private: 84 virtual bool visit(Function *); 85 virtual bool visit(BasicBlock *); 86 87 void replaceCvt(Instruction *); 88 void replaceZero(Instruction *); 89 bool tryReplaceContWithBra(BasicBlock *); 90 void propagateJoin(BasicBlock *); 91 92 struct TexUse 93 { TexUseTexUse94 TexUse(Instruction *use, const Instruction *tex, bool after) 95 : insn(use), tex(tex), after(after), level(-1) { } 96 Instruction *insn; 97 const Instruction *tex; // or split / mov 98 bool after; 99 int level; 100 }; 101 struct Limits 102 { LimitsLimits103 Limits() : min(0), max(0) { } LimitsLimits104 Limits(int min, int max) : min(min), max(max) { } 105 int min, max; 106 }; 107 bool insertTextureBarriers(Function *); 108 inline bool insnDominatedBy(const Instruction *, const Instruction *) const; 109 void findFirstUses(Instruction *texi, std::list<TexUse> &uses); 110 void findFirstUsesBB(int minGPR, int maxGPR, Instruction *start, 111 const Instruction *texi, std::list<TexUse> &uses, 112 std::unordered_set<const BasicBlock *> &visited); 113 void addTexUse(std::list<TexUse>&, Instruction *, const Instruction *); 114 const Instruction *recurseDef(const Instruction *); 115 116 private: 117 LValue *rZero; 118 LValue *carry; 119 LValue *pOne; 120 const bool needTexBar; 121 }; 122 123 class NVC0LoweringPass : public Pass 124 { 125 public: 126 NVC0LoweringPass(Program *); 127 128 protected: 129 bool handleRDSV(Instruction *); 130 bool handleWRSV(Instruction *); 131 bool handleEXPORT(Instruction *); 132 bool handleOUT(Instruction *); 133 bool handleDIV(Instruction *); 134 bool handleMOD(Instruction *); 135 bool handleSQRT(Instruction *); 136 bool handlePOW(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 virtual bool visit(Instruction *); 159 160 private: 161 virtual bool visit(Function *); 162 virtual bool visit(BasicBlock *); 163 164 void readTessCoord(LValue *dst, int c); 165 166 Value *loadResInfo32(Value *ptr, uint32_t off, uint16_t base); 167 Value *loadResInfo64(Value *ptr, uint32_t off, uint16_t base); 168 Value *loadResLength32(Value *ptr, uint32_t off, uint16_t base); 169 Value *loadSuInfo32(Value *ptr, int slot, uint32_t off, bool bindless); 170 Value *loadBufInfo64(Value *ptr, uint32_t off); 171 Value *loadBufLength32(Value *ptr, uint32_t off); 172 Value *loadUboInfo64(Value *ptr, uint32_t off); 173 Value *loadUboLength32(Value *ptr, uint32_t off); 174 Value *loadMsInfo32(Value *ptr, uint32_t off); 175 176 void adjustCoordinatesMS(TexInstruction *); 177 TexInstruction *processSurfaceCoordsGM107(TexInstruction *, Instruction *[4]); 178 void processSurfaceCoordsNVE4(TexInstruction *); 179 void processSurfaceCoordsNVC0(TexInstruction *); 180 void convertSurfaceFormat(TexInstruction *, Instruction **); 181 void insertOOBSurfaceOpResult(TexInstruction *); 182 Value *calculateSampleOffset(Value *sampleID); 183 184 protected: 185 Value *loadTexHandle(Value *ptr, unsigned int slot); 186 187 BuildUtil bld; 188 189 private: 190 const Target *const targ; 191 192 LValue *gpEmitAddress; 193 }; 194 195 } // namespace nv50_ir 196