func_unit.cc revision 10259:ebb376f73dd2
1/*
2 * Copyright (c) 2013-2014 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andrew Bardsley
38 */
39
40#include <iomanip>
41#include <sstream>
42#include <typeinfo>
43
44#include "cpu/minor/func_unit.hh"
45#include "debug/MinorTiming.hh"
46#include "enums/OpClass.hh"
47
48MinorOpClass *
49MinorOpClassParams::create()
50{
51    return new MinorOpClass(this);
52}
53
54MinorOpClassSet *
55MinorOpClassSetParams::create()
56{
57    return new MinorOpClassSet(this);
58}
59
60MinorFUTiming *
61MinorFUTimingParams::create()
62{
63    return new MinorFUTiming(this);
64}
65
66MinorFU *
67MinorFUParams::create()
68{
69    return new MinorFU(this);
70}
71
72MinorFUPool *
73MinorFUPoolParams::create()
74{
75    return new MinorFUPool(this);
76}
77
78MinorOpClassSet::MinorOpClassSet(const MinorOpClassSetParams *params) :
79    SimObject(params),
80    opClasses(params->opClasses),
81    /* Initialise to true for an empty list so that 'fully capable' is
82     *  the default */
83    capabilityList(Num_OpClasses, (opClasses.empty() ? true : false))
84{
85    for (unsigned int i = 0; i < opClasses.size(); i++)
86        capabilityList[opClasses[i]->opClass] = true;
87}
88
89MinorFUTiming::MinorFUTiming(
90    const MinorFUTimingParams *params) :
91    SimObject(params),
92    mask(params->mask),
93    match(params->match),
94    description(params->description),
95    suppress(params->suppress),
96    extraCommitLat(params->extraCommitLat),
97    extraCommitLatExpr(params->extraCommitLatExpr),
98    extraAssumedLat(params->extraAssumedLat),
99    srcRegsRelativeLats(params->srcRegsRelativeLats),
100    opClasses(params->opClasses)
101{ }
102
103namespace Minor
104{
105
106void
107QueuedInst::reportData(std::ostream &os) const
108{
109    inst->reportData(os);
110}
111
112FUPipeline::FUPipeline(const std::string &name, const MinorFU &description_,
113    ClockedObject &timeSource_) :
114    FUPipelineBase(name, "insts", description_.opLat),
115    description(description_),
116    timeSource(timeSource_),
117    nextInsertCycle(Cycles(0))
118{
119    /* Issue latencies are set to 1 in calls to addCapability here.
120     * Issue latencies are associated with the pipeline as a whole,
121     * rather than instruction classes in Minor */
122
123    /* All pipelines should be able to execute No_OpClass instructions */
124    addCapability(No_OpClass, description.opLat, 1);
125
126    /* Add the capabilities listed in the MinorFU for this functional unit */
127    for (unsigned int i = 0; i < description.opClasses->opClasses.size();
128         i++)
129    {
130        addCapability(description.opClasses->opClasses[i]->opClass,
131            description.opLat, 1);
132    }
133
134    for (unsigned int i = 0; i < description.timings.size(); i++) {
135        MinorFUTiming &timing = *(description.timings[i]);
136
137        if (DTRACE(MinorTiming)) {
138            std::ostringstream lats;
139
140            unsigned int num_lats = timing.srcRegsRelativeLats.size();
141            unsigned int j = 0;
142            while (j < num_lats) {
143                lats << timing.srcRegsRelativeLats[j];
144
145                j++;
146                if (j != num_lats)
147                    lats << ',';
148            }
149
150            DPRINTFS(MinorTiming, static_cast<Named *>(this),
151                "Adding extra timing decode pattern %d to FU"
152                " mask: %016x match: %016x srcRegLatencies: %s\n",
153                i, timing.mask, timing.match, lats.str());
154        }
155    }
156
157    const std::vector<unsigned> &cant_forward =
158        description.cantForwardFromFUIndices;
159
160    /* Setup the bit vector cantForward... with the set indices
161     *  specified in the parameters */
162    for (auto i = cant_forward.begin(); i != cant_forward.end(); ++i) {
163        cantForwardFromFUIndices.resize((*i) + 1, false);
164        cantForwardFromFUIndices[*i] = true;
165    }
166}
167
168Cycles
169FUPipeline::cyclesBeforeInsert()
170{
171    if (nextInsertCycle == 0 || timeSource.curCycle() > nextInsertCycle)
172        return Cycles(0);
173    else
174        return nextInsertCycle - timeSource.curCycle();
175}
176
177bool
178FUPipeline::canInsert() const
179{
180    return nextInsertCycle == 0 || timeSource.curCycle() >= nextInsertCycle;
181}
182
183void
184FUPipeline::advance()
185{
186    bool was_stalled = stalled;
187
188    /* If an instruction was pushed into the pipeline, set the delay before
189     *  the next instruction can follow */
190    if (alreadyPushed()) {
191        if (nextInsertCycle <= timeSource.curCycle()) {
192            nextInsertCycle = timeSource.curCycle() + description.issueLat;
193        }
194    } else if (was_stalled && nextInsertCycle != 0) {
195        /* Don't count stalled cycles as part of the issue latency */
196        ++nextInsertCycle;
197    }
198    FUPipelineBase::advance();
199}
200
201MinorFUTiming *
202FUPipeline::findTiming(StaticInstPtr inst)
203{
204#if THE_ISA == ARM_ISA
205    /* This should work for any ISA with a POD mach_inst */
206    TheISA::ExtMachInst mach_inst = inst->machInst;
207#else
208    /* Just allow extra decode based on op classes */
209    uint64_t mach_inst = 0;
210#endif
211
212    const std::vector<MinorFUTiming *> &timings =
213        description.timings;
214    unsigned int num_timings = timings.size();
215
216    for (unsigned int i = 0; i < num_timings; i++) {
217        MinorFUTiming &timing = *timings[i];
218
219        if (timing.provides(inst->opClass()) &&
220            (mach_inst & timing.mask) == timing.match)
221        {
222            DPRINTFS(MinorTiming, static_cast<Named *>(this),
223                "Found extra timing match (pattern %d '%s')"
224                " %s %16x (type %s)\n",
225                i, timing.description, inst->disassemble(0), mach_inst,
226                typeid(*inst).name());
227
228            return &timing;
229        }
230    }
231
232    if (num_timings != 0) {
233        DPRINTFS(MinorTiming, static_cast<Named *>(this),
234            "No extra timing info. found for inst: %s"
235            " mach_inst: %16x\n",
236            inst->disassemble(0), mach_inst);
237    }
238
239    return NULL;
240}
241
242}
243