32 #ifndef __ARCH_VEGA_OPERAND_HH__
33 #define __ARCH_VEGA_OPERAND_HH__
79 virtual void read() = 0;
80 virtual void write() = 0;
96 template<
typename DataType,
bool Const,
size_t NumDwords>
99 template<
typename DataType,
bool Const,
100 size_t NumDwords =
sizeof(DataType) /
sizeof(
VecElemU32)>
104 "Incorrect number of DWORDS for VEGA operand.");
134 ->reservedScalarRegs);
154 for (
auto i = 0;
i < NumDwords; ++
i) {
158 DPRINTF(GPUVRF,
"Read v[%d]\n", vgprIdx);
159 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx);
162 if (NumDwords == 1) {
164 auto vgpr =
vecReg.template as<DataType>();
165 auto reg_file_vgpr =
vrfData[0]->template as<VecElemU32>();
167 std::memcpy((
void*)&vgpr[lane],
168 (
void*)®_file_vgpr[lane],
sizeof(DataType));
170 }
else if (NumDwords == 2) {
173 auto vgpr =
vecReg.template as<VecElemU64>();
174 auto reg_file_vgpr0 =
vrfData[0]->template as<VecElemU32>();
175 auto reg_file_vgpr1 =
vrfData[1]->template as<VecElemU32>();
179 ((
VecElemU32*)&tmp_val)[0] = reg_file_vgpr0[lane];
180 ((
VecElemU32*)&tmp_val)[1] = reg_file_vgpr1[lane];
181 vgpr[lane] = tmp_val;
208 if (NumDwords == 1) {
212 auto reg_file_vgpr =
vrfData[0]->template as<VecElemU32>();
213 auto vgpr =
vecReg.template as<DataType>();
216 if (exec_mask[lane] ||
_gpuDynInst->ignoreExec()) {
217 std::memcpy((
void*)®_file_vgpr[lane],
218 (
void*)&vgpr[lane],
sizeof(DataType));
222 DPRINTF(GPUVRF,
"Write v[%d]\n", vgprIdx);
223 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx);
224 }
else if (NumDwords == 2) {
231 auto reg_file_vgpr0 =
vrfData[0]->template as<VecElemU32>();
232 auto reg_file_vgpr1 =
vrfData[1]->template as<VecElemU32>();
233 auto vgpr =
vecReg.template as<VecElemU64>();
236 if (exec_mask[lane] ||
_gpuDynInst->ignoreExec()) {
237 reg_file_vgpr0[lane] = ((
VecElemU32*)&vgpr[lane])[0];
238 reg_file_vgpr1[lane] = ((
VecElemU32*)&vgpr[lane])[1];
242 DPRINTF(GPUVRF,
"Write v[%d:%d]\n", vgprIdx0, vgprIdx1);
243 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx0);
244 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx1);
265 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && Const>
275 assert(std::is_floating_point_v<DataType>);
276 ret_val = std::fabs(ret_val);
280 assert(std::is_floating_point_v<DataType>);
286 auto vgpr =
vecReg.template as<DataType>();
287 DataType ret_val = vgpr[idx];
290 assert(std::is_floating_point_v<DataType>);
291 ret_val = std::fabs(ret_val);
295 assert(std::is_floating_point_v<DataType>);
308 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
315 return vecReg.template as<DataType>()[idx];
360 std::array<VecRegContainerU32*, NumDwords>
vrfData;
363 template<
typename DataType,
bool Const,
364 size_t NumDwords =
sizeof(DataType) /
sizeof(
ScalarRegU32)>
368 "Incorrect number of DWORDS for VEGA operand.");
389 template<
bool Condition = NumDwords == 1 || NumDwords == 2>
393 assert(
sizeof(DataType) <=
sizeof(
srfData));
394 DataType raw_data((DataType)0);
395 std::memcpy((
void*)&raw_data, (
void*)
srfData.data(),
410 Wavefront *wf = _gpuDynInst->wavefront();
416 for (
auto i = 0;
i < NumDwords; ++
i) {
419 DPRINTF(GPUSRF,
"Read s[%d]\n", sgprIdx);
420 cu->
srf[wf->
simdId]->printReg(wf, sgprIdx);
428 Wavefront *wf = _gpuDynInst->wavefront();
435 if (NumDwords == 1) {
436 std::memcpy((
void*)&new_exec_mask_val,
438 }
else if (NumDwords == 2) {
439 std::memcpy((
void*)&new_exec_mask_val,
442 panic(
"Trying to write more than 2 DWORDS to EXEC\n");
446 DPRINTF(GPUSRF,
"Write EXEC\n");
447 DPRINTF(GPUSRF,
"EXEC = %#x\n", new_exec_mask_val);
453 assert(NumDwords == 1);
457 std::memcpy((
void*)&new_exec_mask_hi_val,
458 (
void*)
srfData.data(),
sizeof(new_exec_mask_hi_val));
460 new_exec_mask_hi_val);
463 DPRINTF(GPUSRF,
"Write EXEC\n");
464 DPRINTF(GPUSRF,
"EXEC = %#x\n", new_exec_mask_val);
466 _gpuDynInst->writeMiscReg(_opIdx,
srfData[0]);
469 for (
auto i = 0;
i < NumDwords; ++
i) {
471 auto &sgpr = cu->
srf[wf->
simdId]->readWriteable(sgprIdx);
472 if (_gpuDynInst->isLoad()) {
475 _gpuDynInst->scalar_data)[
i];
479 DPRINTF(GPUSRF,
"Write s[%d]\n", sgprIdx);
480 cu->
srf[wf->
simdId]->printReg(wf, sgprIdx);
488 template<
bool Condition = NumDwords == 1 || NumDwords == 2>
492 DataType &sgpr = *((DataType*)
srfData.data());
496 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
500 std::memcpy((
void*)
srfData.data(), (
void*)&rhs,
sizeof(DataType));
514 assert(NumDwords == 1 || NumDwords == 2);
520 execMask().to_ullong();
521 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask,
523 DPRINTF(GPUSRF,
"Read EXEC\n");
524 DPRINTF(GPUSRF,
"EXEC = %#x\n", exec_mask);
533 assert(NumDwords == 1);
535 ->execMask().to_ullong();
538 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask_hi,
539 sizeof(exec_mask_hi));
540 DPRINTF(GPUSRF,
"Read EXEC_HI\n");
541 DPRINTF(GPUSRF,
"EXEC_HI = %#x\n", exec_mask_hi);
547 assert(NumDwords == 1);
548 srfData[0] = _gpuDynInst->srcLiteral();
553 std::memcpy((
void*)
srfData.data(), (
void*)&pos_half,
561 std::memcpy((
void*)
srfData.data(), (
void*)&neg_half,
568 std::memcpy(
srfData.data(), &pos_one,
sizeof(pos_one));
574 std::memcpy(
srfData.data(), &neg_one,
sizeof(neg_one));
580 std::memcpy(
srfData.data(), &pos_two,
sizeof(pos_two));
586 std::memcpy(
srfData.data(), &neg_two,
sizeof(neg_two));
592 std::memcpy(
srfData.data(), &pos_four,
sizeof(pos_four));
598 std::memcpy((
void*)
srfData.data(), (
void*)&neg_four ,
611 std::memcpy((
void*)
srfData.data(),
612 (
void*)&pi_u64,
sizeof(pi_u64));
614 std::memcpy((
void*)
srfData.data(),
615 (
void*)&pi_u32,
sizeof(pi_u32));
621 assert(
sizeof(DataType) <=
sizeof(
srfData));
622 DataType misc_val(0);
624 misc_val = (DataType)_gpuDynInst
625 ->readConstVal<DataType>(_opIdx);
627 misc_val = (DataType)_gpuDynInst->readMiscReg(_opIdx);
629 std::memcpy((
void*)
srfData.data(), (
void*)&misc_val,
643 Wavefront *wf = _gpuDynInst->wavefront();
657 assert(NumDwords == 1);
664 assert(sgprIdx > -1);
742 #endif // __ARCH_VEGA_OPERAND_HH__