Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h
4574 views
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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
* OTHER DEALINGS IN THE SOFTWARE.
21
*/
22
23
#ifndef __NV50_IR_BUILD_UTIL__
24
#define __NV50_IR_BUILD_UTIL__
25
26
namespace nv50_ir {
27
28
class BuildUtil
29
{
30
public:
31
BuildUtil();
32
BuildUtil(Program *);
33
34
inline void setProgram(Program *);
35
inline Program *getProgram() const { return prog; }
36
inline Function *getFunction() const { return func; }
37
38
// keeps inserting at head/tail of block
39
inline void setPosition(BasicBlock *, bool tail);
40
// position advances only if @after is true
41
inline void setPosition(Instruction *, bool after);
42
43
inline BasicBlock *getBB() { return bb; }
44
45
inline void insert(Instruction *);
46
inline void remove(Instruction *i) { assert(i->bb == bb); bb->remove(i); }
47
48
inline LValue *getScratch(int size = 4, DataFile = FILE_GPR);
49
// scratch value for a single assignment:
50
inline LValue *getSSA(int size = 4, DataFile = FILE_GPR);
51
52
inline Instruction *mkOp(operation, DataType, Value *);
53
Instruction *mkOp1(operation, DataType, Value *, Value *);
54
Instruction *mkOp2(operation, DataType, Value *, Value *, Value *);
55
Instruction *mkOp3(operation, DataType, Value *, Value *, Value *, Value *);
56
57
LValue *mkOp1v(operation, DataType, Value *, Value *);
58
LValue *mkOp2v(operation, DataType, Value *, Value *, Value *);
59
LValue *mkOp3v(operation, DataType, Value *, Value *, Value *, Value *);
60
61
Instruction *mkLoad(DataType, Value *dst, Symbol *, Value *ptr);
62
Instruction *mkStore(operation, DataType, Symbol *, Value *ptr, Value *val);
63
64
LValue *mkLoadv(DataType, Symbol *, Value *ptr);
65
66
Instruction *mkMov(Value *, Value *, DataType = TYPE_U32);
67
Instruction *mkMovToReg(int id, Value *);
68
Instruction *mkMovFromReg(Value *, int id);
69
inline Instruction *mkBMov(Value *, Value *);
70
71
Instruction *mkInterp(unsigned mode, Value *, int32_t offset, Value *rel);
72
Instruction *mkFetch(Value *, DataType, DataFile, int32_t offset,
73
Value *attrRel, Value *primRel);
74
75
Instruction *mkCvt(operation, DataType, Value *, DataType, Value *);
76
CmpInstruction *mkCmp(operation, CondCode, DataType,
77
Value *,
78
DataType, Value *, Value *, Value * = NULL);
79
TexInstruction *mkTex(operation, TexTarget,
80
uint16_t tic, uint16_t tsc,
81
const std::vector<Value *> &def,
82
const std::vector<Value *> &src);
83
Instruction *mkQuadop(uint8_t qop, Value *, uint8_t l, Value *, Value *);
84
85
FlowInstruction *mkFlow(operation, void *target, CondCode, Value *pred);
86
87
Instruction *mkSelect(Value *pred, Value *dst, Value *trSrc, Value *flSrc);
88
89
Instruction *mkSplit(Value *half[2], uint8_t halfSize, Value *);
90
91
void mkClobber(DataFile file, uint32_t regMask, int regUnitLog2);
92
93
ImmediateValue *mkImm(float);
94
ImmediateValue *mkImm(double);
95
ImmediateValue *mkImm(uint16_t);
96
ImmediateValue *mkImm(uint32_t);
97
ImmediateValue *mkImm(uint64_t);
98
99
ImmediateValue *mkImm(int i) { return mkImm((uint32_t)i); }
100
101
Value *loadImm(Value *dst, float);
102
Value *loadImm(Value *dst, double);
103
Value *loadImm(Value *dst, uint16_t);
104
Value *loadImm(Value *dst, uint32_t);
105
Value *loadImm(Value *dst, uint64_t);
106
107
Value *loadImm(Value *dst, int i) { return loadImm(dst, (uint32_t)i); }
108
109
// returns high part of the operation
110
static Instruction *split64BitOpPostRA(Function *, Instruction *,
111
Value *zero, Value *carry);
112
113
struct Location
114
{
115
Location(unsigned array, unsigned arrayIdx, unsigned i, unsigned c)
116
: array(array), arrayIdx(arrayIdx), i(i), c(c) { }
117
Location(const Location &l)
118
: array(l.array), arrayIdx(l.arrayIdx), i(l.i), c(l.c) { }
119
120
bool operator==(const Location &l) const
121
{
122
return
123
array == l.array && arrayIdx == l.arrayIdx && i == l.i && c == l.c;
124
}
125
126
bool operator<(const Location &l) const
127
{
128
return array != l.array ? array < l.array :
129
arrayIdx != l.arrayIdx ? arrayIdx < l.arrayIdx :
130
i != l.i ? i < l.i :
131
c != l.c ? c < l.c :
132
false;
133
}
134
135
unsigned array, arrayIdx, i, c;
136
};
137
138
typedef bimap<Location, Value *> ValueMap;
139
140
class DataArray
141
{
142
public:
143
DataArray(BuildUtil *bld) : up(bld), array(0), arrayIdx(0), baseAddr(0),
144
arrayLen(0), baseSym(NULL), vecDim(0), eltSize(0), file(FILE_NULL),
145
regOnly(false) { }
146
147
void setup(unsigned array, unsigned arrayIdx,
148
uint32_t base, int len, int vecDim, int eltSize,
149
DataFile file, int8_t fileIdx);
150
151
inline bool exists(ValueMap&, unsigned int i, unsigned int c);
152
153
Value *load(ValueMap&, int i, int c, Value *ptr);
154
void store(ValueMap&, int i, int c, Value *ptr, Value *value);
155
Value *acquire(ValueMap&, int i, int c);
156
157
private:
158
inline Value *lookup(ValueMap&, unsigned i, unsigned c);
159
inline Value *insert(ValueMap&, unsigned i, unsigned c, Value *v);
160
161
Symbol *mkSymbol(int i, int c);
162
163
private:
164
BuildUtil *up;
165
unsigned array, arrayIdx;
166
167
uint32_t baseAddr;
168
uint32_t arrayLen;
169
Symbol *baseSym;
170
171
uint8_t vecDim;
172
uint8_t eltSize; // in bytes
173
174
DataFile file;
175
bool regOnly;
176
};
177
178
Symbol *mkSymbol(DataFile file, int8_t fileIndex,
179
DataType ty, uint32_t baseAddress);
180
181
Symbol *mkSysVal(SVSemantic svName, uint32_t svIndex);
182
Symbol *mkTSVal(TSSemantic tsName);
183
184
private:
185
void init(Program *);
186
void addImmediate(ImmediateValue *);
187
inline unsigned int u32Hash(uint32_t);
188
189
protected:
190
Program *prog;
191
Function *func;
192
Instruction *pos;
193
BasicBlock *bb;
194
bool tail;
195
196
#define NV50_IR_BUILD_IMM_HT_SIZE 256
197
198
ImmediateValue *imms[NV50_IR_BUILD_IMM_HT_SIZE];
199
unsigned int immCount;
200
};
201
202
unsigned int BuildUtil::u32Hash(uint32_t u)
203
{
204
return (u % 273) % NV50_IR_BUILD_IMM_HT_SIZE;
205
}
206
207
void BuildUtil::setProgram(Program *program)
208
{
209
prog = program;
210
}
211
212
void
213
BuildUtil::setPosition(BasicBlock *block, bool atTail)
214
{
215
bb = block;
216
prog = bb->getProgram();
217
func = bb->getFunction();
218
pos = NULL;
219
tail = atTail;
220
}
221
222
void
223
BuildUtil::setPosition(Instruction *i, bool after)
224
{
225
bb = i->bb;
226
prog = bb->getProgram();
227
func = bb->getFunction();
228
pos = i;
229
tail = after;
230
assert(bb);
231
}
232
233
LValue *
234
BuildUtil::getScratch(int size, DataFile f)
235
{
236
LValue *lval = new_LValue(func, f);
237
lval->reg.size = size;
238
return lval;
239
}
240
241
LValue *
242
BuildUtil::getSSA(int size, DataFile f)
243
{
244
LValue *lval = new_LValue(func, f);
245
lval->ssa = 1;
246
lval->reg.size = size;
247
return lval;
248
}
249
250
void BuildUtil::insert(Instruction *i)
251
{
252
if (!pos) {
253
tail ? bb->insertTail(i) : bb->insertHead(i);
254
} else {
255
if (tail) {
256
bb->insertAfter(pos, i);
257
pos = i;
258
} else {
259
bb->insertBefore(pos, i);
260
}
261
}
262
}
263
264
Instruction *
265
BuildUtil::mkOp(operation op, DataType ty, Value *dst)
266
{
267
Instruction *insn = new_Instruction(func, op, ty);
268
insn->setDef(0, dst);
269
insert(insn);
270
if (op == OP_DISCARD || op == OP_EXIT ||
271
op == OP_JOIN ||
272
op == OP_QUADON || op == OP_QUADPOP ||
273
op == OP_EMIT || op == OP_RESTART)
274
insn->fixed = 1;
275
return insn;
276
}
277
278
inline LValue *
279
BuildUtil::mkOp1v(operation op, DataType ty, Value *dst, Value *src)
280
{
281
mkOp1(op, ty, dst, src);
282
return dst->asLValue();
283
}
284
285
inline LValue *
286
BuildUtil::mkOp2v(operation op, DataType ty, Value *dst,
287
Value *src0, Value *src1)
288
{
289
mkOp2(op, ty, dst, src0, src1);
290
return dst->asLValue();
291
}
292
293
inline LValue *
294
BuildUtil::mkOp3v(operation op, DataType ty, Value *dst,
295
Value *src0, Value *src1, Value *src2)
296
{
297
mkOp3(op, ty, dst, src0, src1, src2);
298
return dst->asLValue();
299
}
300
301
inline LValue *
302
BuildUtil::mkLoadv(DataType ty, Symbol *mem, Value *ptr)
303
{
304
LValue *dst = getScratch(typeSizeof(ty));
305
mkLoad(ty, dst, mem, ptr);
306
return dst;
307
}
308
309
inline Instruction *
310
BuildUtil::mkBMov(Value *dst, Value *src)
311
{
312
return mkCvt(OP_CVT, TYPE_U32, dst, TYPE_U32, src);
313
}
314
315
bool
316
BuildUtil::DataArray::exists(ValueMap &m, unsigned int i, unsigned int c)
317
{
318
assert(i < arrayLen && c < vecDim);
319
return !regOnly || m.r.count(Location(array, arrayIdx, i, c));
320
}
321
322
Value *
323
BuildUtil::DataArray::lookup(ValueMap &m, unsigned i, unsigned c)
324
{
325
ValueMap::r_iterator it = m.r.find(Location(array, arrayIdx, i, c));
326
return it != m.r.end() ? it->second : NULL;
327
}
328
329
Value *
330
BuildUtil::DataArray::insert(ValueMap &m, unsigned i, unsigned c, Value *v)
331
{
332
m.insert(Location(array, arrayIdx, i, c), v);
333
return v;
334
}
335
336
} // namespace nv50_ir
337
338
#endif // __NV50_IR_BUILD_UTIL_H__
339
340