34 #ifndef __ARCH_GCN3_OPERAND_HH__
35 #define __ARCH_GCN3_OPERAND_HH__
81 virtual void read() = 0;
82 virtual void write() = 0;
98 template<
typename DataType,
bool Const,
size_t NumDwords>
101 template<
typename DataType,
bool Const,
102 size_t NumDwords =
sizeof(DataType) /
sizeof(
VecElemU32)>
106 "Incorrect number of DWORDS for GCN3 operand.");
136 ->reservedScalarRegs);
156 for (
auto i = 0;
i < NumDwords; ++
i) {
160 DPRINTF(GPUVRF,
"Read v[%d]\n", vgprIdx);
161 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx);
164 if (NumDwords == 1) {
166 auto vgpr =
vecReg.template as<DataType>();
167 auto reg_file_vgpr =
vrfData[0]->template as<VecElemU32>();
169 std::memcpy((
void*)&vgpr[lane],
170 (
void*)®_file_vgpr[lane],
sizeof(DataType));
172 }
else if (NumDwords == 2) {
175 auto vgpr =
vecReg.template as<VecElemU64>();
176 auto reg_file_vgpr0 =
vrfData[0]->template as<VecElemU32>();
177 auto reg_file_vgpr1 =
vrfData[1]->template as<VecElemU32>();
181 ((
VecElemU32*)&tmp_val)[0] = reg_file_vgpr0[lane];
182 ((
VecElemU32*)&tmp_val)[1] = reg_file_vgpr1[lane];
183 vgpr[lane] = tmp_val;
210 if (NumDwords == 1) {
214 auto reg_file_vgpr =
vrfData[0]->template as<VecElemU32>();
215 auto vgpr =
vecReg.template as<DataType>();
218 if (exec_mask[lane] ||
_gpuDynInst->ignoreExec()) {
219 std::memcpy((
void*)®_file_vgpr[lane],
220 (
void*)&vgpr[lane],
sizeof(DataType));
224 DPRINTF(GPUVRF,
"Write v[%d]\n", vgprIdx);
225 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx);
226 }
else if (NumDwords == 2) {
233 auto reg_file_vgpr0 =
vrfData[0]->template as<VecElemU32>();
234 auto reg_file_vgpr1 =
vrfData[1]->template as<VecElemU32>();
235 auto vgpr =
vecReg.template as<VecElemU64>();
238 if (exec_mask[lane] ||
_gpuDynInst->ignoreExec()) {
239 reg_file_vgpr0[lane] = ((
VecElemU32*)&vgpr[lane])[0];
240 reg_file_vgpr1[lane] = ((
VecElemU32*)&vgpr[lane])[1];
244 DPRINTF(GPUVRF,
"Write v[%d:%d]\n", vgprIdx0, vgprIdx1);
245 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx0);
246 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx1);
267 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && Const>
268 typename std::enable_if_t<Condition, const DataType>
277 assert(std::is_floating_point<DataType>::value);
278 ret_val = std::fabs(ret_val);
282 assert(std::is_floating_point<DataType>::value);
288 auto vgpr =
vecReg.template as<DataType>();
289 DataType ret_val = vgpr[idx];
292 assert(std::is_floating_point<DataType>::value);
293 ret_val = std::fabs(ret_val);
297 assert(std::is_floating_point<DataType>::value);
310 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
311 typename std::enable_if_t<Condition, DataType&>
317 return vecReg.template as<DataType>()[idx];
362 std::array<VecRegContainerU32*, NumDwords>
vrfData;
365 template<
typename DataType,
bool Const,
366 size_t NumDwords =
sizeof(DataType) /
sizeof(
ScalarRegU32)>
370 "Incorrect number of DWORDS for GCN3 operand.");
391 template<
bool Condition = NumDwords == 1 || NumDwords == 2>
392 typename std::enable_if_t<Condition, DataType>
395 assert(
sizeof(DataType) <=
sizeof(
srfData));
396 DataType raw_data((DataType)0);
397 std::memcpy((
void*)&raw_data, (
void*)
srfData.data(),
412 Wavefront *wf = _gpuDynInst->wavefront();
418 for (
auto i = 0;
i < NumDwords; ++
i) {
421 DPRINTF(GPUSRF,
"Read s[%d]\n", sgprIdx);
422 cu->
srf[wf->
simdId]->printReg(wf, sgprIdx);
430 Wavefront *wf = _gpuDynInst->wavefront();
437 if (NumDwords == 1) {
438 std::memcpy((
void*)&new_exec_mask_val,
440 }
else if (NumDwords == 2) {
441 std::memcpy((
void*)&new_exec_mask_val,
444 panic(
"Trying to write more than 2 DWORDS to EXEC\n");
448 DPRINTF(GPUSRF,
"Write EXEC\n");
449 DPRINTF(GPUSRF,
"EXEC = %#x\n", new_exec_mask_val);
455 assert(NumDwords == 1);
459 std::memcpy((
void*)&new_exec_mask_hi_val,
460 (
void*)
srfData.data(),
sizeof(new_exec_mask_hi_val));
462 new_exec_mask_hi_val);
465 DPRINTF(GPUSRF,
"Write EXEC\n");
466 DPRINTF(GPUSRF,
"EXEC = %#x\n", new_exec_mask_val);
468 _gpuDynInst->writeMiscReg(_opIdx,
srfData[0]);
471 for (
auto i = 0;
i < NumDwords; ++
i) {
473 auto &sgpr = cu->
srf[wf->
simdId]->readWriteable(sgprIdx);
474 if (_gpuDynInst->isLoad()) {
477 _gpuDynInst->scalar_data)[
i];
481 DPRINTF(GPUSRF,
"Write s[%d]\n", sgprIdx);
482 cu->
srf[wf->
simdId]->printReg(wf, sgprIdx);
490 template<
bool Condition = NumDwords == 1 || NumDwords == 2>
491 typename std::enable_if_t<Condition, void>
494 DataType &sgpr = *((DataType*)
srfData.data());
498 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
499 typename std::enable_if_t<Condition, ScalarOperand&>
502 std::memcpy((
void*)
srfData.data(), (
void*)&rhs,
sizeof(DataType));
516 assert(NumDwords == 1 || NumDwords == 2);
521 if (NumDwords == 1) {
523 execMask().to_ulong();
524 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask,
526 DPRINTF(GPUSRF,
"Read EXEC\n");
527 DPRINTF(GPUSRF,
"EXEC = %#x\n", exec_mask);
529 assert(NumDwords == 2);
531 execMask().to_ullong();
532 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask,
534 DPRINTF(GPUSRF,
"Read EXEC\n");
535 DPRINTF(GPUSRF,
"EXEC = %#x\n", exec_mask);
545 assert(NumDwords == 1);
547 ->execMask().to_ullong();
550 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask_hi,
551 sizeof(exec_mask_hi));
552 DPRINTF(GPUSRF,
"Read EXEC_HI\n");
553 DPRINTF(GPUSRF,
"EXEC_HI = %#x\n", exec_mask_hi);
559 assert(NumDwords == 1);
560 srfData[0] = _gpuDynInst->srcLiteral();
565 std::memcpy((
void*)
srfData.data(), (
void*)&pos_half,
573 std::memcpy((
void*)
srfData.data(), (
void*)&neg_half,
580 std::memcpy(
srfData.data(), &pos_one,
sizeof(pos_one));
586 std::memcpy(
srfData.data(), &neg_one,
sizeof(neg_one));
592 std::memcpy(
srfData.data(), &pos_two,
sizeof(pos_two));
598 std::memcpy(
srfData.data(), &neg_two,
sizeof(neg_two));
604 std::memcpy(
srfData.data(), &pos_four,
sizeof(pos_four));
610 std::memcpy((
void*)
srfData.data(), (
void*)&neg_four ,
623 std::memcpy((
void*)
srfData.data(),
624 (
void*)&pi_u64,
sizeof(pi_u64));
626 std::memcpy((
void*)
srfData.data(),
627 (
void*)&pi_u32,
sizeof(pi_u32));
633 assert(
sizeof(DataType) <=
sizeof(
srfData));
634 DataType misc_val(0);
636 misc_val = (DataType)_gpuDynInst
637 ->readConstVal<DataType>(_opIdx);
639 misc_val = (DataType)_gpuDynInst->readMiscReg(_opIdx);
641 std::memcpy((
void*)
srfData.data(), (
void*)&misc_val,
655 Wavefront *wf = _gpuDynInst->wavefront();
666 assert(NumDwords == 1);
673 assert(sgprIdx > -1);
751 #endif // __ARCH_GCN3_OPERAND_HH__