};
/*! Policy shared by all the internal instructions */
- struct ALIGNED_INSTRUCTION BasePolicy {
+ struct BasePolicy {
/*! Create an instruction from its internal representation */
Instruction convert(void) const {
return Instruction(reinterpret_cast<const char *>(&this->opcode));
};
/*! All 1-source arithmetic instructions */
- class UnaryInstruction : public NaryInstruction<1>
+ class ALIGNED_INSTRUCTION UnaryInstruction :
+ public NaryInstruction<1>
{
public:
UnaryInstruction(Opcode opcode,
};
/*! All 2-source arithmetic instructions */
- class BinaryInstruction : public NaryInstruction<2>
+ class ALIGNED_INSTRUCTION BinaryInstruction :
+ public NaryInstruction<2>
{
public:
BinaryInstruction(Opcode opcode,
/*! This is for MADs mostly. Since three sources cannot be encoded in 64
* bytes, we use tuples of registers
*/
- class TernaryInstruction : public BasePolicy
+ class ALIGNED_INSTRUCTION TernaryInstruction :
+ public BasePolicy
{
public:
TernaryInstruction(Opcode opcode,
* steal all the methods from it, except wellFormed (dst register is always
* a boolean value)
*/
- class CompareInstruction : public BinaryInstruction
+ class ALIGNED_INSTRUCTION CompareInstruction : public NaryInstruction<2>
{
public:
- CompareInstruction(Type type,
- CompareOperation operation,
+ CompareInstruction(Opcode opcode,
+ Type type,
Register dst,
Register src0,
- Register src1) :
- BinaryInstruction(OP_CMP, type, dst, src0, src1)
+ Register src1)
{
- this->operation = operation;
+ this->opcode = opcode;
+ this->type = type;
+ this->dst = dst;
+ this->src[0] = src0;
+ this->src[1] = src1;
}
- INLINE CompareOperation getOperation(void) const { return operation; }
INLINE bool wellFormed(const Function &fn, std::string &whyNot) const;
- CompareOperation operation;
};
class ConvertInstruction : public BasePolicy
bool hasPredicate; //!< Is it predicated?
};
- class LoadInstruction : public BasePolicy
+ class ALIGNED_INSTRUCTION LoadInstruction :
+ public BasePolicy
{
public:
LoadInstruction(Type type,
Tuple dstValues,
Register offset,
MemorySpace memSpace,
- uint16_t valueNum)
+ uint32_t valueNum)
{
+ GBE_ASSERT(valueNum < 255);
this->opcode = OP_STORE;
this->type = type;
this->offset = offset;
Register offset; //!< First source is the offset where to store
Tuple values; //!< Values to load
MemorySpace memSpace; //!< Where to store
- uint16_t valueNum; //!< Number of values to store
+ uint8_t valueNum; //!< Number of values to store
};
- class StoreInstruction : public BasePolicy, public NoDstPolicy
+ class ALIGNED_INSTRUCTION StoreInstruction :
+ public BasePolicy, public NoDstPolicy
{
public:
StoreInstruction(Type type,
Tuple values,
Register offset,
MemorySpace memSpace,
- uint16_t valueNum)
+ uint32_t valueNum)
{
+ GBE_ASSERT(valueNum < 255);
this->opcode = OP_STORE;
this->type = type;
this->offset = offset;
Register offset; //!< First source is the offset where to store
Tuple values; //!< Values to store
MemorySpace memSpace; //!< Where to store
- uint16_t valueNum; //!< Number of values to store
+ uint8_t valueNum; //!< Number of values to store
};
- class TextureInstruction : public BasePolicy, public NoDstPolicy, public NoSrcPolicy // TODO REMOVE THIS
+ class ALIGNED_INSTRUCTION TextureInstruction :
+ public BasePolicy, public NoDstPolicy, public NoSrcPolicy // TODO REMOVE THIS
{
public:
INLINE TextureInstruction(void) { this->opcode = OP_TEX; }
INLINE bool wellFormed(const Function &fn, std::string &why) const;
};
- class LoadImmInstruction : public BasePolicy, public NoSrcPolicy
+ class ALIGNED_INSTRUCTION LoadImmInstruction :
+ public BasePolicy, public NoSrcPolicy
{
public:
INLINE LoadImmInstruction(Type type,
Type type; //!< Type of the immediate
};
- class FenceInstruction : public BasePolicy, public NoSrcPolicy, public NoDstPolicy
+ class ALIGNED_INSTRUCTION FenceInstruction :
+ public BasePolicy, public NoSrcPolicy, public NoDstPolicy
{
public:
INLINE FenceInstruction(MemorySpace memSpace) {
MemorySpace memSpace; //!< The loads and stores to order
};
- class LabelInstruction : public BasePolicy, public NoDstPolicy, public NoSrcPolicy
+ class ALIGNED_INSTRUCTION LabelInstruction :
+ public BasePolicy, public NoDstPolicy, public NoSrcPolicy
{
public:
INLINE LabelInstruction(LabelIndex labelIndex) {
return fn.getRegisterData(this->getSrcIndex(fn, ID));
}
-#define DECL_INSN(OPCODE, CLASS) \
- case OP_##OPCODE: \
+#define DECL_INSN(OPCODE, CLASS) \
+ case OP_##OPCODE: \
return HelperIntrospection<CLASS, RefClass>::value == 1;
-#define START_INTROSPECTION(CLASS) \
- static_assert(sizeof(CLASS)==sizeof(Instruction), "Bad instruction size"); \
- bool CLASS::isClassOf(const Instruction &insn) { \
- const Opcode op = insn.getOpcode(); \
- typedef CLASS RefClass; \
+#define START_INTROSPECTION(CLASS) \
+ static_assert(sizeof(internal::CLASS) == sizeof(Instruction), \
+ "Bad instruction size"); \
+ static_assert(offsetof(internal::CLASS, opcode) == 0, \
+ "Bad opcode offset"); \
+ bool CLASS::isClassOf(const Instruction &insn) { \
+ const Opcode op = insn.getOpcode(); \
+ typedef CLASS RefClass; \
switch (op) {
-#define END_INTROSPECTION(CLASS) \
- default: return false; \
- }; \
- } \
- static_assert(offsetof(internal::CLASS, opcode)==0, "Bad opcode offset");
+#define END_INTROSPECTION(CLASS) \
+ default: return false; \
+ }; \
+ } \
START_INTROSPECTION(UnaryInstruction)
#include "ir/instruction.hxx"
///////////////////////////////////////////////////////////////////////////
#define DECL_INSN(OPCODE, CLASS) \
- case OP_##OPCODE: reinterpret_cast<const internal::CLASS*>(this)->CALL;
+ case OP_##OPCODE: return reinterpret_cast<const internal::CLASS*>(this)->CALL;
#define START_FUNCTION(CLASS, RET, PROTOTYPE) \
RET CLASS::PROTOTYPE const { \
const Opcode op = this->getOpcode(); \
switch (op) {
-#define END_FUNCTION(CLASS, RET) \
- }; \
- return RET(); \
+#define END_FUNCTION(CLASS, RET) \
+ }; \
+ return RET(); \
}
#define CALL getSrcNum()
DECL_MEM_FN(BinaryInstruction, Type, getType(void), getType())
DECL_MEM_FN(TernaryInstruction, Type, getType(void), getType())
DECL_MEM_FN(CompareInstruction, Type, getType(void), getType())
-DECL_MEM_FN(CompareInstruction, CompareOperation, getOperation(void), getOperation())
DECL_MEM_FN(ConvertInstruction, Type, getSrcType(void), getSrcType())
DECL_MEM_FN(ConvertInstruction, Type, getDstType(void), getDstType())
DECL_MEM_FN(StoreInstruction, Type, getValueType(void), getValueType())
// All unary functions
#define DECL_EMIT_FUNCTION(NAME) \
- Instruction NAME(Type type, Register dst, Register src) { \
+ Instruction NAME(Type type, Register dst, Register src) { \
const internal::UnaryInstruction insn(OP_##NAME, type, dst, src); \
return insn.convert(); \
}
// All binary functions
#define DECL_EMIT_FUNCTION(NAME) \
- Instruction NAME(Type type, Register dst, \
- Register src0, \
- Register src1) { \
+ Instruction NAME(Type type, Register dst, Register src0, Register src1) { \
const internal::BinaryInstruction insn(OP_##NAME, type, dst, src0, src1); \
return insn.convert(); \
}
return insn.convert();
}
- // CMP
- Instruction CMP(Type type,
- CompareOperation operation,
- Register dst,
- Register src0,
- Register src1)
- {
- internal::CompareInstruction insn(type, operation, dst, src0, src1);
- return insn.convert();
+ // All compare functions
+#define DECL_EMIT_FUNCTION(NAME) \
+ Instruction NAME(Type type, Register dst, Register src0, Register src1) { \
+ const internal::CompareInstruction insn(OP_##NAME, type, dst, src0, src1);\
+ return insn.convert(); \
}
+ DECL_EMIT_FUNCTION(EQ)
+ DECL_EMIT_FUNCTION(NE)
+ DECL_EMIT_FUNCTION(LE)
+ DECL_EMIT_FUNCTION(LT)
+ DECL_EMIT_FUNCTION(GE)
+ DECL_EMIT_FUNCTION(GT)
+
+#undef DECL_EMIT_FUNCTION
+
// CVT
Instruction CVT(Type dstType, Type srcType, Register dst, Register src) {
internal::ConvertInstruction insn(dstType, srcType, dst, src);
// LOAD and STORE
#define DECL_EMIT_FUNCTION(NAME, CLASS) \
Instruction NAME(Type type, \
- Tuple tuple, \
- Register offset, \
+ Tuple tuple, \
+ Register offset, \
MemorySpace space, \
uint16_t valueNum) \
{ \
static bool isClassOf(const Instruction &insn);
};
- /*! Operation done in comparison */
- enum CompareOperation : uint8_t {
- CMP_EQ = 0, // ==
- CMP_NE, // !=
- CMP_LT, // <
- CMP_LE, // <=
- CMP_GT, // >
- CMP_GE // >=
- };
-
/*! Compare instructions compare anything from the same type and return a
* boolean value
*/
public:
/*! Get the type of the source registers */
Type getType(void) const;
- /*! Compare operation in the instruction */
- CompareOperation getOperation(void) const;
/*! Return true if the given instruction is an instance of this class */
static bool isClassOf(const Instruction &insn);
};
Instruction AND(Type type, Register dst, Register src0, Register src1);
/*! mad.type dst {src0, src1, src2} == src */
Instruction MAD(Type type, Register dst, Tuple src);
- /*! cmp.type.op dst src0 src1 */
- Instruction CMP(Type type, CompareOperation op, Register dst, Register src0, Register src1);
+ /*! eq.type dst src0 src1 */
+ Instruction EQ(Type type, Register dst, Register src0, Register src1);
+ /*! ne.type dst src0 src1 */
+ Instruction NE(Type type, Register dst, Register src0, Register src1);
+ /*! lt.type dst src0 src1 */
+ Instruction LE(Type type, Register dst, Register src0, Register src1);
+ /*! le.type dst src0 src1 */
+ Instruction LT(Type type, Register dst, Register src0, Register src1);
+ /*! gt.type dst src0 src1 */
+ Instruction GE(Type type, Register dst, Register src0, Register src1);
+ /*! ge.type dst src0 src1 */
+ Instruction GT(Type type, Register dst, Register src0, Register src1);
/*! cvt.{dstType <- srcType} dst src */
Instruction CVT(Type dstType, Type srcType, Register dst, Register src0, Register src1);
/*! bra labelIndex */