fn = NULL;
}
- RegisterIndex Context::reg(Register::Family family) {
+ Register Context::reg(RegisterData::Family family) {
GBE_ASSERT(fn != NULL);
return fn->file.append(family);
}
- void Context::input(RegisterIndex reg) {
+ void Context::input(Register reg) {
GBE_ASSERT(fn != NULL && reg < fn->file.regNum());
fn->input.push_back(reg);
}
- void Context::output(RegisterIndex reg) {
+ void Context::output(Register reg) {
GBE_ASSERT(fn != NULL && reg < fn->file.regNum());
fn->output.push_back(reg);
}
/*! Close the function */
void endFunction(void);
/*! Create a new register for the given family */
- RegisterIndex reg(Register::Family family);
+ Register reg(RegisterData::Family family);
/*! Append a new input register for the function */
- void input(RegisterIndex reg);
+ void input(Register reg);
/*! Append a new output register for the function */
- void output(RegisterIndex reg);
+ void output(Register reg);
/*! Append a new tuple */
- template <typename... Args> INLINE TupleIndex tuple(Args...args);
+ template <typename... Args> INLINE Tuple tuple(Args...args);
/*! We just use variadic templates to forward instruction functions */
#define DECL_INSN(NAME, FAMILY) \
template <typename... Args> INLINE void NAME(Args...args);
/*! MAD with sources directly specified */
INLINE void MAD(Type type,
- RegisterIndex dst,
- RegisterIndex src0,
- RegisterIndex src1,
- RegisterIndex src2)
+ Register dst,
+ Register src0,
+ Register src1,
+ Register src2)
{
- const TupleIndex index = this->tuple(src0, src1, src2);
+ const Tuple index = this->tuple(src0, src1, src2);
return this->MAD(type, dst, index);
}
/*! LOAD with the destinations directly specified */
template <typename... Args>
- void LOAD(Type type, RegisterIndex offset, MemorySpace space, Args...values)
+ void LOAD(Type type, Register offset, MemorySpace space, Args...values)
{
- const TupleIndex index = this->tuple(values...);
+ const Tuple index = this->tuple(values...);
const uint16_t valueNum = std::tuple_size<std::tuple<Args...>>::value;
GBE_ASSERT(valueNum > 0);
this->LOAD(type, index, offset, space, valueNum);
/*! STORE with the sources directly specified */
template <typename... Args>
- void STORE(Type type, RegisterIndex offset, MemorySpace space, Args...values)
+ void STORE(Type type, Register offset, MemorySpace space, Args...values)
{
- const TupleIndex index = this->tuple(values...);
+ const Tuple index = this->tuple(values...);
const uint16_t valueNum = std::tuple_size<std::tuple<Args...>>::value;
GBE_ASSERT(valueNum > 0);
this->STORE(type, index, offset, space, valueNum);
#define DECL_CMP(NAME) \
void NAME(Type type, \
- RegisterIndex dst, \
- RegisterIndex src0, \
- RegisterIndex src1) \
+ Register dst, \
+ Register src0, \
+ Register src1) \
{ \
this->CMP(type, CMP_##NAME, dst, src0, src1); \
}
};
template <typename... Args>
- INLINE TupleIndex Context::tuple(Args...args) {
+ INLINE Tuple Context::tuple(Args...args) {
GBE_ASSERT(fn != NULL);
return fn->file.appendTuple(args...);
}
/*! Release everything *including* the basic block pointers */
~Function(void);
/*! Extract the register from the register file */
- INLINE Register getRegister(RegisterIndex ID) const { return file.get(ID); }
+ INLINE RegisterData getRegisterData(Register ID) const { return file.get(ID); }
/*! Get the register index from the tuple vector */
- INLINE RegisterIndex getRegisterIndex(TupleIndex ID, uint32_t which) const {
+ INLINE Register getRegister(Tuple ID, uint32_t which) const {
return file.get(ID, which);
}
/*! Get the given value ie immediate from the function */
private:
friend class Context; //!< Can freely modify a function
- vector<RegisterIndex> input; //!< Input registers of the function
- vector<RegisterIndex> output; //!< Output registers of the function
+ vector<Register> input; //!< Input registers of the function
+ vector<Register> output; //!< Output registers of the function
vector<BasicBlock*> labels; //!< Each label points to a basic block
vector<Immediate> immediates; //!< All immediate values in the function
vector<BasicBlock*> blocks; //!< All chained basic blocks
- RegisterFile file; //!< Registers used by the instructions
+ RegisterFile file; //!< RegisterDatas used by the instructions
GrowingPool<Instruction> insnPool; //!< For fast instruction allocation
GBE_CLASS(Function);
};
/*! Use this when there is no source */
struct NoSrcPolicy {
INLINE uint32_t getSrcNum(void) const { return 0; }
- INLINE RegisterIndex getSrcIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getSrcIndex(const Function &fn, uint32_t ID) const {
NOT_IMPLEMENTED;
- return RegisterIndex(0);
+ return Register(0);
}
};
/*! Use this when there is no destination */
struct NoDstPolicy {
INLINE uint32_t getDstNum(void) const { return 0; }
- INLINE RegisterIndex getDstIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getDstIndex(const Function &fn, uint32_t ID) const {
NOT_IMPLEMENTED;
- return RegisterIndex(0);
+ return Register(0);
}
};
public:
INLINE uint32_t getSrcNum(void) const { return srcNum; }
INLINE uint32_t getDstNum(void) const { return 1; }
- INLINE RegisterIndex getDstIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getDstIndex(const Function &fn, uint32_t ID) const {
assert(ID == 0);
return dst;
}
- INLINE RegisterIndex getSrcIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getSrcIndex(const Function &fn, uint32_t ID) const {
assert(ID <= srcNum);
return src[ID];
}
INLINE Type getType(void) const { return this->type; }
INLINE bool wellFormed(const Function &fn, std::string &whyNot) const;
Type type; //!< Type of the instruction
- RegisterIndex dst; //!< Index of the register in the register file
- RegisterIndex src[srcNum];//!< Indices of the sources
+ Register dst; //!< Index of the register in the register file
+ Register src[srcNum];//!< Indices of the sources
};
/*! All 1-source arithmetic instructions */
public:
UnaryInstruction(Opcode opcode,
Type type,
- RegisterIndex dst,
- RegisterIndex src) {
+ Register dst,
+ Register src) {
this->opcode = opcode;
this->type = type;
this->dst = dst;
public:
BinaryInstruction(Opcode opcode,
Type type,
- RegisterIndex dst,
- RegisterIndex src0,
- RegisterIndex src1) {
+ Register dst,
+ Register src0,
+ Register src1) {
this->opcode = opcode;
this->type = type;
this->dst = dst;
public:
TernaryInstruction(Opcode opcode,
Type type,
- RegisterIndex dst,
- TupleIndex src)
+ Register dst,
+ Tuple src)
{
this->opcode = opcode;
this->type = type;
}
INLINE uint32_t getSrcNum(void) const { return 3; }
INLINE uint32_t getDstNum(void) const { return 1; }
- INLINE RegisterIndex getDstIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getDstIndex(const Function &fn, uint32_t ID) const {
assert(ID == 0);
return dst;
}
- INLINE RegisterIndex getSrcIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getSrcIndex(const Function &fn, uint32_t ID) const {
assert(ID <= 3);
- return fn.getRegisterIndex(src, ID);
+ return fn.getRegister(src, ID);
}
INLINE Type getType(void) const { return this->type; }
INLINE bool wellFormed(const Function &fn, std::string &whyNot) const;
Type type; //!< Type of the instruction
- RegisterIndex dst; //!< Dst is the register index
- TupleIndex src; //!< 3 sources do not fit in 8 bytes -> use a tuple
+ Register dst; //!< Dst is the register index
+ Tuple src; //!< 3 sources do not fit in 8 bytes -> use a tuple
};
/*! Comparison instructions take two sources of the same type and return a
public:
CompareInstruction(Type type,
CompareOperation operation,
- RegisterIndex dst,
- RegisterIndex src0,
- RegisterIndex src1) :
+ Register dst,
+ Register src0,
+ Register src1) :
BinaryInstruction(OP_CMP, type, dst, src0, src1)
{
this->operation = operation;
public:
ConvertInstruction(Type dstType,
Type srcType,
- RegisterIndex dst,
- RegisterIndex src)
+ Register dst,
+ Register src)
{
this->opcode = OP_CVT;
this->dst = dst;
INLINE Type getDstType(void) const { return this->dstType; }
INLINE uint32_t getSrcNum(void) const { return 1; }
INLINE uint32_t getDstNum(void) const { return 1; }
- INLINE RegisterIndex getDstIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getDstIndex(const Function &fn, uint32_t ID) const {
assert(ID == 0);
return dst;
}
- INLINE RegisterIndex getSrcIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getSrcIndex(const Function &fn, uint32_t ID) const {
assert(ID == 0);
return src;
}
INLINE bool wellFormed(const Function &fn, std::string &whyNot) const;
- RegisterIndex dst; //!< Converted value
- RegisterIndex src; //!< To convert
+ Register dst; //!< Converted value
+ Register src; //!< To convert
Type dstType; //!< Type to convert to
Type srcType; //!< Type to convert from
};
class BranchInstruction : public BasePolicy, public NoDstPolicy
{
public:
- INLINE BranchInstruction(LabelIndex labelIndex, RegisterIndex predicate) {
+ INLINE BranchInstruction(LabelIndex labelIndex, Register predicate) {
this->opcode = OP_BRA;
this->predicate = predicate;
this->labelIndex = labelIndex;
this->hasPredicate = false;
}
INLINE uint32_t getSrcNum(void) const { return hasPredicate ? 1 : 0; }
- INLINE RegisterIndex getSrcIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getSrcIndex(const Function &fn, uint32_t ID) const {
assert(ID == 0 && hasPredicate);
return predicate;
}
INLINE bool isPredicated(void) const { return hasPredicate; }
INLINE bool wellFormed(const Function &fn, std::string &why) const;
- RegisterIndex predicate; //!< Predication means conditional branch
+ Register predicate; //!< Predication means conditional branch
LabelIndex labelIndex; //!< Index of the label the branch targets
bool hasPredicate; //!< Is it predicated?
};
{
public:
LoadInstruction(Type type,
- TupleIndex dstValues,
- RegisterIndex offset,
+ Tuple dstValues,
+ Register offset,
MemorySpace memSpace,
uint16_t valueNum)
{
this->memSpace = memSpace;
this->valueNum = valueNum;
}
- INLINE RegisterIndex getSrcIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getSrcIndex(const Function &fn, uint32_t ID) const {
assert(ID == 0u);
return offset;
}
INLINE uint32_t getSrcNum(void) const { return 1; }
- INLINE RegisterIndex getDstIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getDstIndex(const Function &fn, uint32_t ID) const {
assert(ID < valueNum);
- return fn.getRegisterIndex(values, ID);
+ return fn.getRegister(values, ID);
}
INLINE uint32_t getDstNum(void) const { return valueNum; }
INLINE Type getValueType(void) const { return type; }
INLINE MemorySpace getAddressSpace(void) const { return memSpace; }
INLINE bool wellFormed(const Function &fn, std::string &why) const;
Type type; //!< Type to store
- RegisterIndex offset; //!< First source is the offset where to store
- TupleIndex values; //!< Values to load
+ 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
};
{
public:
StoreInstruction(Type type,
- TupleIndex values,
- RegisterIndex offset,
+ Tuple values,
+ Register offset,
MemorySpace memSpace,
uint16_t valueNum)
{
this->memSpace = memSpace;
this->valueNum = valueNum;
}
- INLINE RegisterIndex getSrcIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getSrcIndex(const Function &fn, uint32_t ID) const {
assert(ID < valueNum + 1u); // offset + values to store
if (ID == 0u)
return offset;
else
- return fn.getRegisterIndex(values, ID - 1);
+ return fn.getRegister(values, ID - 1);
}
INLINE uint32_t getSrcNum(void) const { return valueNum + 1u; }
INLINE uint32_t getValueNum(void) const { return valueNum; }
INLINE MemorySpace getAddressSpace(void) const { return memSpace; }
INLINE bool wellFormed(const Function &fn, std::string &why) const;
Type type; //!< Type to store
- RegisterIndex offset; //!< First source is the offset where to store
- TupleIndex values; //!< Values to store
+ 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
};
{
public:
INLINE LoadImmInstruction(Type type,
- RegisterIndex dst,
+ Register dst,
ImmediateIndex immediateIndex)
{
this->dst = dst;
return fn.getImmediate(immediateIndex);
}
INLINE uint32_t getDstNum(void) const{ return 1; }
- INLINE RegisterIndex getDstIndex(const Function &fn, uint32_t ID) const {
+ INLINE Register getDstIndex(const Function &fn, uint32_t ID) const {
assert(ID == 0);
return dst;
}
INLINE Type getType(void) const { return this->type; }
bool wellFormed(const Function &fn, std::string &why) const;
- RegisterIndex dst; //!< Register to store into
+ Register dst; //!< RegisterData to store into
ImmediateIndex immediateIndex; //!< Index in the vector of immediates
Type type; //!< Type of the immediate
};
/*! All Nary instruction register must be of the same family and properly
* defined (i.e. not out-of-bound)
*/
- static INLINE bool checkRegister(Register::Family family,
- const RegisterIndex ID,
+ static INLINE bool checkRegisterData(RegisterData::Family family,
+ const Register ID,
const Function &fn,
std::string &whyNot)
{
whyNot = "Out-of-bound destination register index";
return false;
}
- const Register reg = fn.getRegister(ID);
+ const RegisterData reg = fn.getRegisterData(ID);
if (UNLIKELY(reg.family != family)) {
whyNot = "Destination family does not match instruction type";
return false;
template <uint32_t srcNum>
INLINE bool NaryInstruction<srcNum>::wellFormed(const Function &fn, std::string &whyNot) const
{
- const Register::Family family = getFamily(this->type);
- if (UNLIKELY(checkRegister(family, dst, fn, whyNot) == false))
+ const RegisterData::Family family = getFamily(this->type);
+ if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
return false;
for (uint32_t srcID = 0; srcID < srcNum; ++srcID)
- if (UNLIKELY(checkRegister(family, src[srcID], fn, whyNot) == false))
+ if (UNLIKELY(checkRegisterData(family, src[srcID], fn, whyNot) == false))
return false;
return true;
}
// Idem for ternary instructions except that sources are in a tuple
INLINE bool TernaryInstruction::wellFormed(const Function &fn, std::string &whyNot) const
{
- const Register::Family family = getFamily(this->type);
- if (UNLIKELY(checkRegister(family, dst, fn, whyNot) == false))
+ const RegisterData::Family family = getFamily(this->type);
+ if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
return false;
if (UNLIKELY(src + 3u > fn.tupleNum())) {
whyNot = "Out-of-bound index for ternary instruction";
return false;
}
for (uint32_t srcID = 0; srcID < 3u; ++srcID) {
- const RegisterIndex regID = fn.getRegisterIndex(src, srcID);
- if (UNLIKELY(checkRegister(family, regID, fn, whyNot) == false))
+ const Register regID = fn.getRegister(src, srcID);
+ if (UNLIKELY(checkRegisterData(family, regID, fn, whyNot) == false))
return false;
}
return true;
// boolean
INLINE bool CompareInstruction::wellFormed(const Function &fn, std::string &whyNot) const
{
- if (UNLIKELY(checkRegister(Register::BOOL, dst, fn, whyNot) == false))
+ if (UNLIKELY(checkRegisterData(RegisterData::BOOL, dst, fn, whyNot) == false))
return false;
- const Register::Family family = getFamily(this->type);
+ const RegisterData::Family family = getFamily(this->type);
for (uint32_t srcID = 0; srcID < 2; ++srcID)
- if (UNLIKELY(checkRegister(family, src[srcID], fn, whyNot) == false))
+ if (UNLIKELY(checkRegisterData(family, src[srcID], fn, whyNot) == false))
return false;
return true;
}
// We can convert anything to anything, but types and families must match
INLINE bool ConvertInstruction::wellFormed(const Function &fn, std::string &whyNot) const
{
- const Register::Family dstFamily = getFamily(srcType);
- const Register::Family srcFamily = getFamily(srcType);
- if (UNLIKELY(checkRegister(dstFamily, dst, fn, whyNot) == false))
+ const RegisterData::Family dstFamily = getFamily(srcType);
+ const RegisterData::Family srcFamily = getFamily(srcType);
+ if (UNLIKELY(checkRegisterData(dstFamily, dst, fn, whyNot) == false))
return false;
- if (UNLIKELY(checkRegister(srcFamily, src, fn, whyNot) == false))
+ if (UNLIKELY(checkRegisterData(srcFamily, src, fn, whyNot) == false))
return false;
return true;
}
return false;
}
// Check all registers
- const Register::Family family = getFamily(insn.type);
+ const RegisterData::Family family = getFamily(insn.type);
for (uint32_t valueID = 0; valueID < insn.valueNum; ++valueID) {
- const RegisterIndex regID = fn.getRegisterIndex(insn.values, valueID);
- if (UNLIKELY(checkRegister(family, regID, fn, whyNot) == false))
+ const Register regID = fn.getRegister(insn.values, valueID);
+ if (UNLIKELY(checkRegisterData(family, regID, fn, whyNot) == false))
return false;
}
return true;
whyNot = "Inconsistant type for the immediate value to load";
return false;
}
- const Register::Family family = getFamily(type);
- if (UNLIKELY(checkRegister(family, dst, fn, whyNot) == false))
+ const RegisterData::Family family = getFamily(type);
+ if (UNLIKELY(checkRegisterData(family, dst, fn, whyNot) == false))
return false;
return true;
}
return false;
}
if (hasPredicate)
- if (UNLIKELY(checkRegister(Register::BOOL, predicate, fn, whyNot) == false))
+ if (UNLIKELY(checkRegisterData(RegisterData::BOOL, predicate, fn, whyNot) == false))
return false;
return true;
}
enum { value = 1 };
};
- Register Instruction::getDst(const Function &fn, uint32_t ID) const {
- return fn.getRegister(this->getDstIndex(fn, ID));
+ RegisterData Instruction::getDst(const Function &fn, uint32_t ID) const {
+ return fn.getRegisterData(this->getDstIndex(fn, ID));
}
- Register Instruction::getSrc(const Function &fn, uint32_t ID) const {
- return fn.getRegister(this->getSrcIndex(fn, ID));
+ RegisterData Instruction::getSrc(const Function &fn, uint32_t ID) const {
+ return fn.getRegisterData(this->getSrcIndex(fn, ID));
}
#define DECL_INSN(OPCODE, CLASS) \
#undef CALL
#define CALL getDstIndex(fn, ID)
-START_FUNCTION(Instruction, RegisterIndex, getDstIndex(const Function &fn, uint32_t ID))
+START_FUNCTION(Instruction, Register, getDstIndex(const Function &fn, uint32_t ID))
#include "ir/instruction.hxx"
-END_FUNCTION(Instruction, RegisterIndex)
+END_FUNCTION(Instruction, Register)
#undef CALL
#define CALL getSrcIndex(fn, ID)
-START_FUNCTION(Instruction, RegisterIndex, getSrcIndex(const Function &fn, uint32_t ID))
+START_FUNCTION(Instruction, Register, getSrcIndex(const Function &fn, uint32_t ID))
#include "ir/instruction.hxx"
-END_FUNCTION(Instruction, RegisterIndex)
+END_FUNCTION(Instruction, Register)
#undef CALL
#define CALL wellFormed(fn, whyNot)
// All unary functions
#define DECL_EMIT_FUNCTION(NAME) \
- Instruction NAME(Type type, RegisterIndex dst, RegisterIndex 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, RegisterIndex dst, \
- RegisterIndex src0, \
- RegisterIndex src1) { \
+ Instruction NAME(Type type, Register dst, \
+ Register src0, \
+ Register src1) { \
const internal::BinaryInstruction insn(OP_##NAME, type, dst, src0, src1); \
return insn.convert(); \
}
#undef DECL_EMIT_FUNCTION
// MAD
- Instruction MAD(Type type, RegisterIndex dst, TupleIndex src) {
+ Instruction MAD(Type type, Register dst, Tuple src) {
internal::TernaryInstruction insn(OP_MAD, type, dst, src);
return insn.convert();
}
// CMP
Instruction CMP(Type type,
CompareOperation operation,
- RegisterIndex dst,
- RegisterIndex src0,
- RegisterIndex src1)
+ Register dst,
+ Register src0,
+ Register src1)
{
internal::CompareInstruction insn(type, operation, dst, src0, src1);
return insn.convert();
}
// CVT
- Instruction CVT(Type dstType, Type srcType, RegisterIndex dst, RegisterIndex src) {
+ Instruction CVT(Type dstType, Type srcType, Register dst, Register src) {
internal::ConvertInstruction insn(dstType, srcType, dst, src);
return insn.convert();
}
internal::BranchInstruction insn(labelIndex);
return insn.convert();
}
- Instruction BRA(LabelIndex labelIndex, RegisterIndex pred) {
+ Instruction BRA(LabelIndex labelIndex, Register pred) {
internal::BranchInstruction insn(labelIndex, pred);
return insn.convert();
}
// LOADI
- Instruction LOADI(Type type, RegisterIndex dst, ImmediateIndex value) {
+ Instruction LOADI(Type type, Register dst, ImmediateIndex value) {
internal::LoadImmInstruction insn(type, dst, value);
return insn.convert();
}
// LOAD and STORE
#define DECL_EMIT_FUNCTION(NAME, CLASS) \
Instruction NAME(Type type, \
- TupleIndex tuple, \
- RegisterIndex offset, \
+ Tuple tuple, \
+ Register offset, \
MemorySpace space, \
uint16_t valueNum) \
{ \
/*! Get the number of destination for this instruction */
uint32_t getDstNum(void) const;
/*! Get the register index of the given source */
- RegisterIndex getSrcIndex(const Function &fn, uint32_t ID = 0u) const;
+ Register getSrcIndex(const Function &fn, uint32_t ID = 0u) const;
/*! Get the register index of the given destination */
- RegisterIndex getDstIndex(const Function &fn, uint32_t ID = 0u) const;
+ Register getDstIndex(const Function &fn, uint32_t ID = 0u) const;
/*! Get the register of the given source */
- Register getDst(const Function &fn, uint32_t ID = 0u) const;
+ RegisterData getDst(const Function &fn, uint32_t ID = 0u) const;
/*! Get the register of the given destination */
- Register getSrc(const Function &fn, uint32_t ID = 0u) const;
+ RegisterData getSrc(const Function &fn, uint32_t ID = 0u) const;
/*! Check that the instruction is well formed (type properly match,
* registers not of bound and so on). If not well formed, provide a reason
* in string why
/*! Indicate if the branch is predicated */
bool isPredicated(void) const;
/*! Return the predicate register (if predicated) */
- Register getPredicate(const Function &fn) const {
+ RegisterData getPredicate(const Function &fn) const {
assert(this->isPredicated() == true);
return this->getSrc(fn, 0);
}
/*! Return the predicate register index (if predicated) */
- RegisterIndex getPredicateIndex(const Function &fn) const {
+ Register getPredicateIndex(const Function &fn) const {
assert(this->isPredicated() == true);
return this->getSrcIndex(fn, 0);
}
///////////////////////////////////////////////////////////////////////////
/*! mov.type dst src */
- Instruction MOV(Type type, RegisterIndex dst, RegisterIndex src);
+ Instruction MOV(Type type, Register dst, Register src);
/*! cos.type dst src */
- Instruction COS(Type type, RegisterIndex dst, RegisterIndex src);
+ Instruction COS(Type type, Register dst, Register src);
/*! sin.type dst src */
- Instruction SIN(Type type, RegisterIndex dst, RegisterIndex src);
+ Instruction SIN(Type type, Register dst, Register src);
/*! tan.type dst src */
- Instruction TAN(Type type, RegisterIndex dst, RegisterIndex src);
+ Instruction TAN(Type type, Register dst, Register src);
/*! log.type dst src */
- Instruction LOG(Type type, RegisterIndex dst, RegisterIndex src);
+ Instruction LOG(Type type, Register dst, Register src);
/*! sqr.type dst src */
- Instruction SQR(Type type, RegisterIndex dst, RegisterIndex src);
+ Instruction SQR(Type type, Register dst, Register src);
/*! rsq.type dst src */
- Instruction RSQ(Type type, RegisterIndex dst, RegisterIndex src);
+ Instruction RSQ(Type type, Register dst, Register src);
/*! pow.type dst src0 src1 */
- Instruction POW(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction POW(Type type, Register dst, Register src0, Register src1);
/*! mul.type dst src0 src1 */
- Instruction MUL(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction MUL(Type type, Register dst, Register src0, Register src1);
/*! add.type dst src0 src1 */
- Instruction ADD(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction ADD(Type type, Register dst, Register src0, Register src1);
/*! sub.type dst src0 src1 */
- Instruction SUB(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction SUB(Type type, Register dst, Register src0, Register src1);
/*! div.type dst src0 src1 */
- Instruction DIV(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction DIV(Type type, Register dst, Register src0, Register src1);
/*! rem.type dst src0 src1 */
- Instruction REM(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction REM(Type type, Register dst, Register src0, Register src1);
/*! shl.type dst src0 src1 */
- Instruction SHL(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction SHL(Type type, Register dst, Register src0, Register src1);
/*! shr.type dst src0 src1 */
- Instruction SHR(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction SHR(Type type, Register dst, Register src0, Register src1);
/*! asr.type dst src0 src1 */
- Instruction ASR(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction ASR(Type type, Register dst, Register src0, Register src1);
/*! bsf.type dst src0 src1 */
- Instruction BSF(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction BSF(Type type, Register dst, Register src0, Register src1);
/*! bsb.type dst src0 src1 */
- Instruction BSB(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction BSB(Type type, Register dst, Register src0, Register src1);
/*! or.type dst src0 src1 */
- Instruction OR(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction OR(Type type, Register dst, Register src0, Register src1);
/*! xor.type dst src0 src1 */
- Instruction XOR(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction XOR(Type type, Register dst, Register src0, Register src1);
/*! and.type dst src0 src1 */
- Instruction AND(Type type, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction AND(Type type, Register dst, Register src0, Register src1);
/*! mad.type dst {src0, src1, src2} == src */
- Instruction MAD(Type type, RegisterIndex dst, TupleIndex src);
+ Instruction MAD(Type type, Register dst, Tuple src);
/*! cmp.type.op dst src0 src1 */
- Instruction CMP(Type type, CompareOperation op, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction CMP(Type type, CompareOperation op, Register dst, Register src0, Register src1);
/*! cvt.{dstType <- srcType} dst src */
- Instruction CVT(Type dstType, Type srcType, RegisterIndex dst, RegisterIndex src0, RegisterIndex src1);
+ Instruction CVT(Type dstType, Type srcType, Register dst, Register src0, Register src1);
/*! bra labelIndex */
Instruction BRA(LabelIndex labelIndex);
/*! (pred) bra labelIndex */
- Instruction BRA(LabelIndex labelIndex, RegisterIndex pred);
+ Instruction BRA(LabelIndex labelIndex, Register pred);
/*! loadi.type dst value */
- Instruction LOADI(Type type, RegisterIndex dst, ImmediateIndex value);
+ Instruction LOADI(Type type, Register dst, ImmediateIndex value);
/*! load.type.space {dst1,...,dst_valueNum} offset value */
- Instruction LOAD(Type type, TupleIndex dst, RegisterIndex offset, MemorySpace space, uint16_t valueNum);
+ Instruction LOAD(Type type, Tuple dst, Register offset, MemorySpace space, uint16_t valueNum);
/*! store.type.space offset {src1,...,src_valueNum} value */
- Instruction STORE(Type type, TupleIndex src, RegisterIndex offset, MemorySpace space, uint16_t valueNum);
+ Instruction STORE(Type type, Tuple src, Register offset, MemorySpace space, uint16_t valueNum);
/*! fence.space */
Instruction FENCE(MemorySpace space);
/*! label labelIndex */
namespace gbe {
namespace ir {
- /*! A register can be either a byte, a word, a dword or a qword. It can be
- * either scalar or a vector. Everything is packed in 32 bits
+ /*! A register can be either a byte, a word, a dword or a qword. We store this
+ * value into a register data (which makes the register file)
*/
- class Register
+ class RegisterData
{
public:
- /*! Register family */
+ /*! RegisterData family */
enum Family : uint8_t {
BOOL = 0,
BYTE = 1,
QWORD = 4
};
/*! Build a register. All fields will be immutable */
- INLINE Register(Family family = DWORD) : family(family) {}
+ INLINE RegisterData(Family family = DWORD) : family(family) {}
/*! Copy constructor */
- INLINE Register(const Register &other) : family(other.family) {}
+ INLINE RegisterData(const RegisterData &other) : family(other.family) {}
/*! Copy operator */
- INLINE Register &operator= (const Register &other) {
+ INLINE RegisterData &operator= (const RegisterData &other) {
this->family = other.family;
return *this;
}
/*! Nothing really happens here */
- INLINE ~Register(void) {}
+ INLINE ~RegisterData(void) {}
Family family;
- GBE_CLASS(Register);
+ GBE_CLASS(RegisterData);
};
- /*! Register index is the position of the register in the register file. We
- * enforce type safety with this class
+ /*! Register is the position of the index of the register data in the register
+ * file. We enforce type safety with this class
*/
- TYPE_SAFE(RegisterIndex, uint16_t)
+ TYPE_SAFE(Register, uint16_t)
- /*! Tuple index is the position of the register index in the tuple vector. We
+ /*! Tuple is the position of the first register in the tuple vector. We
* enforce type safety with this class
*/
- TYPE_SAFE(TupleIndex, uint16_t)
+ TYPE_SAFE(Tuple, uint16_t)
/*! A register file allocates and destroys registers. Basically, we will have
* one register file per function
{
public:
/*! Return the index of a newly allocated register register */
- INLINE RegisterIndex append(Register::Family family) {
+ INLINE Register append(RegisterData::Family family) {
GBE_ASSERT(regNum() <= MAX_INDEX);
const uint16_t index = regNum();
- const Register reg(family);
+ const RegisterData reg(family);
regs.push_back(reg);
- return RegisterIndex(index);
+ return Register(index);
}
/*! Make a tuple and return the index to the first element of the tuple */
template <typename First, typename... Rest>
- INLINE TupleIndex appendTuple(First first, Rest... rest) {
- const TupleIndex index = TupleIndex(regTuples.size());
+ INLINE Tuple appendTuple(First first, Rest... rest) {
+ const Tuple index = Tuple(regTuples.size());
GBE_ASSERT(first < regNum());
regTuples.push_back(first);
appendTuple(rest...);
/*! To terminate variadic recursion */
INLINE void appendTuple(void) {}
/*! Return a copy of the register at index */
- INLINE Register get(RegisterIndex index) const {
+ INLINE RegisterData get(Register index) const {
GBE_ASSERT(index < regNum());
return regs[index];
}
/*! Get the register index from the tuple */
- INLINE RegisterIndex get(TupleIndex index, uint32_t which) const {
+ INLINE Register get(Tuple index, uint32_t which) const {
GBE_ASSERT(uint16_t(index) + which < regTuples.size());
return regTuples[uint16_t(index) + which];
}
/*! Number of tuples in the register file */
INLINE uint32_t tupleNum(void) const { return regTuples.size(); }
private:
- vector<Register> regs; //!< All the registers together
- vector<RegisterIndex> regTuples; //!< Tuples are used for many src / dst
+ vector<RegisterData> regs; //!< All the registers together
+ vector<Register> regTuples; //!< Tuples are used for many src / dst
enum { MAX_INDEX = 0xffff }; //!< register and tuple indices are short
GBE_CLASS(RegisterFile);
};
};
/*! Get the register family for each type */
- INLINE Register::Family getFamily(Type type) {
+ INLINE RegisterData::Family getFamily(Type type) {
switch (type) {
case TYPE_BOOL:
- return Register::BOOL;
+ return RegisterData::BOOL;
case TYPE_S8:
case TYPE_U8:
- return Register::BYTE;
+ return RegisterData::BYTE;
case TYPE_S16:
case TYPE_U16:
case TYPE_HALF:
- return Register::WORD;
+ return RegisterData::WORD;
case TYPE_S32:
case TYPE_U32:
case TYPE_FLOAT:
- return Register::DWORD;
+ return RegisterData::DWORD;
case TYPE_S64:
case TYPE_U64:
case TYPE_DOUBLE:
- return Register::QWORD;
+ return RegisterData::QWORD;
};
- return Register::DWORD;
+ return RegisterData::DWORD;
}
} /* namespace ir */
};
} /* namespace gbe */
-/*! Register a new unit test */
+/*! RegisterData a new unit test */
#define UTEST_REGISTER(FN) static const gbe::UTest __##NAME##__(FN, #FN);
/*! No assert is expected */
Unit unit;
Context ctx(unit);
ctx.startFunction("hop");
- const RegisterIndex reg0 = ctx.reg(Register::DWORD);
- const RegisterIndex reg1 = ctx.reg(Register::DWORD);
- const RegisterIndex reg2 = ctx.reg(Register::DWORD);
+ const Register reg0 = ctx.reg(RegisterData::DWORD);
+ const Register reg1 = ctx.reg(RegisterData::DWORD);
+ const Register reg2 = ctx.reg(RegisterData::DWORD);
ctx.MAD(TYPE_FLOAT, reg0, reg0, reg1, reg2);
ctx.endFunction();
}