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
;
85 return flt
? TYPE_F32
: (sgn
? TYPE_S32
: TYPE_U32
);
91 static inline bool isFloatType(DataType ty
)
93 return (ty
>= TYPE_F16
&& ty
<= TYPE_F64
);
96 static inline bool isSignedIntType(DataType ty
)
98 return (ty
== TYPE_S8
|| ty
== TYPE_S16
|| ty
== TYPE_S32
);
101 static inline bool isSignedType(DataType ty
)
116 const ValueRef
*ValueRef::getIndirect(int dim
) const
118 return isIndirect(dim
) ? &insn
->src(indirect
[dim
]) : NULL
;
121 DataFile
ValueRef::getFile() const
123 return value
? value
->reg
.file
: FILE_NULL
;
126 unsigned int ValueRef::getSize() const
128 return value
? value
->reg
.size
: 0;
131 Value
*ValueRef::rep() const
137 Value
*ValueDef::rep() const
143 DataFile
ValueDef::getFile() const
145 return value
? value
->reg
.file
: FILE_NULL
;
148 unsigned int ValueDef::getSize() const
150 return value
? value
->reg
.size
: 0;
153 void ValueDef::setSSA(LValue
*lval
)
155 origin
= value
->asLValue();
159 const LValue
*ValueDef::preSSA() const
164 Instruction
*Value::getInsn() const
166 return defs
.empty() ? NULL
: defs
.front()->getInsn();
169 Instruction
*Value::getUniqueInsn() const
174 // after regalloc, the definitions of coalesced values are linked
176 for (DefCIterator it
= defs
.begin(); it
!= defs
.end(); ++it
)
177 if ((*it
)->get() == this)
178 return (*it
)->getInsn();
179 // should be unreachable and trigger assertion at the end
182 if (reg
.data
.id
< 0) {
184 for (DefCIterator it
= defs
.begin(); n
< 2 && it
!= defs
.end(); ++it
)
185 if ((*it
)->get() == this) // don't count joined values
188 WARN("value %%%i not uniquely defined\n", id
); // return NULL ?
191 assert(defs
.front()->get() == this);
192 return defs
.front()->getInsn();
195 Value
*Instruction::getIndirect(int s
, int dim
) const
197 return srcs
[s
].isIndirect(dim
) ? getSrc(srcs
[s
].indirect
[dim
]) : NULL
;
200 Value
*Instruction::getPredicate() const
202 return (predSrc
>= 0) ? getSrc(predSrc
) : NULL
;
205 void Instruction::setFlagsDef(int d
, Value
*val
)
210 setDef(flagsDef
, val
);
213 setDef(flagsDef
, NULL
);
219 void Instruction::setFlagsSrc(int s
, Value
*val
)
222 setSrc(flagsSrc
, val
);
225 Value
*TexInstruction::getIndirectR() const
227 return tex
.rIndirectSrc
>= 0 ? getSrc(tex
.rIndirectSrc
) : NULL
;
230 Value
*TexInstruction::getIndirectS() const
232 return tex
.rIndirectSrc
>= 0 ? getSrc(tex
.rIndirectSrc
) : NULL
;
235 CmpInstruction
*Instruction::asCmp()
237 if (op
>= OP_SET_AND
&& op
<= OP_SLCT
&& op
!= OP_SELP
)
238 return static_cast<CmpInstruction
*>(this);
242 const CmpInstruction
*Instruction::asCmp() const
244 if (op
>= OP_SET_AND
&& op
<= OP_SLCT
&& op
!= OP_SELP
)
245 return static_cast<const CmpInstruction
*>(this);
249 FlowInstruction
*Instruction::asFlow()
251 if (op
>= OP_BRA
&& op
<= OP_JOIN
)
252 return static_cast<FlowInstruction
*>(this);
256 const FlowInstruction
*Instruction::asFlow() const
258 if (op
>= OP_BRA
&& op
<= OP_JOINAT
)
259 return static_cast<const FlowInstruction
*>(this);
263 TexInstruction
*Instruction::asTex()
265 if (op
>= OP_TEX
&& op
<= OP_TEXCSAA
)
266 return static_cast<TexInstruction
*>(this);
270 const TexInstruction
*Instruction::asTex() const
272 if (op
>= OP_TEX
&& op
<= OP_TEXCSAA
)
273 return static_cast<const TexInstruction
*>(this);
277 // XXX: use a virtual function so we're really really safe ?
278 LValue
*Value::asLValue()
280 if (reg
.file
>= FILE_GPR
&& reg
.file
<= FILE_ADDRESS
)
281 return static_cast<LValue
*>(this);
285 Symbol
*Value::asSym()
287 if (reg
.file
>= FILE_MEMORY_CONST
)
288 return static_cast<Symbol
*>(this);
292 const Symbol
*Value::asSym() const
294 if (reg
.file
>= FILE_MEMORY_CONST
)
295 return static_cast<const Symbol
*>(this);
299 void Symbol::setOffset(int32_t offset
)
301 reg
.data
.offset
= offset
;
304 void Symbol::setAddress(Symbol
*base
, int32_t offset
)
307 reg
.data
.offset
= offset
;
310 void Symbol::setSV(SVSemantic sv
, uint32_t index
)
313 reg
.data
.sv
.index
= index
;
316 ImmediateValue
*Value::asImm()
318 if (reg
.file
== FILE_IMMEDIATE
)
319 return static_cast<ImmediateValue
*>(this);
323 const ImmediateValue
*Value::asImm() const
325 if (reg
.file
== FILE_IMMEDIATE
)
326 return static_cast<const ImmediateValue
*>(this);
330 Value
*Value::get(Iterator
&it
)
332 return reinterpret_cast<Value
*>(it
.get());
335 bool BasicBlock::reachableBy(BasicBlock
*by
, BasicBlock
*term
)
337 return cfg
.reachableBy(&by
->cfg
, &term
->cfg
);
340 BasicBlock
*BasicBlock::get(Iterator
&iter
)
342 return reinterpret_cast<BasicBlock
*>(iter
.get());
345 BasicBlock
*BasicBlock::get(Graph::Node
*node
)
348 return reinterpret_cast<BasicBlock
*>(node
->data
);
351 LValue
*Function::getLValue(int id
)
353 assert((unsigned int)id
< (unsigned int)allLValues
.getSize());
354 return reinterpret_cast<LValue
*>(allLValues
.get(id
));
357 #endif // __NV50_IR_INLINES_H__