diff options
author | Rekai Gonzalez-Alberquilla <Rekai.GonzalezAlberquilla@arm.com> | 2017-04-05 13:24:00 -0500 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2017-07-05 14:43:49 +0000 |
commit | 00da08902918da13fccc3f2266b7b2f5d0080708 (patch) | |
tree | b495a0ceba7e073adca005cf84a7575d0aad5f27 /src/cpu/simple_thread.hh | |
parent | 0747a432d25ade2c197ca6393270e12606419872 (diff) | |
download | gem5-00da08902918da13fccc3f2266b7b2f5d0080708.tar.xz |
cpu: Added interface for vector reg file
This patch adds some more functionality to the cpu model and the arch to
interface with the vector register file.
This change consists mainly of augmenting ThreadContexts and ExecContexts
with calls to get/set full vectors, underlying microarchitectural elements
or lanes. Those are meant to interface with the vector register file. All
classes that implement this interface also get an appropriate implementation.
This requires implementing the vector register file for the different
models using the VecRegContainer class.
This change set also updates the Result abstraction to contemplate the
possibility of having a vector as result.
The changes also affect how the remote_gdb connection works.
There are some (nasty) side effects, such as the need to define dummy
numPhysVecRegs parameter values for architectures that do not implement
vector extensions.
Nathanael Premillieu's work with an increasing number of fixes and
improvements of mine.
Change-Id: Iee65f4e8b03abfe1e94e6940a51b68d0977fd5bb
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
[ Fix RISCV build issues and CC reg free list initialisation ]
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2705
Diffstat (limited to 'src/cpu/simple_thread.hh')
-rw-r--r-- | src/cpu/simple_thread.hh | 158 |
1 files changed, 157 insertions, 1 deletions
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 286d91766..4ea8b91ba 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2012 ARM Limited + * Copyright (c) 2011-2012, 2016 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * @@ -58,6 +58,7 @@ #include "debug/CCRegs.hh" #include "debug/FloatRegs.hh" #include "debug/IntRegs.hh" +#include "debug/VecRegs.hh" #include "mem/page_table.hh" #include "mem/request.hh" #include "sim/byteswap.hh" @@ -102,6 +103,8 @@ class SimpleThread : public ThreadState typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; typedef TheISA::CCReg CCReg; + using VecRegContainer = TheISA::VecRegContainer; + using VecElem = TheISA::VecElem; public: typedef ThreadContext::Status Status; @@ -111,6 +114,7 @@ class SimpleThread : public ThreadState FloatRegBits i[TheISA::NumFloatRegs]; } floatRegs; TheISA::IntReg intRegs[TheISA::NumIntRegs]; + VecRegContainer vecRegs[TheISA::NumVecRegs]; #ifdef ISA_HAS_CC_REGS TheISA::CCReg ccRegs[TheISA::NumCCRegs]; #endif @@ -227,6 +231,9 @@ class SimpleThread : public ThreadState _pcState = 0; memset(intRegs, 0, sizeof(intRegs)); memset(floatRegs.i, 0, sizeof(floatRegs.i)); + for (int i = 0; i < TheISA::NumVecRegs; i++) { + vecRegs[i].zero(); + } #ifdef ISA_HAS_CC_REGS memset(ccRegs, 0, sizeof(ccRegs)); #endif @@ -266,6 +273,98 @@ class SimpleThread : public ThreadState return regVal; } + const VecRegContainer& + readVecReg(const RegId& reg) const + { + int flatIndex = isa->flattenVecIndex(reg.index()); + assert(flatIndex < TheISA::NumVecRegs); + const VecRegContainer& regVal = readVecRegFlat(flatIndex); + DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n", + reg.index(), flatIndex, regVal.as<TheISA::VecElem>().print()); + return regVal; + } + + VecRegContainer& + getWritableVecReg(const RegId& reg) + { + int flatIndex = isa->flattenVecIndex(reg.index()); + assert(flatIndex < TheISA::NumVecRegs); + VecRegContainer& regVal = getWritableVecRegFlat(flatIndex); + DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n", + reg.index(), flatIndex, regVal.as<TheISA::VecElem>().print()); + return regVal; + } + + /** Vector Register Lane Interfaces. */ + /** @{ */ + /** Reads source vector <T> operand. */ + template <typename T> + VecLaneT<T, true> + readVecLane(const RegId& reg) const + { + int flatIndex = isa->flattenVecIndex(reg.index()); + assert(flatIndex < TheISA::NumVecRegs); + auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex()); + DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n", + reg.index(), flatIndex, reg.elemIndex(), regVal); + return regVal; + } + + /** Reads source vector 8bit operand. */ + virtual ConstVecLane8 + readVec8BitLaneReg(const RegId& reg) const + { return readVecLane<uint8_t>(reg); } + + /** Reads source vector 16bit operand. */ + virtual ConstVecLane16 + readVec16BitLaneReg(const RegId& reg) const + { return readVecLane<uint16_t>(reg); } + + /** Reads source vector 32bit operand. */ + virtual ConstVecLane32 + readVec32BitLaneReg(const RegId& reg) const + { return readVecLane<uint32_t>(reg); } + + /** Reads source vector 64bit operand. */ + virtual ConstVecLane64 + readVec64BitLaneReg(const RegId& reg) const + { return readVecLane<uint64_t>(reg); } + + /** Write a lane of the destination vector register. */ + template <typename LD> + void setVecLaneT(const RegId& reg, const LD& val) + { + int flatIndex = isa->flattenVecIndex(reg.index()); + assert(flatIndex < TheISA::NumVecRegs); + setVecLaneFlat(flatIndex, reg.elemIndex(), val); + DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n", + reg.index(), flatIndex, reg.elemIndex(), val); + } + virtual void setVecLane(const RegId& reg, + const LaneData<LaneSize::Byte>& val) + { return setVecLaneT(reg, val); } + virtual void setVecLane(const RegId& reg, + const LaneData<LaneSize::TwoByte>& val) + { return setVecLaneT(reg, val); } + virtual void setVecLane(const RegId& reg, + const LaneData<LaneSize::FourByte>& val) + { return setVecLaneT(reg, val); } + virtual void setVecLane(const RegId& reg, + const LaneData<LaneSize::EightByte>& val) + { return setVecLaneT(reg, val); } + /** @} */ + + const VecElem& readVecElem(const RegId& reg) const + { + int flatIndex = isa->flattenVecElemIndex(reg.index()); + assert(flatIndex < TheISA::NumVecRegs); + const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex()); + DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as" + " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal); + return regVal; + } + + CCReg readCCReg(int reg_idx) { #ifdef ISA_HAS_CC_REGS @@ -312,6 +411,24 @@ class SimpleThread : public ThreadState reg_idx, flatIndex, val, floatRegs.f[flatIndex]); } + void setVecReg(const RegId& reg, const VecRegContainer& val) + { + int flatIndex = isa->flattenVecIndex(reg.index()); + assert(flatIndex < TheISA::NumVecRegs); + setVecRegFlat(flatIndex, val); + DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n", + reg.index(), flatIndex, val.print()); + } + + void setVecElem(const RegId& reg, const VecElem& val) + { + int flatIndex = isa->flattenVecElemIndex(reg.index()); + assert(flatIndex < TheISA::NumVecRegs); + setVecElemFlat(flatIndex, reg.elemIndex(), val); + DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to" + " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val); + } + void setCCReg(int reg_idx, CCReg val) { #ifdef ISA_HAS_CC_REGS @@ -428,6 +545,45 @@ class SimpleThread : public ThreadState floatRegs.i[idx] = val; } + const VecRegContainer& readVecRegFlat(const RegIndex& reg) const + { + return vecRegs[reg]; + } + + VecRegContainer& getWritableVecRegFlat(const RegIndex& reg) + { + return vecRegs[reg]; + } + + void setVecRegFlat(const RegIndex& reg, const VecRegContainer& val) + { + vecRegs[reg] = val; + } + + template <typename T> + VecLaneT<T, true> readVecLaneFlat(const RegIndex& reg, int lId) const + { + return vecRegs[reg].laneView<T>(lId); + } + + template <typename LD> + void setVecLaneFlat(const RegIndex& reg, int lId, const LD& val) + { + vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val; + } + + const VecElem& readVecElemFlat(const RegIndex& reg, + const ElemIndex& elemIndex) const + { + return vecRegs[reg].as<TheISA::VecElem>()[elemIndex]; + } + + void setVecElemFlat(const RegIndex& reg, const ElemIndex& elemIndex, + const VecElem val) + { + vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val; + } + #ifdef ISA_HAS_CC_REGS CCReg readCCRegFlat(int idx) { return ccRegs[idx]; } void setCCRegFlat(int idx, CCReg val) { ccRegs[idx] = val; } |