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