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 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.
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 // contrary to asTex(), this will never include SULD/SUST
44 static inline bool isTextureOp(operation op
)
46 return (op
>= OP_TEX
&& op
<= OP_TEXPREP
);
49 static inline bool isSurfaceOp(operation op
)
51 return (op
>= OP_SULDB
&& op
<= OP_SULEA
);
54 static inline unsigned int typeSizeof(DataType ty
)
81 static inline unsigned int typeSizeofLog2(DataType ty
)
106 static inline DataType
typeOfSize(unsigned int size
,
107 bool flt
= false, bool sgn
= false)
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
;
116 return flt
? TYPE_F32
: (sgn
? TYPE_S32
: TYPE_U32
);
122 static inline bool isFloatType(DataType ty
)
124 return (ty
>= TYPE_F16
&& ty
<= TYPE_F64
);
127 static inline bool isSignedIntType(DataType ty
)
129 return (ty
== TYPE_S8
|| ty
== TYPE_S16
|| ty
== TYPE_S32
);
132 static inline bool isSignedType(DataType ty
)
147 static inline DataType
intTypeToSigned(DataType ty
)
150 case TYPE_U32
: return TYPE_S32
;
151 case TYPE_U16
: return TYPE_S16
;
152 case TYPE_U8
: return TYPE_S8
;
158 const ValueRef
*ValueRef::getIndirect(int dim
) const
160 return isIndirect(dim
) ? &insn
->src(indirect
[dim
]) : NULL
;
163 DataFile
ValueRef::getFile() const
165 return value
? value
->reg
.file
: FILE_NULL
;
168 unsigned int ValueRef::getSize() const
170 return value
? value
->reg
.size
: 0;
173 Value
*ValueRef::rep() const
179 Value
*ValueDef::rep() const
185 DataFile
ValueDef::getFile() const
187 return value
? value
->reg
.file
: FILE_NULL
;
190 unsigned int ValueDef::getSize() const
192 return value
? value
->reg
.size
: 0;
195 void ValueDef::setSSA(LValue
*lval
)
197 origin
= value
->asLValue();
201 const LValue
*ValueDef::preSSA() const
206 Instruction
*Value::getInsn() const
208 return defs
.empty() ? NULL
: defs
.front()->getInsn();
211 Instruction
*Value::getUniqueInsn() const
216 // after regalloc, the definitions of coalesced values are linked
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
224 if (reg
.data
.id
< 0) {
226 for (DefCIterator it
= defs
.begin(); n
< 2 && it
!= defs
.end(); ++it
)
227 if ((*it
)->get() == this) // don't count joined values
230 WARN("value %%%i not uniquely defined\n", id
); // return NULL ?
233 assert(defs
.front()->get() == this);
234 return defs
.front()->getInsn();
237 inline bool Instruction::constrainedDefs() const
239 return defExists(1) || op
== OP_UNION
;
242 Value
*Instruction::getIndirect(int s
, int dim
) const
244 return srcs
[s
].isIndirect(dim
) ? getSrc(srcs
[s
].indirect
[dim
]) : NULL
;
247 Value
*Instruction::getPredicate() const
249 return (predSrc
>= 0) ? getSrc(predSrc
) : NULL
;
252 void Instruction::setFlagsDef(int d
, Value
*val
)
257 setDef(flagsDef
, val
);
260 setDef(flagsDef
, NULL
);
266 void Instruction::setFlagsSrc(int s
, Value
*val
)
269 setSrc(flagsSrc
, val
);
272 Value
*TexInstruction::getIndirectR() const
274 return tex
.rIndirectSrc
>= 0 ? getSrc(tex
.rIndirectSrc
) : NULL
;
277 Value
*TexInstruction::getIndirectS() const
279 return tex
.rIndirectSrc
>= 0 ? getSrc(tex
.rIndirectSrc
) : NULL
;
282 CmpInstruction
*Instruction::asCmp()
284 if (op
>= OP_SET_AND
&& op
<= OP_SLCT
&& op
!= OP_SELP
)
285 return static_cast<CmpInstruction
*>(this);
289 const CmpInstruction
*Instruction::asCmp() const
291 if (op
>= OP_SET_AND
&& op
<= OP_SLCT
&& op
!= OP_SELP
)
292 return static_cast<const CmpInstruction
*>(this);
296 FlowInstruction
*Instruction::asFlow()
298 if (op
>= OP_BRA
&& op
<= OP_JOIN
)
299 return static_cast<FlowInstruction
*>(this);
303 const FlowInstruction
*Instruction::asFlow() const
305 if (op
>= OP_BRA
&& op
<= OP_JOINAT
)
306 return static_cast<const FlowInstruction
*>(this);
310 TexInstruction
*Instruction::asTex()
312 if (op
>= OP_TEX
&& op
<= OP_SULEA
)
313 return static_cast<TexInstruction
*>(this);
317 const TexInstruction
*Instruction::asTex() const
319 if (op
>= OP_TEX
&& op
<= OP_SULEA
)
320 return static_cast<const TexInstruction
*>(this);
324 static inline Instruction
*cloneForward(Function
*ctx
, Instruction
*obj
)
326 DeepClonePolicy
<Function
> pol(ctx
);
328 for (int i
= 0; obj
->srcExists(i
); ++i
)
329 pol
.set(obj
->getSrc(i
), obj
->getSrc(i
));
331 return obj
->clone(pol
);
334 // XXX: use a virtual function so we're really really safe ?
335 LValue
*Value::asLValue()
337 if (reg
.file
>= FILE_GPR
&& reg
.file
<= FILE_ADDRESS
)
338 return static_cast<LValue
*>(this);
342 Symbol
*Value::asSym()
344 if (reg
.file
>= FILE_MEMORY_CONST
)
345 return static_cast<Symbol
*>(this);
349 const Symbol
*Value::asSym() const
351 if (reg
.file
>= FILE_MEMORY_CONST
)
352 return static_cast<const Symbol
*>(this);
356 void Symbol::setOffset(int32_t offset
)
358 reg
.data
.offset
= offset
;
361 void Symbol::setAddress(Symbol
*base
, int32_t offset
)
364 reg
.data
.offset
= offset
;
367 void Symbol::setSV(SVSemantic sv
, uint32_t index
)
370 reg
.data
.sv
.index
= index
;
373 ImmediateValue
*Value::asImm()
375 if (reg
.file
== FILE_IMMEDIATE
)
376 return static_cast<ImmediateValue
*>(this);
380 const ImmediateValue
*Value::asImm() const
382 if (reg
.file
== FILE_IMMEDIATE
)
383 return static_cast<const ImmediateValue
*>(this);
387 Value
*Value::get(Iterator
&it
)
389 return reinterpret_cast<Value
*>(it
.get());
392 bool BasicBlock::reachableBy(const BasicBlock
*by
, const BasicBlock
*term
)
394 return cfg
.reachableBy(&by
->cfg
, &term
->cfg
);
397 BasicBlock
*BasicBlock::get(Iterator
&iter
)
399 return reinterpret_cast<BasicBlock
*>(iter
.get());
402 BasicBlock
*BasicBlock::get(Graph::Node
*node
)
405 return reinterpret_cast<BasicBlock
*>(node
->data
);
408 Function
*Function::get(Graph::Node
*node
)
411 return reinterpret_cast<Function
*>(node
->data
);
414 LValue
*Function::getLValue(int id
)
416 assert((unsigned int)id
< (unsigned int)allLValues
.getSize());
417 return reinterpret_cast<LValue
*>(allLValues
.get(id
));
420 #endif // __NV50_IR_INLINES_H__