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#ifndef __NV50_IR_TARGET_H__ 24#define __NV50_IR_TARGET_H__ 25 26#include "nv50_ir.h" 27 28namespace nv50_ir { 29 30struct RelocInfo; 31 32struct RelocEntry 33{ 34 enum Type 35 { 36 TYPE_CODE, 37 TYPE_BUILTIN, 38 TYPE_DATA 39 }; 40 41 uint32_t data; 42 uint32_t mask; 43 uint32_t offset; 44 int8_t bitPos; 45 Type type; 46 47 inline void apply(uint32_t *binary, const RelocInfo *info) const; 48}; 49 50struct RelocInfo 51{ 52 uint32_t codePos; 53 uint32_t libPos; 54 uint32_t dataPos; 55 56 uint32_t count; 57 58 RelocEntry entry[0]; 59}; 60 61struct FixupData { 62 FixupData(bool force, bool flat, uint8_t alphatest, bool msaa) : 63 force_persample_interp(force), flatshade(flat), alphatest(alphatest), msaa(msaa) {} 64 bool force_persample_interp; 65 bool flatshade; 66 uint8_t alphatest; 67 bool msaa; 68}; 69 70struct FixupEntry; 71typedef void (*FixupApply)(const FixupEntry*, uint32_t*, const FixupData&); 72 73struct FixupEntry 74{ 75 FixupEntry(FixupApply apply, int ipa, int reg, int loc) : 76 apply(apply), ipa(ipa), reg(reg), loc(loc) {} 77 78 FixupApply apply; 79 union { 80 struct { 81 uint32_t ipa:4; // SC mode used to identify colors 82 uint32_t reg:8; // The reg used for perspective division 83 uint32_t loc:20; // Let's hope we don't have more than 1M-sized shaders 84 }; 85 uint32_t val; 86 }; 87}; 88 89struct FixupInfo 90{ 91 uint32_t count; 92 FixupEntry entry[0]; 93}; 94 95class CodeEmitter 96{ 97public: 98 CodeEmitter(const Target *); 99 virtual ~CodeEmitter() { } 100 101 // returns whether the instruction was encodable and written 102 virtual bool emitInstruction(Instruction *) = 0; 103 104 virtual uint32_t getMinEncodingSize(const Instruction *) const = 0; 105 106 void setCodeLocation(void *, uint32_t size); 107 inline void *getCodeLocation() const { return code; } 108 inline uint32_t getCodeSize() const { return codeSize; } 109 110 bool addReloc(RelocEntry::Type, int w, uint32_t data, uint32_t m, 111 int s); 112 113 inline void *getRelocInfo() const { return relocInfo; } 114 115 bool addInterp(int ipa, int reg, FixupApply apply); 116 inline void *getFixupInfo() const { return fixupInfo; } 117 118 virtual void prepareEmission(Program *); 119 virtual void prepareEmission(Function *); 120 virtual void prepareEmission(BasicBlock *); 121 122 void printBinary() const; 123 124protected: 125 const Target *targ; 126 127 uint32_t *code; 128 uint32_t codeSize; 129 uint32_t codeSizeLimit; 130 131 RelocInfo *relocInfo; 132 FixupInfo *fixupInfo; 133}; 134 135 136enum OpClass 137{ 138 OPCLASS_MOVE = 0, 139 OPCLASS_LOAD = 1, 140 OPCLASS_STORE = 2, 141 OPCLASS_ARITH = 3, 142 OPCLASS_SHIFT = 4, 143 OPCLASS_SFU = 5, 144 OPCLASS_LOGIC = 6, 145 OPCLASS_COMPARE = 7, 146 OPCLASS_CONVERT = 8, 147 OPCLASS_ATOMIC = 9, 148 OPCLASS_TEXTURE = 10, 149 OPCLASS_SURFACE = 11, 150 OPCLASS_FLOW = 12, 151 OPCLASS_PSEUDO = 14, 152 OPCLASS_VECTOR = 15, 153 OPCLASS_BITFIELD = 16, 154 OPCLASS_CONTROL = 17, 155 OPCLASS_OTHER = 18 156}; 157 158class Target 159{ 160public: 161 Target(bool m, bool j, bool s) : hasJoin(m), joinAnterior(j), hasSWSched(s) { } 162 virtual ~Target() { } 163 164 static Target *create(uint32_t chipset); 165 static void destroy(Target *); 166 167 // 0x50 and 0x84 to 0xaf for nv50 168 // 0xc0 to 0xdf for nvc0 169 inline uint32_t getChipset() const { return chipset; } 170 171 virtual CodeEmitter *getCodeEmitter(Program::Type) = 0; 172 173 // Drivers should upload this so we can use it from all programs. 174 // The address chosen is supplied to the relocation routine. 175 virtual void getBuiltinCode(const uint32_t **code, uint32_t *size) const = 0; 176 177 virtual void parseDriverInfo(const struct nv50_ir_prog_info *info, 178 const struct nv50_ir_prog_info_out *info_out) { 179 if (info_out->type == PIPE_SHADER_COMPUTE) { 180 threads = info->prop.cp.numThreads[0] * 181 info->prop.cp.numThreads[1] * 182 info->prop.cp.numThreads[2]; 183 if (threads == 0) 184 threads = info->target >= NVISA_GK104_CHIPSET ? 1024 : 512; 185 } else { 186 threads = 32; // doesn't matter, just not too big. 187 } 188 } 189 190 virtual bool runLegalizePass(Program *, CGStage stage) const = 0; 191 192public: 193 struct OpInfo 194 { 195 OpInfo *variants; 196 operation op; 197 uint16_t srcTypes; 198 uint16_t dstTypes; 199 uint32_t immdBits; 200 uint8_t srcNr; 201 uint8_t srcMods[3]; 202 uint8_t dstMods; 203 uint16_t srcFiles[3]; 204 uint16_t dstFiles; 205 unsigned int minEncSize : 5; 206 unsigned int vector : 1; 207 unsigned int predicate : 1; 208 unsigned int commutative : 1; 209 unsigned int pseudo : 1; 210 unsigned int flow : 1; 211 unsigned int hasDest : 1; 212 unsigned int terminator : 1; 213 }; 214 215 inline const OpInfo& getOpInfo(const Instruction *) const; 216 inline const OpInfo& getOpInfo(const operation) const; 217 218 inline DataFile nativeFile(DataFile f) const; 219 220 virtual bool insnCanLoad(const Instruction *insn, int s, 221 const Instruction *ld) const = 0; 222 virtual bool insnCanLoadOffset(const Instruction *insn, int s, 223 int offset) const = 0; 224 virtual bool isOpSupported(operation, DataType) const = 0; 225 virtual bool isAccessSupported(DataFile, DataType) const = 0; 226 virtual bool isModSupported(const Instruction *, 227 int s, Modifier) const = 0; 228 virtual bool isSatSupported(const Instruction *) const = 0; 229 virtual bool isPostMultiplySupported(operation op, float f, 230 int& e) const { return false; } 231 virtual bool mayPredicate(const Instruction *, 232 const Value *) const = 0; 233 234 // whether @insn can be issued together with @next (order matters) 235 virtual bool canDualIssue(const Instruction *insn, 236 const Instruction *next) const { return false; } 237 virtual int getLatency(const Instruction *) const { return 1; } 238 virtual int getThroughput(const Instruction *) const { return 1; } 239 240 virtual unsigned int getFileSize(DataFile) const = 0; 241 virtual unsigned int getFileUnit(DataFile) const = 0; 242 243 virtual uint32_t getSVAddress(DataFile, const Symbol *) const = 0; 244 245public: 246 const bool hasJoin; // true if instructions have a join modifier 247 const bool joinAnterior; // true if join is executed before the op 248 const bool hasSWSched; // true if code should provide scheduling data 249 250 static const uint8_t operationSrcNr[]; 251 static const OpClass operationClass[]; 252 253 static inline uint8_t getOpSrcNr(operation op) 254 { 255 return operationSrcNr[op]; 256 } 257 static inline OpClass getOpClass(operation op) 258 { 259 return operationClass[op]; 260 } 261 262protected: 263 uint32_t chipset; 264 uint32_t threads; 265 266 DataFile nativeFileMap[DATA_FILE_COUNT]; 267 268 OpInfo opInfo[OP_LAST + 1]; 269}; 270 271const Target::OpInfo& Target::getOpInfo(const Instruction *insn) const 272{ 273 return opInfo[MIN2(insn->op, OP_LAST)]; 274} 275 276const Target::OpInfo& Target::getOpInfo(const operation op) const 277{ 278 return opInfo[op]; 279} 280 281inline DataFile Target::nativeFile(DataFile f) const 282{ 283 return nativeFileMap[f]; 284} 285 286} // namespace nv50_ir 287 288#endif // __NV50_IR_TARGET_H__ 289