From 022a48f9f6e97d04a0f2ed955a174a0791ca2549 Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Mon, 26 Dec 2022 09:11:14 -0800 Subject: [PATCH] arch-vega: Implement ds_add_u32 atomic This instruction does an atomic add of unsigned 32-bit data with a VGPR and value in LDS atomically, without return. Change-Id: I87579a94f6200a9a066f8f7390e57fb5fb6eff8e Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67072 Maintainer: Matt Sinclair Tested-by: kokoro Reviewed-by: Matt Sinclair --- src/arch/amdgpu/vega/insts/instructions.cc | 49 ++++++++++++++++++++-- src/arch/amdgpu/vega/insts/instructions.hh | 2 + 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/arch/amdgpu/vega/insts/instructions.cc b/src/arch/amdgpu/vega/insts/instructions.cc index 1f37ff14cc..afdfde3855 100644 --- a/src/arch/amdgpu/vega/insts/instructions.cc +++ b/src/arch/amdgpu/vega/insts/instructions.cc @@ -34071,6 +34071,10 @@ namespace VegaISA Inst_DS__DS_ADD_U32::Inst_DS__DS_ADD_U32(InFmt_DS *iFmt) : Inst_DS(iFmt, "ds_add_u32") { + setFlag(MemoryRef); + setFlag(GroupSegment); + setFlag(AtomicAdd); + setFlag(AtomicNoReturn); } // Inst_DS__DS_ADD_U32 Inst_DS__DS_ADD_U32::~Inst_DS__DS_ADD_U32() @@ -34079,14 +34083,53 @@ namespace VegaISA // --- description from .arch file --- // 32b: - // tmp = MEM[ADDR]; // MEM[ADDR] += DATA; - // RETURN_DATA = tmp. void Inst_DS__DS_ADD_U32::execute(GPUDynInstPtr gpuDynInst) { - panicUnimplemented(); + Wavefront *wf = gpuDynInst->wavefront(); + + if (gpuDynInst->exec_mask.none()) { + wf->decLGKMInstsIssued(); + return; + } + + gpuDynInst->execUnitId = wf->execUnitId; + gpuDynInst->latency.init(gpuDynInst->computeUnit()); + gpuDynInst->latency.set( + gpuDynInst->computeUnit()->cyclesToTicks(Cycles(24))); + ConstVecOperandU32 addr(gpuDynInst, extData.ADDR); + ConstVecOperandU32 data(gpuDynInst, extData.DATA0); + + addr.read(); + data.read(); + + calcAddr(gpuDynInst, addr); + + for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) { + if (gpuDynInst->exec_mask[lane]) { + (reinterpret_cast(gpuDynInst->a_data))[lane] + = data[lane]; + } + } + + gpuDynInst->computeUnit()->localMemoryPipe.issueRequest(gpuDynInst); } // execute + + void + Inst_DS__DS_ADD_U32::initiateAcc(GPUDynInstPtr gpuDynInst) + { + Addr offset0 = instData.OFFSET0; + Addr offset1 = instData.OFFSET1; + Addr offset = (offset1 << 8) | offset0; + + initAtomicAccess(gpuDynInst, offset); + } // initiateAcc + + void + Inst_DS__DS_ADD_U32::completeAcc(GPUDynInstPtr gpuDynInst) + { + } // completeAcc // --- Inst_DS__DS_SUB_U32 class methods --- Inst_DS__DS_SUB_U32::Inst_DS__DS_SUB_U32(InFmt_DS *iFmt) diff --git a/src/arch/amdgpu/vega/insts/instructions.hh b/src/arch/amdgpu/vega/insts/instructions.hh index 1c422481de..33be33ef31 100644 --- a/src/arch/amdgpu/vega/insts/instructions.hh +++ b/src/arch/amdgpu/vega/insts/instructions.hh @@ -31211,6 +31211,8 @@ namespace VegaISA } } // getOperandSize + void initiateAcc(GPUDynInstPtr gpuDynInst) override; + void completeAcc(GPUDynInstPtr gpuDynInst) override; void execute(GPUDynInstPtr) override; }; // Inst_DS__DS_ADD_U32