X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcpu%2Fo3%2Fregfile.hh;h=163a13a25373252d015548be08d8a3111022e1f7;hb=5edfb67041ad1c246f4ceca147f06b9db3c0ecc3;hp=b6677b4b1037e0843658241c658bd71d53eb2ef8;hpb=44974a4462e019cfc5c65d20ad620faa9bc7f8cf;p=gem5.git diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index b6677b4b1..163a13a25 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -1,5 +1,18 @@ /* + * Copyright (c) 2016-2017 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,275 +45,355 @@ #ifndef __CPU_O3_REGFILE_HH__ #define __CPU_O3_REGFILE_HH__ +#include + #include "arch/isa_traits.hh" -#include "arch/faults.hh" +#include "arch/kernel_stats.hh" #include "arch/types.hh" #include "base/trace.hh" -#include "config/full_system.hh" +#include "config/the_isa.hh" #include "cpu/o3/comm.hh" +#include "debug/IEW.hh" +#include "enums/VecRegRenameMode.hh" -#if FULL_SYSTEM -#include "kern/kernel_stats.hh" - -#endif - -#include +class UnifiedFreeList; /** * Simple physical register file class. - * Right now this is specific to Alpha until we decide if/how to make things - * generic enough to support other ISAs. */ -template class PhysRegFile { - protected: - typedef TheISA::IntReg IntReg; - typedef TheISA::FloatReg FloatReg; - typedef TheISA::FloatRegBits FloatRegBits; - typedef TheISA::MiscRegFile MiscRegFile; - typedef TheISA::MiscReg MiscReg; - - typedef union { - FloatReg d; - FloatRegBits q; - } PhysFloatReg; - - // Note that most of the definitions of the IntReg, FloatReg, etc. exist - // within the Impl/ISA class and not within this PhysRegFile class. - - // Will make these registers public for now, but they probably should - // be private eventually with some accessor functions. + private: + + typedef TheISA::CCReg CCReg; + using VecElem = TheISA::VecElem; + using VecRegContainer = TheISA::VecRegContainer; + using PhysIds = std::vector; + using VecMode = Enums::VecRegRenameMode; + using VecPredRegContainer = TheISA::VecPredRegContainer; public: - typedef typename Impl::O3CPU O3CPU; + using IdRange = std::pair; + private: + static constexpr auto NumVecElemPerVecReg = TheISA::NumVecElemPerVecReg; + + /** Integer register file. */ + std::vector intRegFile; + std::vector intRegIds; + + /** Floating point register file. */ + std::vector floatRegFile; + std::vector floatRegIds; + + /** Vector register file. */ + std::vector vectorRegFile; + std::vector vecRegIds; + std::vector vecElemIds; + + /** Predicate register file. */ + std::vector vecPredRegFile; + std::vector vecPredRegIds; + + /** Condition-code register file. */ + std::vector ccRegFile; + std::vector ccRegIds; + + /** Misc Reg Ids */ + std::vector miscRegIds; + + /** + * Number of physical general purpose registers + */ + unsigned numPhysicalIntRegs; + + /** + * Number of physical floating point registers + */ + unsigned numPhysicalFloatRegs; + /** + * Number of physical vector registers + */ + unsigned numPhysicalVecRegs; + + /** + * Number of physical vector element registers + */ + unsigned numPhysicalVecElemRegs; + + /** + * Number of physical predicate registers + */ + unsigned numPhysicalVecPredRegs; + + /** + * Number of physical CC registers + */ + unsigned numPhysicalCCRegs; + + /** Total number of physical registers. */ + unsigned totalNumRegs; + + /** Mode in which vector registers are addressed. */ + VecMode vecMode; + + public: /** * Constructs a physical register file with the specified amount of * integer and floating point registers. */ PhysRegFile(unsigned _numPhysicalIntRegs, - unsigned _numPhysicalFloatRegs); + unsigned _numPhysicalFloatRegs, + unsigned _numPhysicalVecRegs, + unsigned _numPhysicalVecPredRegs, + unsigned _numPhysicalCCRegs, + VecMode vmode + ); - //Everything below should be pretty well identical to the normal - //register file that exists within AlphaISA class. - //The duplication is unfortunate but it's better than having - //different ways to access certain registers. + /** + * Destructor to free resources + */ + ~PhysRegFile() {} - /** Reads an integer register. */ - uint64_t readIntReg(PhysRegIndex reg_idx) - { - assert(reg_idx < numPhysicalIntRegs); + /** Initialize the free list */ + void initFreeList(UnifiedFreeList *freeList); - DPRINTF(IEW, "RegFile: Access to int register %i, has data " - "%#x\n", int(reg_idx), intRegFile[reg_idx]); - return intRegFile[reg_idx]; - } + /** @return the number of integer physical registers. */ + unsigned numIntPhysRegs() const { return numPhysicalIntRegs; } - FloatReg readFloatReg(PhysRegIndex reg_idx, int width) - { - // Remove the base Float reg dependency. - reg_idx = reg_idx - numPhysicalIntRegs; + /** @return the number of floating-point physical registers. */ + unsigned numFloatPhysRegs() const { return numPhysicalFloatRegs; } + /** @return the number of vector physical registers. */ + unsigned numVecPhysRegs() const { return numPhysicalVecRegs; } + /** @return the number of predicate physical registers. */ + unsigned numPredPhysRegs() const { return numPhysicalVecPredRegs; } - assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); + /** @return the number of vector physical registers. */ + unsigned numVecElemPhysRegs() const { return numPhysicalVecElemRegs; } - FloatReg floatReg = floatRegFile[reg_idx].d; + /** @return the number of condition-code physical registers. */ + unsigned numCCPhysRegs() const { return numPhysicalCCRegs; } - DPRINTF(IEW, "RegFile: Access to %d byte float register %i, has " - "data %#x\n", int(reg_idx), floatRegFile[reg_idx].q); + /** @return the total number of physical registers. */ + unsigned totalNumPhysRegs() const { return totalNumRegs; } - return floatReg; + /** Gets a misc register PhysRegIdPtr. */ + PhysRegIdPtr getMiscRegId(RegIndex reg_idx) { + return &miscRegIds[reg_idx]; } - /** Reads a floating point register (double precision). */ - FloatReg readFloatReg(PhysRegIndex reg_idx) + /** Reads an integer register. */ + RegVal + readIntReg(PhysRegIdPtr phys_reg) const { - // Remove the base Float reg dependency. - reg_idx = reg_idx - numPhysicalIntRegs; - - assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); - - FloatReg floatReg = floatRegFile[reg_idx].d; + assert(phys_reg->isIntPhysReg()); - DPRINTF(IEW, "RegFile: Access to float register %i, has " - "data %#x\n", int(reg_idx), floatRegFile[reg_idx].q); - - return floatReg; + DPRINTF(IEW, "RegFile: Access to int register %i, has data " + "%#x\n", phys_reg->index(), intRegFile[phys_reg->index()]); + return intRegFile[phys_reg->index()]; } - /** Reads a floating point register as an integer. */ - FloatRegBits readFloatRegBits(PhysRegIndex reg_idx, int width) + RegVal + readFloatReg(PhysRegIdPtr phys_reg) const { - // Remove the base Float reg dependency. - reg_idx = reg_idx - numPhysicalIntRegs; + assert(phys_reg->isFloatPhysReg()); - assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); - - FloatRegBits floatRegBits = floatRegFile[reg_idx].q; + RegVal floatRegBits = floatRegFile[phys_reg->index()]; DPRINTF(IEW, "RegFile: Access to float register %i as int, " - "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits); + "has data %#x\n", phys_reg->index(), floatRegBits); return floatRegBits; } - FloatRegBits readFloatRegBits(PhysRegIndex reg_idx) + /** Reads a vector register. */ + const VecRegContainer & + readVecReg(PhysRegIdPtr phys_reg) const { - // Remove the base Float reg dependency. - reg_idx = reg_idx - numPhysicalIntRegs; + assert(phys_reg->isVectorPhysReg()); - assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); + DPRINTF(IEW, "RegFile: Access to vector register %i, has " + "data %s\n", int(phys_reg->index()), + vectorRegFile[phys_reg->index()].print()); - FloatRegBits floatRegBits = floatRegFile[reg_idx].q; + return vectorRegFile[phys_reg->index()]; + } - DPRINTF(IEW, "RegFile: Access to float register %i as int, " - "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits); + /** Reads a vector register for modification. */ + VecRegContainer & + getWritableVecReg(PhysRegIdPtr phys_reg) + { + /* const_cast for not duplicating code above. */ + return const_cast(readVecReg(phys_reg)); + } - return floatRegBits; + /** Reads a vector register lane. */ + template + VecLaneT + readVecLane(PhysRegIdPtr phys_reg) const + { + return readVecReg(phys_reg).laneView(); } - /** Sets an integer register to the given value. */ - void setIntReg(PhysRegIndex reg_idx, uint64_t val) + /** Reads a vector register lane. */ + template + VecLaneT + readVecLane(PhysRegIdPtr phys_reg) const { - assert(reg_idx < numPhysicalIntRegs); + return readVecReg(phys_reg).laneView(phys_reg->elemIndex()); + } - DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n", - int(reg_idx), val); + /** Get a vector register lane for modification. */ + template + void + setVecLane(PhysRegIdPtr phys_reg, const LD& val) + { + assert(phys_reg->isVectorPhysReg()); - if (reg_idx != TheISA::ZeroReg) - intRegFile[reg_idx] = val; + DPRINTF(IEW, "RegFile: Setting vector register %i[%d] to %lx\n", + int(phys_reg->index()), phys_reg->elemIndex(), val); + + vectorRegFile[phys_reg->index()].laneView( + phys_reg->elemIndex()) = val; } - /** Sets a single precision floating point register to the given value. */ - void setFloatReg(PhysRegIndex reg_idx, FloatReg val, int width) + /** Reads a vector element. */ + const VecElem & + readVecElem(PhysRegIdPtr phys_reg) const { - // Remove the base Float reg dependency. - reg_idx = reg_idx - numPhysicalIntRegs; + assert(phys_reg->isVectorPhysElem()); + auto ret = vectorRegFile[phys_reg->index()].as(); + const VecElem& val = ret[phys_reg->elemIndex()]; + DPRINTF(IEW, "RegFile: Access to element %d of vector register %i," + " has data %#x\n", phys_reg->elemIndex(), + int(phys_reg->index()), val); + + return val; + } - assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); + /** Reads a predicate register. */ + const VecPredRegContainer& readVecPredReg(PhysRegIdPtr phys_reg) const + { + assert(phys_reg->isVecPredPhysReg()); - DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", - int(reg_idx), (uint64_t)val); + DPRINTF(IEW, "RegFile: Access to predicate register %i, has " + "data %s\n", int(phys_reg->index()), + vecPredRegFile[phys_reg->index()].print()); - if (reg_idx != TheISA::ZeroReg) - floatRegFile[reg_idx].d = val; + return vecPredRegFile[phys_reg->index()]; } - /** Sets a double precision floating point register to the given value. */ - void setFloatReg(PhysRegIndex reg_idx, FloatReg val) + VecPredRegContainer& getWritableVecPredReg(PhysRegIdPtr phys_reg) { - // Remove the base Float reg dependency. - reg_idx = reg_idx - numPhysicalIntRegs; + /* const_cast for not duplicating code above. */ + return const_cast(readVecPredReg(phys_reg)); + } - assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); + /** Reads a condition-code register. */ + CCReg + readCCReg(PhysRegIdPtr phys_reg) + { + assert(phys_reg->isCCPhysReg()); - DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", - int(reg_idx), (uint64_t)val); + DPRINTF(IEW, "RegFile: Access to cc register %i, has " + "data %#x\n", phys_reg->index(), + ccRegFile[phys_reg->index()]); - if (reg_idx != TheISA::ZeroReg) - floatRegFile[reg_idx].d = val; + return ccRegFile[phys_reg->index()]; } - /** Sets a floating point register to the given integer value. */ - void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val, int width) + /** Sets an integer register to the given value. */ + void + setIntReg(PhysRegIdPtr phys_reg, RegVal val) { - // Remove the base Float reg dependency. - reg_idx = reg_idx - numPhysicalIntRegs; - - assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); + assert(phys_reg->isIntPhysReg()); - DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", - int(reg_idx), (uint64_t)val); + DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n", + phys_reg->index(), val); - floatRegFile[reg_idx].q = val; + if (!phys_reg->isZeroReg()) + intRegFile[phys_reg->index()] = val; } - void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val) + void + setFloatReg(PhysRegIdPtr phys_reg, RegVal val) { - // Remove the base Float reg dependency. - reg_idx = reg_idx - numPhysicalIntRegs; - - assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); + assert(phys_reg->isFloatPhysReg()); DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", - int(reg_idx), (uint64_t)val); + phys_reg->index(), (uint64_t)val); - floatRegFile[reg_idx].q = val; + if (!phys_reg->isZeroReg()) + floatRegFile[phys_reg->index()] = val; } - MiscReg readMiscReg(int misc_reg, unsigned thread_id) + /** Sets a vector register to the given value. */ + void + setVecReg(PhysRegIdPtr phys_reg, const VecRegContainer& val) { - return miscRegs[thread_id].readReg(misc_reg); - } + assert(phys_reg->isVectorPhysReg()); - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault, - unsigned thread_id) - { - return miscRegs[thread_id].readRegWithEffect(misc_reg, fault, - cpu->tcBase(thread_id)); + DPRINTF(IEW, "RegFile: Setting vector register %i to %s\n", + int(phys_reg->index()), val.print()); + + vectorRegFile[phys_reg->index()] = val; } - Fault setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id) + /** Sets a vector register to the given value. */ + void + setVecElem(PhysRegIdPtr phys_reg, const VecElem val) { - return miscRegs[thread_id].setReg(misc_reg, val); + assert(phys_reg->isVectorPhysElem()); + + DPRINTF(IEW, "RegFile: Setting element %d of vector register %i to" + " %#x\n", phys_reg->elemIndex(), int(phys_reg->index()), val); + + vectorRegFile[phys_reg->index()].as()[phys_reg->elemIndex()] = + val; } - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val, - unsigned thread_id) + /** Sets a predicate register to the given value. */ + void setVecPredReg(PhysRegIdPtr phys_reg, const VecPredRegContainer& val) { - return miscRegs[thread_id].setRegWithEffect(misc_reg, val, - cpu->tcBase(thread_id)); - } + assert(phys_reg->isVecPredPhysReg()); -#if FULL_SYSTEM - int readIntrFlag() { return intrflag; } - /** Sets an interrupt flag. */ - void setIntrFlag(int val) { intrflag = val; } -#endif + DPRINTF(IEW, "RegFile: Setting predicate register %i to %s\n", + int(phys_reg->index()), val.print()); - public: - /** (signed) integer register file. */ - IntReg *intRegFile; + vecPredRegFile[phys_reg->index()] = val; + } - /** Floating point register file. */ - PhysFloatReg *floatRegFile; + /** Sets a condition-code register to the given value. */ + void + setCCReg(PhysRegIdPtr phys_reg, CCReg val) + { + assert(phys_reg->isCCPhysReg()); - /** Miscellaneous register file. */ - MiscRegFile miscRegs[Impl::MaxThreads]; + DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n", + phys_reg->index(), (uint64_t)val); -#if FULL_SYSTEM - private: - int intrflag; // interrupt flag -#endif + ccRegFile[phys_reg->index()] = val; + } - private: - /** CPU pointer. */ - O3CPU *cpu; + /** Get the PhysRegIds of the elems of a vector register. + * Auxiliary function to transition from Full vector mode to Elem mode. + */ + IdRange getRegElemIds(PhysRegIdPtr reg); - public: - /** Sets the CPU pointer. */ - void setCPU(O3CPU *cpu_ptr) { cpu = cpu_ptr; } + /** + * Get the PhysRegIds of the elems of all vector registers. + * Auxiliary function to transition from Full vector mode to Elem mode + * and to initialise the rename map. + */ + IdRange getRegIds(RegClass cls); - /** Number of physical integer registers. */ - unsigned numPhysicalIntRegs; - /** Number of physical floating point registers. */ - unsigned numPhysicalFloatRegs; + /** + * Get the true physical register id. + * As many parts work with PhysRegIdPtr, we need to be able to produce + * the pointer out of just class and register idx. + */ + PhysRegIdPtr getTrueId(PhysRegIdPtr reg); }; -template -PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, - unsigned _numPhysicalFloatRegs) - : numPhysicalIntRegs(_numPhysicalIntRegs), - numPhysicalFloatRegs(_numPhysicalFloatRegs) -{ - intRegFile = new IntReg[numPhysicalIntRegs]; - floatRegFile = new PhysFloatReg[numPhysicalFloatRegs]; - - for (int i = 0; i < Impl::MaxThreads; ++i) { - miscRegs[i].clear(); - } - - memset(intRegFile, 0, sizeof(IntReg) * numPhysicalIntRegs); - memset(floatRegFile, 0, sizeof(PhysFloatReg) * numPhysicalFloatRegs); -} -#endif +#endif //__CPU_O3_REGFILE_HH__