2 * Copyright (c) 2013-2014 ARM Limited
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.
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.
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.
38 #include "cpu/minor/func_unit.hh"
44 #include "debug/MinorTiming.hh"
45 #include "enums/OpClass.hh"
48 MinorOpClassParams::create()
50 return new MinorOpClass(this);
54 MinorOpClassSetParams::create()
56 return new MinorOpClassSet(this);
60 MinorFUTimingParams::create()
62 return new MinorFUTiming(this);
66 MinorFUParams::create()
68 return new MinorFU(this);
72 MinorFUPoolParams::create()
74 return new MinorFUPool(this);
77 MinorOpClassSet::MinorOpClassSet(const MinorOpClassSetParams
*params
) :
79 opClasses(params
->opClasses
),
80 /* Initialise to true for an empty list so that 'fully capable' is
82 capabilityList(Num_OpClasses
, (opClasses
.empty() ? true : false))
84 for (unsigned int i
= 0; i
< opClasses
.size(); i
++)
85 capabilityList
[opClasses
[i
]->opClass
] = true;
88 MinorFUTiming::MinorFUTiming(
89 const MinorFUTimingParams
*params
) :
93 description(params
->description
),
94 suppress(params
->suppress
),
95 extraCommitLat(params
->extraCommitLat
),
96 extraCommitLatExpr(params
->extraCommitLatExpr
),
97 extraAssumedLat(params
->extraAssumedLat
),
98 srcRegsRelativeLats(params
->srcRegsRelativeLats
),
99 opClasses(params
->opClasses
)
106 QueuedInst::reportData(std::ostream
&os
) const
108 inst
->reportData(os
);
111 FUPipeline::FUPipeline(const std::string
&name
, const MinorFU
&description_
,
112 ClockedObject
&timeSource_
) :
113 FUPipelineBase(name
, "insts", description_
.opLat
),
114 description(description_
),
115 timeSource(timeSource_
),
116 nextInsertCycle(Cycles(0))
118 /* Issue latencies are set to 1 in calls to addCapability here.
119 * Issue latencies are associated with the pipeline as a whole,
120 * rather than instruction classes in Minor */
122 /* All pipelines should be able to execute No_OpClass instructions */
123 addCapability(No_OpClass
, description
.opLat
, 1);
125 /* Add the capabilities listed in the MinorFU for this functional unit */
126 for (unsigned int i
= 0; i
< description
.opClasses
->opClasses
.size();
129 addCapability(description
.opClasses
->opClasses
[i
]->opClass
,
130 description
.opLat
, 1);
133 for (unsigned int i
= 0; i
< description
.timings
.size(); i
++) {
134 MinorFUTiming
&timing
= *(description
.timings
[i
]);
136 if (DTRACE(MinorTiming
)) {
137 std::ostringstream lats
;
139 unsigned int num_lats
= timing
.srcRegsRelativeLats
.size();
141 while (j
< num_lats
) {
142 lats
<< timing
.srcRegsRelativeLats
[j
];
149 DPRINTFS(MinorTiming
, static_cast<Named
*>(this),
150 "Adding extra timing decode pattern %d to FU"
151 " mask: %016x match: %016x srcRegLatencies: %s\n",
152 i
, timing
.mask
, timing
.match
, lats
.str());
156 const std::vector
<unsigned> &cant_forward
=
157 description
.cantForwardFromFUIndices
;
159 /* Setup the bit vector cantForward... with the set indices
160 * specified in the parameters */
161 for (auto i
= cant_forward
.begin(); i
!= cant_forward
.end(); ++i
) {
162 cantForwardFromFUIndices
.resize((*i
) + 1, false);
163 cantForwardFromFUIndices
[*i
] = true;
168 FUPipeline::cyclesBeforeInsert()
170 if (nextInsertCycle
== 0 || timeSource
.curCycle() > nextInsertCycle
)
173 return nextInsertCycle
- timeSource
.curCycle();
177 FUPipeline::canInsert() const
179 return nextInsertCycle
== 0 || timeSource
.curCycle() >= nextInsertCycle
;
183 FUPipeline::advance()
185 bool was_stalled
= stalled
;
187 /* If an instruction was pushed into the pipeline, set the delay before
188 * the next instruction can follow */
189 if (alreadyPushed()) {
190 if (nextInsertCycle
<= timeSource
.curCycle()) {
191 nextInsertCycle
= timeSource
.curCycle() + description
.issueLat
;
193 } else if (was_stalled
&& nextInsertCycle
!= 0) {
194 /* Don't count stalled cycles as part of the issue latency */
197 FUPipelineBase::advance();
201 FUPipeline::findTiming(const StaticInstPtr
&inst
)
203 #if THE_ISA == ARM_ISA
204 /* This should work for any ISA with a POD mach_inst */
205 TheISA::ExtMachInst mach_inst
= inst
->machInst
;
207 /* Just allow extra decode based on op classes */
208 uint64_t mach_inst
= 0;
211 const std::vector
<MinorFUTiming
*> &timings
=
213 unsigned int num_timings
= timings
.size();
215 for (unsigned int i
= 0; i
< num_timings
; i
++) {
216 MinorFUTiming
&timing
= *timings
[i
];
218 if (timing
.provides(inst
->opClass()) &&
219 (mach_inst
& timing
.mask
) == timing
.match
)
221 DPRINTFS(MinorTiming
, static_cast<Named
*>(this),
222 "Found extra timing match (pattern %d '%s')"
223 " %s %16x (type %s)\n",
224 i
, timing
.description
, inst
->disassemble(0), mach_inst
,
225 typeid(inst
).name());
231 if (num_timings
!= 0) {
232 DPRINTFS(MinorTiming
, static_cast<Named
*>(this),
233 "No extra timing info. found for inst: %s"
234 " mach_inst: %16x\n",
235 inst
->disassemble(0), mach_inst
);