110259SAndrew.Bardsley@arm.com/*
210259SAndrew.Bardsley@arm.com * Copyright (c) 2013-2014 ARM Limited
310259SAndrew.Bardsley@arm.com * All rights reserved
410259SAndrew.Bardsley@arm.com *
510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall
610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual
710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating
810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software
910259SAndrew.Bardsley@arm.com * licensed hereunder.  You may use the software subject to the license
1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated
1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software,
1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form.
1310259SAndrew.Bardsley@arm.com *
1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without
1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are
1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright
1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer;
1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright
1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the
2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution;
2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its
2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from
2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission.
2410259SAndrew.Bardsley@arm.com *
2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610259SAndrew.Bardsley@arm.com *
3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley
3810259SAndrew.Bardsley@arm.com */
3910259SAndrew.Bardsley@arm.com
4011793Sbrandon.potter@amd.com#include "cpu/minor/func_unit.hh"
4111793Sbrandon.potter@amd.com
4210259SAndrew.Bardsley@arm.com#include <iomanip>
4310259SAndrew.Bardsley@arm.com#include <sstream>
4410259SAndrew.Bardsley@arm.com#include <typeinfo>
4510259SAndrew.Bardsley@arm.com
4610259SAndrew.Bardsley@arm.com#include "debug/MinorTiming.hh"
4710259SAndrew.Bardsley@arm.com#include "enums/OpClass.hh"
4810259SAndrew.Bardsley@arm.com
4910259SAndrew.Bardsley@arm.comMinorOpClass *
5010259SAndrew.Bardsley@arm.comMinorOpClassParams::create()
5110259SAndrew.Bardsley@arm.com{
5210259SAndrew.Bardsley@arm.com    return new MinorOpClass(this);
5310259SAndrew.Bardsley@arm.com}
5410259SAndrew.Bardsley@arm.com
5510259SAndrew.Bardsley@arm.comMinorOpClassSet *
5610259SAndrew.Bardsley@arm.comMinorOpClassSetParams::create()
5710259SAndrew.Bardsley@arm.com{
5810259SAndrew.Bardsley@arm.com    return new MinorOpClassSet(this);
5910259SAndrew.Bardsley@arm.com}
6010259SAndrew.Bardsley@arm.com
6110259SAndrew.Bardsley@arm.comMinorFUTiming *
6210259SAndrew.Bardsley@arm.comMinorFUTimingParams::create()
6310259SAndrew.Bardsley@arm.com{
6410259SAndrew.Bardsley@arm.com    return new MinorFUTiming(this);
6510259SAndrew.Bardsley@arm.com}
6610259SAndrew.Bardsley@arm.com
6710259SAndrew.Bardsley@arm.comMinorFU *
6810259SAndrew.Bardsley@arm.comMinorFUParams::create()
6910259SAndrew.Bardsley@arm.com{
7010259SAndrew.Bardsley@arm.com    return new MinorFU(this);
7110259SAndrew.Bardsley@arm.com}
7210259SAndrew.Bardsley@arm.com
7310259SAndrew.Bardsley@arm.comMinorFUPool *
7410259SAndrew.Bardsley@arm.comMinorFUPoolParams::create()
7510259SAndrew.Bardsley@arm.com{
7610259SAndrew.Bardsley@arm.com    return new MinorFUPool(this);
7710259SAndrew.Bardsley@arm.com}
7810259SAndrew.Bardsley@arm.com
7910259SAndrew.Bardsley@arm.comMinorOpClassSet::MinorOpClassSet(const MinorOpClassSetParams *params) :
8010259SAndrew.Bardsley@arm.com    SimObject(params),
8110259SAndrew.Bardsley@arm.com    opClasses(params->opClasses),
8210259SAndrew.Bardsley@arm.com    /* Initialise to true for an empty list so that 'fully capable' is
8310259SAndrew.Bardsley@arm.com     *  the default */
8410259SAndrew.Bardsley@arm.com    capabilityList(Num_OpClasses, (opClasses.empty() ? true : false))
8510259SAndrew.Bardsley@arm.com{
8610259SAndrew.Bardsley@arm.com    for (unsigned int i = 0; i < opClasses.size(); i++)
8710259SAndrew.Bardsley@arm.com        capabilityList[opClasses[i]->opClass] = true;
8810259SAndrew.Bardsley@arm.com}
8910259SAndrew.Bardsley@arm.com
9010259SAndrew.Bardsley@arm.comMinorFUTiming::MinorFUTiming(
9110259SAndrew.Bardsley@arm.com    const MinorFUTimingParams *params) :
9210259SAndrew.Bardsley@arm.com    SimObject(params),
9310259SAndrew.Bardsley@arm.com    mask(params->mask),
9410259SAndrew.Bardsley@arm.com    match(params->match),
9510259SAndrew.Bardsley@arm.com    description(params->description),
9610259SAndrew.Bardsley@arm.com    suppress(params->suppress),
9710259SAndrew.Bardsley@arm.com    extraCommitLat(params->extraCommitLat),
9810259SAndrew.Bardsley@arm.com    extraCommitLatExpr(params->extraCommitLatExpr),
9910259SAndrew.Bardsley@arm.com    extraAssumedLat(params->extraAssumedLat),
10010259SAndrew.Bardsley@arm.com    srcRegsRelativeLats(params->srcRegsRelativeLats),
10110259SAndrew.Bardsley@arm.com    opClasses(params->opClasses)
10210259SAndrew.Bardsley@arm.com{ }
10310259SAndrew.Bardsley@arm.com
10410259SAndrew.Bardsley@arm.comnamespace Minor
10510259SAndrew.Bardsley@arm.com{
10610259SAndrew.Bardsley@arm.com
10710259SAndrew.Bardsley@arm.comvoid
10810259SAndrew.Bardsley@arm.comQueuedInst::reportData(std::ostream &os) const
10910259SAndrew.Bardsley@arm.com{
11010259SAndrew.Bardsley@arm.com    inst->reportData(os);
11110259SAndrew.Bardsley@arm.com}
11210259SAndrew.Bardsley@arm.com
11310259SAndrew.Bardsley@arm.comFUPipeline::FUPipeline(const std::string &name, const MinorFU &description_,
11410259SAndrew.Bardsley@arm.com    ClockedObject &timeSource_) :
11510259SAndrew.Bardsley@arm.com    FUPipelineBase(name, "insts", description_.opLat),
11610259SAndrew.Bardsley@arm.com    description(description_),
11710259SAndrew.Bardsley@arm.com    timeSource(timeSource_),
11810259SAndrew.Bardsley@arm.com    nextInsertCycle(Cycles(0))
11910259SAndrew.Bardsley@arm.com{
12010259SAndrew.Bardsley@arm.com    /* Issue latencies are set to 1 in calls to addCapability here.
12110259SAndrew.Bardsley@arm.com     * Issue latencies are associated with the pipeline as a whole,
12210259SAndrew.Bardsley@arm.com     * rather than instruction classes in Minor */
12310259SAndrew.Bardsley@arm.com
12410259SAndrew.Bardsley@arm.com    /* All pipelines should be able to execute No_OpClass instructions */
12510259SAndrew.Bardsley@arm.com    addCapability(No_OpClass, description.opLat, 1);
12610259SAndrew.Bardsley@arm.com
12710259SAndrew.Bardsley@arm.com    /* Add the capabilities listed in the MinorFU for this functional unit */
12810259SAndrew.Bardsley@arm.com    for (unsigned int i = 0; i < description.opClasses->opClasses.size();
12910259SAndrew.Bardsley@arm.com         i++)
13010259SAndrew.Bardsley@arm.com    {
13110259SAndrew.Bardsley@arm.com        addCapability(description.opClasses->opClasses[i]->opClass,
13210259SAndrew.Bardsley@arm.com            description.opLat, 1);
13310259SAndrew.Bardsley@arm.com    }
13410259SAndrew.Bardsley@arm.com
13510259SAndrew.Bardsley@arm.com    for (unsigned int i = 0; i < description.timings.size(); i++) {
13610259SAndrew.Bardsley@arm.com        MinorFUTiming &timing = *(description.timings[i]);
13710259SAndrew.Bardsley@arm.com
13810259SAndrew.Bardsley@arm.com        if (DTRACE(MinorTiming)) {
13910259SAndrew.Bardsley@arm.com            std::ostringstream lats;
14010259SAndrew.Bardsley@arm.com
14110259SAndrew.Bardsley@arm.com            unsigned int num_lats = timing.srcRegsRelativeLats.size();
14210259SAndrew.Bardsley@arm.com            unsigned int j = 0;
14310259SAndrew.Bardsley@arm.com            while (j < num_lats) {
14410259SAndrew.Bardsley@arm.com                lats << timing.srcRegsRelativeLats[j];
14510259SAndrew.Bardsley@arm.com
14610259SAndrew.Bardsley@arm.com                j++;
14710259SAndrew.Bardsley@arm.com                if (j != num_lats)
14810259SAndrew.Bardsley@arm.com                    lats << ',';
14910259SAndrew.Bardsley@arm.com            }
15010259SAndrew.Bardsley@arm.com
15110259SAndrew.Bardsley@arm.com            DPRINTFS(MinorTiming, static_cast<Named *>(this),
15210259SAndrew.Bardsley@arm.com                "Adding extra timing decode pattern %d to FU"
15310259SAndrew.Bardsley@arm.com                " mask: %016x match: %016x srcRegLatencies: %s\n",
15410259SAndrew.Bardsley@arm.com                i, timing.mask, timing.match, lats.str());
15510259SAndrew.Bardsley@arm.com        }
15610259SAndrew.Bardsley@arm.com    }
15710259SAndrew.Bardsley@arm.com
15810259SAndrew.Bardsley@arm.com    const std::vector<unsigned> &cant_forward =
15910259SAndrew.Bardsley@arm.com        description.cantForwardFromFUIndices;
16010259SAndrew.Bardsley@arm.com
16110259SAndrew.Bardsley@arm.com    /* Setup the bit vector cantForward... with the set indices
16210259SAndrew.Bardsley@arm.com     *  specified in the parameters */
16310259SAndrew.Bardsley@arm.com    for (auto i = cant_forward.begin(); i != cant_forward.end(); ++i) {
16410259SAndrew.Bardsley@arm.com        cantForwardFromFUIndices.resize((*i) + 1, false);
16510259SAndrew.Bardsley@arm.com        cantForwardFromFUIndices[*i] = true;
16610259SAndrew.Bardsley@arm.com    }
16710259SAndrew.Bardsley@arm.com}
16810259SAndrew.Bardsley@arm.com
16910259SAndrew.Bardsley@arm.comCycles
17010259SAndrew.Bardsley@arm.comFUPipeline::cyclesBeforeInsert()
17110259SAndrew.Bardsley@arm.com{
17210259SAndrew.Bardsley@arm.com    if (nextInsertCycle == 0 || timeSource.curCycle() > nextInsertCycle)
17310259SAndrew.Bardsley@arm.com        return Cycles(0);
17410259SAndrew.Bardsley@arm.com    else
17510259SAndrew.Bardsley@arm.com        return nextInsertCycle - timeSource.curCycle();
17610259SAndrew.Bardsley@arm.com}
17710259SAndrew.Bardsley@arm.com
17810259SAndrew.Bardsley@arm.combool
17910259SAndrew.Bardsley@arm.comFUPipeline::canInsert() const
18010259SAndrew.Bardsley@arm.com{
18110259SAndrew.Bardsley@arm.com    return nextInsertCycle == 0 || timeSource.curCycle() >= nextInsertCycle;
18210259SAndrew.Bardsley@arm.com}
18310259SAndrew.Bardsley@arm.com
18410259SAndrew.Bardsley@arm.comvoid
18510259SAndrew.Bardsley@arm.comFUPipeline::advance()
18610259SAndrew.Bardsley@arm.com{
18710259SAndrew.Bardsley@arm.com    bool was_stalled = stalled;
18810259SAndrew.Bardsley@arm.com
18910259SAndrew.Bardsley@arm.com    /* If an instruction was pushed into the pipeline, set the delay before
19010259SAndrew.Bardsley@arm.com     *  the next instruction can follow */
19110259SAndrew.Bardsley@arm.com    if (alreadyPushed()) {
19210259SAndrew.Bardsley@arm.com        if (nextInsertCycle <= timeSource.curCycle()) {
19310259SAndrew.Bardsley@arm.com            nextInsertCycle = timeSource.curCycle() + description.issueLat;
19410259SAndrew.Bardsley@arm.com        }
19510259SAndrew.Bardsley@arm.com    } else if (was_stalled && nextInsertCycle != 0) {
19610259SAndrew.Bardsley@arm.com        /* Don't count stalled cycles as part of the issue latency */
19710259SAndrew.Bardsley@arm.com        ++nextInsertCycle;
19810259SAndrew.Bardsley@arm.com    }
19910259SAndrew.Bardsley@arm.com    FUPipelineBase::advance();
20010259SAndrew.Bardsley@arm.com}
20110259SAndrew.Bardsley@arm.com
20210259SAndrew.Bardsley@arm.comMinorFUTiming *
20310417Sandreas.hansson@arm.comFUPipeline::findTiming(const StaticInstPtr &inst)
20410259SAndrew.Bardsley@arm.com{
20510259SAndrew.Bardsley@arm.com#if THE_ISA == ARM_ISA
20610259SAndrew.Bardsley@arm.com    /* This should work for any ISA with a POD mach_inst */
20710259SAndrew.Bardsley@arm.com    TheISA::ExtMachInst mach_inst = inst->machInst;
20810259SAndrew.Bardsley@arm.com#else
20910259SAndrew.Bardsley@arm.com    /* Just allow extra decode based on op classes */
21010259SAndrew.Bardsley@arm.com    uint64_t mach_inst = 0;
21110259SAndrew.Bardsley@arm.com#endif
21210259SAndrew.Bardsley@arm.com
21310259SAndrew.Bardsley@arm.com    const std::vector<MinorFUTiming *> &timings =
21410259SAndrew.Bardsley@arm.com        description.timings;
21510259SAndrew.Bardsley@arm.com    unsigned int num_timings = timings.size();
21610259SAndrew.Bardsley@arm.com
21710259SAndrew.Bardsley@arm.com    for (unsigned int i = 0; i < num_timings; i++) {
21810259SAndrew.Bardsley@arm.com        MinorFUTiming &timing = *timings[i];
21910259SAndrew.Bardsley@arm.com
22010259SAndrew.Bardsley@arm.com        if (timing.provides(inst->opClass()) &&
22110259SAndrew.Bardsley@arm.com            (mach_inst & timing.mask) == timing.match)
22210259SAndrew.Bardsley@arm.com        {
22310259SAndrew.Bardsley@arm.com            DPRINTFS(MinorTiming, static_cast<Named *>(this),
22410259SAndrew.Bardsley@arm.com                "Found extra timing match (pattern %d '%s')"
22510259SAndrew.Bardsley@arm.com                " %s %16x (type %s)\n",
22610259SAndrew.Bardsley@arm.com                i, timing.description, inst->disassemble(0), mach_inst,
22711169Sandreas.hansson@arm.com                typeid(inst).name());
22810259SAndrew.Bardsley@arm.com
22910259SAndrew.Bardsley@arm.com            return &timing;
23010259SAndrew.Bardsley@arm.com        }
23110259SAndrew.Bardsley@arm.com    }
23210259SAndrew.Bardsley@arm.com
23310259SAndrew.Bardsley@arm.com    if (num_timings != 0) {
23410259SAndrew.Bardsley@arm.com        DPRINTFS(MinorTiming, static_cast<Named *>(this),
23510259SAndrew.Bardsley@arm.com            "No extra timing info. found for inst: %s"
23610259SAndrew.Bardsley@arm.com            " mach_inst: %16x\n",
23710259SAndrew.Bardsley@arm.com            inst->disassemble(0), mach_inst);
23810259SAndrew.Bardsley@arm.com    }
23910259SAndrew.Bardsley@arm.com
24010259SAndrew.Bardsley@arm.com    return NULL;
24110259SAndrew.Bardsley@arm.com}
24210259SAndrew.Bardsley@arm.com
24310259SAndrew.Bardsley@arm.com}
244