11689SN/A/*
213610Sgiacomo.gabrielli@arm.com * Copyright (c) 2015-2017 ARM Limited
310715SRekai.GonzalezAlberquilla@arm.com * All rights reserved.
410715SRekai.GonzalezAlberquilla@arm.com *
510715SRekai.GonzalezAlberquilla@arm.com * The license below extends only to copyright in the software and shall
610715SRekai.GonzalezAlberquilla@arm.com * not be construed as granting a license to any other intellectual
710715SRekai.GonzalezAlberquilla@arm.com * property including but not limited to intellectual property relating
810715SRekai.GonzalezAlberquilla@arm.com * to a hardware implementation of the functionality of the software
910715SRekai.GonzalezAlberquilla@arm.com * licensed hereunder.  You may use the software subject to the license
1010715SRekai.GonzalezAlberquilla@arm.com * terms below provided that you ensure that this notice is replicated
1110715SRekai.GonzalezAlberquilla@arm.com * unmodified and in its entirety in all distributions of the software,
1210715SRekai.GonzalezAlberquilla@arm.com * modified or unmodified, in source code or in binary form.
1310715SRekai.GonzalezAlberquilla@arm.com *
141689SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
159919Ssteve.reinhardt@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
161689SN/A * All rights reserved.
171689SN/A *
181689SN/A * Redistribution and use in source and binary forms, with or without
191689SN/A * modification, are permitted provided that the following conditions are
201689SN/A * met: redistributions of source code must retain the above copyright
211689SN/A * notice, this list of conditions and the following disclaimer;
221689SN/A * redistributions in binary form must reproduce the above copyright
231689SN/A * notice, this list of conditions and the following disclaimer in the
241689SN/A * documentation and/or other materials provided with the distribution;
251689SN/A * neither the name of the copyright holders nor the names of its
261689SN/A * contributors may be used to endorse or promote products derived from
271689SN/A * this software without specific prior written permission.
281689SN/A *
291689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
301689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
311689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
321689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
331689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
341689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
351689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
361689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
371689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
381689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
391689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402665Ssaidi@eecs.umich.edu *
412665Ssaidi@eecs.umich.edu * Authors: Kevin Lim
429919Ssteve.reinhardt@amd.com *          Steve Reinhardt
431689SN/A */
441689SN/A
452292SN/A#ifndef __CPU_O3_RENAME_MAP_HH__
462292SN/A#define __CPU_O3_RENAME_MAP_HH__
471060SN/A
481060SN/A#include <iostream>
491461SN/A#include <utility>
501060SN/A#include <vector>
511060SN/A
526658Snate@binkert.org#include "arch/types.hh"
536658Snate@binkert.org#include "config/the_isa.hh"
541717SN/A#include "cpu/o3/free_list.hh"
559919Ssteve.reinhardt@amd.com#include "cpu/o3/regfile.hh"
569919Ssteve.reinhardt@amd.com#include "cpu/reg_class.hh"
5712109SRekai.GonzalezAlberquilla@arm.com#include "enums/VecRegRenameMode.hh"
581060SN/A
599919Ssteve.reinhardt@amd.com/**
609919Ssteve.reinhardt@amd.com * Register rename map for a single class of registers (e.g., integer
619919Ssteve.reinhardt@amd.com * or floating point).  Because the register class is implicitly
629919Ssteve.reinhardt@amd.com * determined by the rename map instance being accessed, all
639919Ssteve.reinhardt@amd.com * architectural register index parameters and values in this class
649919Ssteve.reinhardt@amd.com * are relative (e.g., %fp2 is just index 2).
659919Ssteve.reinhardt@amd.com */
661060SN/Aclass SimpleRenameMap
671060SN/A{
689919Ssteve.reinhardt@amd.com  private:
6912106SRekai.GonzalezAlberquilla@arm.com    using Arch2PhysMap = std::vector<PhysRegIdPtr>;
709919Ssteve.reinhardt@amd.com    /** The acutal arch-to-phys register map */
7112106SRekai.GonzalezAlberquilla@arm.com    Arch2PhysMap map;
7212109SRekai.GonzalezAlberquilla@arm.com  public:
7312109SRekai.GonzalezAlberquilla@arm.com    using iterator = Arch2PhysMap::iterator;
7412109SRekai.GonzalezAlberquilla@arm.com    using const_iterator = Arch2PhysMap::const_iterator;
7512109SRekai.GonzalezAlberquilla@arm.com  private:
769919Ssteve.reinhardt@amd.com
779919Ssteve.reinhardt@amd.com    /**
789919Ssteve.reinhardt@amd.com     * Pointer to the free list from which new physical registers
799919Ssteve.reinhardt@amd.com     * should be allocated in rename()
809919Ssteve.reinhardt@amd.com     */
819919Ssteve.reinhardt@amd.com    SimpleFreeList *freeList;
829919Ssteve.reinhardt@amd.com
839919Ssteve.reinhardt@amd.com    /**
849919Ssteve.reinhardt@amd.com     * The architectural index of the zero register. This register is
859919Ssteve.reinhardt@amd.com     * mapped but read-only, so we ignore attempts to rename it via
869919Ssteve.reinhardt@amd.com     * the rename() method.  If there is no such register for this map
879919Ssteve.reinhardt@amd.com     * table, it should be set to an invalid index so that it never
889919Ssteve.reinhardt@amd.com     * matches.
899919Ssteve.reinhardt@amd.com     */
9012106SRekai.GonzalezAlberquilla@arm.com    RegId zeroReg;
919919Ssteve.reinhardt@amd.com
921060SN/A  public:
939919Ssteve.reinhardt@amd.com
949919Ssteve.reinhardt@amd.com    SimpleRenameMap();
959919Ssteve.reinhardt@amd.com
969919Ssteve.reinhardt@amd.com    ~SimpleRenameMap() {};
979919Ssteve.reinhardt@amd.com
981060SN/A    /**
999919Ssteve.reinhardt@amd.com     * Because we have an array of rename maps (one per thread) in the CPU,
1009919Ssteve.reinhardt@amd.com     * it's awkward to initialize this object via the constructor.
1019919Ssteve.reinhardt@amd.com     * Instead, this method is used for initialization.
1021060SN/A     */
1039919Ssteve.reinhardt@amd.com    void init(unsigned size, SimpleFreeList *_freeList, RegIndex _zeroReg);
1041060SN/A
1051060SN/A    /**
1061060SN/A     * Pair of a physical register and a physical register.  Used to
1071060SN/A     * return the physical register that a logical register has been
1081060SN/A     * renamed to, and the previous physical register that the same
1091060SN/A     * logical register was previously mapped to.
1101060SN/A     */
11112105Snathanael.premillieu@arm.com    typedef std::pair<PhysRegIdPtr, PhysRegIdPtr> RenameInfo;
1121060SN/A
1139919Ssteve.reinhardt@amd.com    /**
1149919Ssteve.reinhardt@amd.com     * Tell rename map to get a new free physical register to remap
1159919Ssteve.reinhardt@amd.com     * the specified architectural register.
1169919Ssteve.reinhardt@amd.com     * @param arch_reg The architectural register to remap.
1179919Ssteve.reinhardt@amd.com     * @return A RenameInfo pair indicating both the new and previous
1189919Ssteve.reinhardt@amd.com     * physical registers.
1199919Ssteve.reinhardt@amd.com     */
12012106SRekai.GonzalezAlberquilla@arm.com    RenameInfo rename(const RegId& arch_reg);
1219919Ssteve.reinhardt@amd.com
1229919Ssteve.reinhardt@amd.com    /**
1239919Ssteve.reinhardt@amd.com     * Look up the physical register mapped to an architectural register.
1249919Ssteve.reinhardt@amd.com     * @param arch_reg The architectural register to look up.
1259919Ssteve.reinhardt@amd.com     * @return The physical register it is currently mapped to.
1269919Ssteve.reinhardt@amd.com     */
12712106SRekai.GonzalezAlberquilla@arm.com    PhysRegIdPtr lookup(const RegId& arch_reg) const
1289919Ssteve.reinhardt@amd.com    {
12912106SRekai.GonzalezAlberquilla@arm.com        assert(arch_reg.flatIndex() <= map.size());
13012106SRekai.GonzalezAlberquilla@arm.com        return map[arch_reg.flatIndex()];
1319919Ssteve.reinhardt@amd.com    }
1329919Ssteve.reinhardt@amd.com
1339919Ssteve.reinhardt@amd.com    /**
1349919Ssteve.reinhardt@amd.com     * Update rename map with a specific mapping.  Generally used to
1359919Ssteve.reinhardt@amd.com     * roll back to old mappings on a squash.
1369919Ssteve.reinhardt@amd.com     * @param arch_reg The architectural register to remap.
1379919Ssteve.reinhardt@amd.com     * @param phys_reg The physical register to remap it to.
1389919Ssteve.reinhardt@amd.com     */
13912106SRekai.GonzalezAlberquilla@arm.com    void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg)
1409919Ssteve.reinhardt@amd.com    {
14112106SRekai.GonzalezAlberquilla@arm.com        assert(arch_reg.flatIndex() <= map.size());
14212106SRekai.GonzalezAlberquilla@arm.com        map[arch_reg.flatIndex()] = phys_reg;
1439919Ssteve.reinhardt@amd.com    }
1449919Ssteve.reinhardt@amd.com
1459919Ssteve.reinhardt@amd.com    /** Return the number of free entries on the associated free list. */
1469919Ssteve.reinhardt@amd.com    unsigned numFreeEntries() const { return freeList->numFreeRegs(); }
14712109SRekai.GonzalezAlberquilla@arm.com
14812109SRekai.GonzalezAlberquilla@arm.com    /** Forward begin/cbegin to the map. */
14912109SRekai.GonzalezAlberquilla@arm.com    /** @{ */
15012109SRekai.GonzalezAlberquilla@arm.com    iterator begin() { return map.begin(); }
15112109SRekai.GonzalezAlberquilla@arm.com    const_iterator begin() const { return map.begin(); }
15212109SRekai.GonzalezAlberquilla@arm.com    const_iterator cbegin() const { return map.cbegin(); }
15312109SRekai.GonzalezAlberquilla@arm.com    /** @} */
15412109SRekai.GonzalezAlberquilla@arm.com
15512109SRekai.GonzalezAlberquilla@arm.com    /** Forward end/cend to the map. */
15612109SRekai.GonzalezAlberquilla@arm.com    /** @{ */
15712109SRekai.GonzalezAlberquilla@arm.com    iterator end() { return map.end(); }
15812109SRekai.GonzalezAlberquilla@arm.com    const_iterator end() const { return map.end(); }
15912109SRekai.GonzalezAlberquilla@arm.com    const_iterator cend() const { return map.cend(); }
16012109SRekai.GonzalezAlberquilla@arm.com    /** @} */
1619919Ssteve.reinhardt@amd.com};
1629919Ssteve.reinhardt@amd.com
1639919Ssteve.reinhardt@amd.com/**
1649919Ssteve.reinhardt@amd.com * Unified register rename map for all classes of registers.  Wraps a
1659919Ssteve.reinhardt@amd.com * set of class-specific rename maps.  Methods that do not specify a
16612104Snathanael.premillieu@arm.com * register class (e.g., rename()) take register ids,
1679919Ssteve.reinhardt@amd.com * while methods that do specify a register class (e.g., renameInt())
16812104Snathanael.premillieu@arm.com * take register indices.
1699919Ssteve.reinhardt@amd.com */
1709919Ssteve.reinhardt@amd.comclass UnifiedRenameMap
1719919Ssteve.reinhardt@amd.com{
1729919Ssteve.reinhardt@amd.com  private:
17312109SRekai.GonzalezAlberquilla@arm.com    static constexpr uint32_t NVecElems = TheISA::NumVecElemPerVecReg;
17412109SRekai.GonzalezAlberquilla@arm.com    using VecReg = TheISA::VecReg;
17513610Sgiacomo.gabrielli@arm.com    using VecPredReg = TheISA::VecPredReg;
1769919Ssteve.reinhardt@amd.com
1779919Ssteve.reinhardt@amd.com    /** The integer register rename map */
1789919Ssteve.reinhardt@amd.com    SimpleRenameMap intMap;
1799919Ssteve.reinhardt@amd.com
1809919Ssteve.reinhardt@amd.com    /** The floating-point register rename map */
1819919Ssteve.reinhardt@amd.com    SimpleRenameMap floatMap;
1829919Ssteve.reinhardt@amd.com
18312105Snathanael.premillieu@arm.com    /** The condition-code register rename map */
18412105Snathanael.premillieu@arm.com    SimpleRenameMap ccMap;
18512105Snathanael.premillieu@arm.com
18612109SRekai.GonzalezAlberquilla@arm.com    /** The vector register rename map */
18712109SRekai.GonzalezAlberquilla@arm.com    SimpleRenameMap vecMap;
18812109SRekai.GonzalezAlberquilla@arm.com
18912109SRekai.GonzalezAlberquilla@arm.com    /** The vector element register rename map */
19012109SRekai.GonzalezAlberquilla@arm.com    SimpleRenameMap vecElemMap;
19112109SRekai.GonzalezAlberquilla@arm.com
19213610Sgiacomo.gabrielli@arm.com    /** The predicate register rename map */
19313610Sgiacomo.gabrielli@arm.com    SimpleRenameMap predMap;
19413610Sgiacomo.gabrielli@arm.com
19512109SRekai.GonzalezAlberquilla@arm.com    using VecMode = Enums::VecRegRenameMode;
19612109SRekai.GonzalezAlberquilla@arm.com    VecMode vecMode;
19712109SRekai.GonzalezAlberquilla@arm.com
1989919Ssteve.reinhardt@amd.com    /**
19912105Snathanael.premillieu@arm.com     * The register file object is used only to get PhysRegIdPtr
20012105Snathanael.premillieu@arm.com     * on MiscRegs, as they are stored in it.
2019919Ssteve.reinhardt@amd.com     */
2029919Ssteve.reinhardt@amd.com    PhysRegFile *regFile;
2039919Ssteve.reinhardt@amd.com
2041060SN/A  public:
2059919Ssteve.reinhardt@amd.com
2069919Ssteve.reinhardt@amd.com    typedef SimpleRenameMap::RenameInfo RenameInfo;
2079919Ssteve.reinhardt@amd.com
2082348SN/A    /** Default constructor.  init() must be called prior to use. */
20910537Sandreas.hansson@arm.com    UnifiedRenameMap() : regFile(nullptr) {};
2101060SN/A
2111061SN/A    /** Destructor. */
2129919Ssteve.reinhardt@amd.com    ~UnifiedRenameMap() {};
2131061SN/A
2142348SN/A    /** Initializes rename map with given parameters. */
2159919Ssteve.reinhardt@amd.com    void init(PhysRegFile *_regFile,
2162292SN/A              RegIndex _intZeroReg,
2172292SN/A              RegIndex _floatZeroReg,
21812109SRekai.GonzalezAlberquilla@arm.com              UnifiedFreeList *freeList,
21912109SRekai.GonzalezAlberquilla@arm.com              VecMode _mode);
2202292SN/A
2219919Ssteve.reinhardt@amd.com    /**
2229919Ssteve.reinhardt@amd.com     * Tell rename map to get a new free physical register to remap
22312104Snathanael.premillieu@arm.com     * the specified architectural register. This version takes a
22412106SRekai.GonzalezAlberquilla@arm.com     * RegId and reads the  appropriate class-specific rename table.
22512106SRekai.GonzalezAlberquilla@arm.com     * @param arch_reg The architectural register id to remap.
2269919Ssteve.reinhardt@amd.com     * @return A RenameInfo pair indicating both the new and previous
2279919Ssteve.reinhardt@amd.com     * physical registers.
2289919Ssteve.reinhardt@amd.com     */
22912106SRekai.GonzalezAlberquilla@arm.com    RenameInfo rename(const RegId& arch_reg)
23012106SRekai.GonzalezAlberquilla@arm.com    {
23112106SRekai.GonzalezAlberquilla@arm.com        switch (arch_reg.classValue()) {
23212106SRekai.GonzalezAlberquilla@arm.com          case IntRegClass:
23312106SRekai.GonzalezAlberquilla@arm.com            return intMap.rename(arch_reg);
23412106SRekai.GonzalezAlberquilla@arm.com          case FloatRegClass:
23512106SRekai.GonzalezAlberquilla@arm.com            return floatMap.rename(arch_reg);
23612109SRekai.GonzalezAlberquilla@arm.com          case VecRegClass:
23712109SRekai.GonzalezAlberquilla@arm.com            assert(vecMode == Enums::Full);
23812109SRekai.GonzalezAlberquilla@arm.com            return vecMap.rename(arch_reg);
23912109SRekai.GonzalezAlberquilla@arm.com          case VecElemClass:
24012109SRekai.GonzalezAlberquilla@arm.com            assert(vecMode == Enums::Elem);
24112109SRekai.GonzalezAlberquilla@arm.com            return vecElemMap.rename(arch_reg);
24213610Sgiacomo.gabrielli@arm.com          case VecPredRegClass:
24313610Sgiacomo.gabrielli@arm.com            return predMap.rename(arch_reg);
24412106SRekai.GonzalezAlberquilla@arm.com          case CCRegClass:
24512106SRekai.GonzalezAlberquilla@arm.com            return ccMap.rename(arch_reg);
24612106SRekai.GonzalezAlberquilla@arm.com          case MiscRegClass:
24712106SRekai.GonzalezAlberquilla@arm.com            {
24812106SRekai.GonzalezAlberquilla@arm.com            // misc regs aren't really renamed, just remapped
24912106SRekai.GonzalezAlberquilla@arm.com            PhysRegIdPtr phys_reg = lookup(arch_reg);
25012106SRekai.GonzalezAlberquilla@arm.com            // Set the new register to the previous one to keep the same
25112106SRekai.GonzalezAlberquilla@arm.com            // mapping throughout the execution.
25212106SRekai.GonzalezAlberquilla@arm.com            return RenameInfo(phys_reg, phys_reg);
25312106SRekai.GonzalezAlberquilla@arm.com            }
2541060SN/A
25512106SRekai.GonzalezAlberquilla@arm.com          default:
25612106SRekai.GonzalezAlberquilla@arm.com            panic("rename rename(): unknown reg class %s\n",
25712106SRekai.GonzalezAlberquilla@arm.com                  arch_reg.className());
25812106SRekai.GonzalezAlberquilla@arm.com        }
2599919Ssteve.reinhardt@amd.com    }
2601060SN/A
2611060SN/A    /**
2629919Ssteve.reinhardt@amd.com     * Look up the physical register mapped to an architectural register.
26312104Snathanael.premillieu@arm.com     * This version takes a flattened architectural register id
2649919Ssteve.reinhardt@amd.com     * and calls the appropriate class-specific rename table.
26512104Snathanael.premillieu@arm.com     * @param arch_reg The architectural register to look up.
2669919Ssteve.reinhardt@amd.com     * @return The physical register it is currently mapped to.
2679919Ssteve.reinhardt@amd.com     */
26812106SRekai.GonzalezAlberquilla@arm.com    PhysRegIdPtr lookup(const RegId& arch_reg) const
26912106SRekai.GonzalezAlberquilla@arm.com    {
27012106SRekai.GonzalezAlberquilla@arm.com        switch (arch_reg.classValue()) {
27112106SRekai.GonzalezAlberquilla@arm.com          case IntRegClass:
27212106SRekai.GonzalezAlberquilla@arm.com            return intMap.lookup(arch_reg);
2731060SN/A
27412106SRekai.GonzalezAlberquilla@arm.com          case FloatRegClass:
27512106SRekai.GonzalezAlberquilla@arm.com            return  floatMap.lookup(arch_reg);
2761060SN/A
27712109SRekai.GonzalezAlberquilla@arm.com          case VecRegClass:
27812109SRekai.GonzalezAlberquilla@arm.com            assert(vecMode == Enums::Full);
27912109SRekai.GonzalezAlberquilla@arm.com            return  vecMap.lookup(arch_reg);
28012109SRekai.GonzalezAlberquilla@arm.com
28112109SRekai.GonzalezAlberquilla@arm.com          case VecElemClass:
28212109SRekai.GonzalezAlberquilla@arm.com            assert(vecMode == Enums::Elem);
28312109SRekai.GonzalezAlberquilla@arm.com            return  vecElemMap.lookup(arch_reg);
28412109SRekai.GonzalezAlberquilla@arm.com
28513610Sgiacomo.gabrielli@arm.com          case VecPredRegClass:
28613610Sgiacomo.gabrielli@arm.com            return predMap.lookup(arch_reg);
28713610Sgiacomo.gabrielli@arm.com
28812106SRekai.GonzalezAlberquilla@arm.com          case CCRegClass:
28912106SRekai.GonzalezAlberquilla@arm.com            return ccMap.lookup(arch_reg);
2901060SN/A
29112106SRekai.GonzalezAlberquilla@arm.com          case MiscRegClass:
29212106SRekai.GonzalezAlberquilla@arm.com            // misc regs aren't really renamed, they keep the same
29312106SRekai.GonzalezAlberquilla@arm.com            // mapping throughout the execution.
29412106SRekai.GonzalezAlberquilla@arm.com            return regFile->getMiscRegId(arch_reg.flatIndex());
2959920Syasuko.eckert@amd.com
29612106SRekai.GonzalezAlberquilla@arm.com          default:
29712106SRekai.GonzalezAlberquilla@arm.com            panic("rename lookup(): unknown reg class %s\n",
29812106SRekai.GonzalezAlberquilla@arm.com                  arch_reg.className());
29912106SRekai.GonzalezAlberquilla@arm.com        }
3009919Ssteve.reinhardt@amd.com    }
3011060SN/A
3029919Ssteve.reinhardt@amd.com    /**
3039919Ssteve.reinhardt@amd.com     * Update rename map with a specific mapping.  Generally used to
3049919Ssteve.reinhardt@amd.com     * roll back to old mappings on a squash.  This version takes a
30512104Snathanael.premillieu@arm.com     * flattened architectural register id and calls the
3069919Ssteve.reinhardt@amd.com     * appropriate class-specific rename table.
30712104Snathanael.premillieu@arm.com     * @param arch_reg The architectural register to remap.
3089919Ssteve.reinhardt@amd.com     * @param phys_reg The physical register to remap it to.
3099919Ssteve.reinhardt@amd.com     */
31012106SRekai.GonzalezAlberquilla@arm.com    void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg)
31112106SRekai.GonzalezAlberquilla@arm.com    {
31212106SRekai.GonzalezAlberquilla@arm.com        switch (arch_reg.classValue()) {
31312106SRekai.GonzalezAlberquilla@arm.com          case IntRegClass:
31412106SRekai.GonzalezAlberquilla@arm.com            assert(phys_reg->isIntPhysReg());
31512106SRekai.GonzalezAlberquilla@arm.com            return intMap.setEntry(arch_reg, phys_reg);
3161060SN/A
31712106SRekai.GonzalezAlberquilla@arm.com          case FloatRegClass:
31812106SRekai.GonzalezAlberquilla@arm.com            assert(phys_reg->isFloatPhysReg());
31912106SRekai.GonzalezAlberquilla@arm.com            return floatMap.setEntry(arch_reg, phys_reg);
3201060SN/A
32112109SRekai.GonzalezAlberquilla@arm.com          case VecRegClass:
32212109SRekai.GonzalezAlberquilla@arm.com            assert(phys_reg->isVectorPhysReg());
32312109SRekai.GonzalezAlberquilla@arm.com            assert(vecMode == Enums::Full);
32412109SRekai.GonzalezAlberquilla@arm.com            return vecMap.setEntry(arch_reg, phys_reg);
32512109SRekai.GonzalezAlberquilla@arm.com
32612109SRekai.GonzalezAlberquilla@arm.com          case VecElemClass:
32712109SRekai.GonzalezAlberquilla@arm.com            assert(phys_reg->isVectorPhysElem());
32812109SRekai.GonzalezAlberquilla@arm.com            assert(vecMode == Enums::Elem);
32912109SRekai.GonzalezAlberquilla@arm.com            return vecElemMap.setEntry(arch_reg, phys_reg);
33012109SRekai.GonzalezAlberquilla@arm.com
33113610Sgiacomo.gabrielli@arm.com          case VecPredRegClass:
33213610Sgiacomo.gabrielli@arm.com            assert(phys_reg->isVecPredPhysReg());
33313610Sgiacomo.gabrielli@arm.com            return predMap.setEntry(arch_reg, phys_reg);
33413610Sgiacomo.gabrielli@arm.com
33512106SRekai.GonzalezAlberquilla@arm.com          case CCRegClass:
33612106SRekai.GonzalezAlberquilla@arm.com            assert(phys_reg->isCCPhysReg());
33712106SRekai.GonzalezAlberquilla@arm.com            return ccMap.setEntry(arch_reg, phys_reg);
3381060SN/A
33912106SRekai.GonzalezAlberquilla@arm.com          case MiscRegClass:
34012106SRekai.GonzalezAlberquilla@arm.com            // Misc registers do not actually rename, so don't change
34112106SRekai.GonzalezAlberquilla@arm.com            // their mappings.  We end up here when a commit or squash
34212106SRekai.GonzalezAlberquilla@arm.com            // tries to update or undo a hardwired misc reg nmapping,
34312106SRekai.GonzalezAlberquilla@arm.com            // which should always be setting it to what it already is.
34412106SRekai.GonzalezAlberquilla@arm.com            assert(phys_reg == lookup(arch_reg));
34512106SRekai.GonzalezAlberquilla@arm.com            return;
34612106SRekai.GonzalezAlberquilla@arm.com
34712106SRekai.GonzalezAlberquilla@arm.com          default:
34812106SRekai.GonzalezAlberquilla@arm.com            panic("rename setEntry(): unknown reg class %s\n",
34912106SRekai.GonzalezAlberquilla@arm.com                  arch_reg.className());
35012106SRekai.GonzalezAlberquilla@arm.com        }
3519920Syasuko.eckert@amd.com    }
3529920Syasuko.eckert@amd.com
3539920Syasuko.eckert@amd.com    /**
3549919Ssteve.reinhardt@amd.com     * Return the minimum number of free entries across all of the
3559919Ssteve.reinhardt@amd.com     * register classes.  The minimum is used so we guarantee that
3569919Ssteve.reinhardt@amd.com     * this number of entries is available regardless of which class
3579919Ssteve.reinhardt@amd.com     * of registers is requested.
3581060SN/A     */
3599919Ssteve.reinhardt@amd.com    unsigned numFreeEntries() const
3601060SN/A    {
36113610Sgiacomo.gabrielli@arm.com        return std::min(std::min(
36212109SRekai.GonzalezAlberquilla@arm.com                std::min(intMap.numFreeEntries(), floatMap.numFreeEntries()),
36312109SRekai.GonzalezAlberquilla@arm.com                vecMode == Enums::Full ? vecMap.numFreeEntries()
36413610Sgiacomo.gabrielli@arm.com                                    : vecElemMap.numFreeEntries()),
36513610Sgiacomo.gabrielli@arm.com                predMap.numFreeEntries());
3669919Ssteve.reinhardt@amd.com    }
36710715SRekai.GonzalezAlberquilla@arm.com
36812109SRekai.GonzalezAlberquilla@arm.com    unsigned numFreeIntEntries() const { return intMap.numFreeEntries(); }
36912109SRekai.GonzalezAlberquilla@arm.com    unsigned numFreeFloatEntries() const { return floatMap.numFreeEntries(); }
37012109SRekai.GonzalezAlberquilla@arm.com    unsigned numFreeVecEntries() const
37112109SRekai.GonzalezAlberquilla@arm.com    {
37212109SRekai.GonzalezAlberquilla@arm.com        return vecMode == Enums::Full
37312109SRekai.GonzalezAlberquilla@arm.com                ? vecMap.numFreeEntries()
37412109SRekai.GonzalezAlberquilla@arm.com                : vecElemMap.numFreeEntries();
37512109SRekai.GonzalezAlberquilla@arm.com    }
37613610Sgiacomo.gabrielli@arm.com    unsigned numFreePredEntries() const { return predMap.numFreeEntries(); }
37712109SRekai.GonzalezAlberquilla@arm.com    unsigned numFreeCCEntries() const { return ccMap.numFreeEntries(); }
37812109SRekai.GonzalezAlberquilla@arm.com
37910715SRekai.GonzalezAlberquilla@arm.com    /**
38010715SRekai.GonzalezAlberquilla@arm.com     * Return whether there are enough registers to serve the request.
38110715SRekai.GonzalezAlberquilla@arm.com     */
38212109SRekai.GonzalezAlberquilla@arm.com    bool canRename(uint32_t intRegs, uint32_t floatRegs, uint32_t vectorRegs,
38313610Sgiacomo.gabrielli@arm.com                   uint32_t vecElemRegs, uint32_t vecPredRegs,
38413610Sgiacomo.gabrielli@arm.com                   uint32_t ccRegs) const
38510715SRekai.GonzalezAlberquilla@arm.com    {
38610715SRekai.GonzalezAlberquilla@arm.com        return intRegs <= intMap.numFreeEntries() &&
38710715SRekai.GonzalezAlberquilla@arm.com            floatRegs <= floatMap.numFreeEntries() &&
38812109SRekai.GonzalezAlberquilla@arm.com            vectorRegs <= vecMap.numFreeEntries() &&
38912109SRekai.GonzalezAlberquilla@arm.com            vecElemRegs <= vecElemMap.numFreeEntries() &&
39013610Sgiacomo.gabrielli@arm.com            vecPredRegs <= predMap.numFreeEntries() &&
39110935Snilay@cs.wisc.edu            ccRegs <= ccMap.numFreeEntries();
39210715SRekai.GonzalezAlberquilla@arm.com    }
39312109SRekai.GonzalezAlberquilla@arm.com    /**
39412109SRekai.GonzalezAlberquilla@arm.com     * Set vector mode to Full or Elem.
39512109SRekai.GonzalezAlberquilla@arm.com     * Ignore 'silent' modifications.
39613601Sgiacomo.travaglini@arm.com     *
39713601Sgiacomo.travaglini@arm.com     * @param newVecMode new vector renaming mode
39812109SRekai.GonzalezAlberquilla@arm.com     */
39913601Sgiacomo.travaglini@arm.com    void switchMode(VecMode newVecMode);
40013601Sgiacomo.travaglini@arm.com
40113601Sgiacomo.travaglini@arm.com    /**
40213601Sgiacomo.travaglini@arm.com     * Switch freeList of registers from Full to Elem or vicevers
40313601Sgiacomo.travaglini@arm.com     * depending on vecMode (vector renaming mode).
40413601Sgiacomo.travaglini@arm.com     */
40513601Sgiacomo.travaglini@arm.com    void switchFreeList(UnifiedFreeList* freeList);
40610715SRekai.GonzalezAlberquilla@arm.com
4071060SN/A};
4081060SN/A
4092292SN/A#endif //__CPU_O3_RENAME_MAP_HH__
410