nv50_ir_build_util.h revision d2d19ea51fa3575a8d014a69a9b835c335728817
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Copyright 2011 Christoph Bumiller 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 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_BUILD_UTIL__ 24#define __NV50_IR_BUILD_UTIL__ 25 26namespace nv50_ir { 27 28class BuildUtil 29{ 30public: 31 BuildUtil(); 32 33 inline void setProgram(Program *); 34 inline Program *getProgram() const { return prog; } 35 inline Function *getFunction() const { return func; } 36 37 // keeps inserting at head/tail of block 38 inline void setPosition(BasicBlock *, bool tail); 39 // position advances only if @after is true 40 inline void setPosition(Instruction *, bool after); 41 42 inline BasicBlock *getBB() { return bb; } 43 44 inline void insert(Instruction *); 45 inline void remove(Instruction *i) { assert(i->bb == bb); bb->remove(i); } 46 47 inline LValue *getScratch(int size = 4); 48 inline LValue *getSSA(int size = 4); // scratch value for a single assignment 49 50 inline Instruction *mkOp(operation, DataType, Value *); 51 Instruction *mkOp1(operation, DataType, Value *, Value *); 52 Instruction *mkOp2(operation, DataType, Value *, Value *, Value *); 53 Instruction *mkOp3(operation, DataType, Value *, Value *, Value *, Value *); 54 55 LValue *mkOp1v(operation, DataType, Value *, Value *); 56 LValue *mkOp2v(operation, DataType, Value *, Value *, Value *); 57 LValue *mkOp3v(operation, DataType, Value *, Value *, Value *, Value *); 58 59 LValue *mkLoad(DataType, Symbol *, Value *ptr); 60 Instruction *mkStore(operation, DataType, Symbol *, Value *ptr, Value *val); 61 62 Instruction *mkMov(Value *, Value *, DataType = TYPE_U32); 63 Instruction *mkMovToReg(int id, Value *); 64 Instruction *mkMovFromReg(Value *, int id); 65 66 Instruction *mkFetch(Value *, DataType, DataFile, int32_t offset, 67 Value *attrRel, Value *primRel); 68 69 Instruction *mkCvt(operation, DataType, Value *, DataType, Value *); 70 Instruction *mkCmp(operation, CondCode, DataType, 71 Value *, 72 Value *, Value *, Value * = NULL); 73 Instruction *mkTex(operation, TexTarget, uint8_t tic, uint8_t tsc, 74 Value **def, Value **src); 75 Instruction *mkQuadop(uint8_t qop, Value *, uint8_t l, Value *, Value *); 76 77 FlowInstruction *mkFlow(operation, BasicBlock *target, 78 CondCode, Value *pred); 79 80 Instruction *mkSelect(Value *pred, Value *dst, Value *trSrc, Value *flSrc); 81 82 void mkClobber(DataFile file, uint32_t regMask, int regUnitLog2); 83 84 ImmediateValue *mkImm(float); 85 ImmediateValue *mkImm(uint32_t); 86 ImmediateValue *mkImm(uint64_t); 87 88 ImmediateValue *mkImm(int i) { return mkImm((uint32_t)i); } 89 90 Value *loadImm(Value *dst, float); 91 Value *loadImm(Value *dst, uint32_t); 92 Value *loadImm(Value *dst, uint64_t); 93 94 Value *loadImm(Value *dst, int i) { return loadImm(dst, (uint32_t)i); } 95 96 class DataArray 97 { 98 public: 99 DataArray(); 100 DataArray(BuildUtil *); 101 ~DataArray(); 102 103 inline void setParent(BuildUtil *bld) { assert(!up); up = bld; } 104 105 void setup(uint32_t base, int len, int vecDim, int size, 106 DataFile, int8_t fileIndex = 0); 107 108 inline bool exists(unsigned int i, unsigned int c); 109 110 Value *load(int i, int c, Value *ptr); 111 void store(int i, int c, Value *ptr, Value *value); 112 Value *acquire(int i, int c); 113 114 private: 115 Symbol *mkSymbol(int i, int c, Symbol *base); 116 117 private: 118 Value **values; 119 uint32_t baseAddr; 120 uint32_t arrayLen; 121 Symbol *baseSym; 122 123 uint8_t vecDim; 124 uint8_t eltSize; // in bytes 125 126 DataFile file; 127 bool regOnly; 128 129 BuildUtil *up; 130 131 void init(); 132 }; 133 134 Symbol *mkSymbol(DataFile file, int8_t fileIndex, 135 DataType ty, uint32_t baseAddress); 136 137 Symbol *mkSysVal(SVSemantic svName, uint32_t svIndex); 138 139private: 140 void addImmediate(ImmediateValue *); 141 inline unsigned int u32Hash(uint32_t); 142 143protected: 144 Program *prog; 145 Function *func; 146 Instruction *pos; 147 BasicBlock *bb; 148 bool tail; 149 150#define NV50_IR_BUILD_IMM_HT_SIZE 256 151 152 ImmediateValue *imms[NV50_IR_BUILD_IMM_HT_SIZE]; 153 unsigned int immCount; 154}; 155 156unsigned int BuildUtil::u32Hash(uint32_t u) 157{ 158 return (u % 273) % NV50_IR_BUILD_IMM_HT_SIZE; 159} 160 161void BuildUtil::setProgram(Program *program) 162{ 163 prog = program; 164} 165 166void 167BuildUtil::setPosition(BasicBlock *block, bool atTail) 168{ 169 bb = block; 170 prog = bb->getProgram(); 171 func = bb->getFunction(); 172 pos = NULL; 173 tail = atTail; 174} 175 176void 177BuildUtil::setPosition(Instruction *i, bool after) 178{ 179 bb = i->bb; 180 prog = bb->getProgram(); 181 func = bb->getFunction(); 182 pos = i; 183 tail = after; 184 assert(bb); 185} 186 187LValue * 188BuildUtil::getScratch(int size) 189{ 190 LValue *lval = new_LValue(func, FILE_GPR); 191 if (size != 4) 192 lval->reg.size = size; 193 return lval; 194} 195 196LValue * 197BuildUtil::getSSA(int size) 198{ 199 LValue *lval = new_LValue(func, FILE_GPR); 200 lval->ssa = 1; 201 if (size != 4) 202 lval->reg.size = size; 203 return lval; 204} 205 206void BuildUtil::insert(Instruction *i) 207{ 208 if (!pos) { 209 tail ? bb->insertTail(i) : bb->insertHead(i); 210 } else { 211 if (tail) { 212 bb->insertAfter(pos, i); 213 pos = i; 214 } else { 215 bb->insertBefore(pos, i); 216 } 217 } 218} 219 220Instruction * 221BuildUtil::mkOp(operation op, DataType ty, Value *dst) 222{ 223 Instruction *insn = new_Instruction(func, op, ty); 224 insn->setDef(0, dst); 225 insert(insn); 226 if (op == OP_DISCARD || op == OP_EXIT || 227 op == OP_JOIN || 228 op == OP_QUADON || op == OP_QUADPOP || 229 op == OP_EMIT || op == OP_RESTART) 230 insn->fixed = 1; 231 return insn; 232} 233 234inline LValue * 235BuildUtil::mkOp1v(operation op, DataType ty, Value *dst, Value *src) 236{ 237 mkOp1(op, ty, dst, src); 238 return dst->asLValue(); 239} 240 241inline LValue * 242BuildUtil::mkOp2v(operation op, DataType ty, Value *dst, 243 Value *src0, Value *src1) 244{ 245 mkOp2(op, ty, dst, src0, src1); 246 return dst->asLValue(); 247} 248 249inline LValue * 250BuildUtil::mkOp3v(operation op, DataType ty, Value *dst, 251 Value *src0, Value *src1, Value *src2) 252{ 253 mkOp3(op, ty, dst, src0, src1, src2); 254 return dst->asLValue(); 255} 256 257bool 258BuildUtil::DataArray::exists(unsigned int i, unsigned int c) 259{ 260 assert(i < arrayLen && c < vecDim); 261 return !regOnly || values[i * vecDim + c]; 262} 263 264} // namespace nv50_ir 265 266#endif // __NV50_IR_BUILD_UTIL_H__ 267