From 9fc5344c0a82eb4f0cac3c06bfbd110759df6677 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Nov 2020 01:57:29 -0800 Subject: [PATCH] cpu: Access src and dest reg indexes using a pointer to member. This will eventually let subclasses provide their own appropriately sized storage for these indexes. By using a pointer to member instead of a regular pointer, we ensure that even if the StaticInst is copied/moved somewhere, it will still find its indexes correctly, without any additional performance overhead or maintenance. Unfortunately C++ has decided that arrays with known bounds are not convertible/compatible with arrays with unknown bounds. I've found at least two standards proposals in various stages of acceptance which say that that's dumb and they should change that (because it's dumb and they should change that), but in the mean time we can get everything to compile by using the reinterpret_cast hammer. While this is *technically* undefined behavior, it's basically not and should be pretty safe. Change-Id: Id747b0cf68d1a0b4809ebb66a32472187110d7d8 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36876 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Giacomo Travaglini --- src/cpu/static_inst.hh | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 4f3dd04fe..22e55ca40 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -93,11 +93,16 @@ class StaticInst : public RefCounted, public StaticInstFlags MaxInstDestRegs = TheISA::MaxInstDestRegs //< Max dest regs }; + using RegIdArrayPtr = RegId (StaticInst:: *)[]; + private: - /// See destRegIdx(). - RegId _destRegIdx[MaxInstDestRegs]; /// See srcRegIdx(). RegId _srcRegIdx[MaxInstSrcRegs]; + RegIdArrayPtr _srcRegIdxPtr = nullptr; + + /// See destRegIdx(). + RegId _destRegIdx[MaxInstDestRegs]; + RegIdArrayPtr _destRegIdxPtr = nullptr; protected: @@ -236,15 +241,23 @@ class StaticInst : public RefCounted, public StaticInstFlags /// Return logical index (architectural reg num) of i'th destination reg. /// Only the entries from 0 through numDestRegs()-1 are valid. - const RegId& destRegIdx(int i) const { return _destRegIdx[i]; } + const RegId &destRegIdx(int i) const { return (this->*_destRegIdxPtr)[i]; } - void setDestRegIdx(int i, const RegId &val) { _destRegIdx[i] = val; } + void + setDestRegIdx(int i, const RegId &val) + { + (this->*_destRegIdxPtr)[i] = val; + } /// Return logical index (architectural reg num) of i'th source reg. /// Only the entries from 0 through numSrcRegs()-1 are valid. - const RegId& srcRegIdx(int i) const { return _srcRegIdx[i]; } + const RegId &srcRegIdx(int i) const { return (this->*_srcRegIdxPtr)[i]; } - void setSrcRegIdx(int i, const RegId &val) { _srcRegIdx[i] = val; } + void + setSrcRegIdx(int i, const RegId &val) + { + (this->*_srcRegIdxPtr)[i] = val; + } /// Pointer to a statically allocated "null" instruction object. static StaticInstPtr nullStaticInstPtr; @@ -283,10 +296,15 @@ class StaticInst : public RefCounted, public StaticInstFlags /// the fields that are meaningful for the particular /// instruction. StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass) - : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0), - _numFPDestRegs(0), _numIntDestRegs(0), _numCCDestRegs(0), - _numVecDestRegs(0), _numVecElemDestRegs(0), _numVecPredDestRegs(0), - machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0) + : _srcRegIdxPtr( + reinterpret_cast(&StaticInst::_srcRegIdx)), + _destRegIdxPtr( + reinterpret_cast(&StaticInst::_destRegIdx)), + _opClass(__opClass), + _numSrcRegs(0), _numDestRegs(0), _numFPDestRegs(0), + _numIntDestRegs(0), _numCCDestRegs(0), _numVecDestRegs(0), + _numVecElemDestRegs(0), _numVecPredDestRegs(0), machInst(_machInst), + mnemonic(_mnemonic), cachedDisassembly(0) { } public: -- 2.30.2