regfile.cc revision 12109
19919Ssteve.reinhardt@amd.com/*
212109SRekai.GonzalezAlberquilla@arm.com * Copyright (c) 2016 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,
5512109SRekai.GonzalezAlberquilla@arm.com                         unsigned _numPhysicalCCRegs,
5612109SRekai.GonzalezAlberquilla@arm.com                         VecMode vmode)
579919Ssteve.reinhardt@amd.com    : intRegFile(_numPhysicalIntRegs),
589919Ssteve.reinhardt@amd.com      floatRegFile(_numPhysicalFloatRegs),
5912109SRekai.GonzalezAlberquilla@arm.com      vectorRegFile(_numPhysicalVecRegs),
609920Syasuko.eckert@amd.com      ccRegFile(_numPhysicalCCRegs),
6112105Snathanael.premillieu@arm.com      numPhysicalIntRegs(_numPhysicalIntRegs),
6212105Snathanael.premillieu@arm.com      numPhysicalFloatRegs(_numPhysicalFloatRegs),
6312109SRekai.GonzalezAlberquilla@arm.com      numPhysicalVecRegs(_numPhysicalVecRegs),
6412109SRekai.GonzalezAlberquilla@arm.com      numPhysicalVecElemRegs(_numPhysicalVecRegs *
6512109SRekai.GonzalezAlberquilla@arm.com                             NumVecElemPerVecReg),
6612105Snathanael.premillieu@arm.com      numPhysicalCCRegs(_numPhysicalCCRegs),
679920Syasuko.eckert@amd.com      totalNumRegs(_numPhysicalIntRegs
689920Syasuko.eckert@amd.com                   + _numPhysicalFloatRegs
6912109SRekai.GonzalezAlberquilla@arm.com                   + _numPhysicalVecRegs
7012109SRekai.GonzalezAlberquilla@arm.com                   + _numPhysicalVecRegs * NumVecElemPerVecReg
7112109SRekai.GonzalezAlberquilla@arm.com                   + _numPhysicalCCRegs),
7212109SRekai.GonzalezAlberquilla@arm.com      vecMode(vmode)
739919Ssteve.reinhardt@amd.com{
7412105Snathanael.premillieu@arm.com    PhysRegIndex phys_reg;
7512105Snathanael.premillieu@arm.com    PhysRegIndex flat_reg_idx = 0;
7612105Snathanael.premillieu@arm.com
779920Syasuko.eckert@amd.com    if (TheISA::NumCCRegs == 0 && _numPhysicalCCRegs != 0) {
789920Syasuko.eckert@amd.com        // Just make this a warning and go ahead and allocate them
799920Syasuko.eckert@amd.com        // anyway, to keep from having to add checks everywhere
809920Syasuko.eckert@amd.com        warn("Non-zero number of physical CC regs specified, even though\n"
819920Syasuko.eckert@amd.com             "    ISA does not use them.\n");
829920Syasuko.eckert@amd.com    }
8312105Snathanael.premillieu@arm.com    // The initial batch of registers are the integer ones
8412105Snathanael.premillieu@arm.com    for (phys_reg = 0; phys_reg < numPhysicalIntRegs; phys_reg++) {
8512105Snathanael.premillieu@arm.com        intRegIds.emplace_back(IntRegClass, phys_reg, flat_reg_idx++);
8612105Snathanael.premillieu@arm.com    }
8712105Snathanael.premillieu@arm.com
8812105Snathanael.premillieu@arm.com    // The next batch of the registers are the floating-point physical
8912105Snathanael.premillieu@arm.com    // registers; put them onto the floating-point free list.
9012105Snathanael.premillieu@arm.com    for (phys_reg = 0; phys_reg < numPhysicalFloatRegs; phys_reg++) {
9112105Snathanael.premillieu@arm.com        floatRegIds.emplace_back(FloatRegClass, phys_reg, flat_reg_idx++);
9212105Snathanael.premillieu@arm.com    }
9312105Snathanael.premillieu@arm.com
9412109SRekai.GonzalezAlberquilla@arm.com    // The next batch of the registers are the vector physical
9512109SRekai.GonzalezAlberquilla@arm.com    // registers; put them onto the vector free list.
9612109SRekai.GonzalezAlberquilla@arm.com    for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) {
9712109SRekai.GonzalezAlberquilla@arm.com        vectorRegFile[phys_reg].zero();
9812109SRekai.GonzalezAlberquilla@arm.com        vecRegIds.emplace_back(VecRegClass, phys_reg, flat_reg_idx++);
9912109SRekai.GonzalezAlberquilla@arm.com    }
10012109SRekai.GonzalezAlberquilla@arm.com    // The next batch of the registers are the vector element physical
10112109SRekai.GonzalezAlberquilla@arm.com    // registers; they refer to the same containers as the vector
10212109SRekai.GonzalezAlberquilla@arm.com    // registers, just a different (and incompatible) way to access
10312109SRekai.GonzalezAlberquilla@arm.com    // them; put them onto the vector free list.
10412109SRekai.GonzalezAlberquilla@arm.com    for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) {
10512109SRekai.GonzalezAlberquilla@arm.com        for (ElemIndex eIdx = 0; eIdx < NumVecElemPerVecReg; eIdx++) {
10612109SRekai.GonzalezAlberquilla@arm.com            vecElemIds.emplace_back(VecElemClass, phys_reg,
10712109SRekai.GonzalezAlberquilla@arm.com                    eIdx, flat_reg_idx++);
10812109SRekai.GonzalezAlberquilla@arm.com        }
10912109SRekai.GonzalezAlberquilla@arm.com    }
11012109SRekai.GonzalezAlberquilla@arm.com
11112105Snathanael.premillieu@arm.com    // The rest of the registers are the condition-code physical
11212105Snathanael.premillieu@arm.com    // registers; put them onto the condition-code free list.
11312105Snathanael.premillieu@arm.com    for (phys_reg = 0; phys_reg < numPhysicalCCRegs; phys_reg++) {
11412105Snathanael.premillieu@arm.com        ccRegIds.emplace_back(CCRegClass, phys_reg, flat_reg_idx++);
11512105Snathanael.premillieu@arm.com    }
11612105Snathanael.premillieu@arm.com
11712105Snathanael.premillieu@arm.com    // Misc regs have a fixed mapping but still need PhysRegIds.
11812105Snathanael.premillieu@arm.com    for (phys_reg = 0; phys_reg < TheISA::NumMiscRegs; phys_reg++) {
11912105Snathanael.premillieu@arm.com        miscRegIds.emplace_back(MiscRegClass, phys_reg, 0);
12012105Snathanael.premillieu@arm.com    }
1219919Ssteve.reinhardt@amd.com}
1229919Ssteve.reinhardt@amd.com
1239919Ssteve.reinhardt@amd.com
1249919Ssteve.reinhardt@amd.comvoid
1259919Ssteve.reinhardt@amd.comPhysRegFile::initFreeList(UnifiedFreeList *freeList)
1269919Ssteve.reinhardt@amd.com{
1279919Ssteve.reinhardt@amd.com    // Initialize the free lists.
12812105Snathanael.premillieu@arm.com    int reg_idx = 0;
1299919Ssteve.reinhardt@amd.com
1309919Ssteve.reinhardt@amd.com    // The initial batch of registers are the integer ones
13112105Snathanael.premillieu@arm.com    for (reg_idx = 0; reg_idx < numPhysicalIntRegs; reg_idx++) {
13212106SRekai.GonzalezAlberquilla@arm.com        assert(intRegIds[reg_idx].index() == reg_idx);
1339919Ssteve.reinhardt@amd.com    }
13412109SRekai.GonzalezAlberquilla@arm.com    freeList->addRegs(intRegIds.begin(), intRegIds.end());
1359919Ssteve.reinhardt@amd.com
1369920Syasuko.eckert@amd.com    // The next batch of the registers are the floating-point physical
1379919Ssteve.reinhardt@amd.com    // registers; put them onto the floating-point free list.
13812105Snathanael.premillieu@arm.com    for (reg_idx = 0; reg_idx < numPhysicalFloatRegs; reg_idx++) {
13912106SRekai.GonzalezAlberquilla@arm.com        assert(floatRegIds[reg_idx].index() == reg_idx);
1409919Ssteve.reinhardt@amd.com    }
14112109SRekai.GonzalezAlberquilla@arm.com    freeList->addRegs(floatRegIds.begin(), floatRegIds.end());
14212109SRekai.GonzalezAlberquilla@arm.com
14312109SRekai.GonzalezAlberquilla@arm.com    /* The next batch of the registers are the vector physical
14412109SRekai.GonzalezAlberquilla@arm.com     * registers; put them onto the vector free list. */
14512109SRekai.GonzalezAlberquilla@arm.com    for (reg_idx = 0; reg_idx < numPhysicalVecRegs; reg_idx++) {
14612109SRekai.GonzalezAlberquilla@arm.com        assert(vecRegIds[reg_idx].index() == reg_idx);
14712109SRekai.GonzalezAlberquilla@arm.com        for (ElemIndex elemIdx = 0; elemIdx < NumVecElemPerVecReg; elemIdx++) {
14812109SRekai.GonzalezAlberquilla@arm.com            assert(vecElemIds[reg_idx * NumVecElemPerVecReg +
14912109SRekai.GonzalezAlberquilla@arm.com                    elemIdx].index() == reg_idx);
15012109SRekai.GonzalezAlberquilla@arm.com            assert(vecElemIds[reg_idx * NumVecElemPerVecReg +
15112109SRekai.GonzalezAlberquilla@arm.com                    elemIdx].elemIndex() == elemIdx);
15212109SRekai.GonzalezAlberquilla@arm.com        }
15312109SRekai.GonzalezAlberquilla@arm.com    }
15412109SRekai.GonzalezAlberquilla@arm.com
15512109SRekai.GonzalezAlberquilla@arm.com    /* depending on the mode we add the vector registers as whole units or
15612109SRekai.GonzalezAlberquilla@arm.com     * as different elements. */
15712109SRekai.GonzalezAlberquilla@arm.com    if (vecMode == Enums::Full)
15812109SRekai.GonzalezAlberquilla@arm.com        freeList->addRegs(vecRegIds.begin(), vecRegIds.end());
15912109SRekai.GonzalezAlberquilla@arm.com    else
16012109SRekai.GonzalezAlberquilla@arm.com        freeList->addRegs(vecElemIds.begin(), vecElemIds.end());
1619920Syasuko.eckert@amd.com
16210935Snilay@cs.wisc.edu    // The rest of the registers are the condition-code physical
1639920Syasuko.eckert@amd.com    // registers; put them onto the condition-code free list.
16412105Snathanael.premillieu@arm.com    for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) {
16512106SRekai.GonzalezAlberquilla@arm.com        assert(ccRegIds[reg_idx].index() == reg_idx);
1669920Syasuko.eckert@amd.com    }
16712109SRekai.GonzalezAlberquilla@arm.com    freeList->addRegs(ccRegIds.begin(), ccRegIds.end());
1689919Ssteve.reinhardt@amd.com}
16912109SRekai.GonzalezAlberquilla@arm.com
17012109SRekai.GonzalezAlberquilla@arm.comauto
17112109SRekai.GonzalezAlberquilla@arm.comPhysRegFile::getRegElemIds(PhysRegIdPtr reg) -> IdRange
17212109SRekai.GonzalezAlberquilla@arm.com{
17312109SRekai.GonzalezAlberquilla@arm.com    panic_if(!reg->isVectorPhysReg(),
17412109SRekai.GonzalezAlberquilla@arm.com            "Trying to get elems of a %s register", reg->className());
17512109SRekai.GonzalezAlberquilla@arm.com    auto idx = reg->index();
17612109SRekai.GonzalezAlberquilla@arm.com    return std::make_pair(
17712109SRekai.GonzalezAlberquilla@arm.com                vecElemIds.begin() + idx * NumVecElemPerVecReg,
17812109SRekai.GonzalezAlberquilla@arm.com                vecElemIds.begin() + (idx+1) * NumVecElemPerVecReg);
17912109SRekai.GonzalezAlberquilla@arm.com}
18012109SRekai.GonzalezAlberquilla@arm.com
18112109SRekai.GonzalezAlberquilla@arm.comauto
18212109SRekai.GonzalezAlberquilla@arm.comPhysRegFile::getRegIds(RegClass cls) -> IdRange
18312109SRekai.GonzalezAlberquilla@arm.com{
18412109SRekai.GonzalezAlberquilla@arm.com    switch (cls)
18512109SRekai.GonzalezAlberquilla@arm.com    {
18612109SRekai.GonzalezAlberquilla@arm.com      case IntRegClass:
18712109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(intRegIds.begin(), intRegIds.end());
18812109SRekai.GonzalezAlberquilla@arm.com      case FloatRegClass:
18912109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(floatRegIds.begin(), floatRegIds.end());
19012109SRekai.GonzalezAlberquilla@arm.com      case VecRegClass:
19112109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(vecRegIds.begin(), vecRegIds.end());
19212109SRekai.GonzalezAlberquilla@arm.com      case VecElemClass:
19312109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(vecElemIds.begin(), vecElemIds.end());
19412109SRekai.GonzalezAlberquilla@arm.com      case CCRegClass:
19512109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(ccRegIds.begin(), ccRegIds.end());
19612109SRekai.GonzalezAlberquilla@arm.com      case MiscRegClass:
19712109SRekai.GonzalezAlberquilla@arm.com        return std::make_pair(miscRegIds.begin(), miscRegIds.end());
19812109SRekai.GonzalezAlberquilla@arm.com    }
19912109SRekai.GonzalezAlberquilla@arm.com    /* There is no way to make an empty iterator */
20012109SRekai.GonzalezAlberquilla@arm.com    return std::make_pair(PhysIds::const_iterator(),
20112109SRekai.GonzalezAlberquilla@arm.com                          PhysIds::const_iterator());
20212109SRekai.GonzalezAlberquilla@arm.com}
20312109SRekai.GonzalezAlberquilla@arm.com
20412109SRekai.GonzalezAlberquilla@arm.comPhysRegIdPtr
20512109SRekai.GonzalezAlberquilla@arm.comPhysRegFile::getTrueId(PhysRegIdPtr reg)
20612109SRekai.GonzalezAlberquilla@arm.com{
20712109SRekai.GonzalezAlberquilla@arm.com    switch (reg->classValue()) {
20812109SRekai.GonzalezAlberquilla@arm.com    case VecRegClass:
20912109SRekai.GonzalezAlberquilla@arm.com        return &vecRegIds[reg->index()];
21012109SRekai.GonzalezAlberquilla@arm.com    case VecElemClass:
21112109SRekai.GonzalezAlberquilla@arm.com        return &vecElemIds[reg->index() * NumVecElemPerVecReg +
21212109SRekai.GonzalezAlberquilla@arm.com            reg->elemIndex()];
21312109SRekai.GonzalezAlberquilla@arm.com    default:
21412109SRekai.GonzalezAlberquilla@arm.com        panic_if(!reg->isVectorPhysElem(),
21512109SRekai.GonzalezAlberquilla@arm.com            "Trying to get the register of a %s register", reg->className());
21612109SRekai.GonzalezAlberquilla@arm.com    }
21712109SRekai.GonzalezAlberquilla@arm.com    return nullptr;
21812109SRekai.GonzalezAlberquilla@arm.com}
21912109SRekai.GonzalezAlberquilla@arm.com
220