2 * Copyright 2011 Christoph Bumiller
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #ifndef __NV50_IR_INLINES_H__
24 #define __NV50_IR_INLINES_H__
26 static inline CondCode
reverseCondCode(CondCode cc
)
28 static const uint8_t ccRev
[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
30 return static_cast<CondCode
>(ccRev
[cc
& 7] | (cc
& ~7));
33 static inline CondCode
inverseCondCode(CondCode cc
)
35 return static_cast<CondCode
>(cc
^ 7);
38 static inline bool isMemoryFile(DataFile f
)
40 return (f
>= FILE_MEMORY_CONST
&& f
<= FILE_MEMORY_LOCAL
);
43 static inline bool isTextureOp(operation op
)
45 return (op
>= OP_TEX
&& op
<= OP_TEXCSAA
);
48 static inline unsigned int typeSizeof(DataType ty
)
75 static inline DataType
typeOfSize(unsigned int size
,
76 bool flt
= false, bool sgn
= false)
79 case 1: return sgn
? TYPE_S8
: TYPE_U8
;
80 case 2: return flt
? TYPE_F16
: (sgn
? TYPE_S16
: TYPE_U16
);
81 case 8: return flt
? TYPE_F64
: (sgn
? TYPE_S64
: TYPE_U64
);
82 case 12: return TYPE_B96
;
83 case 16: return TYPE_B128
;
86 return flt
? TYPE_F32
: (sgn
? TYPE_S32
: TYPE_U32
);
90 static inline bool isFloatType(DataType ty
)
92 return (ty
>= TYPE_F16
&& ty
<= TYPE_F64
);
95 static inline bool isSignedIntType(DataType ty
)
97 return (ty
== TYPE_S8
|| ty
== TYPE_S16
|| ty
== TYPE_S32
);
100 static inline bool isSignedType(DataType ty
)
115 const ValueRef
*ValueRef::getIndirect(int dim
) const
117 return isIndirect(dim
) ? &insn
->src
[indirect
[dim
]] : NULL
;
120 DataFile
ValueRef::getFile() const
122 return value
? value
->reg
.file
: FILE_NULL
;
125 unsigned int ValueRef::getSize() const
127 return value
? value
->reg
.size
: 0;
130 Value
*ValueRef::rep() const
136 Value
*ValueDef::rep() const
142 DataFile
ValueDef::getFile() const
144 return value
? value
->reg
.file
: FILE_NULL
;
147 unsigned int ValueDef::getSize() const
149 return value
? value
->reg
.size
: 0;
152 void ValueDef::setSSA(LValue
*lval
)
157 prev
= reinterpret_cast<ValueDef
*>(save
);
162 void ValueDef::restoreDefList()
168 const LValue
*ValueDef::preSSA() const
170 return reinterpret_cast<LValue
*>(prev
);
173 Instruction
*Value::getInsn() const
175 assert(!defs
|| getUniqueInsn());
176 return defs
? defs
->getInsn() : NULL
;
179 Instruction
*Value::getUniqueInsn() const
183 ValueDef::Iterator it
= defs
->iterator();
184 while (!it
.end() && it
.get()->get() != this)
186 assert(it
.get()->get() == this);
187 return it
.get()->getInsn();
190 // after regalloc, the definitions of coalesced values are linked
191 if (reg
.data
.id
< 0) {
192 ValueDef::Iterator it
= defs
->iterator();
194 for (nDef
= 0; !it
.end() && nDef
< 2; it
.next())
195 if (it
.get()->get() == this) // don't count joined values
198 WARN("value %%%i not uniquely defined\n", id
); // return NULL ?
201 assert(defs
->get() == this);
202 return defs
->getInsn();
207 Value
*Instruction::getIndirect(int s
, int dim
) const
209 return src
[s
].isIndirect(dim
) ? getSrc(src
[s
].indirect
[dim
]) : NULL
;
212 Value
*Instruction::getPredicate() const
214 return (predSrc
>= 0) ? getSrc(predSrc
) : NULL
;
217 Value
*TexInstruction::getIndirectR() const
219 return tex
.rIndirectSrc
>= 0 ? getSrc(tex
.rIndirectSrc
) : NULL
;
222 Value
*TexInstruction::getIndirectS() const
224 return tex
.rIndirectSrc
>= 0 ? getSrc(tex
.rIndirectSrc
) : NULL
;
227 CmpInstruction
*Instruction::asCmp()
229 if (op
>= OP_SET_AND
&& op
<= OP_SLCT
&& op
!= OP_SELP
)
230 return static_cast<CmpInstruction
*>(this);
234 const CmpInstruction
*Instruction::asCmp() const
236 if (op
>= OP_SET_AND
&& op
<= OP_SLCT
&& op
!= OP_SELP
)
237 return static_cast<const CmpInstruction
*>(this);
241 FlowInstruction
*Instruction::asFlow()
243 if (op
>= OP_BRA
&& op
<= OP_JOIN
)
244 return static_cast<FlowInstruction
*>(this);
248 const FlowInstruction
*Instruction::asFlow() const
250 if (op
>= OP_BRA
&& op
<= OP_JOINAT
)
251 return static_cast<const FlowInstruction
*>(this);
255 TexInstruction
*Instruction::asTex()
257 if (op
>= OP_TEX
&& op
<= OP_TEXCSAA
)
258 return static_cast<TexInstruction
*>(this);
262 const TexInstruction
*Instruction::asTex() const
264 if (op
>= OP_TEX
&& op
<= OP_TEXCSAA
)
265 return static_cast<const TexInstruction
*>(this);
269 // XXX: use a virtual function so we're really really safe ?
270 LValue
*Value::asLValue()
272 if (reg
.file
>= FILE_GPR
&& reg
.file
<= FILE_ADDRESS
)
273 return static_cast<LValue
*>(this);
277 Symbol
*Value::asSym()
279 if (reg
.file
>= FILE_MEMORY_CONST
)
280 return static_cast<Symbol
*>(this);
284 const Symbol
*Value::asSym() const
286 if (reg
.file
>= FILE_MEMORY_CONST
)
287 return static_cast<const Symbol
*>(this);
291 void Symbol::setOffset(int32_t offset
)
293 reg
.data
.offset
= offset
;
296 void Symbol::setAddress(Symbol
*base
, int32_t offset
)
299 reg
.data
.offset
= offset
;
302 void Symbol::setSV(SVSemantic sv
, uint32_t index
)
305 reg
.data
.sv
.index
= index
;
308 ImmediateValue
*Value::asImm()
310 if (reg
.file
== FILE_IMMEDIATE
)
311 return static_cast<ImmediateValue
*>(this);
315 const ImmediateValue
*Value::asImm() const
317 if (reg
.file
== FILE_IMMEDIATE
)
318 return static_cast<const ImmediateValue
*>(this);
322 Value
*Value::get(Iterator
&it
)
324 return reinterpret_cast<Value
*>(it
.get());
327 bool BasicBlock::reachableBy(BasicBlock
*by
, BasicBlock
*term
)
329 return cfg
.reachableBy(&by
->cfg
, &term
->cfg
);
332 BasicBlock
*BasicBlock::get(Iterator
&iter
)
334 return reinterpret_cast<BasicBlock
*>(iter
.get());
337 BasicBlock
*BasicBlock::get(Graph::Node
*node
)
340 return reinterpret_cast<BasicBlock
*>(node
->data
);
343 LValue
*Function::getLValue(int id
)
345 assert((unsigned int)id
< (unsigned int)allLValues
.getSize());
346 return reinterpret_cast<LValue
*>(allLValues
.get(id
));
349 #endif // __NV50_IR_INLINES_H__