19919Ssteve.reinhardt@amd.com/*
214025Sgiacomo.gabrielli@arm.com * Copyright (c) 2016-2018 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 *
149919Ssteve.reinhardt@amd.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
159919Ssteve.reinhardt@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
169919Ssteve.reinhardt@amd.com * All rights reserved.
179919Ssteve.reinhardt@amd.com *
189919Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without
199919Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are
209919Ssteve.reinhardt@amd.com * met: redistributions of source code must retain the above copyright
219919Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer;
229919Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright
239919Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer in the
249919Ssteve.reinhardt@amd.com * documentation and/or other materials provided with the distribution;
259919Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its
269919Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from
279919Ssteve.reinhardt@amd.com * this software without specific prior written permission.
289919Ssteve.reinhardt@amd.com *
299919Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
309919Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
319919Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
329919Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
339919Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
349919Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
359919Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
369919Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
379919Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
389919Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
399919Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
409919Ssteve.reinhardt@amd.com *
419919Ssteve.reinhardt@amd.com * Authors: Kevin Lim
429919Ssteve.reinhardt@amd.com *          Gabe Black
439919Ssteve.reinhardt@amd.com *          Steve Reinhardt
449919Ssteve.reinhardt@amd.com */
459919Ssteve.reinhardt@amd.com
469919Ssteve.reinhardt@amd.com#include "cpu/o3/regfile.hh"
479919Ssteve.reinhardt@amd.com
4811793Sbrandon.potter@amd.com#include "cpu/o3/free_list.hh"
4912109SRekai.GonzalezAlberquilla@arm.com#include "arch/generic/types.hh"
5012109SRekai.GonzalezAlberquilla@arm.com#include "cpu/o3/free_list.hh"
519919Ssteve.reinhardt@amd.com
529919Ssteve.reinhardt@amd.comPhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
539920Syasuko.eckert@amd.com                         unsigned _numPhysicalFloatRegs,
5412109SRekai.GonzalezAlberquilla@arm.com                         unsigned _numPhysicalVecRegs,
5513610Sgiacomo.gabrielli@arm.com                         unsigned _numPhysicalVecPredRegs,
5612109SRekai.GonzalezAlberquilla@arm.com                         unsigned _numPhysicalCCRegs,
5712109SRekai.GonzalezAlberquilla@arm.com                         VecMode vmode)
589919Ssteve.reinhardt@amd.com    : intRegFile(_numPhysicalIntRegs),
599919Ssteve.reinhardt@amd.com      floatRegFile(_numPhysicalFloatRegs),
6012109SRekai.GonzalezAlberquilla@arm.com      vectorRegFile(_numPhysicalVecRegs),
6113610Sgiacomo.gabrielli@arm.com      vecPredRegFile(_numPhysicalVecPredRegs),
629920Syasuko.eckert@amd.com      ccRegFile(_numPhysicalCCRegs),
6312105Snathanael.premillieu@arm.com      numPhysicalIntRegs(_numPhysicalIntRegs),
6412105Snathanael.premillieu@arm.com      numPhysicalFloatRegs(_numPhysicalFloatRegs),
6512109SRekai.GonzalezAlberquilla@arm.com      numPhysicalVecRegs(_numPhysicalVecRegs),
6612109SRekai.GonzalezAlberquilla@arm.com      numPhysicalVecElemRegs(_numPhysicalVecRegs *
6712109SRekai.GonzalezAlberquilla@arm.com                             NumVecElemPerVecReg),
6813610Sgiacomo.gabrielli@arm.com      numPhysicalVecPredRegs(_numPhysicalVecPredRegs),
6912105Snathanael.premillieu@arm.com      numPhysicalCCRegs(_numPhysicalCCRegs),
709920Syasuko.eckert@amd.com      totalNumRegs(_numPhysicalIntRegs
719920Syasuko.eckert@amd.com                   + _numPhysicalFloatRegs
7212109SRekai.GonzalezAlberquilla@arm.com                   + _numPhysicalVecRegs
7312109SRekai.GonzalezAlberquilla@arm.com                   + _numPhysicalVecRegs * NumVecElemPerVecReg
7413610Sgiacomo.gabrielli@arm.com                   + _numPhysicalVecPredRegs
7512109SRekai.GonzalezAlberquilla@arm.com                   + _numPhysicalCCRegs),
7612109SRekai.GonzalezAlberquilla@arm.com      vecMode(vmode)
779919Ssteve.reinhardt@amd.com{
7812105Snathanael.premillieu@arm.com    PhysRegIndex phys_reg;
7912105Snathanael.premillieu@arm.com    PhysRegIndex flat_reg_idx = 0;
8012105Snathanael.premillieu@arm.com
819920Syasuko.eckert@amd.com    if (TheISA::NumCCRegs == 0 && _numPhysicalCCRegs != 0) {
829920Syasuko.eckert@amd.com        // Just make this a warning and go ahead and allocate them
839920Syasuko.eckert@amd.com        // anyway, to keep from having to add checks everywhere
849920Syasuko.eckert@amd.com        warn("Non-zero number of physical CC regs specified, even though\n"
859920Syasuko.eckert@amd.com             "    ISA does not use them.\n");
869920Syasuko.eckert@amd.com    }
8712105Snathanael.premillieu@arm.com    // The initial batch of registers are the integer ones
8812105Snathanael.premillieu@arm.com    for (phys_reg = 0; phys_reg < numPhysicalIntRegs; phys_reg++) {
8912105Snathanael.premillieu@arm.com        intRegIds.emplace_back(IntRegClass, phys_reg, flat_reg_idx++);
9012105Snathanael.premillieu@arm.com    }
9112105Snathanael.premillieu@arm.com
9212105Snathanael.premillieu@arm.com    // The next batch of the registers are the floating-point physical
9312105Snathanael.premillieu@arm.com    // registers; put them onto the floating-point free list.
9412105Snathanael.premillieu@arm.com    for (phys_reg = 0; phys_reg < numPhysicalFloatRegs; phys_reg++) {
9512105Snathanael.premillieu@arm.com        floatRegIds.emplace_back(FloatRegClass, phys_reg, flat_reg_idx++);
9612105Snathanael.premillieu@arm.com    }
9712105Snathanael.premillieu@arm.com
9812109SRekai.GonzalezAlberquilla@arm.com    // The next batch of the registers are the vector physical
9912109SRekai.GonzalezAlberquilla@arm.com    // registers; put them onto the vector free list.
10012109SRekai.GonzalezAlberquilla@arm.com    for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) {
10112109SRekai.GonzalezAlberquilla@arm.com        vectorRegFile[phys_reg].zero();
10212109SRekai.GonzalezAlberquilla@arm.com        vecRegIds.emplace_back(VecRegClass, phys_reg, flat_reg_idx++);
10312109SRekai.GonzalezAlberquilla@arm.com    }
10412109SRekai.GonzalezAlberquilla@arm.com    // The next batch of the registers are the vector element physical
10512109SRekai.GonzalezAlberquilla@arm.com    // registers; they refer to the same containers as the vector
10612109SRekai.GonzalezAlberquilla@arm.com    // registers, just a different (and incompatible) way to access
10712109SRekai.GonzalezAlberquilla@arm.com    // them; put them onto the vector free list.
10812109SRekai.GonzalezAlberquilla@arm.com    for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) {
10912109SRekai.GonzalezAlberquilla@arm.com        for (ElemIndex eIdx = 0; eIdx < NumVecElemPerVecReg; eIdx++) {
11012109SRekai.GonzalezAlberquilla@arm.com            vecElemIds.emplace_back(VecElemClass, phys_reg,
11112109SRekai.GonzalezAlberquilla@arm.com                    eIdx, flat_reg_idx++);
11212109SRekai.GonzalezAlberquilla@arm.com        }
11312109SRekai.GonzalezAlberquilla@arm.com    }
11412109SRekai.GonzalezAlberquilla@arm.com
11513610Sgiacomo.gabrielli@arm.com    // The next batch of the registers are the predicate physical
11613610Sgiacomo.gabrielli@arm.com    // registers; put them onto the predicate free list.
11713610Sgiacomo.gabrielli@arm.com    for (phys_reg = 0; phys_reg < numPhysicalVecPredRegs; phys_reg++) {
11813610Sgiacomo.gabrielli@arm.com        vecPredRegIds.emplace_back(VecPredRegClass, phys_reg, flat_reg_idx++);
11913610Sgiacomo.gabrielli@arm.com    }
12013610Sgiacomo.gabrielli@arm.com
12112105Snathanael.premillieu@arm.com    // The rest of the registers are the condition-code physical
12212105Snathanael.premillieu@arm.com    // registers; put them onto the condition-code free list.
12312105Snathanael.premillieu@arm.com    for (phys_reg = 0; phys_reg < numPhysicalCCRegs; phys_reg++) {
12412105Snathanael.premillieu@arm.com        ccRegIds.emplace_back(CCRegClass, phys_reg, flat_reg_idx++);
12512105Snathanael.premillieu@arm.com    }
12612105Snathanael.premillieu@arm.com
12712105Snathanael.premillieu@arm.com    // Misc regs have a fixed mapping but still need PhysRegIds.
12812105Snathanael.premillieu@arm.com    for (phys_reg = 0; phys_reg < TheISA::NumMiscRegs; phys_reg++) {
12912105Snathanael.premillieu@arm.com        miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
13012105Snathanael.premillieu@arm.com    }
1319919Ssteve.reinhardt@amd.com}
1329919Ssteve.reinhardt@amd.com
1339919Ssteve.reinhardt@amd.com
1349919Ssteve.reinhardt@amd.comvoid
1359919Ssteve.reinhardt@amd.comPhysRegFile::initFreeList(UnifiedFreeList *freeList)
1369919Ssteve.reinhardt@amd.com{
1379919Ssteve.reinhardt@amd.com    // Initialize the free lists.
13812105Snathanael.premillieu@arm.com    int reg_idx = 0;
1399919Ssteve.reinhardt@amd.com
1409919Ssteve.reinhardt@amd.com    // The initial batch of registers are the integer ones
14112105Snathanael.premillieu@arm.com    for (reg_idx = 0; reg_idx < numPhysicalIntRegs; reg_idx++) {
14212106SRekai.GonzalezAlberquilla@arm.com        assert(intRegIds[reg_idx].index() == reg_idx);
1439919Ssteve.reinhardt@amd.com    }
14412109SRekai.GonzalezAlberquilla@arm.com    freeList->addRegs(intRegIds.begin(), intRegIds.end());
1459919Ssteve.reinhardt@amd.com
1469920Syasuko.eckert@amd.com    // The next batch of the registers are the floating-point physical
1479919Ssteve.reinhardt@amd.com    // registers; put them onto the floating-point free list.
14812105Snathanael.premillieu@arm.com    for (reg_idx = 0; reg_idx < numPhysicalFloatRegs; reg_idx++) {
14912106SRekai.GonzalezAlberquilla@arm.com        assert(floatRegIds[reg_idx].index() == reg_idx);
1509919Ssteve.reinhardt@amd.com    }
15112109SRekai.GonzalezAlberquilla@arm.com    freeList->addRegs(floatRegIds.begin(), floatRegIds.end());
15212109SRekai.GonzalezAlberquilla@arm.com
15312109SRekai.GonzalezAlberquilla@arm.com    /* The next batch of the registers are the vector physical
15412109SRekai.GonzalezAlberquilla@arm.com     * registers; put them onto the vector free list. */
15512109SRekai.GonzalezAlberquilla@arm.com    for (reg_idx = 0; reg_idx < numPhysicalVecRegs; reg_idx++) {
15612109SRekai.GonzalezAlberquilla@arm.com        assert(vecRegIds[reg_idx].index() == reg_idx);
15712109SRekai.GonzalezAlberquilla@arm.com        for (ElemIndex elemIdx = 0; elemIdx < NumVecElemPerVecReg; elemIdx++) {
15812109SRekai.GonzalezAlberquilla@arm.com            assert(vecElemIds[reg_idx * NumVecElemPerVecReg +
15912109SRekai.GonzalezAlberquilla@arm.com                    elemIdx].index() == reg_idx);
16012109SRekai.GonzalezAlberquilla@arm.com            assert(vecElemIds[reg_idx * NumVecElemPerVecReg +
16112109SRekai.GonzalezAlberquilla@arm.com                    elemIdx].elemIndex() == elemIdx);
16212109SRekai.GonzalezAlberquilla@arm.com        }
16312109SRekai.GonzalezAlberquilla@arm.com    }
16412109SRekai.GonzalezAlberquilla@arm.com
16512109SRekai.GonzalezAlberquilla@arm.com    /* depending on the mode we add the vector registers as whole units or
16612109SRekai.GonzalezAlberquilla@arm.com     * as different elements. */
16712109SRekai.GonzalezAlberquilla@arm.com    if (vecMode == Enums::Full)
16812109SRekai.GonzalezAlberquilla@arm.com        freeList->addRegs(vecRegIds.begin(), vecRegIds.end());
16912109SRekai.GonzalezAlberquilla@arm.com    else
17012109SRekai.GonzalezAlberquilla@arm.com        freeList->addRegs(vecElemIds.begin(), vecElemIds.end());
1719920Syasuko.eckert@amd.com
17213610Sgiacomo.gabrielli@arm.com    // The next batch of the registers are the predicate physical
17313610Sgiacomo.gabrielli@arm.com    // registers; put them onto the predicate free list.
17413610Sgiacomo.gabrielli@arm.com    for (reg_idx = 0; reg_idx < numPhysicalVecPredRegs; reg_idx++) {
17513610Sgiacomo.gabrielli@arm.com        assert(vecPredRegIds[reg_idx].index() == reg_idx);
17613610Sgiacomo.gabrielli@arm.com    }
17713610Sgiacomo.gabrielli@arm.com    freeList->addRegs(vecPredRegIds.begin(), vecPredRegIds.end());
17813610Sgiacomo.gabrielli@arm.com
17910935Snilay@cs.wisc.edu    // The rest of the registers are the condition-code physical
1809920Syasuko.eckert@amd.com    // registers; put them onto the condition-code free list.
18112105Snathanael.premillieu@arm.com    for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) {
18212106SRekai.GonzalezAlberquilla@arm.com        assert(ccRegIds[reg_idx].index() == reg_idx);
1839920Syasuko.eckert@amd.com    }
18412109SRekai.GonzalezAlberquilla@arm.com    freeList->addRegs(ccRegIds.begin(), ccRegIds.end());
1859919Ssteve.reinhardt@amd.com}
18612109SRekai.GonzalezAlberquilla@arm.com
18712109SRekai.GonzalezAlberquilla@arm.comauto
18812109SRekai.GonzalezAlberquilla@arm.comPhysRegFile::getRegElemIds(PhysRegIdPtr reg) -> IdRange
18912109SRekai.GonzalezAlberquilla@arm.com{
19012109SRekai.GonzalezAlberquilla@arm.com    panic_if(!reg->isVectorPhysReg(),
19112109SRekai.GonzalezAlberquilla@arm.com            "Trying to get elems of a %s register", reg->className());
19212109SRekai.GonzalezAlberquilla@arm.com    auto idx = reg->index();
19312109SRekai.GonzalezAlberquilla@arm.com    return std::make_pair(
19412109SRekai.GonzalezAlberquilla@arm.com                vecElemIds.begin() + idx * NumVecElemPerVecReg,
19512109SRekai.GonzalezAlberquilla@arm.com                vecElemIds.begin() + (idx+1) * NumVecElemPerVecReg);
19612109SRekai.GonzalezAlberquilla@arm.com}
19712109SRekai.GonzalezAlberquilla@arm.com
19812109SRekai.GonzalezAlberquilla@arm.comauto
19912109SRekai.GonzalezAlberquilla@arm.comPhysRegFile::getRegIds(RegClass cls) -> IdRange
20012109SRekai.GonzalezAlberquilla@arm.com{
20112109SRekai.GonzalezAlberquilla@arm.com    switch (cls)
20212109SRekai.GonzalezAlberquilla@arm.com    {
20312109SRekai.GonzalezAlberquilla@arm.com      case IntRegClass:
20412109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(intRegIds.begin(), intRegIds.end());
20512109SRekai.GonzalezAlberquilla@arm.com      case FloatRegClass:
20612109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(floatRegIds.begin(), floatRegIds.end());
20712109SRekai.GonzalezAlberquilla@arm.com      case VecRegClass:
20812109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(vecRegIds.begin(), vecRegIds.end());
20912109SRekai.GonzalezAlberquilla@arm.com      case VecElemClass:
21012109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(vecElemIds.begin(), vecElemIds.end());
21113610Sgiacomo.gabrielli@arm.com      case VecPredRegClass:
21213610Sgiacomo.gabrielli@arm.com        return std::make_pair(vecPredRegIds.begin(), vecPredRegIds.end());
21312109SRekai.GonzalezAlberquilla@arm.com      case CCRegClass:
21412109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(ccRegIds.begin(), ccRegIds.end());
21512109SRekai.GonzalezAlberquilla@arm.com      case MiscRegClass:
21612109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(miscRegIds.begin(), miscRegIds.end());
21712109SRekai.GonzalezAlberquilla@arm.com    }
21812109SRekai.GonzalezAlberquilla@arm.com    /* There is no way to make an empty iterator */
21914025Sgiacomo.gabrielli@arm.com    return std::make_pair(PhysIds::iterator(),
22014025Sgiacomo.gabrielli@arm.com                          PhysIds::iterator());
22112109SRekai.GonzalezAlberquilla@arm.com}
22212109SRekai.GonzalezAlberquilla@arm.com
22312109SRekai.GonzalezAlberquilla@arm.comPhysRegIdPtr
22412109SRekai.GonzalezAlberquilla@arm.comPhysRegFile::getTrueId(PhysRegIdPtr reg)
22512109SRekai.GonzalezAlberquilla@arm.com{
22612109SRekai.GonzalezAlberquilla@arm.com    switch (reg->classValue()) {
22712109SRekai.GonzalezAlberquilla@arm.com    case VecRegClass:
22812109SRekai.GonzalezAlberquilla@arm.com        return &vecRegIds[reg->index()];
22912109SRekai.GonzalezAlberquilla@arm.com    case VecElemClass:
23012109SRekai.GonzalezAlberquilla@arm.com        return &vecElemIds[reg->index() * NumVecElemPerVecReg +
23112109SRekai.GonzalezAlberquilla@arm.com            reg->elemIndex()];
23212109SRekai.GonzalezAlberquilla@arm.com    default:
23312109SRekai.GonzalezAlberquilla@arm.com        panic_if(!reg->isVectorPhysElem(),
23412109SRekai.GonzalezAlberquilla@arm.com            "Trying to get the register of a %s register", reg->className());
23512109SRekai.GonzalezAlberquilla@arm.com    }
23612109SRekai.GonzalezAlberquilla@arm.com    return nullptr;
23712109SRekai.GonzalezAlberquilla@arm.com}
23812109SRekai.GonzalezAlberquilla@arm.com
239