From ccee639904b6735d7424db2242685c6e90608ab1 Mon Sep 17 00:00:00 2001 From: Tony Gutierrez Date: Thu, 26 Jul 2018 17:28:39 -0400 Subject: [PATCH] arch-gcn3, gpu-compute: Fix issue when reading const operands Currently, when an instruction has an operand that reads a const value, it goes thru the same readMiscReg() api call as other misc registers (real HW registers, not constant values). There is an issue, however, when casting from the const values (which are 32b) to higher precision values, like 64b. This change creates a separate, templated function call to the GPU's ISA state that will return the correct type. Change-Id: I41965ebeeed20bb70e919fce5ad94d957b3af802 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/29927 Reviewed-by: Anthony Gutierrez Maintainer: Anthony Gutierrez Tested-by: kokoro --- src/arch/gcn3/gpu_isa.hh | 24 +++++++++++++++++++++--- src/arch/gcn3/isa.cc | 10 +--------- src/arch/gcn3/operand.hh | 13 +++++++++---- src/arch/gcn3/registers.cc | 25 +++++++++++++++++++++++++ src/arch/gcn3/registers.hh | 3 +++ src/gpu-compute/gpu_exec_context.hh | 8 +++++++- 6 files changed, 66 insertions(+), 17 deletions(-) diff --git a/src/arch/gcn3/gpu_isa.hh b/src/arch/gcn3/gpu_isa.hh index 26b79c7c6..228c3fe36 100644 --- a/src/arch/gcn3/gpu_isa.hh +++ b/src/arch/gcn3/gpu_isa.hh @@ -37,6 +37,7 @@ #define __ARCH_GCN3_GPU_ISA_HH__ #include +#include #include "arch/gcn3/registers.hh" #include "gpu-compute/dispatcher.hh" @@ -52,6 +53,24 @@ namespace Gcn3ISA public: GPUISA(Wavefront &wf); + template T + readConstVal(int opIdx) const + { + panic_if(!std::is_integral::value, "Constant values must " + "be an integer.\n"); + T val(0); + + if (isPosConstVal(opIdx)) { + val = (T)readPosConstReg(opIdx); + } + + if (isNegConstVal(opIdx)) { + val = (T)readNegConstReg(opIdx); + } + + return val; + } + ScalarRegU32 readMiscReg(int opIdx) const; void writeMiscReg(int opIdx, ScalarRegU32 operandVal); bool hasScalarUnit() const { return true; } @@ -63,10 +82,9 @@ namespace Gcn3ISA return posConstRegs[opIdx - REG_INT_CONST_POS_MIN]; } - ScalarRegU32 readNegConstReg(int opIdx) const + ScalarRegI32 readNegConstReg(int opIdx) const { - return *((ScalarRegU32*) - &negConstRegs[opIdx - REG_INT_CONST_NEG_MIN]); + return negConstRegs[opIdx - REG_INT_CONST_NEG_MIN]; } static const std::array diff --git a/src/arch/gcn3/isa.cc b/src/arch/gcn3/isa.cc index 036c771e1..3bd122dd0 100644 --- a/src/arch/gcn3/isa.cc +++ b/src/arch/gcn3/isa.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Advanced Micro Devices, Inc. + * Copyright (c) 2016-2018 Advanced Micro Devices, Inc. * All rights reserved. * * For use for simulation and test purposes only @@ -49,14 +49,6 @@ namespace Gcn3ISA ScalarRegU32 GPUISA::readMiscReg(int opIdx) const { - if (opIdx >= REG_INT_CONST_POS_MIN && opIdx <= REG_INT_CONST_POS_MAX) { - return readPosConstReg(opIdx); - } - - if (opIdx >= REG_INT_CONST_NEG_MIN && opIdx <= REG_INT_CONST_NEG_MAX) { - return readNegConstReg(opIdx); - } - switch (opIdx) { case REG_M0: return m0; diff --git a/src/arch/gcn3/operand.hh b/src/arch/gcn3/operand.hh index 218faf8cc..7f70fab74 100644 --- a/src/arch/gcn3/operand.hh +++ b/src/arch/gcn3/operand.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Advanced Micro Devices, Inc. + * Copyright (c) 2017-2018 Advanced Micro Devices, Inc. * All rights reserved. * * For use for simulation and test purposes only @@ -583,10 +583,15 @@ namespace Gcn3ISA default: { assert(sizeof(DataType) <= sizeof(srfData)); - DataType misc_val - = (DataType)_gpuDynInst->readMiscReg(_opIdx); + DataType misc_val(0); + if (isConstVal(_opIdx)) { + misc_val = (DataType)_gpuDynInst + ->readConstVal(_opIdx); + } else { + misc_val = (DataType)_gpuDynInst->readMiscReg(_opIdx); + } std::memcpy((void*)srfData.data(), (void*)&misc_val, - sizeof(DataType)); + sizeof(DataType)); } } } diff --git a/src/arch/gcn3/registers.cc b/src/arch/gcn3/registers.cc index 0872ff9f8..016160f54 100644 --- a/src/arch/gcn3/registers.cc +++ b/src/arch/gcn3/registers.cc @@ -162,6 +162,31 @@ namespace Gcn3ISA return regIdx; } + bool + isPosConstVal(int opIdx) + { + bool is_pos_const_val = (opIdx >= REG_INT_CONST_POS_MIN + && opIdx <= REG_INT_CONST_POS_MAX); + + return is_pos_const_val; + } + + bool + isNegConstVal(int opIdx) + { + bool is_neg_const_val = (opIdx >= REG_INT_CONST_NEG_MIN + && opIdx <= REG_INT_CONST_NEG_MAX); + + return is_neg_const_val; + } + + bool + isConstVal(int opIdx) + { + bool is_const_val = isPosConstVal(opIdx) || isNegConstVal(opIdx); + return is_const_val; + } + bool isLiteral(int opIdx) { diff --git a/src/arch/gcn3/registers.hh b/src/arch/gcn3/registers.hh index 9922e5d7a..6e95807a5 100644 --- a/src/arch/gcn3/registers.hh +++ b/src/arch/gcn3/registers.hh @@ -238,6 +238,9 @@ namespace Gcn3ISA std::string opSelectorToRegSym(int opIdx, int numRegs=0); int opSelectorToRegIdx(int opIdx, int numScalarRegs); + bool isPosConstVal(int opIdx); + bool isNegConstVal(int opIdx); + bool isConstVal(int opIdx); bool isLiteral(int opIdx); bool isScalarReg(int opIdx); bool isVectorReg(int opIdx); diff --git a/src/gpu-compute/gpu_exec_context.hh b/src/gpu-compute/gpu_exec_context.hh index 6fc71f0fd..15cbd550d 100644 --- a/src/gpu-compute/gpu_exec_context.hh +++ b/src/gpu-compute/gpu_exec_context.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Advanced Micro Devices, Inc. + * Copyright (c) 2015-2018 Advanced Micro Devices, Inc. * All rights reserved. * * For use for simulation and test purposes only @@ -48,6 +48,12 @@ class GPUExecContext Wavefront* wavefront(); ComputeUnit* computeUnit(); + template T + readConstVal(int opIdx) const + { + return gpuISA->readConstVal(opIdx); + } + RegVal readMiscReg(int opIdx) const; void writeMiscReg(int opIdx, RegVal operandVal); -- 2.30.2