2 * Copyright 2011 Christoph Bumiller
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
23 #ifndef __NV50_IR_BUILD_UTIL__
24 #define __NV50_IR_BUILD_UTIL__
33 inline void setProgram(Program *);
34 inline Program *getProgram() const { return prog; }
35 inline Function *getFunction() const { return func; }
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);
42 inline BasicBlock *getBB() { return bb; }
44 inline void insert(Instruction *);
45 inline void remove(Instruction *i) { assert(i->bb == bb); bb->remove(i); }
47 inline LValue *getScratch(int size = 4);
48 inline LValue *getSSA(int size = 4); // scratch value for a single assignment
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 *);
55 LValue *mkOp1v(operation, DataType, Value *, Value *);
56 LValue *mkOp2v(operation, DataType, Value *, Value *, Value *);
57 LValue *mkOp3v(operation, DataType, Value *, Value *, Value *, Value *);
59 LValue *mkLoad(DataType, Symbol *, Value *ptr);
60 Instruction *mkStore(operation, DataType, Symbol *, Value *ptr, Value *val);
62 Instruction *mkMov(Value *, Value *, DataType = TYPE_U32);
63 Instruction *mkMovToReg(int id, Value *);
64 Instruction *mkMovFromReg(Value *, int id);
66 Instruction *mkInterp(unsigned mode, Value *, int32_t offset, Value *rel);
67 Instruction *mkFetch(Value *, DataType, DataFile, int32_t offset,
68 Value *attrRel, Value *primRel);
70 Instruction *mkCvt(operation, DataType, Value *, DataType, Value *);
71 CmpInstruction *mkCmp(operation, CondCode, DataType,
73 Value *, Value *, Value * = NULL);
74 Instruction *mkTex(operation, TexTarget, uint8_t tic, uint8_t tsc,
75 Value **def, Value **src);
76 Instruction *mkQuadop(uint8_t qop, Value *, uint8_t l, Value *, Value *);
78 FlowInstruction *mkFlow(operation, BasicBlock *target,
79 CondCode, Value *pred);
81 Instruction *mkSelect(Value *pred, Value *dst, Value *trSrc, Value *flSrc);
83 void mkClobber(DataFile file, uint32_t regMask, int regUnitLog2);
85 ImmediateValue *mkImm(float);
86 ImmediateValue *mkImm(uint32_t);
87 ImmediateValue *mkImm(uint64_t);
89 ImmediateValue *mkImm(int i) { return mkImm((uint32_t)i); }
91 Value *loadImm(Value *dst, float);
92 Value *loadImm(Value *dst, uint32_t);
93 Value *loadImm(Value *dst, uint64_t);
95 Value *loadImm(Value *dst, int i) { return loadImm(dst, (uint32_t)i); }
101 DataArray(BuildUtil *);
104 inline void setParent(BuildUtil *bld) { assert(!up); up = bld; }
106 void setup(uint32_t base, int len, int vecDim, int size,
107 DataFile, int8_t fileIndex = 0);
109 inline bool exists(unsigned int i, unsigned int c);
111 Value *load(int i, int c, Value *ptr);
112 void store(int i, int c, Value *ptr, Value *value);
113 Value *acquire(int i, int c);
116 Symbol *mkSymbol(int i, int c, Symbol *base);
125 uint8_t eltSize; // in bytes
135 Symbol *mkSymbol(DataFile file, int8_t fileIndex,
136 DataType ty, uint32_t baseAddress);
138 Symbol *mkSysVal(SVSemantic svName, uint32_t svIndex);
141 void addImmediate(ImmediateValue *);
142 inline unsigned int u32Hash(uint32_t);
151 #define NV50_IR_BUILD_IMM_HT_SIZE 256
153 ImmediateValue *imms[NV50_IR_BUILD_IMM_HT_SIZE];
154 unsigned int immCount;
157 unsigned int BuildUtil::u32Hash(uint32_t u)
159 return (u % 273) % NV50_IR_BUILD_IMM_HT_SIZE;
162 void BuildUtil::setProgram(Program *program)
168 BuildUtil::setPosition(BasicBlock *block, bool atTail)
171 prog = bb->getProgram();
172 func = bb->getFunction();
178 BuildUtil::setPosition(Instruction *i, bool after)
181 prog = bb->getProgram();
182 func = bb->getFunction();
189 BuildUtil::getScratch(int size)
191 LValue *lval = new_LValue(func, FILE_GPR);
193 lval->reg.size = size;
198 BuildUtil::getSSA(int size)
200 LValue *lval = new_LValue(func, FILE_GPR);
203 lval->reg.size = size;
207 void BuildUtil::insert(Instruction *i)
210 tail ? bb->insertTail(i) : bb->insertHead(i);
213 bb->insertAfter(pos, i);
216 bb->insertBefore(pos, i);
222 BuildUtil::mkOp(operation op, DataType ty, Value *dst)
224 Instruction *insn = new_Instruction(func, op, ty);
225 insn->setDef(0, dst);
227 if (op == OP_DISCARD || op == OP_EXIT ||
229 op == OP_QUADON || op == OP_QUADPOP ||
230 op == OP_EMIT || op == OP_RESTART)
236 BuildUtil::mkOp1v(operation op, DataType ty, Value *dst, Value *src)
238 mkOp1(op, ty, dst, src);
239 return dst->asLValue();
243 BuildUtil::mkOp2v(operation op, DataType ty, Value *dst,
244 Value *src0, Value *src1)
246 mkOp2(op, ty, dst, src0, src1);
247 return dst->asLValue();
251 BuildUtil::mkOp3v(operation op, DataType ty, Value *dst,
252 Value *src0, Value *src1, Value *src2)
254 mkOp3(op, ty, dst, src0, src1, src2);
255 return dst->asLValue();
259 BuildUtil::DataArray::exists(unsigned int i, unsigned int c)
261 assert(i < arrayLen && c < vecDim);
262 return !regOnly || values[i * vecDim + c];
265 } // namespace nv50_ir
267 #endif // __NV50_IR_BUILD_UTIL_H__