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