summaryrefslogtreecommitdiff
path: root/src/arch/hsail/operand.hh
diff options
context:
space:
mode:
authorjkalamat <john.kalamatianos@amd.com>2016-06-09 11:24:55 -0400
committerjkalamat <john.kalamatianos@amd.com>2016-06-09 11:24:55 -0400
commit3724fb15faafaaca54cc7a500df9c1490a387049 (patch)
treebbd671b68ba971087a1cd45b208947c09a622d38 /src/arch/hsail/operand.hh
parente5b7b6780f9748b6f13ef91e3e22d53ebdf47968 (diff)
downloadgem5-3724fb15faafaaca54cc7a500df9c1490a387049.tar.xz
gpu-compute: parametrize Wavefront size
Eliminate the VSZ constant that defined the Wavefront size (in numbers of work items); replaced it with a parameter in the GPU.py configuration script. Changed all data structures dependent on the Wavefront size to be dynamically sized. Legal values of Wavefront size are 16, 32, 64 for now and checked at initialization time.
Diffstat (limited to 'src/arch/hsail/operand.hh')
-rw-r--r--src/arch/hsail/operand.hh44
1 files changed, 31 insertions, 13 deletions
diff --git a/src/arch/hsail/operand.hh b/src/arch/hsail/operand.hh
index e3d275b10..4d981ee00 100644
--- a/src/arch/hsail/operand.hh
+++ b/src/arch/hsail/operand.hh
@@ -42,6 +42,7 @@
* Defines classes encapsulating HSAIL instruction operands.
*/
+#include <limits>
#include <string>
#include "arch/hsail/Brig.h"
@@ -346,6 +347,8 @@ class CRegOperand : public BaseRegOperand
template<typename T>
class ImmOperand : public BaseOperand
{
+ private:
+ uint16_t kind;
public:
T bits;
@@ -355,11 +358,21 @@ class ImmOperand : public BaseOperand
template<typename OperandType>
OperandType
- get()
+ get(Wavefront *w)
{
assert(sizeof(OperandType) <= sizeof(T));
+ panic_if(w == nullptr, "WF pointer needs to be set");
+
+ switch (kind) {
+ // immediate operand is WF size
+ case Brig::BRIG_KIND_OPERAND_WAVESIZE:
+ return (OperandType)w->computeUnit->wfSize();
+ break;
- return *(OperandType*)&bits;
+ default:
+ return *(OperandType*)&bits;
+ break;
+ }
}
// This version of get() takes a WF* and a lane id for
@@ -368,7 +381,7 @@ class ImmOperand : public BaseOperand
OperandType
get(Wavefront *w, int lane)
{
- return get<OperandType>();
+ return get<OperandType>(w);
}
};
@@ -388,16 +401,18 @@ ImmOperand<T>::init(unsigned opOffset, const BrigObject *obj)
auto cbptr = (Brig::BrigOperandConstantBytes*)brigOp;
bits = *((T*)(obj->getData(cbptr->bytes + 4)));
-
+ kind = brigOp->kind;
return true;
}
break;
case Brig::BRIG_KIND_OPERAND_WAVESIZE:
- bits = VSZ;
+ kind = brigOp->kind;
+ bits = std::numeric_limits<unsigned long long>::digits;
return true;
default:
+ kind = Brig::BRIG_KIND_NONE;
return false;
}
}
@@ -409,6 +424,7 @@ ImmOperand<T>::init_from_vect(unsigned opOffset, const BrigObject *obj, int at)
const Brig::BrigOperand *brigOp = obj->getOperand(opOffset);
if (brigOp->kind != Brig::BRIG_KIND_OPERAND_OPERAND_LIST) {
+ kind = Brig::BRIG_KIND_NONE;
return false;
}
@@ -423,6 +439,7 @@ ImmOperand<T>::init_from_vect(unsigned opOffset, const BrigObject *obj, int at)
(const Brig::BrigOperand *)obj->getOperand(*data_offset);
if (p->kind != Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES) {
+ kind = Brig::BRIG_KIND_NONE;
return false;
}
@@ -456,7 +473,7 @@ class RegOrImmOperand : public BaseOperand
OperandType
get(Wavefront *w, int lane)
{
- return is_imm ? imm_op.template get<OperandType>() :
+ return is_imm ? imm_op.template get<OperandType>(w) :
reg_op.template get<OperandType>(w, lane);
}
@@ -571,7 +588,7 @@ class AddrOperandBase : public BaseOperand
uint64_t calcUniformBase();
public:
- virtual void calcVector(Wavefront *w, uint64_t *addrVec) = 0;
+ virtual void calcVector(Wavefront *w, std::vector<Addr> &addrVec) = 0;
virtual uint64_t calcLane(Wavefront *w, int lane=0) = 0;
uint64_t offset;
@@ -586,7 +603,7 @@ class RegAddrOperand : public AddrOperandBase
RegOperandType reg;
void init(unsigned opOffset, const BrigObject *obj);
uint64_t calcUniform();
- void calcVector(Wavefront *w, uint64_t *addrVec);
+ void calcVector(Wavefront *w, std::vector<Addr> &addrVec);
uint64_t calcLane(Wavefront *w, int lane=0);
uint32_t opSize() { return reg.opSize(); }
bool isVectorRegister() { return reg.registerType == Enums::RT_VECTOR; }
@@ -641,11 +658,12 @@ RegAddrOperand<RegOperandType>::calcUniform()
template<typename RegOperandType>
void
-RegAddrOperand<RegOperandType>::calcVector(Wavefront *w, uint64_t *addrVec)
+RegAddrOperand<RegOperandType>::calcVector(Wavefront *w,
+ std::vector<Addr> &addrVec)
{
Addr address = calcUniformBase();
- for (int lane = 0; lane < VSZ; ++lane) {
+ for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) {
if (w->execMask(lane)) {
if (reg.regFileChar == 's') {
addrVec[lane] = address + reg.template get<uint32_t>(w, lane);
@@ -680,7 +698,7 @@ class NoRegAddrOperand : public AddrOperandBase
public:
void init(unsigned opOffset, const BrigObject *obj);
uint64_t calcUniform();
- void calcVector(Wavefront *w, uint64_t *addrVec);
+ void calcVector(Wavefront *w, std::vector<Addr> &addrVec);
uint64_t calcLane(Wavefront *w, int lane=0);
std::string disassemble();
};
@@ -698,11 +716,11 @@ NoRegAddrOperand::calcLane(Wavefront *w, int lane)
}
inline void
-NoRegAddrOperand::calcVector(Wavefront *w, uint64_t *addrVec)
+NoRegAddrOperand::calcVector(Wavefront *w, std::vector<Addr> &addrVec)
{
uint64_t address = calcUniformBase();
- for (int lane = 0; lane < VSZ; ++lane)
+ for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane)
addrVec[lane] = address;
}