From fff185993a4d9115a90fc6179bcab82aef45450b Mon Sep 17 00:00:00 2001 From: Xianwei Zhang Date: Thu, 24 May 2018 13:01:49 -0400 Subject: [PATCH] arch-gcn3: implement instruction s_setreg_b32 Instruction s_setreg_b32 was unimplemented, but is used by hipified rodinia 'srad'. The instruction sets values of hardware internal registers. If the instruction is writing into MODE to control single-precision FP round and denorm modes, a simple warn will be printed; for all other cases (non-MODE hw register or other precisions), panic will happen. Change-Id: Idb1cd5f60548a146bc980f1a27faff30259e74ce Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/29949 Maintainer: Anthony Gutierrez Tested-by: kokoro Reviewed-by: Xianwei Zhang --- src/arch/gcn3/insts/instructions.cc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/arch/gcn3/insts/instructions.cc b/src/arch/gcn3/insts/instructions.cc index 6ffd049f2..8b72e0da1 100644 --- a/src/arch/gcn3/insts/instructions.cc +++ b/src/arch/gcn3/insts/instructions.cc @@ -1800,6 +1800,7 @@ namespace Gcn3ISA Inst_SOPK__S_SETREG_B32::Inst_SOPK__S_SETREG_B32(InFmt_SOPK *iFmt) : Inst_SOPK(iFmt, "s_setreg_b32") { + setFlag(ALU); } // Inst_SOPK__S_SETREG_B32 Inst_SOPK__S_SETREG_B32::~Inst_SOPK__S_SETREG_B32() @@ -1813,6 +1814,32 @@ namespace Gcn3ISA void Inst_SOPK__S_SETREG_B32::execute(GPUDynInstPtr gpuDynInst) { + ScalarRegI16 simm16 = instData.SIMM16; + ScalarRegU32 hwregId = simm16 & 0x3f; + ScalarRegU32 offset = (simm16 >> 6) & 31; + ScalarRegU32 size = ((simm16 >> 11) & 31) + 1; + + ScalarOperandU32 hwreg(gpuDynInst, hwregId); + ScalarOperandU32 sdst(gpuDynInst, instData.SDST); + hwreg.read(); + sdst.read(); + + // Store value from SDST to part of the hardware register. + ScalarRegU32 mask = (((1U << size) - 1U) << offset); + hwreg = ((hwreg.rawData() & ~mask) + | ((sdst.rawData() << offset) & mask)); + hwreg.write(); + + // set MODE register to control the behavior of single precision + // floating-point numbers: denormal mode or round mode + if (hwregId==1 && size==2 + && (offset==4 || offset==0)) { + warn_once("Be cautious that s_setreg_b32 has no real effect " + "on FP modes: %s\n", gpuDynInst->disassemble()); + return; + } + + // panic if not changing MODE of floating-point numbers panicUnimplemented(); } -- 2.30.2