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