11689SN/A/*
214025Sgiacomo.gabrielli@arm.com * Copyright (c) 2016-2018,2019 ARM Limited
312109SRekai.GonzalezAlberquilla@arm.com * All rights reserved
412109SRekai.GonzalezAlberquilla@arm.com *
512109SRekai.GonzalezAlberquilla@arm.com * The license below extends only to copyright in the software and shall
612109SRekai.GonzalezAlberquilla@arm.com * not be construed as granting a license to any other intellectual
712109SRekai.GonzalezAlberquilla@arm.com * property including but not limited to intellectual property relating
812109SRekai.GonzalezAlberquilla@arm.com * to a hardware implementation of the functionality of the software
912109SRekai.GonzalezAlberquilla@arm.com * licensed hereunder. You may use the software subject to the license
1012109SRekai.GonzalezAlberquilla@arm.com * terms below provided that you ensure that this notice is replicated
1112109SRekai.GonzalezAlberquilla@arm.com * unmodified and in its entirety in all distributions of the software,
1212109SRekai.GonzalezAlberquilla@arm.com * modified or unmodified, in source code or in binary form.
1312109SRekai.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
421689SN/A */
431464SN/A
4411793Sbrandon.potter@amd.com#include "cpu/o3/rename_map.hh"
4511793Sbrandon.potter@amd.com
461464SN/A#include <vector>
471060SN/A
4812857Sradwang@ucdavis.edu#include "cpu/reg_class.hh"
498232Snate@binkert.org#include "debug/Rename.hh"
501060SN/A
511464SN/Ausing namespace std;
521464SN/A
539919Ssteve.reinhardt@amd.com/**** SimpleRenameMap methods ****/
541060SN/A
559919Ssteve.reinhardt@amd.comSimpleRenameMap::SimpleRenameMap()
5612106SRekai.GonzalezAlberquilla@arm.com    : freeList(NULL), zeroReg(IntRegClass,0)
571060SN/A{
582292SN/A}
592292SN/A
601061SN/A
611060SN/Avoid
629919Ssteve.reinhardt@amd.comSimpleRenameMap::init(unsigned size, SimpleFreeList *_freeList,
639919Ssteve.reinhardt@amd.com                      RegIndex _zeroReg)
641060SN/A{
659919Ssteve.reinhardt@amd.com    assert(freeList == NULL);
669919Ssteve.reinhardt@amd.com    assert(map.empty());
679919Ssteve.reinhardt@amd.com
689919Ssteve.reinhardt@amd.com    map.resize(size);
699919Ssteve.reinhardt@amd.com    freeList = _freeList;
7012106SRekai.GonzalezAlberquilla@arm.com    zeroReg = RegId(IntRegClass, _zeroReg);
711060SN/A}
721060SN/A
731060SN/ASimpleRenameMap::RenameInfo
7412106SRekai.GonzalezAlberquilla@arm.comSimpleRenameMap::rename(const RegId& arch_reg)
751060SN/A{
7612105Snathanael.premillieu@arm.com    PhysRegIdPtr renamed_reg;
779919Ssteve.reinhardt@amd.com    // Record the current physical register that is renamed to the
789919Ssteve.reinhardt@amd.com    // requested architected register.
7913600Sgiacomo.travaglini@arm.com    PhysRegIdPtr prev_reg = map[arch_reg.flatIndex()];
801060SN/A
8114025Sgiacomo.gabrielli@arm.com    if (arch_reg == zeroReg) {
8212105Snathanael.premillieu@arm.com        assert(prev_reg->isZeroReg());
8312105Snathanael.premillieu@arm.com        renamed_reg = prev_reg;
8414025Sgiacomo.gabrielli@arm.com    } else if (prev_reg->getNumPinnedWrites() > 0) {
8514025Sgiacomo.gabrielli@arm.com        // Do not rename if the register is pinned
8614025Sgiacomo.gabrielli@arm.com        assert(arch_reg.getNumPinnedWrites() == 0);  // Prevent pinning the
8714025Sgiacomo.gabrielli@arm.com                                                     // same register twice
8814025Sgiacomo.gabrielli@arm.com        DPRINTF(Rename, "Renaming pinned reg, numPinnedWrites %d\n",
8914025Sgiacomo.gabrielli@arm.com                prev_reg->getNumPinnedWrites());
9014025Sgiacomo.gabrielli@arm.com        renamed_reg = prev_reg;
9114025Sgiacomo.gabrielli@arm.com        renamed_reg->decrNumPinnedWrites();
9214025Sgiacomo.gabrielli@arm.com    } else {
9314025Sgiacomo.gabrielli@arm.com        renamed_reg = freeList->getReg();
9414025Sgiacomo.gabrielli@arm.com        map[arch_reg.flatIndex()] = renamed_reg;
9514025Sgiacomo.gabrielli@arm.com        renamed_reg->setNumPinnedWrites(arch_reg.getNumPinnedWrites());
9614025Sgiacomo.gabrielli@arm.com        renamed_reg->setNumPinnedWritesToComplete(
9714025Sgiacomo.gabrielli@arm.com            arch_reg.getNumPinnedWrites() + 1);
981060SN/A    }
991060SN/A
10012105Snathanael.premillieu@arm.com    DPRINTF(Rename, "Renamed reg %d to physical reg %d (%d) old mapping was"
10112105Snathanael.premillieu@arm.com            " %d (%d)\n",
10213600Sgiacomo.travaglini@arm.com            arch_reg, renamed_reg->flatIndex(), renamed_reg->flatIndex(),
10313600Sgiacomo.travaglini@arm.com            prev_reg->flatIndex(), prev_reg->flatIndex());
1043867Sbinkertn@umich.edu
1051060SN/A    return RenameInfo(renamed_reg, prev_reg);
1061060SN/A}
1071060SN/A
1089919Ssteve.reinhardt@amd.com
1099919Ssteve.reinhardt@amd.com/**** UnifiedRenameMap methods ****/
1109919Ssteve.reinhardt@amd.com
1119919Ssteve.reinhardt@amd.comvoid
1129919Ssteve.reinhardt@amd.comUnifiedRenameMap::init(PhysRegFile *_regFile,
1139919Ssteve.reinhardt@amd.com                       RegIndex _intZeroReg,
1149919Ssteve.reinhardt@amd.com                       RegIndex _floatZeroReg,
11512109SRekai.GonzalezAlberquilla@arm.com                       UnifiedFreeList *freeList,
11612109SRekai.GonzalezAlberquilla@arm.com                       VecMode _mode)
1179919Ssteve.reinhardt@amd.com{
1189919Ssteve.reinhardt@amd.com    regFile = _regFile;
11912109SRekai.GonzalezAlberquilla@arm.com    vecMode = _mode;
1209919Ssteve.reinhardt@amd.com
1219919Ssteve.reinhardt@amd.com    intMap.init(TheISA::NumIntRegs, &(freeList->intList), _intZeroReg);
1229919Ssteve.reinhardt@amd.com
1239919Ssteve.reinhardt@amd.com    floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg);
1249920Syasuko.eckert@amd.com
12512109SRekai.GonzalezAlberquilla@arm.com    vecMap.init(TheISA::NumVecRegs, &(freeList->vecList), (RegIndex)-1);
12612109SRekai.GonzalezAlberquilla@arm.com
12712109SRekai.GonzalezAlberquilla@arm.com    vecElemMap.init(TheISA::NumVecRegs * NVecElems,
12812109SRekai.GonzalezAlberquilla@arm.com            &(freeList->vecElemList), (RegIndex)-1);
12912109SRekai.GonzalezAlberquilla@arm.com
13013610Sgiacomo.gabrielli@arm.com    predMap.init(TheISA::NumVecPredRegs, &(freeList->predList), (RegIndex)-1);
13113610Sgiacomo.gabrielli@arm.com
13210897Snilay@cs.wisc.edu    ccMap.init(TheISA::NumCCRegs, &(freeList->ccList), (RegIndex)-1);
13312105Snathanael.premillieu@arm.com
1349919Ssteve.reinhardt@amd.com}
1359919Ssteve.reinhardt@amd.com
13612109SRekai.GonzalezAlberquilla@arm.comvoid
13713601Sgiacomo.travaglini@arm.comUnifiedRenameMap::switchFreeList(UnifiedFreeList* freeList)
13812109SRekai.GonzalezAlberquilla@arm.com{
13913601Sgiacomo.travaglini@arm.com    if (vecMode == Enums::Elem) {
14013601Sgiacomo.travaglini@arm.com
14112109SRekai.GonzalezAlberquilla@arm.com        /* The free list should currently be tracking full registers. */
14212109SRekai.GonzalezAlberquilla@arm.com        panic_if(freeList->hasFreeVecElems(),
14312109SRekai.GonzalezAlberquilla@arm.com                "The free list is already tracking Vec elems");
14412109SRekai.GonzalezAlberquilla@arm.com        panic_if(freeList->numFreeVecRegs() !=
14512109SRekai.GonzalezAlberquilla@arm.com                regFile->numVecPhysRegs() - TheISA::NumVecRegs,
14612109SRekai.GonzalezAlberquilla@arm.com                "The free list has lost vector registers");
14713601Sgiacomo.travaglini@arm.com
14812109SRekai.GonzalezAlberquilla@arm.com        /* Split the free regs. */
14912109SRekai.GonzalezAlberquilla@arm.com        while (freeList->hasFreeVecRegs()) {
15012109SRekai.GonzalezAlberquilla@arm.com            auto vr = freeList->getVecReg();
15112109SRekai.GonzalezAlberquilla@arm.com            auto range = this->regFile->getRegElemIds(vr);
15212109SRekai.GonzalezAlberquilla@arm.com            freeList->addRegs(range.first, range.second);
15312109SRekai.GonzalezAlberquilla@arm.com        }
15413601Sgiacomo.travaglini@arm.com
15513601Sgiacomo.travaglini@arm.com    } else if (vecMode == Enums::Full) {
15613601Sgiacomo.travaglini@arm.com
15712109SRekai.GonzalezAlberquilla@arm.com        /* The free list should currently be tracking register elems. */
15812109SRekai.GonzalezAlberquilla@arm.com        panic_if(freeList->hasFreeVecRegs(),
15912109SRekai.GonzalezAlberquilla@arm.com                "The free list is already tracking full Vec");
16013598Sgiacomo.travaglini@arm.com        panic_if(freeList->numFreeVecElems() !=
16113843Sgiacomo.travaglini@arm.com                 regFile->numVecElemPhysRegs() -
16213843Sgiacomo.travaglini@arm.com                 TheISA::NumVecRegs * TheISA::NumVecElemPerVecReg,
16313843Sgiacomo.travaglini@arm.com                 "The free list has lost vector register elements");
16413601Sgiacomo.travaglini@arm.com
16513601Sgiacomo.travaglini@arm.com        auto range = regFile->getRegIds(VecRegClass);
16613601Sgiacomo.travaglini@arm.com        freeList->addRegs(range.first + TheISA::NumVecRegs, range.second);
16713601Sgiacomo.travaglini@arm.com
16813601Sgiacomo.travaglini@arm.com        /* We remove the elems from the free list. */
16913601Sgiacomo.travaglini@arm.com        while (freeList->hasFreeVecElems())
17013601Sgiacomo.travaglini@arm.com            freeList->getVecElem();
17113601Sgiacomo.travaglini@arm.com    }
17213601Sgiacomo.travaglini@arm.com}
17313601Sgiacomo.travaglini@arm.com
17413601Sgiacomo.travaglini@arm.comvoid
17513601Sgiacomo.travaglini@arm.comUnifiedRenameMap::switchMode(VecMode newVecMode)
17613601Sgiacomo.travaglini@arm.com{
17713601Sgiacomo.travaglini@arm.com    if (newVecMode == Enums::Elem && vecMode == Enums::Full) {
17813601Sgiacomo.travaglini@arm.com
17913601Sgiacomo.travaglini@arm.com        /* Switch to vector element rename mode. */
18013601Sgiacomo.travaglini@arm.com        vecMode = Enums::Elem;
18113601Sgiacomo.travaglini@arm.com
18213601Sgiacomo.travaglini@arm.com        /* Split the mapping of each arch reg. */
18313601Sgiacomo.travaglini@arm.com        int vec_idx = 0;
18413601Sgiacomo.travaglini@arm.com        for (auto &vec: vecMap) {
18513601Sgiacomo.travaglini@arm.com            PhysRegFile::IdRange range = this->regFile->getRegElemIds(vec);
18613601Sgiacomo.travaglini@arm.com            auto idx = 0;
18713601Sgiacomo.travaglini@arm.com            for (auto phys_elem = range.first;
18813601Sgiacomo.travaglini@arm.com                 phys_elem < range.second; idx++, phys_elem++) {
18913601Sgiacomo.travaglini@arm.com
19013601Sgiacomo.travaglini@arm.com                setEntry(RegId(VecElemClass, vec_idx, idx), &(*phys_elem));
19113601Sgiacomo.travaglini@arm.com            }
19213601Sgiacomo.travaglini@arm.com            vec_idx++;
19313601Sgiacomo.travaglini@arm.com        }
19413601Sgiacomo.travaglini@arm.com
19513601Sgiacomo.travaglini@arm.com    } else if (newVecMode == Enums::Full && vecMode == Enums::Elem) {
19613601Sgiacomo.travaglini@arm.com
19713601Sgiacomo.travaglini@arm.com        /* Switch to full vector register rename mode. */
19813601Sgiacomo.travaglini@arm.com        vecMode = Enums::Full;
19913601Sgiacomo.travaglini@arm.com
20012109SRekai.GonzalezAlberquilla@arm.com        /* To rebuild the arch regs we take the easy road:
20112109SRekai.GonzalezAlberquilla@arm.com         *  1.- Stitch the elems together into vectors.
20212109SRekai.GonzalezAlberquilla@arm.com         *  2.- Replace the contents of the register file with the vectors
20312109SRekai.GonzalezAlberquilla@arm.com         *  3.- Set the remaining registers as free
20412109SRekai.GonzalezAlberquilla@arm.com         */
20512109SRekai.GonzalezAlberquilla@arm.com        TheISA::VecRegContainer new_RF[TheISA::NumVecRegs];
20612109SRekai.GonzalezAlberquilla@arm.com        for (uint32_t i = 0; i < TheISA::NumVecRegs; i++) {
20712109SRekai.GonzalezAlberquilla@arm.com            VecReg dst = new_RF[i].as<TheISA::VecElem>();
20812109SRekai.GonzalezAlberquilla@arm.com            for (uint32_t l = 0; l < NVecElems; l++) {
20912109SRekai.GonzalezAlberquilla@arm.com                RegId s_rid(VecElemClass, i, l);
21012109SRekai.GonzalezAlberquilla@arm.com                PhysRegIdPtr s_prid = vecElemMap.lookup(s_rid);
21112109SRekai.GonzalezAlberquilla@arm.com                dst[l] = regFile->readVecElem(s_prid);
21212109SRekai.GonzalezAlberquilla@arm.com            }
21312109SRekai.GonzalezAlberquilla@arm.com        }
21412109SRekai.GonzalezAlberquilla@arm.com
21512109SRekai.GonzalezAlberquilla@arm.com        for (uint32_t i = 0; i < TheISA::NumVecRegs; i++) {
21612109SRekai.GonzalezAlberquilla@arm.com            PhysRegId pregId(VecRegClass, i, 0);
21712109SRekai.GonzalezAlberquilla@arm.com            regFile->setVecReg(regFile->getTrueId(&pregId), new_RF[i]);
21812109SRekai.GonzalezAlberquilla@arm.com        }
21912109SRekai.GonzalezAlberquilla@arm.com
22012109SRekai.GonzalezAlberquilla@arm.com    }
22112109SRekai.GonzalezAlberquilla@arm.com}
222