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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 */ 22 23 #ifndef __NV50_IR_TARGET_H__ 24 #define __NV50_IR_TARGET_H__ 25 26 #include "nv50_ir.h" 27 28 namespace nv50_ir { 29 30 struct RelocInfo; 31 32 struct 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 50 struct 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 61 class CodeEmitter 62 { 63 public: 64 CodeEmitter(const Target *); 65 66 // returns whether the instruction was encodable and written 67 virtual bool emitInstruction(Instruction *) = 0; 68 69 virtual uint32_t getMinEncodingSize(const Instruction *) const = 0; 70 71 void setCodeLocation(void *, uint32_t size); 72 inline void *getCodeLocation() const { return code; } 73 inline uint32_t getCodeSize() const { return codeSize; } 74 75 bool addReloc(RelocEntry::Type, int w, uint32_t data, uint32_t m, 76 int s); 77 78 inline void *getRelocInfo() const { return relocInfo; } 79 80 void prepareEmission(Program *); 81 virtual void prepareEmission(Function *); 82 virtual void prepareEmission(BasicBlock *); 83 84 void printBinary() const; 85 86 protected: 87 const Target *targ; 88 89 uint32_t *code; 90 uint32_t codeSize; 91 uint32_t codeSizeLimit; 92 93 RelocInfo *relocInfo; 94 }; 95 96 97 enum OpClass 98 { 99 OPCLASS_MOVE = 0, 100 OPCLASS_LOAD = 1, 101 OPCLASS_STORE = 2, 102 OPCLASS_ARITH = 3, 103 OPCLASS_SHIFT = 4, 104 OPCLASS_SFU = 5, 105 OPCLASS_LOGIC = 6, 106 OPCLASS_COMPARE = 7, 107 OPCLASS_CONVERT = 8, 108 OPCLASS_ATOMIC = 9, 109 OPCLASS_TEXTURE = 10, 110 OPCLASS_SURFACE = 11, 111 OPCLASS_FLOW = 12, 112 OPCLASS_PSEUDO = 14, 113 OPCLASS_OTHER = 15 114 }; 115 116 class Target 117 { 118 public: 119 Target(bool j, bool s) : joinAnterior(j), hasSWSched(s) { } 120 121 static Target *create(uint32_t chipset); 122 static void destroy(Target *); 123 124 // 0x50 and 0x84 to 0xaf for nv50 125 // 0xc0 to 0xdf for nvc0 126 inline uint32_t getChipset() const { return chipset; } 127 128 virtual CodeEmitter *getCodeEmitter(Program::Type) = 0; 129 130 // Drivers should upload this so we can use it from all programs. 131 // The address chosen is supplied to the relocation routine. 132 virtual void getBuiltinCode(const uint32_t **code, uint32_t *size) const = 0; 133 134 virtual void parseDriverInfo(const struct nv50_ir_prog_info *info) { } 135 136 virtual bool runLegalizePass(Program *, CGStage stage) const = 0; 137 138 public: 139 struct OpInfo 140 { 141 OpInfo *variants; 142 operation op; 143 uint16_t srcTypes; 144 uint16_t dstTypes; 145 uint32_t immdBits; 146 uint8_t srcNr; 147 uint8_t srcMods[3]; 148 uint8_t dstMods; 149 uint8_t srcFiles[3]; 150 uint8_t dstFiles; 151 unsigned int minEncSize : 4; 152 unsigned int vector : 1; 153 unsigned int predicate : 1; 154 unsigned int commutative : 1; 155 unsigned int pseudo : 1; 156 unsigned int flow : 1; 157 unsigned int hasDest : 1; 158 unsigned int terminator : 1; 159 }; 160 161 inline const OpInfo& getOpInfo(const Instruction *) const; 162 inline const OpInfo& getOpInfo(const operation) const; 163 164 inline DataFile nativeFile(DataFile f) const; 165 166 virtual bool insnCanLoad(const Instruction *insn, int s, 167 const Instruction *ld) const = 0; 168 virtual bool isOpSupported(operation, DataType) const = 0; 169 virtual bool isAccessSupported(DataFile, DataType) const = 0; 170 virtual bool isModSupported(const Instruction *, 171 int s, Modifier) const = 0; 172 virtual bool isSatSupported(const Instruction *) const = 0; 173 virtual bool isPostMultiplySupported(operation op, float f, 174 int& e) const { return false; } 175 virtual bool mayPredicate(const Instruction *, 176 const Value *) const = 0; 177 178 // whether @insn can be issued together with @next (order matters) 179 virtual bool canDualIssue(const Instruction *insn, 180 const Instruction *next) const { return false; } 181 virtual int getLatency(const Instruction *) const { return 1; } 182 virtual int getThroughput(const Instruction *) const { return 1; } 183 184 virtual unsigned int getFileSize(DataFile) const = 0; 185 virtual unsigned int getFileUnit(DataFile) const = 0; 186 187 virtual uint32_t getSVAddress(DataFile, const Symbol *) const = 0; 188 189 public: 190 const bool joinAnterior; // true if join is executed before the op 191 const bool hasSWSched; // true if code should provide scheduling data 192 193 static const uint8_t operationSrcNr[OP_LAST + 1]; 194 static const OpClass operationClass[OP_LAST + 1]; 195 196 static inline uint8_t getOpSrcNr(operation op) 197 { 198 return operationSrcNr[op]; 199 } 200 static inline OpClass getOpClass(operation op) 201 { 202 return operationClass[op]; 203 } 204 205 protected: 206 uint32_t chipset; 207 208 DataFile nativeFileMap[DATA_FILE_COUNT]; 209 210 OpInfo opInfo[OP_LAST + 1]; 211 }; 212 213 const Target::OpInfo& Target::getOpInfo(const Instruction *insn) const 214 { 215 return opInfo[MIN2(insn->op, OP_LAST)]; 216 } 217 218 const Target::OpInfo& Target::getOpInfo(const operation op) const 219 { 220 return opInfo[op]; 221 } 222 223 inline DataFile Target::nativeFile(DataFile f) const 224 { 225 return nativeFileMap[f]; 226 } 227 228 } // namespace nv50_ir 229 230 #endif // __NV50_IR_TARGET_H__ 231