36 #ifndef __ARCH_HSAIL_INSTS_DECL_HH__ 37 #define __ARCH_HSAIL_INSTS_DECL_HH__ 43 #include "debug/HSAIL.hh" 49 template<
typename _DestOperand,
typename _SrcOperand>
64 template<
typename _OperandType,
typename _CType, Enums::MemType _memType,
71 static const Enums::MemType memType = _memType;
101 template<
typename DestOperandType,
typename SrcOperandType,
106 typename DestOperandType::DestOperand
dest;
107 typename SrcOperandType::SrcOperand src[NumSrcOperands];
115 for (
int i = 0;
i < NumSrcOperands; ++
i) {
117 disassembly += src[
i].disassemble();
121 virtual std::string opcode_suffix() = 0;
132 dest.init(op_offs, obj);
134 for (
int i = 0;
i < NumSrcOperands; ++
i) {
136 src[
i].init(op_offs, obj);
141 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
142 if (operandIndex < NumSrcOperands)
143 return src[operandIndex].isVectorRegister();
145 return dest.isVectorRegister();
148 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
149 if (operandIndex < NumSrcOperands)
150 return src[operandIndex].isCondRegister();
152 return dest.isCondRegister();
155 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
156 if (operandIndex < NumSrcOperands)
157 return src[operandIndex].isScalarRegister();
159 return dest.isScalarRegister();
162 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
163 if (operandIndex < NumSrcOperands)
169 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
170 if (operandIndex >= NumSrcOperands)
175 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
176 if (operandIndex < NumSrcOperands)
177 return src[operandIndex].opSize();
179 return dest.opSize();
184 assert(operandIndex >= 0 && operandIndex < getNumOperands());
186 if (operandIndex < NumSrcOperands)
187 return src[operandIndex].regIndex();
189 return dest.regIndex();
193 for (
int i = 0;
i < NumSrcOperands;
i++) {
194 if (src[
i].isVectorRegister()) {
204 template<
typename DataType,
int NumSrcOperands>
206 typename DataType::OperandType,
215 typename DataType::OperandType,
216 NumSrcOperands>(ib, obj, opcode)
221 template<
typename DestOperandType,
typename Src0OperandType,
222 typename Src1OperandType,
typename Src2OperandType>
226 typename DestOperandType::DestOperand
dest;
227 typename Src0OperandType::SrcOperand
src0;
228 typename Src1OperandType::SrcOperand
src1;
229 typename Src2OperandType::SrcOperand
src2;
234 disassembly =
csprintf(
"%s %s,%s,%s,%s",
opcode, dest.disassemble(),
235 src0.disassemble(), src1.disassemble(),
248 dest.init(op_offs, obj);
251 src0.init(op_offs, obj);
254 src1.init(op_offs, obj);
257 src2.init(op_offs, obj);
261 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
263 return src0.isVectorRegister();
264 else if (operandIndex == 1)
265 return src1.isVectorRegister();
266 else if (operandIndex == 2)
267 return src2.isVectorRegister();
269 return dest.isVectorRegister();
272 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
274 return src0.isCondRegister();
275 else if (operandIndex == 1)
276 return src1.isCondRegister();
277 else if (operandIndex == 2)
278 return src2.isCondRegister();
280 return dest.isCondRegister();
283 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
285 return src0.isScalarRegister();
286 else if (operandIndex == 1)
287 return src1.isScalarRegister();
288 else if (operandIndex == 2)
289 return src2.isScalarRegister();
291 return dest.isScalarRegister();
294 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
295 if (operandIndex < 3)
301 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
302 if (operandIndex >= 3)
308 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
310 return src0.opSize();
311 else if (operandIndex == 1)
312 return src1.opSize();
313 else if (operandIndex == 2)
314 return src2.opSize();
316 return dest.opSize();
322 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
324 return src0.regIndex();
325 else if (operandIndex == 1)
326 return src1.regIndex();
327 else if (operandIndex == 2)
328 return src2.regIndex();
330 return dest.regIndex();
335 if (src0.isVectorRegister()) {
338 if (src1.isVectorRegister()) {
341 if (src2.isVectorRegister()) {
350 template<
typename DestDataType,
typename Src0DataType,
351 typename Src1DataType,
typename Src2DataType>
354 typename Src0DataType::OperandType,
355 typename Src1DataType::OperandType,
356 typename Src2DataType::OperandType>
367 typename Src0DataType::OperandType,
368 typename Src1DataType::OperandType,
369 typename Src2DataType::OperandType>(ib,
375 template<
typename DataType>
383 DataType>(ib, obj, opcode)
388 template<
typename DataType>
397 U32>(ib, obj, opcode)
402 template<
typename DestOperandType,
typename Src0OperandType,
403 typename Src1OperandType>
407 typename DestOperandType::DestOperand
dest;
408 typename Src0OperandType::SrcOperand
src0;
409 typename Src1OperandType::SrcOperand
src1;
415 src0.disassemble(), src1.disassemble());
427 dest.init(op_offs, obj);
430 src0.init(op_offs, obj);
433 src1.init(op_offs, obj);
436 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
438 return src0.isVectorRegister();
439 else if (operandIndex == 1)
440 return src1.isVectorRegister();
442 return dest.isVectorRegister();
445 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
447 return src0.isCondRegister();
448 else if (operandIndex == 1)
449 return src1.isCondRegister();
451 return dest.isCondRegister();
454 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
456 return src0.isScalarRegister();
457 else if (operandIndex == 1)
458 return src1.isScalarRegister();
460 return dest.isScalarRegister();
463 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
464 if (operandIndex < 2)
470 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
471 if (operandIndex >= 2)
477 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
479 return src0.opSize();
480 else if (operandIndex == 1)
481 return src1.opSize();
483 return dest.opSize();
489 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
491 return src0.regIndex();
492 else if (operandIndex == 1)
493 return src1.regIndex();
495 return dest.regIndex();
500 if (src0.isVectorRegister()) {
503 if (src1.isVectorRegister()) {
512 template<
typename DestDataType,
typename Src0DataType,
513 typename Src1DataType>
516 typename Src0DataType::OperandType,
517 typename Src1DataType::OperandType>
527 typename Src0DataType::OperandType,
528 typename Src1DataType::OperandType>(ib,
541 if ((src1 & 0x3) && (fpclass == FP_NAN)) {
546 if ((src1 & 0x4) && fpclass == FP_INFINITE)
548 if ((src1 & 0x8) && fpclass == FP_NORMAL)
550 if ((src1 & 0x10) && fpclass == FP_SUBNORMAL)
552 if ((src1 & 0x20) && fpclass == FP_ZERO)
555 if ((src1 & 0x40) && fpclass == FP_ZERO)
557 if ((src1 & 0x80) && fpclass == FP_SUBNORMAL)
559 if ((src1 & 0x100) && fpclass == FP_NORMAL)
561 if ((src1 & 0x200) && fpclass == FP_INFINITE)
567 template<
typename DataType>
578 template<
typename DataType>
594 using namespace Brig;
601 return (src0 == src1);
607 return (src0 != src1);
613 return (src0 < src1);
619 return (src0 <= src1);
625 return (src0 > src1);
631 return (src0 >= src1);
635 return (src0 == src0) || (src1 == src1);
639 return (src0 != src0) || (src1 != src1);
642 fatal(
"Bad cmpOp value %d\n", (
int)cmpOp);
654 T tmp = ((int64_t)src0 < 0) ? (~src0) : (src0);
657 int pos = 8 *
sizeof(T) - 1;
661 while (!(tmp & (1 << pos))) {
670 template<
typename DestOperandType,
typename SrcOperandType>
689 template<
typename DestDataType,
typename SrcDataType>
691 typename SrcDataType::OperandType>
698 DestDataType::label, SrcDataType::label);
704 typename SrcDataType::OperandType>(ib, obj, _opcode)
709 template<
typename DestDataType,
typename SrcDataType>
711 typename SrcDataType::OperandType, 1>
716 return csprintf(
"_%s_%s", DestDataType::label, SrcDataType::label);
722 typename SrcDataType::OperandType,
728 template<
typename DestDataType,
typename SrcDataType>
731 typename SrcDataType::OperandType, 1>
736 return csprintf(
"_%s_%s", DestDataType::label, SrcDataType::label);
742 typename SrcDataType::OperandType,
807 template<
typename DestOperandType>
811 typename DestOperandType::DestOperand
dest;
824 dest.init(op_offs, obj);
828 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
829 return dest.isVectorRegister();
832 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
833 return dest.isCondRegister();
836 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
837 return dest.isScalarRegister();
842 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
843 return dest.opSize();
849 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
850 return dest.regIndex();
858 template<
typename DestDataType>
873 template<
typename DestOperandType>
879 typename DestOperandType::DestOperand
dest;
897 dest.init(op_offs, obj);
900 src0.
init(op_offs, obj);
903 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
904 return dest.isVectorRegister();
907 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
908 return dest.isCondRegister();
911 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
912 return dest.isScalarRegister();
917 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
918 return dest.opSize();
924 assert((operandIndex >= 0) && (operandIndex < getNumOperands()));
925 return dest.regIndex();
933 template<
typename DestDataType>
954 : Base(ib, obj,
"ret")
956 setFlag(GPUStaticInst::Return);
969 : Base(ib, obj,
"barrier")
971 setFlag(GPUStaticInst::MemBarrier);
990 : Base(ib, obj,
"memfence")
1007 setFlag(GPUStaticInst::MemFence);
1009 switch (memFenceMemOrder) {
1014 setFlag(RelaxedOrder);
1023 setFlag(AcquireRelease);
1026 fatal(
"MemInst has bad BrigMemoryOrder\n");
1032 setFlag(GPUStaticInst::GlobalSegment);
1042 switch (memFenceScopeSegGlobal) {
1047 setFlag(WorkitemScope);
1050 setFlag(WorkgroupScope);
1053 setFlag(DeviceScope);
1056 setFlag(SystemScope);
1059 fatal(
"MemFence has bad global scope type\n");
1062 setFlag(GPUStaticInst::GlobalSegment);
1064 switch (memFenceScopeSegGlobal) {
1069 setFlag(WorkitemScope);
1072 setFlag(WorkgroupScope);
1075 setFlag(DeviceScope);
1078 setFlag(SystemScope);
1081 fatal(
"MemFence has bad global scope type\n");
1084 setFlag(GPUStaticInst::GroupSegment);
1086 switch (memFenceScopeSegGroup) {
1091 setFlag(WorkitemScope);
1094 setFlag(WorkgroupScope);
1097 setFlag(DeviceScope);
1100 setFlag(SystemScope);
1103 fatal(
"MemFence has bad group scope type\n");
1106 fatal(
"MemFence constructor: bad scope specifiers\n");
1113 Wavefront *wave = gpuDynInst->wavefront();
1128 if (isGlobalSeg()) {
1129 gpuDynInst->simdId = w->
simdId;
1130 gpuDynInst->wfSlotId = w->
wfSlotId;
1131 gpuDynInst->wfDynId = w->
wfDynId;
1132 gpuDynInst->kern_id = w->
kernId;
1135 gpuDynInst->useContinuation =
false;
1143 }
else if (isGroupSeg()) {
1146 fatal(
"MemFence execute: bad op type\n");
1160 if (dest.disassemble() ==
"") {
1162 src1.disassemble());
1165 src0.disassemble(), dest.disassemble(),
1166 src1.disassemble());
1173 std::string func_name = src0.disassemble();
1174 if (func_name.find(
"__gem5_hsail_op") != std::string::npos) {
1204 void MagicAtomicNRAddGlobalU32Reg(
Wavefront *w,
1207 void MagicAtomicNRAddGroupU32Reg(
Wavefront *w,
1214 void MagicMostSigBroadcast(
Wavefront *w);
1224 dest.
init(op_offs, obj);
1226 src0.
init(op_offs, obj);
1230 if (!isPseudoOp()) {
1231 func_ptr =
dynamic_cast<HsailCode*
>(obj->
1232 getFunction(func_name));
1235 fatal(
"call::exec cannot find function: %s\n", func_name);
1239 src1.
init(op_offs, obj);
1262 execPseudoInst(w, gpuDynInst);
1264 fatal(
"Native HSAIL functions are not yet implemented: %s\n",
1273 template<
typename T> T
heynot(T arg) {
return ~arg; }
1298 #endif // __ARCH_HSAIL_INSTS_DECL_HH__
DestDataType::CType DestCType
bool isSrcOperand(int operandIndex)
void init(unsigned opOffset, const BrigObject *obj)
ShiftInst(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *opcode)
DestOperandType::DestOperand dest
int numSrcRegOperands() override
void injectGlobalMemFence(GPUDynInstPtr gpuDynInst, bool kernelLaunch=true, RequestPtr req=nullptr)
#define fatal(...)
This implements a cprintf based fatal() function.
BrigDataOffsetOperandList32_t operands
HsailDataType< SRegOperandType, uint8_t, Enums::M_U8, VT_32 > U8
Call(const Brig::BrigInstBase *ib, const BrigObject *obj)
int numSrcRegOperands() override
ArithInst(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *opcode)
int getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
void init(unsigned opOffset, const BrigObject *obj)
bool isCondRegister(int operandIndex)
HsailDataType< SRegOperandType, uint16_t, Enums::M_U16, VT_32 > U16
CmovInst(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *opcode)
bool isScalarRegister(int operandIndex)
HsailDataType< SRegOperandType, float, Enums::M_F32, VT_32 > F32
HsailDataType< SRegOperandType, uint32_t, Enums::M_U32, VT_32, 1 > B32
bool isCondRegister(int operandIndex)
int getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
bool isCondRegister(int operandIndex)
bool fpclassify(T src0, uint32_t src1)
int getNumOperands() override
SpecialInstNoSrc(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
Brig::BrigCompareOperation cmpOp
SpecialInst1SrcBase(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
bool isVectorRegister(int operandIndex)
HsailDataType< DRegOperandType, int64_t, Enums::M_S64, VT_64 > S64
int getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) override
bool isDstOperand(int operandIndex) override
Ret(const Brig::BrigInstBase *ib, const BrigObject *obj)
ImmOperand< SrcCType > src0
void generateDisassembly()
HsailDataType< SRegOperandType, uint16_t, Enums::M_U16, VT_32, 1 > B16
CmpInst(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
HsailDataType< CRegOperandType, bool, Enums::M_U8, VT_32, 1 > B1
HsailOperandType< DRegOperand, DRegOrImmOperand > DRegOperandType
HsailDataType< DRegOperandType, uint64_t, Enums::M_U64, VT_64, 1 > B64
bool isCondRegister(int operandIndex) override
int getOperandSize(int operandIndex)
bool isSrcOperand(int operandIndex) override
bool isVectorRegister(int operandIndex) override
bool isDstOperand(int operandIndex) override
Brig::BrigMemoryScope memFenceScopeSegGroup
bool isScalarRegister(int operandIndex)
int getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst) override
int getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
static const char * label
void initiateAcc(GPUDynInstPtr gpuDynInst)
Stub(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
GlobalMemPipeline globalMemoryPipe
int getOperandSize(int operandIndex)
bool isDstOperand(int operandIndex)
std::shared_ptr< GPUDynInst > GPUDynInstPtr
bool init(unsigned opOffset, const BrigObject *obj)
HsailDataType< DRegOperandType, double, Enums::M_F64, VT_64 > F64
bool isVectorRegister(int operandIndex)
std::string opcode_suffix()
std::string csprintf(const char *format, const Args &...args)
unsigned getOperandPtr(int offs, int index) const
bool heynot< bool >(bool arg)
int getNumOperands() override
HsailDataType< SRegOperandType, uint8_t, Enums::M_U8, VT_32, 1 > B8
void generateDisassembly()
HsailDataType< SRegOperandType, int16_t, Enums::M_S16, VT_32 > S16
Brig::BrigMemoryScope memFenceScopeSegGlobal
int getOperandSize(int operandIndex)
SpecialInstNoSrcNoDest Base
void generateDisassembly()
void execute(GPUDynInstPtr gpuDynInst)
DestOperandType::DestOperand dest
ComputeUnit * computeUnit
SpecialInstNoSrcNoDest Base
DestDataType::CType DestCType
bool isDstOperand(int operandIndex)
DestOperandType::DestOperand dest
bool isCondRegister(int operandIndex)
std::string opcode_suffix()
const char * cmpOpToString(Brig::BrigCompareOperation cmpOp)
SpecialInstNoSrcBase(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
int getOperandSize(int operandIndex) override
bool isDstOperand(int operandIndex)
std::string disassemble()
bool isDstOperand(int operandIndex)
bool isVectorRegister(int operandIndex) override
bool isScalarRegister(int operandIndex)
bool isScalarRegister(int operandIndex)
bool isVectorRegister(int operandIndex)
bool isCondRegister(int operandIndex) override
void generateDisassembly() override
bool isScalarRegister(int operandIndex) override
HsailDataType< DRegOperandType, uint64_t, Enums::M_U64, VT_64 > U64
bool isScalarRegister(int operandIndex) override
CommonInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *opcode)
bool isSrcOperand(int operandIndex) override
HsailOperandType< CRegOperand, CRegOrImmOperand > CRegOperandType
PopcountInst(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
bool isSrcOperand(int operandIndex)
std::string opcode_suffix()
Barrier(const Brig::BrigInstBase *ib, const BrigObject *obj)
void execute(GPUDynInstPtr gpuDynInst)
void issueRequest(GPUDynInstPtr gpuDynInst)
issues a request to the pipeline - i.e., enqueue it in the request buffer.
SpecialInstNoSrcNoDest(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
Bitfield< 24, 21 > opcode
bool isSrcOperand(int operandIndex)
std::string opcode_suffix()
std::string disassemble()
bool isVectorRegister(int operandIndex)
bool compare(T src0, T src1, Brig::BrigCompareOperation cmpOp)
SpecialInstNoSrcNoDest Base
MemFence(const Brig::BrigInstBase *ib, const BrigObject *obj)
Brig::BrigMemoryScope memFenceScopeSegImage
bool isSrcOperand(int operandIndex)
HsailDataType< SRegOperandType, int32_t, Enums::M_S32, VT_32 > S32
void generateDisassembly()
int numDstRegOperands() override
ClassInst(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *opcode)
HsailDataType< SRegOperandType, int8_t, Enums::M_S8, VT_32 > S8
int getRegisterIndex(int operandIndex, GPUDynInstPtr gpuDynInst)
CmpInstBase(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
CvtInst(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
HsailOperandType< SRegOperand, SRegOrImmOperand > SRegOperandType
int getOperandSize(int operandIndex)
HsailDataType< SRegOperandType, uint32_t, Enums::M_U32, VT_32 > U32
int numDstRegOperands() override
int getOperandSize(int operandIndex) override
SpecialInst1Src(const Brig::BrigInstBase *ib, const BrigObject *obj, const char *_opcode)
BrigCompareOperation8_t compare
Brig::BrigMemoryOrder memFenceMemOrder