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_inlines.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_INLINES_H__
24
#define __NV50_IR_INLINES_H__
25
26
static inline CondCode reverseCondCode(CondCode cc)
27
{
28
static const uint8_t ccRev[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
29
30
return static_cast<CondCode>(ccRev[cc & 7] | (cc & ~7));
31
}
32
33
static inline CondCode inverseCondCode(CondCode cc)
34
{
35
return static_cast<CondCode>(cc ^ 7);
36
}
37
38
static inline bool isMemoryFile(DataFile f)
39
{
40
return (f >= FILE_MEMORY_CONST && f <= FILE_MEMORY_LOCAL);
41
}
42
43
// contrary to asTex(), this will never include SULD/SUST
44
static inline bool isTextureOp(operation op)
45
{
46
return (op >= OP_TEX && op <= OP_TEXPREP);
47
}
48
49
static inline bool isSurfaceOp(operation op)
50
{
51
return (op >= OP_SULDB && op <= OP_SULEA) || (op == OP_SUQ);
52
}
53
54
static inline unsigned int typeSizeof(DataType ty)
55
{
56
switch (ty) {
57
case TYPE_U8:
58
case TYPE_S8:
59
return 1;
60
case TYPE_F16:
61
case TYPE_U16:
62
case TYPE_S16:
63
return 2;
64
case TYPE_F32:
65
case TYPE_U32:
66
case TYPE_S32:
67
return 4;
68
case TYPE_F64:
69
case TYPE_U64:
70
case TYPE_S64:
71
return 8;
72
case TYPE_B96:
73
return 12;
74
case TYPE_B128:
75
return 16;
76
default:
77
return 0;
78
}
79
}
80
81
static inline unsigned int typeSizeofLog2(DataType ty)
82
{
83
switch (ty) {
84
case TYPE_F16:
85
case TYPE_U16:
86
case TYPE_S16:
87
return 1;
88
case TYPE_F32:
89
case TYPE_U32:
90
case TYPE_S32:
91
return 2;
92
case TYPE_F64:
93
case TYPE_U64:
94
case TYPE_S64:
95
return 3;
96
case TYPE_B96:
97
case TYPE_B128:
98
return 4;
99
case TYPE_U8:
100
case TYPE_S8:
101
default:
102
return 0;
103
}
104
}
105
106
static inline DataType typeOfSize(unsigned int size,
107
bool flt = false, bool sgn = false)
108
{
109
switch (size) {
110
case 1: return sgn ? TYPE_S8 : TYPE_U8;
111
case 2: return flt ? TYPE_F16 : (sgn ? TYPE_S16 : TYPE_U16);
112
case 8: return flt ? TYPE_F64 : (sgn ? TYPE_S64 : TYPE_U64);
113
case 12: return TYPE_B96;
114
case 16: return TYPE_B128;
115
case 4:
116
return flt ? TYPE_F32 : (sgn ? TYPE_S32 : TYPE_U32);
117
default:
118
return TYPE_NONE;
119
}
120
}
121
122
static inline bool isFloatType(DataType ty)
123
{
124
return (ty >= TYPE_F16 && ty <= TYPE_F64);
125
}
126
127
static inline bool isSignedIntType(DataType ty)
128
{
129
return (ty == TYPE_S8 || ty == TYPE_S16 || ty == TYPE_S32 || ty == TYPE_S64);
130
}
131
132
static inline bool isSignedType(DataType ty)
133
{
134
switch (ty) {
135
case TYPE_NONE:
136
case TYPE_U8:
137
case TYPE_U16:
138
case TYPE_U32:
139
case TYPE_U64:
140
case TYPE_B96:
141
case TYPE_B128:
142
return false;
143
default:
144
return true;
145
}
146
}
147
148
static inline DataType intTypeToSigned(DataType ty)
149
{
150
switch (ty) {
151
case TYPE_U64: return TYPE_S64;
152
case TYPE_U32: return TYPE_S32;
153
case TYPE_U16: return TYPE_S16;
154
case TYPE_U8: return TYPE_S8;
155
default:
156
return ty;
157
}
158
}
159
160
const ValueRef *ValueRef::getIndirect(int dim) const
161
{
162
return isIndirect(dim) ? &insn->src(indirect[dim]) : NULL;
163
}
164
165
DataFile ValueRef::getFile() const
166
{
167
return value ? value->reg.file : FILE_NULL;
168
}
169
170
unsigned int ValueRef::getSize() const
171
{
172
return value ? value->reg.size : 0;
173
}
174
175
Value *ValueRef::rep() const
176
{
177
assert(value);
178
return value->join;
179
}
180
181
Value *ValueDef::rep() const
182
{
183
assert(value);
184
return value->join;
185
}
186
187
DataFile ValueDef::getFile() const
188
{
189
return value ? value->reg.file : FILE_NULL;
190
}
191
192
unsigned int ValueDef::getSize() const
193
{
194
return value ? value->reg.size : 0;
195
}
196
197
void ValueDef::setSSA(LValue *lval)
198
{
199
origin = value->asLValue();
200
set(lval);
201
}
202
203
const LValue *ValueDef::preSSA() const
204
{
205
return origin;
206
}
207
208
Instruction *Value::getInsn() const
209
{
210
return defs.empty() ? NULL : defs.front()->getInsn();
211
}
212
213
Instruction *Value::getUniqueInsn() const
214
{
215
if (defs.empty())
216
return NULL;
217
218
// after regalloc, the definitions of coalesced values are linked
219
if (join != this) {
220
for (DefCIterator it = defs.begin(); it != defs.end(); ++it)
221
if ((*it)->get() == this)
222
return (*it)->getInsn();
223
// should be unreachable and trigger assertion at the end
224
}
225
#ifndef NDEBUG
226
if (reg.data.id < 0) {
227
int n = 0;
228
for (DefCIterator it = defs.begin(); n < 2 && it != defs.end(); ++it)
229
if ((*it)->get() == this) // don't count joined values
230
++n;
231
if (n > 1)
232
WARN("value %%%i not uniquely defined\n", id); // return NULL ?
233
}
234
#endif
235
assert(defs.front()->get() == this);
236
return defs.front()->getInsn();
237
}
238
239
inline bool Instruction::constrainedDefs() const
240
{
241
return defExists(1) || op == OP_UNION;
242
}
243
244
Value *Instruction::getIndirect(int s, int dim) const
245
{
246
return srcs[s].isIndirect(dim) ? getSrc(srcs[s].indirect[dim]) : NULL;
247
}
248
249
Value *Instruction::getPredicate() const
250
{
251
return (predSrc >= 0) ? getSrc(predSrc) : NULL;
252
}
253
254
void Instruction::setFlagsDef(int d, Value *val)
255
{
256
if (val) {
257
if (flagsDef < 0)
258
flagsDef = d;
259
setDef(flagsDef, val);
260
} else {
261
if (flagsDef >= 0) {
262
setDef(flagsDef, NULL);
263
flagsDef = -1;
264
}
265
}
266
}
267
268
void Instruction::setFlagsSrc(int s, Value *val)
269
{
270
flagsSrc = s;
271
setSrc(flagsSrc, val);
272
}
273
274
Value *TexInstruction::getIndirectR() const
275
{
276
return tex.rIndirectSrc >= 0 ? getSrc(tex.rIndirectSrc) : NULL;
277
}
278
279
Value *TexInstruction::getIndirectS() const
280
{
281
return tex.rIndirectSrc >= 0 ? getSrc(tex.rIndirectSrc) : NULL;
282
}
283
284
CmpInstruction *Instruction::asCmp()
285
{
286
if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)
287
return static_cast<CmpInstruction *>(this);
288
return NULL;
289
}
290
291
const CmpInstruction *Instruction::asCmp() const
292
{
293
if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)
294
return static_cast<const CmpInstruction *>(this);
295
return NULL;
296
}
297
298
FlowInstruction *Instruction::asFlow()
299
{
300
if (op >= OP_BRA && op <= OP_JOIN)
301
return static_cast<FlowInstruction *>(this);
302
return NULL;
303
}
304
305
const FlowInstruction *Instruction::asFlow() const
306
{
307
if (op >= OP_BRA && op <= OP_JOIN)
308
return static_cast<const FlowInstruction *>(this);
309
return NULL;
310
}
311
312
TexInstruction *Instruction::asTex()
313
{
314
if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ)
315
return static_cast<TexInstruction *>(this);
316
return NULL;
317
}
318
319
const TexInstruction *Instruction::asTex() const
320
{
321
if ((op >= OP_TEX && op <= OP_SULEA) || op == OP_SUQ)
322
return static_cast<const TexInstruction *>(this);
323
return NULL;
324
}
325
326
static inline Instruction *cloneForward(Function *ctx, Instruction *obj)
327
{
328
DeepClonePolicy<Function> pol(ctx);
329
330
for (int i = 0; obj->srcExists(i); ++i)
331
pol.set(obj->getSrc(i), obj->getSrc(i));
332
333
return obj->clone(pol);
334
}
335
336
// XXX: use a virtual function so we're really really safe ?
337
LValue *Value::asLValue()
338
{
339
if (reg.file >= FILE_GPR && reg.file <= LAST_REGISTER_FILE)
340
return static_cast<LValue *>(this);
341
return NULL;
342
}
343
344
Symbol *Value::asSym()
345
{
346
if (reg.file >= FILE_MEMORY_CONST)
347
return static_cast<Symbol *>(this);
348
return NULL;
349
}
350
351
const Symbol *Value::asSym() const
352
{
353
if (reg.file >= FILE_MEMORY_CONST)
354
return static_cast<const Symbol *>(this);
355
return NULL;
356
}
357
358
void Symbol::setOffset(int32_t offset)
359
{
360
reg.data.offset = offset;
361
}
362
363
void Symbol::setAddress(Symbol *base, int32_t offset)
364
{
365
baseSym = base;
366
reg.data.offset = offset;
367
}
368
369
void Symbol::setSV(SVSemantic sv, uint32_t index)
370
{
371
reg.data.sv.sv = sv;
372
reg.data.sv.index = index;
373
}
374
375
ImmediateValue *Value::asImm()
376
{
377
if (reg.file == FILE_IMMEDIATE)
378
return static_cast<ImmediateValue *>(this);
379
return NULL;
380
}
381
382
const ImmediateValue *Value::asImm() const
383
{
384
if (reg.file == FILE_IMMEDIATE)
385
return static_cast<const ImmediateValue *>(this);
386
return NULL;
387
}
388
389
Value *Value::get(Iterator &it)
390
{
391
return reinterpret_cast<Value *>(it.get());
392
}
393
394
bool BasicBlock::reachableBy(const BasicBlock *by, const BasicBlock *term)
395
{
396
return cfg.reachableBy(&by->cfg, &term->cfg);
397
}
398
399
BasicBlock *BasicBlock::get(Iterator &iter)
400
{
401
return reinterpret_cast<BasicBlock *>(iter.get());
402
}
403
404
BasicBlock *BasicBlock::get(Graph::Node *node)
405
{
406
assert(node);
407
return reinterpret_cast<BasicBlock *>(node->data);
408
}
409
410
Function *Function::get(Graph::Node *node)
411
{
412
assert(node);
413
return reinterpret_cast<Function *>(node->data);
414
}
415
416
LValue *Function::getLValue(int id)
417
{
418
assert((unsigned int)id < (unsigned int)allLValues.getSize());
419
return reinterpret_cast<LValue *>(allLValues.get(id));
420
}
421
422
#endif // __NV50_IR_INLINES_H__
423
424