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