34 #ifndef __ARCH_GCN3_OPERAND_HH__
35 #define __ARCH_GCN3_OPERAND_HH__
78 virtual void read() = 0;
79 virtual void write() = 0;
95 template<
typename DataType,
bool Const,
size_t NumDwords>
98 template<
typename DataType,
bool Const,
99 size_t NumDwords =
sizeof(DataType) /
sizeof(
VecElemU32)>
103 "Incorrect number of DWORDS for GCN3 operand.");
133 ->reservedScalarRegs);
153 for (
auto i = 0;
i < NumDwords; ++
i) {
157 DPRINTF(GPUVRF,
"Read v[%d]\n", vgprIdx);
158 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx);
161 if (NumDwords == 1) {
163 auto vgpr =
vecReg.template as<DataType>();
164 auto reg_file_vgpr =
vrfData[0]->template as<VecElemU32>();
166 std::memcpy((
void*)&vgpr[lane],
167 (
void*)®_file_vgpr[lane],
sizeof(DataType));
169 }
else if (NumDwords == 2) {
172 auto vgpr =
vecReg.template as<VecElemU64>();
173 auto reg_file_vgpr0 =
vrfData[0]->template as<VecElemU32>();
174 auto reg_file_vgpr1 =
vrfData[1]->template as<VecElemU32>();
178 ((
VecElemU32*)&tmp_val)[0] = reg_file_vgpr0[lane];
179 ((
VecElemU32*)&tmp_val)[1] = reg_file_vgpr1[lane];
180 vgpr[lane] = tmp_val;
207 if (NumDwords == 1) {
211 auto reg_file_vgpr =
vrfData[0]->template as<VecElemU32>();
212 auto vgpr =
vecReg.template as<DataType>();
215 if (exec_mask[lane] ||
_gpuDynInst->ignoreExec()) {
216 std::memcpy((
void*)®_file_vgpr[lane],
217 (
void*)&vgpr[lane],
sizeof(DataType));
221 DPRINTF(GPUVRF,
"Write v[%d]\n", vgprIdx);
222 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx);
223 }
else if (NumDwords == 2) {
230 auto reg_file_vgpr0 =
vrfData[0]->template as<VecElemU32>();
231 auto reg_file_vgpr1 =
vrfData[1]->template as<VecElemU32>();
232 auto vgpr =
vecReg.template as<VecElemU64>();
235 if (exec_mask[lane] ||
_gpuDynInst->ignoreExec()) {
236 reg_file_vgpr0[lane] = ((
VecElemU32*)&vgpr[lane])[0];
237 reg_file_vgpr1[lane] = ((
VecElemU32*)&vgpr[lane])[1];
241 DPRINTF(GPUVRF,
"Write v[%d:%d]\n", vgprIdx0, vgprIdx1);
242 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx0);
243 cu->
vrf[wf->
simdId]->printReg(wf, vgprIdx1);
264 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && Const>
265 typename std::enable_if_t<Condition, const DataType>
274 assert(std::is_floating_point<DataType>::value);
275 ret_val = std::fabs(ret_val);
279 assert(std::is_floating_point<DataType>::value);
285 auto vgpr =
vecReg.template as<DataType>();
286 DataType ret_val = vgpr[idx];
289 assert(std::is_floating_point<DataType>::value);
290 ret_val = std::fabs(ret_val);
294 assert(std::is_floating_point<DataType>::value);
307 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
308 typename std::enable_if_t<Condition, DataType&>
314 return vecReg.template as<DataType>()[idx];
329 using VecRegCont =
typename std::conditional<NumDwords == 2,
332 typename std::conditional<
sizeof(DataType)
363 std::array<VecRegContainerU32*, NumDwords>
vrfData;
366 template<
typename DataType,
bool Const,
367 size_t NumDwords =
sizeof(DataType) /
sizeof(
ScalarRegU32)>
371 "Incorrect number of DWORDS for GCN3 operand.");
392 template<
bool Condition = NumDwords == 1 || NumDwords == 2>
393 typename std::enable_if_t<Condition, DataType>
396 assert(
sizeof(DataType) <=
sizeof(
srfData));
397 DataType raw_data((DataType)0);
398 std::memcpy((
void*)&raw_data, (
void*)
srfData.data(),
413 Wavefront *wf = _gpuDynInst->wavefront();
419 for (
auto i = 0;
i < NumDwords; ++
i) {
422 DPRINTF(GPUSRF,
"Read s[%d]\n", sgprIdx);
423 cu->
srf[wf->
simdId]->printReg(wf, sgprIdx);
431 Wavefront *wf = _gpuDynInst->wavefront();
438 if (NumDwords == 1) {
439 std::memcpy((
void*)&new_exec_mask_val,
441 }
else if (NumDwords == 2) {
442 std::memcpy((
void*)&new_exec_mask_val,
445 panic(
"Trying to write more than 2 DWORDS to EXEC\n");
449 DPRINTF(GPUSRF,
"Write EXEC\n");
450 DPRINTF(GPUSRF,
"EXEC = %#x\n", new_exec_mask_val);
456 assert(NumDwords == 1);
460 std::memcpy((
void*)&new_exec_mask_hi_val,
461 (
void*)
srfData.data(),
sizeof(new_exec_mask_hi_val));
463 new_exec_mask_hi_val);
466 DPRINTF(GPUSRF,
"Write EXEC\n");
467 DPRINTF(GPUSRF,
"EXEC = %#x\n", new_exec_mask_val);
469 _gpuDynInst->writeMiscReg(_opIdx,
srfData[0]);
472 for (
auto i = 0;
i < NumDwords; ++
i) {
474 auto &sgpr = cu->
srf[wf->
simdId]->readWriteable(sgprIdx);
475 if (_gpuDynInst->isLoad()) {
478 _gpuDynInst->scalar_data)[
i];
482 DPRINTF(GPUSRF,
"Write s[%d]\n", sgprIdx);
483 cu->
srf[wf->
simdId]->printReg(wf, sgprIdx);
491 template<
bool Condition = NumDwords == 1 || NumDwords == 2>
492 typename std::enable_if_t<Condition, void>
495 DataType &sgpr = *((DataType*)
srfData.data());
499 template<
bool Condition = (NumDwords == 1 || NumDwords == 2) && !Const>
500 typename std::enable_if_t<Condition, ScalarOperand&>
503 std::memcpy((
void*)
srfData.data(), (
void*)&rhs,
sizeof(DataType));
517 assert(NumDwords == 1 || NumDwords == 2);
522 if (NumDwords == 1) {
524 execMask().to_ulong();
525 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask,
527 DPRINTF(GPUSRF,
"Read EXEC\n");
528 DPRINTF(GPUSRF,
"EXEC = %#x\n", exec_mask);
530 assert(NumDwords == 2);
532 execMask().to_ullong();
533 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask,
535 DPRINTF(GPUSRF,
"Read EXEC\n");
536 DPRINTF(GPUSRF,
"EXEC = %#x\n", exec_mask);
546 assert(NumDwords == 1);
548 ->execMask().to_ullong();
551 std::memcpy((
void*)
srfData.data(), (
void*)&exec_mask_hi,
552 sizeof(exec_mask_hi));
553 DPRINTF(GPUSRF,
"Read EXEC_HI\n");
554 DPRINTF(GPUSRF,
"EXEC_HI = %#x\n", exec_mask_hi);
560 assert(NumDwords == 1);
561 srfData[0] = _gpuDynInst->srcLiteral();
566 std::memcpy((
void*)
srfData.data(), (
void*)&pos_half,
574 std::memcpy((
void*)
srfData.data(), (
void*)&neg_half,
581 std::memcpy(
srfData.data(), &pos_one,
sizeof(pos_one));
587 std::memcpy(
srfData.data(), &neg_one,
sizeof(neg_one));
593 std::memcpy(
srfData.data(), &pos_two,
sizeof(pos_two));
599 std::memcpy(
srfData.data(), &neg_two,
sizeof(neg_two));
605 std::memcpy(
srfData.data(), &pos_four,
sizeof(pos_four));
611 std::memcpy((
void*)
srfData.data(), (
void*)&neg_four ,
624 std::memcpy((
void*)
srfData.data(),
625 (
void*)&pi_u64,
sizeof(pi_u64));
627 std::memcpy((
void*)
srfData.data(),
628 (
void*)&pi_u32,
sizeof(pi_u32));
634 assert(
sizeof(DataType) <=
sizeof(
srfData));
635 DataType misc_val(0);
637 misc_val = (DataType)_gpuDynInst
638 ->readConstVal<DataType>(_opIdx);
640 misc_val = (DataType)_gpuDynInst->readMiscReg(_opIdx);
642 std::memcpy((
void*)
srfData.data(), (
void*)&misc_val,
656 Wavefront *wf = _gpuDynInst->wavefront();
667 assert(NumDwords == 1);
674 assert(sgprIdx > -1);
750 #endif // __ARCH_GCN3_OPERAND_HH__