36 #ifndef __ARCH_GCN3_OPERAND_HH__
37 #define __ARCH_GCN3_OPERAND_HH__
80 virtual void read() = 0;
81 virtual void write() = 0;
97 template<
typename DataType,
bool Const,
size_t NumDwords>
100 template<
typename DataType,
bool Const,
101 size_t NumDwords =
sizeof(DataType) /
sizeof(
VecElemU32)>
105 "Incorrect number of DWORDS for GCN3 operand.");
135 ->reservedScalarRegs);
155 for (
auto i = 0;
i < NumDwords; ++
i) {
159 DPRINTF(GPUVRF,
"Read v[%d]\n", vgprIdx);
160 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx);
163 if (NumDwords == 1) {
165 auto vgpr =
vecReg.template as<DataType>();
166 auto reg_file_vgpr =
vrfData[0]->template as<VecElemU32>();
168 std::memcpy((
void*)&vgpr[lane],
169 (
void*)®_file_vgpr[lane],
sizeof(DataType));
171 }
else if (NumDwords == 2) {
174 auto vgpr =
vecReg.template as<VecElemU64>();
175 auto reg_file_vgpr0 =
vrfData[0]->template as<VecElemU32>();
176 auto reg_file_vgpr1 =
vrfData[1]->template as<VecElemU32>();
180 ((
VecElemU32*)&tmp_val)[0] = reg_file_vgpr0[lane];
181 ((
VecElemU32*)&tmp_val)[1] = reg_file_vgpr1[lane];
182 vgpr[lane] = tmp_val;
209 if (NumDwords == 1) {
213 auto reg_file_vgpr =
vrfData[0]->template as<VecElemU32>();
214 auto vgpr =
vecReg.template as<DataType>();
217 if (exec_mask[lane] ||
_gpuDynInst->ignoreExec()) {
218 std::memcpy((
void*)®_file_vgpr[lane],
219 (
void*)&vgpr[lane],
sizeof(DataType));
223 DPRINTF(GPUVRF,
"Write v[%d]\n", vgprIdx);
224 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx);
225 }
else if (NumDwords == 2) {
232 auto reg_file_vgpr0 =
vrfData[0]->template as<VecElemU32>();
233 auto reg_file_vgpr1 =
vrfData[1]->template as<VecElemU32>();
234 auto vgpr =
vecReg.template as<VecElemU64>();
237 if (exec_mask[lane] ||
_gpuDynInst->ignoreExec()) {
238 reg_file_vgpr0[lane] = ((
VecElemU32*)&vgpr[lane])[0];
239 reg_file_vgpr1[lane] = ((
VecElemU32*)&vgpr[lane])[1];
243 DPRINTF(GPUVRF,
"Write v[%d:%d]\n", vgprIdx0, vgprIdx1);
244 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx0);
245 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx1);
266 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && Const>
276 assert(std::is_floating_point<DataType>::value);
277 ret_val = std::fabs(ret_val);
281 assert(std::is_floating_point<DataType>::value);
287 auto vgpr =
vecReg.template as<DataType>();
288 DataType ret_val = vgpr[idx];
291 assert(std::is_floating_point<DataType>::value);
292 ret_val = std::fabs(ret_val);
296 assert(std::is_floating_point<DataType>::value);
309 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
316 return vecReg.template as<DataType>()[idx];
331 using VecRegCont =
typename std::conditional<NumDwords == 2,
334 typename std::conditional<
sizeof(DataType)
365 std::array<VecRegContainerU32*, NumDwords>
vrfData;
368 template<
typename DataType,
bool Const,
369 size_t NumDwords =
sizeof(DataType) /
sizeof(
ScalarRegU32)>
373 "Incorrect number of DWORDS for GCN3 operand.");
394 template<
bool Condition = NumDwords == 1 || NumDwords == 2>
398 assert(
sizeof(DataType) <=
sizeof(
srfData));
399 DataType raw_data((DataType)0);
400 std::memcpy((
void*)&raw_data, (
void*)
srfData.data(),
415 Wavefront *wf = _gpuDynInst->wavefront();
421 for (
auto i = 0;
i < NumDwords; ++
i) {
424 DPRINTF(GPUSRF,
"Read s[%d]\n", sgprIdx);
425 cu->
srf[wf->
simdId]->printReg(wf, sgprIdx);
433 Wavefront *wf = _gpuDynInst->wavefront();
440 if (NumDwords == 1) {
441 std::memcpy((
void*)&new_exec_mask_val,
443 }
else if (NumDwords == 2) {
444 std::memcpy((
void*)&new_exec_mask_val,
447 panic(
"Trying to write more than 2 DWORDS to EXEC\n");
451 DPRINTF(GPUSRF,
"Write EXEC\n");
452 DPRINTF(GPUSRF,
"EXEC = %#x\n", new_exec_mask_val);
458 assert(NumDwords == 1);
462 std::memcpy((
void*)&new_exec_mask_hi_val,
463 (
void*)
srfData.data(),
sizeof(new_exec_mask_hi_val));
465 new_exec_mask_hi_val);
468 DPRINTF(GPUSRF,
"Write EXEC\n");
469 DPRINTF(GPUSRF,
"EXEC = %#x\n", new_exec_mask_val);
471 _gpuDynInst->writeMiscReg(_opIdx,
srfData[0]);
474 for (
auto i = 0;
i < NumDwords; ++
i) {
476 auto &sgpr = cu->
srf[wf->
simdId]->readWriteable(sgprIdx);
477 if (_gpuDynInst->isLoad()) {
480 _gpuDynInst->scalar_data)[
i];
484 DPRINTF(GPUSRF,
"Write s[%d]\n", sgprIdx);
485 cu->
srf[wf->
simdId]->printReg(wf, sgprIdx);
493 template<
bool Condition = NumDwords == 1 || NumDwords == 2>
497 DataType &sgpr = *((DataType*)
srfData.data());
501 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
505 std::memcpy((
void*)
srfData.data(), (
void*)&rhs,
sizeof(DataType));
519 assert(NumDwords == 1 || NumDwords == 2);
524 if (NumDwords == 1) {
526 execMask().to_ulong();
527 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask,
529 DPRINTF(GPUSRF,
"Read EXEC\n");
530 DPRINTF(GPUSRF,
"EXEC = %#x\n", exec_mask);
532 assert(NumDwords == 2);
534 execMask().to_ullong();
535 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask,
537 DPRINTF(GPUSRF,
"Read EXEC\n");
538 DPRINTF(GPUSRF,
"EXEC = %#x\n", exec_mask);
548 assert(NumDwords == 1);
550 ->execMask().to_ullong();
553 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask_hi,
554 sizeof(exec_mask_hi));
555 DPRINTF(GPUSRF,
"Read EXEC_HI\n");
556 DPRINTF(GPUSRF,
"EXEC_HI = %#x\n", exec_mask_hi);
562 assert(NumDwords == 1);
563 srfData[0] = _gpuDynInst->srcLiteral();
568 std::memcpy((
void*)
srfData.data(), (
void*)&pos_half,
576 std::memcpy((
void*)
srfData.data(), (
void*)&neg_half,
583 std::memcpy(
srfData.data(), &pos_one,
sizeof(pos_one));
589 std::memcpy(
srfData.data(), &neg_one,
sizeof(neg_one));
595 std::memcpy(
srfData.data(), &pos_two,
sizeof(pos_two));
601 std::memcpy(
srfData.data(), &neg_two,
sizeof(neg_two));
607 std::memcpy(
srfData.data(), &pos_four,
sizeof(pos_four));
613 std::memcpy((
void*)
srfData.data(), (
void*)&neg_four ,
626 std::memcpy((
void*)
srfData.data(),
627 (
void*)&pi_u64,
sizeof(pi_u64));
629 std::memcpy((
void*)
srfData.data(),
630 (
void*)&pi_u32,
sizeof(pi_u32));
636 assert(
sizeof(DataType) <=
sizeof(
srfData));
637 DataType misc_val(0);
639 misc_val = (DataType)_gpuDynInst
640 ->readConstVal<DataType>(_opIdx);
642 misc_val = (DataType)_gpuDynInst->readMiscReg(_opIdx);
644 std::memcpy((
void*)
srfData.data(), (
void*)&misc_val,
658 Wavefront *wf = _gpuDynInst->wavefront();
669 assert(NumDwords == 1);
676 assert(sgprIdx > -1);
752 #endif // __ARCH_GCN3_OPERAND_HH__