rename_impl.hh (13601:f5c84915eb7f) rename_impl.hh (13610:5d5404ac6288)
1/*
2 * Copyright (c) 2010-2012, 2014-2016 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Kevin Lim
42 * Korey Sewell
43 */
44
45#ifndef __CPU_O3_RENAME_IMPL_HH__
46#define __CPU_O3_RENAME_IMPL_HH__
47
48#include <list>
49
50#include "arch/isa_traits.hh"
51#include "arch/registers.hh"
52#include "config/the_isa.hh"
53#include "cpu/o3/rename.hh"
54#include "cpu/reg_class.hh"
55#include "debug/Activity.hh"
56#include "debug/Rename.hh"
57#include "debug/O3PipeView.hh"
58#include "params/DerivO3CPU.hh"
59
60using namespace std;
61
62template <class Impl>
63DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params)
64 : cpu(_cpu),
65 iewToRenameDelay(params->iewToRenameDelay),
66 decodeToRenameDelay(params->decodeToRenameDelay),
67 commitToRenameDelay(params->commitToRenameDelay),
68 renameWidth(params->renameWidth),
69 commitWidth(params->commitWidth),
70 numThreads(params->numThreads)
71{
72 if (renameWidth > Impl::MaxWidth)
73 fatal("renameWidth (%d) is larger than compiled limit (%d),\n"
74 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
75 renameWidth, static_cast<int>(Impl::MaxWidth));
76
77 // @todo: Make into a parameter.
78 skidBufferMax = (decodeToRenameDelay + 1) * params->decodeWidth;
79 for (uint32_t tid = 0; tid < Impl::MaxThreads; tid++) {
80 renameStatus[tid] = Idle;
81 renameMap[tid] = nullptr;
82 instsInProgress[tid] = 0;
83 loadsInProgress[tid] = 0;
84 storesInProgress[tid] = 0;
85 freeEntries[tid] = {0, 0, 0, 0};
86 emptyROB[tid] = true;
87 stalls[tid] = {false, false};
88 serializeInst[tid] = nullptr;
89 serializeOnNextInst[tid] = false;
90 }
91}
92
93template <class Impl>
94std::string
95DefaultRename<Impl>::name() const
96{
97 return cpu->name() + ".rename";
98}
99
100template <class Impl>
101void
102DefaultRename<Impl>::regStats()
103{
104 renameSquashCycles
105 .name(name() + ".SquashCycles")
106 .desc("Number of cycles rename is squashing")
107 .prereq(renameSquashCycles);
108 renameIdleCycles
109 .name(name() + ".IdleCycles")
110 .desc("Number of cycles rename is idle")
111 .prereq(renameIdleCycles);
112 renameBlockCycles
113 .name(name() + ".BlockCycles")
114 .desc("Number of cycles rename is blocking")
115 .prereq(renameBlockCycles);
116 renameSerializeStallCycles
117 .name(name() + ".serializeStallCycles")
118 .desc("count of cycles rename stalled for serializing inst")
119 .flags(Stats::total);
120 renameRunCycles
121 .name(name() + ".RunCycles")
122 .desc("Number of cycles rename is running")
123 .prereq(renameIdleCycles);
124 renameUnblockCycles
125 .name(name() + ".UnblockCycles")
126 .desc("Number of cycles rename is unblocking")
127 .prereq(renameUnblockCycles);
128 renameRenamedInsts
129 .name(name() + ".RenamedInsts")
130 .desc("Number of instructions processed by rename")
131 .prereq(renameRenamedInsts);
132 renameSquashedInsts
133 .name(name() + ".SquashedInsts")
134 .desc("Number of squashed instructions processed by rename")
135 .prereq(renameSquashedInsts);
136 renameROBFullEvents
137 .name(name() + ".ROBFullEvents")
138 .desc("Number of times rename has blocked due to ROB full")
139 .prereq(renameROBFullEvents);
140 renameIQFullEvents
141 .name(name() + ".IQFullEvents")
142 .desc("Number of times rename has blocked due to IQ full")
143 .prereq(renameIQFullEvents);
144 renameLQFullEvents
145 .name(name() + ".LQFullEvents")
146 .desc("Number of times rename has blocked due to LQ full")
147 .prereq(renameLQFullEvents);
148 renameSQFullEvents
149 .name(name() + ".SQFullEvents")
150 .desc("Number of times rename has blocked due to SQ full")
151 .prereq(renameSQFullEvents);
152 renameFullRegistersEvents
153 .name(name() + ".FullRegisterEvents")
154 .desc("Number of times there has been no free registers")
155 .prereq(renameFullRegistersEvents);
156 renameRenamedOperands
157 .name(name() + ".RenamedOperands")
158 .desc("Number of destination operands rename has renamed")
159 .prereq(renameRenamedOperands);
160 renameRenameLookups
161 .name(name() + ".RenameLookups")
162 .desc("Number of register rename lookups that rename has made")
163 .prereq(renameRenameLookups);
164 renameCommittedMaps
165 .name(name() + ".CommittedMaps")
166 .desc("Number of HB maps that are committed")
167 .prereq(renameCommittedMaps);
168 renameUndoneMaps
169 .name(name() + ".UndoneMaps")
170 .desc("Number of HB maps that are undone due to squashing")
171 .prereq(renameUndoneMaps);
172 renamedSerializing
173 .name(name() + ".serializingInsts")
174 .desc("count of serializing insts renamed")
175 .flags(Stats::total)
176 ;
177 renamedTempSerializing
178 .name(name() + ".tempSerializingInsts")
179 .desc("count of temporary serializing insts renamed")
180 .flags(Stats::total)
181 ;
182 renameSkidInsts
183 .name(name() + ".skidInsts")
184 .desc("count of insts added to the skid buffer")
185 .flags(Stats::total)
186 ;
187 intRenameLookups
188 .name(name() + ".int_rename_lookups")
189 .desc("Number of integer rename lookups")
190 .prereq(intRenameLookups);
191 fpRenameLookups
192 .name(name() + ".fp_rename_lookups")
193 .desc("Number of floating rename lookups")
194 .prereq(fpRenameLookups);
195 vecRenameLookups
196 .name(name() + ".vec_rename_lookups")
197 .desc("Number of vector rename lookups")
198 .prereq(vecRenameLookups);
1/*
2 * Copyright (c) 2010-2012, 2014-2016 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2006 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Kevin Lim
42 * Korey Sewell
43 */
44
45#ifndef __CPU_O3_RENAME_IMPL_HH__
46#define __CPU_O3_RENAME_IMPL_HH__
47
48#include <list>
49
50#include "arch/isa_traits.hh"
51#include "arch/registers.hh"
52#include "config/the_isa.hh"
53#include "cpu/o3/rename.hh"
54#include "cpu/reg_class.hh"
55#include "debug/Activity.hh"
56#include "debug/Rename.hh"
57#include "debug/O3PipeView.hh"
58#include "params/DerivO3CPU.hh"
59
60using namespace std;
61
62template <class Impl>
63DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params)
64 : cpu(_cpu),
65 iewToRenameDelay(params->iewToRenameDelay),
66 decodeToRenameDelay(params->decodeToRenameDelay),
67 commitToRenameDelay(params->commitToRenameDelay),
68 renameWidth(params->renameWidth),
69 commitWidth(params->commitWidth),
70 numThreads(params->numThreads)
71{
72 if (renameWidth > Impl::MaxWidth)
73 fatal("renameWidth (%d) is larger than compiled limit (%d),\n"
74 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
75 renameWidth, static_cast<int>(Impl::MaxWidth));
76
77 // @todo: Make into a parameter.
78 skidBufferMax = (decodeToRenameDelay + 1) * params->decodeWidth;
79 for (uint32_t tid = 0; tid < Impl::MaxThreads; tid++) {
80 renameStatus[tid] = Idle;
81 renameMap[tid] = nullptr;
82 instsInProgress[tid] = 0;
83 loadsInProgress[tid] = 0;
84 storesInProgress[tid] = 0;
85 freeEntries[tid] = {0, 0, 0, 0};
86 emptyROB[tid] = true;
87 stalls[tid] = {false, false};
88 serializeInst[tid] = nullptr;
89 serializeOnNextInst[tid] = false;
90 }
91}
92
93template <class Impl>
94std::string
95DefaultRename<Impl>::name() const
96{
97 return cpu->name() + ".rename";
98}
99
100template <class Impl>
101void
102DefaultRename<Impl>::regStats()
103{
104 renameSquashCycles
105 .name(name() + ".SquashCycles")
106 .desc("Number of cycles rename is squashing")
107 .prereq(renameSquashCycles);
108 renameIdleCycles
109 .name(name() + ".IdleCycles")
110 .desc("Number of cycles rename is idle")
111 .prereq(renameIdleCycles);
112 renameBlockCycles
113 .name(name() + ".BlockCycles")
114 .desc("Number of cycles rename is blocking")
115 .prereq(renameBlockCycles);
116 renameSerializeStallCycles
117 .name(name() + ".serializeStallCycles")
118 .desc("count of cycles rename stalled for serializing inst")
119 .flags(Stats::total);
120 renameRunCycles
121 .name(name() + ".RunCycles")
122 .desc("Number of cycles rename is running")
123 .prereq(renameIdleCycles);
124 renameUnblockCycles
125 .name(name() + ".UnblockCycles")
126 .desc("Number of cycles rename is unblocking")
127 .prereq(renameUnblockCycles);
128 renameRenamedInsts
129 .name(name() + ".RenamedInsts")
130 .desc("Number of instructions processed by rename")
131 .prereq(renameRenamedInsts);
132 renameSquashedInsts
133 .name(name() + ".SquashedInsts")
134 .desc("Number of squashed instructions processed by rename")
135 .prereq(renameSquashedInsts);
136 renameROBFullEvents
137 .name(name() + ".ROBFullEvents")
138 .desc("Number of times rename has blocked due to ROB full")
139 .prereq(renameROBFullEvents);
140 renameIQFullEvents
141 .name(name() + ".IQFullEvents")
142 .desc("Number of times rename has blocked due to IQ full")
143 .prereq(renameIQFullEvents);
144 renameLQFullEvents
145 .name(name() + ".LQFullEvents")
146 .desc("Number of times rename has blocked due to LQ full")
147 .prereq(renameLQFullEvents);
148 renameSQFullEvents
149 .name(name() + ".SQFullEvents")
150 .desc("Number of times rename has blocked due to SQ full")
151 .prereq(renameSQFullEvents);
152 renameFullRegistersEvents
153 .name(name() + ".FullRegisterEvents")
154 .desc("Number of times there has been no free registers")
155 .prereq(renameFullRegistersEvents);
156 renameRenamedOperands
157 .name(name() + ".RenamedOperands")
158 .desc("Number of destination operands rename has renamed")
159 .prereq(renameRenamedOperands);
160 renameRenameLookups
161 .name(name() + ".RenameLookups")
162 .desc("Number of register rename lookups that rename has made")
163 .prereq(renameRenameLookups);
164 renameCommittedMaps
165 .name(name() + ".CommittedMaps")
166 .desc("Number of HB maps that are committed")
167 .prereq(renameCommittedMaps);
168 renameUndoneMaps
169 .name(name() + ".UndoneMaps")
170 .desc("Number of HB maps that are undone due to squashing")
171 .prereq(renameUndoneMaps);
172 renamedSerializing
173 .name(name() + ".serializingInsts")
174 .desc("count of serializing insts renamed")
175 .flags(Stats::total)
176 ;
177 renamedTempSerializing
178 .name(name() + ".tempSerializingInsts")
179 .desc("count of temporary serializing insts renamed")
180 .flags(Stats::total)
181 ;
182 renameSkidInsts
183 .name(name() + ".skidInsts")
184 .desc("count of insts added to the skid buffer")
185 .flags(Stats::total)
186 ;
187 intRenameLookups
188 .name(name() + ".int_rename_lookups")
189 .desc("Number of integer rename lookups")
190 .prereq(intRenameLookups);
191 fpRenameLookups
192 .name(name() + ".fp_rename_lookups")
193 .desc("Number of floating rename lookups")
194 .prereq(fpRenameLookups);
195 vecRenameLookups
196 .name(name() + ".vec_rename_lookups")
197 .desc("Number of vector rename lookups")
198 .prereq(vecRenameLookups);
199 vecPredRenameLookups
200 .name(name() + ".vec_pred_rename_lookups")
201 .desc("Number of vector predicate rename lookups")
202 .prereq(vecPredRenameLookups);
199}
200
201template <class Impl>
202void
203DefaultRename<Impl>::regProbePoints()
204{
205 ppRename = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Rename");
206 ppSquashInRename = new ProbePointArg<SeqNumRegPair>(cpu->getProbeManager(),
207 "SquashInRename");
208}
209
210template <class Impl>
211void
212DefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
213{
214 timeBuffer = tb_ptr;
215
216 // Setup wire to read information from time buffer, from IEW stage.
217 fromIEW = timeBuffer->getWire(-iewToRenameDelay);
218
219 // Setup wire to read infromation from time buffer, from commit stage.
220 fromCommit = timeBuffer->getWire(-commitToRenameDelay);
221
222 // Setup wire to write information to previous stages.
223 toDecode = timeBuffer->getWire(0);
224}
225
226template <class Impl>
227void
228DefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
229{
230 renameQueue = rq_ptr;
231
232 // Setup wire to write information to future stages.
233 toIEW = renameQueue->getWire(0);
234}
235
236template <class Impl>
237void
238DefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
239{
240 decodeQueue = dq_ptr;
241
242 // Setup wire to get information from decode.
243 fromDecode = decodeQueue->getWire(-decodeToRenameDelay);
244}
245
246template <class Impl>
247void
248DefaultRename<Impl>::startupStage()
249{
250 resetStage();
251}
252
253template <class Impl>
254void
255DefaultRename<Impl>::resetStage()
256{
257 _status = Inactive;
258
259 resumeSerialize = false;
260 resumeUnblocking = false;
261
262 // Grab the number of free entries directly from the stages.
263 for (ThreadID tid = 0; tid < numThreads; tid++) {
264 renameStatus[tid] = Idle;
265
266 freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
267 freeEntries[tid].lqEntries = iew_ptr->ldstQueue.numFreeLoadEntries(tid);
268 freeEntries[tid].sqEntries = iew_ptr->ldstQueue.numFreeStoreEntries(tid);
269 freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
270 emptyROB[tid] = true;
271
272 stalls[tid].iew = false;
273 serializeInst[tid] = NULL;
274
275 instsInProgress[tid] = 0;
276 loadsInProgress[tid] = 0;
277 storesInProgress[tid] = 0;
278
279 serializeOnNextInst[tid] = false;
280 }
281}
282
283template<class Impl>
284void
285DefaultRename<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
286{
287 activeThreads = at_ptr;
288}
289
290
291template <class Impl>
292void
293DefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[])
294{
295 for (ThreadID tid = 0; tid < numThreads; tid++)
296 renameMap[tid] = &rm_ptr[tid];
297}
298
299template <class Impl>
300void
301DefaultRename<Impl>::setFreeList(FreeList *fl_ptr)
302{
303 freeList = fl_ptr;
304}
305
306template<class Impl>
307void
308DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
309{
310 scoreboard = _scoreboard;
311}
312
313template <class Impl>
314bool
315DefaultRename<Impl>::isDrained() const
316{
317 for (ThreadID tid = 0; tid < numThreads; tid++) {
318 if (instsInProgress[tid] != 0 ||
319 !historyBuffer[tid].empty() ||
320 !skidBuffer[tid].empty() ||
321 !insts[tid].empty() ||
322 (renameStatus[tid] != Idle && renameStatus[tid] != Running))
323 return false;
324 }
325 return true;
326}
327
328template <class Impl>
329void
330DefaultRename<Impl>::takeOverFrom()
331{
332 resetStage();
333}
334
335template <class Impl>
336void
337DefaultRename<Impl>::drainSanityCheck() const
338{
339 for (ThreadID tid = 0; tid < numThreads; tid++) {
340 assert(historyBuffer[tid].empty());
341 assert(insts[tid].empty());
342 assert(skidBuffer[tid].empty());
343 assert(instsInProgress[tid] == 0);
344 }
345}
346
347template <class Impl>
348void
349DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, ThreadID tid)
350{
351 DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid);
352
353 // Clear the stall signal if rename was blocked or unblocking before.
354 // If it still needs to block, the blocking should happen the next
355 // cycle and there should be space to hold everything due to the squash.
356 if (renameStatus[tid] == Blocked ||
357 renameStatus[tid] == Unblocking) {
358 toDecode->renameUnblock[tid] = 1;
359
360 resumeSerialize = false;
361 serializeInst[tid] = NULL;
362 } else if (renameStatus[tid] == SerializeStall) {
363 if (serializeInst[tid]->seqNum <= squash_seq_num) {
364 DPRINTF(Rename, "Rename will resume serializing after squash\n");
365 resumeSerialize = true;
366 assert(serializeInst[tid]);
367 } else {
368 resumeSerialize = false;
369 toDecode->renameUnblock[tid] = 1;
370
371 serializeInst[tid] = NULL;
372 }
373 }
374
375 // Set the status to Squashing.
376 renameStatus[tid] = Squashing;
377
378 // Squash any instructions from decode.
379 for (int i=0; i<fromDecode->size; i++) {
380 if (fromDecode->insts[i]->threadNumber == tid &&
381 fromDecode->insts[i]->seqNum > squash_seq_num) {
382 fromDecode->insts[i]->setSquashed();
383 wroteToTimeBuffer = true;
384 }
385
386 }
387
388 // Clear the instruction list and skid buffer in case they have any
389 // insts in them.
390 insts[tid].clear();
391
392 // Clear the skid buffer in case it has any data in it.
393 skidBuffer[tid].clear();
394
395 doSquash(squash_seq_num, tid);
396}
397
398template <class Impl>
399void
400DefaultRename<Impl>::tick()
401{
402 wroteToTimeBuffer = false;
403
404 blockThisCycle = false;
405
406 bool status_change = false;
407
408 toIEWIndex = 0;
409
410 sortInsts();
411
412 list<ThreadID>::iterator threads = activeThreads->begin();
413 list<ThreadID>::iterator end = activeThreads->end();
414
415 // Check stall and squash signals.
416 while (threads != end) {
417 ThreadID tid = *threads++;
418
419 DPRINTF(Rename, "Processing [tid:%i]\n", tid);
420
421 status_change = checkSignalsAndUpdate(tid) || status_change;
422
423 rename(status_change, tid);
424 }
425
426 if (status_change) {
427 updateStatus();
428 }
429
430 if (wroteToTimeBuffer) {
431 DPRINTF(Activity, "Activity this cycle.\n");
432 cpu->activityThisCycle();
433 }
434
435 threads = activeThreads->begin();
436
437 while (threads != end) {
438 ThreadID tid = *threads++;
439
440 // If we committed this cycle then doneSeqNum will be > 0
441 if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
442 !fromCommit->commitInfo[tid].squash &&
443 renameStatus[tid] != Squashing) {
444
445 removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,
446 tid);
447 }
448 }
449
450 // @todo: make into updateProgress function
451 for (ThreadID tid = 0; tid < numThreads; tid++) {
452 instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
453 loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ;
454 storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ;
455 assert(loadsInProgress[tid] >= 0);
456 assert(storesInProgress[tid] >= 0);
457 assert(instsInProgress[tid] >=0);
458 }
459
460}
461
462template<class Impl>
463void
464DefaultRename<Impl>::rename(bool &status_change, ThreadID tid)
465{
466 // If status is Running or idle,
467 // call renameInsts()
468 // If status is Unblocking,
469 // buffer any instructions coming from decode
470 // continue trying to empty skid buffer
471 // check if stall conditions have passed
472
473 if (renameStatus[tid] == Blocked) {
474 ++renameBlockCycles;
475 } else if (renameStatus[tid] == Squashing) {
476 ++renameSquashCycles;
477 } else if (renameStatus[tid] == SerializeStall) {
478 ++renameSerializeStallCycles;
479 // If we are currently in SerializeStall and resumeSerialize
480 // was set, then that means that we are resuming serializing
481 // this cycle. Tell the previous stages to block.
482 if (resumeSerialize) {
483 resumeSerialize = false;
484 block(tid);
485 toDecode->renameUnblock[tid] = false;
486 }
487 } else if (renameStatus[tid] == Unblocking) {
488 if (resumeUnblocking) {
489 block(tid);
490 resumeUnblocking = false;
491 toDecode->renameUnblock[tid] = false;
492 }
493 }
494
495 if (renameStatus[tid] == Running ||
496 renameStatus[tid] == Idle) {
497 DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run "
498 "stage.\n", tid);
499
500 renameInsts(tid);
501 } else if (renameStatus[tid] == Unblocking) {
502 renameInsts(tid);
503
504 if (validInsts()) {
505 // Add the current inputs to the skid buffer so they can be
506 // reprocessed when this stage unblocks.
507 skidInsert(tid);
508 }
509
510 // If we switched over to blocking, then there's a potential for
511 // an overall status change.
512 status_change = unblock(tid) || status_change || blockThisCycle;
513 }
514}
515
516template <class Impl>
517void
518DefaultRename<Impl>::renameInsts(ThreadID tid)
519{
520 // Instructions can be either in the skid buffer or the queue of
521 // instructions coming from decode, depending on the status.
522 int insts_available = renameStatus[tid] == Unblocking ?
523 skidBuffer[tid].size() : insts[tid].size();
524
525 // Check the decode queue to see if instructions are available.
526 // If there are no available instructions to rename, then do nothing.
527 if (insts_available == 0) {
528 DPRINTF(Rename, "[tid:%u]: Nothing to do, breaking out early.\n",
529 tid);
530 // Should I change status to idle?
531 ++renameIdleCycles;
532 return;
533 } else if (renameStatus[tid] == Unblocking) {
534 ++renameUnblockCycles;
535 } else if (renameStatus[tid] == Running) {
536 ++renameRunCycles;
537 }
538
539 // Will have to do a different calculation for the number of free
540 // entries.
541 int free_rob_entries = calcFreeROBEntries(tid);
542 int free_iq_entries = calcFreeIQEntries(tid);
543 int min_free_entries = free_rob_entries;
544
545 FullSource source = ROB;
546
547 if (free_iq_entries < min_free_entries) {
548 min_free_entries = free_iq_entries;
549 source = IQ;
550 }
551
552 // Check if there's any space left.
553 if (min_free_entries <= 0) {
554 DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/ "
555 "entries.\n"
556 "ROB has %i free entries.\n"
557 "IQ has %i free entries.\n",
558 tid,
559 free_rob_entries,
560 free_iq_entries);
561
562 blockThisCycle = true;
563
564 block(tid);
565
566 incrFullStat(source);
567
568 return;
569 } else if (min_free_entries < insts_available) {
570 DPRINTF(Rename, "[tid:%u]: Will have to block this cycle."
571 "%i insts available, but only %i insts can be "
572 "renamed due to ROB/IQ/LSQ limits.\n",
573 tid, insts_available, min_free_entries);
574
575 insts_available = min_free_entries;
576
577 blockThisCycle = true;
578
579 incrFullStat(source);
580 }
581
582 InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ?
583 skidBuffer[tid] : insts[tid];
584
585 DPRINTF(Rename, "[tid:%u]: %i available instructions to "
586 "send iew.\n", tid, insts_available);
587
588 DPRINTF(Rename, "[tid:%u]: %i insts pipelining from Rename | %i insts "
589 "dispatched to IQ last cycle.\n",
590 tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched);
591
592 // Handle serializing the next instruction if necessary.
593 if (serializeOnNextInst[tid]) {
594 if (emptyROB[tid] && instsInProgress[tid] == 0) {
595 // ROB already empty; no need to serialize.
596 serializeOnNextInst[tid] = false;
597 } else if (!insts_to_rename.empty()) {
598 insts_to_rename.front()->setSerializeBefore();
599 }
600 }
601
602 int renamed_insts = 0;
603
604 while (insts_available > 0 && toIEWIndex < renameWidth) {
605 DPRINTF(Rename, "[tid:%u]: Sending instructions to IEW.\n", tid);
606
607 assert(!insts_to_rename.empty());
608
609 DynInstPtr inst = insts_to_rename.front();
610
611 //For all kind of instructions, check ROB and IQ first
612 //For load instruction, check LQ size and take into account the inflight loads
613 //For store instruction, check SQ size and take into account the inflight stores
614
615 if (inst->isLoad()) {
616 if (calcFreeLQEntries(tid) <= 0) {
617 DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free LQ\n");
618 source = LQ;
619 incrFullStat(source);
620 break;
621 }
622 }
623
624 if (inst->isStore()) {
625 if (calcFreeSQEntries(tid) <= 0) {
626 DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free SQ\n");
627 source = SQ;
628 incrFullStat(source);
629 break;
630 }
631 }
632
633 insts_to_rename.pop_front();
634
635 if (renameStatus[tid] == Unblocking) {
636 DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%s from rename "
637 "skidBuffer\n", tid, inst->seqNum, inst->pcState());
638 }
639
640 if (inst->isSquashed()) {
641 DPRINTF(Rename, "[tid:%u]: instruction %i with PC %s is "
642 "squashed, skipping.\n", tid, inst->seqNum,
643 inst->pcState());
644
645 ++renameSquashedInsts;
646
647 // Decrement how many instructions are available.
648 --insts_available;
649
650 continue;
651 }
652
653 DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
654 "PC %s.\n", tid, inst->seqNum, inst->pcState());
655
656 // Check here to make sure there are enough destination registers
657 // to rename to. Otherwise block.
658 if (!renameMap[tid]->canRename(inst->numIntDestRegs(),
659 inst->numFPDestRegs(),
660 inst->numVecDestRegs(),
661 inst->numVecElemDestRegs(),
203}
204
205template <class Impl>
206void
207DefaultRename<Impl>::regProbePoints()
208{
209 ppRename = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Rename");
210 ppSquashInRename = new ProbePointArg<SeqNumRegPair>(cpu->getProbeManager(),
211 "SquashInRename");
212}
213
214template <class Impl>
215void
216DefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
217{
218 timeBuffer = tb_ptr;
219
220 // Setup wire to read information from time buffer, from IEW stage.
221 fromIEW = timeBuffer->getWire(-iewToRenameDelay);
222
223 // Setup wire to read infromation from time buffer, from commit stage.
224 fromCommit = timeBuffer->getWire(-commitToRenameDelay);
225
226 // Setup wire to write information to previous stages.
227 toDecode = timeBuffer->getWire(0);
228}
229
230template <class Impl>
231void
232DefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
233{
234 renameQueue = rq_ptr;
235
236 // Setup wire to write information to future stages.
237 toIEW = renameQueue->getWire(0);
238}
239
240template <class Impl>
241void
242DefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
243{
244 decodeQueue = dq_ptr;
245
246 // Setup wire to get information from decode.
247 fromDecode = decodeQueue->getWire(-decodeToRenameDelay);
248}
249
250template <class Impl>
251void
252DefaultRename<Impl>::startupStage()
253{
254 resetStage();
255}
256
257template <class Impl>
258void
259DefaultRename<Impl>::resetStage()
260{
261 _status = Inactive;
262
263 resumeSerialize = false;
264 resumeUnblocking = false;
265
266 // Grab the number of free entries directly from the stages.
267 for (ThreadID tid = 0; tid < numThreads; tid++) {
268 renameStatus[tid] = Idle;
269
270 freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
271 freeEntries[tid].lqEntries = iew_ptr->ldstQueue.numFreeLoadEntries(tid);
272 freeEntries[tid].sqEntries = iew_ptr->ldstQueue.numFreeStoreEntries(tid);
273 freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
274 emptyROB[tid] = true;
275
276 stalls[tid].iew = false;
277 serializeInst[tid] = NULL;
278
279 instsInProgress[tid] = 0;
280 loadsInProgress[tid] = 0;
281 storesInProgress[tid] = 0;
282
283 serializeOnNextInst[tid] = false;
284 }
285}
286
287template<class Impl>
288void
289DefaultRename<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
290{
291 activeThreads = at_ptr;
292}
293
294
295template <class Impl>
296void
297DefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[])
298{
299 for (ThreadID tid = 0; tid < numThreads; tid++)
300 renameMap[tid] = &rm_ptr[tid];
301}
302
303template <class Impl>
304void
305DefaultRename<Impl>::setFreeList(FreeList *fl_ptr)
306{
307 freeList = fl_ptr;
308}
309
310template<class Impl>
311void
312DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
313{
314 scoreboard = _scoreboard;
315}
316
317template <class Impl>
318bool
319DefaultRename<Impl>::isDrained() const
320{
321 for (ThreadID tid = 0; tid < numThreads; tid++) {
322 if (instsInProgress[tid] != 0 ||
323 !historyBuffer[tid].empty() ||
324 !skidBuffer[tid].empty() ||
325 !insts[tid].empty() ||
326 (renameStatus[tid] != Idle && renameStatus[tid] != Running))
327 return false;
328 }
329 return true;
330}
331
332template <class Impl>
333void
334DefaultRename<Impl>::takeOverFrom()
335{
336 resetStage();
337}
338
339template <class Impl>
340void
341DefaultRename<Impl>::drainSanityCheck() const
342{
343 for (ThreadID tid = 0; tid < numThreads; tid++) {
344 assert(historyBuffer[tid].empty());
345 assert(insts[tid].empty());
346 assert(skidBuffer[tid].empty());
347 assert(instsInProgress[tid] == 0);
348 }
349}
350
351template <class Impl>
352void
353DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, ThreadID tid)
354{
355 DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid);
356
357 // Clear the stall signal if rename was blocked or unblocking before.
358 // If it still needs to block, the blocking should happen the next
359 // cycle and there should be space to hold everything due to the squash.
360 if (renameStatus[tid] == Blocked ||
361 renameStatus[tid] == Unblocking) {
362 toDecode->renameUnblock[tid] = 1;
363
364 resumeSerialize = false;
365 serializeInst[tid] = NULL;
366 } else if (renameStatus[tid] == SerializeStall) {
367 if (serializeInst[tid]->seqNum <= squash_seq_num) {
368 DPRINTF(Rename, "Rename will resume serializing after squash\n");
369 resumeSerialize = true;
370 assert(serializeInst[tid]);
371 } else {
372 resumeSerialize = false;
373 toDecode->renameUnblock[tid] = 1;
374
375 serializeInst[tid] = NULL;
376 }
377 }
378
379 // Set the status to Squashing.
380 renameStatus[tid] = Squashing;
381
382 // Squash any instructions from decode.
383 for (int i=0; i<fromDecode->size; i++) {
384 if (fromDecode->insts[i]->threadNumber == tid &&
385 fromDecode->insts[i]->seqNum > squash_seq_num) {
386 fromDecode->insts[i]->setSquashed();
387 wroteToTimeBuffer = true;
388 }
389
390 }
391
392 // Clear the instruction list and skid buffer in case they have any
393 // insts in them.
394 insts[tid].clear();
395
396 // Clear the skid buffer in case it has any data in it.
397 skidBuffer[tid].clear();
398
399 doSquash(squash_seq_num, tid);
400}
401
402template <class Impl>
403void
404DefaultRename<Impl>::tick()
405{
406 wroteToTimeBuffer = false;
407
408 blockThisCycle = false;
409
410 bool status_change = false;
411
412 toIEWIndex = 0;
413
414 sortInsts();
415
416 list<ThreadID>::iterator threads = activeThreads->begin();
417 list<ThreadID>::iterator end = activeThreads->end();
418
419 // Check stall and squash signals.
420 while (threads != end) {
421 ThreadID tid = *threads++;
422
423 DPRINTF(Rename, "Processing [tid:%i]\n", tid);
424
425 status_change = checkSignalsAndUpdate(tid) || status_change;
426
427 rename(status_change, tid);
428 }
429
430 if (status_change) {
431 updateStatus();
432 }
433
434 if (wroteToTimeBuffer) {
435 DPRINTF(Activity, "Activity this cycle.\n");
436 cpu->activityThisCycle();
437 }
438
439 threads = activeThreads->begin();
440
441 while (threads != end) {
442 ThreadID tid = *threads++;
443
444 // If we committed this cycle then doneSeqNum will be > 0
445 if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
446 !fromCommit->commitInfo[tid].squash &&
447 renameStatus[tid] != Squashing) {
448
449 removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,
450 tid);
451 }
452 }
453
454 // @todo: make into updateProgress function
455 for (ThreadID tid = 0; tid < numThreads; tid++) {
456 instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
457 loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ;
458 storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ;
459 assert(loadsInProgress[tid] >= 0);
460 assert(storesInProgress[tid] >= 0);
461 assert(instsInProgress[tid] >=0);
462 }
463
464}
465
466template<class Impl>
467void
468DefaultRename<Impl>::rename(bool &status_change, ThreadID tid)
469{
470 // If status is Running or idle,
471 // call renameInsts()
472 // If status is Unblocking,
473 // buffer any instructions coming from decode
474 // continue trying to empty skid buffer
475 // check if stall conditions have passed
476
477 if (renameStatus[tid] == Blocked) {
478 ++renameBlockCycles;
479 } else if (renameStatus[tid] == Squashing) {
480 ++renameSquashCycles;
481 } else if (renameStatus[tid] == SerializeStall) {
482 ++renameSerializeStallCycles;
483 // If we are currently in SerializeStall and resumeSerialize
484 // was set, then that means that we are resuming serializing
485 // this cycle. Tell the previous stages to block.
486 if (resumeSerialize) {
487 resumeSerialize = false;
488 block(tid);
489 toDecode->renameUnblock[tid] = false;
490 }
491 } else if (renameStatus[tid] == Unblocking) {
492 if (resumeUnblocking) {
493 block(tid);
494 resumeUnblocking = false;
495 toDecode->renameUnblock[tid] = false;
496 }
497 }
498
499 if (renameStatus[tid] == Running ||
500 renameStatus[tid] == Idle) {
501 DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run "
502 "stage.\n", tid);
503
504 renameInsts(tid);
505 } else if (renameStatus[tid] == Unblocking) {
506 renameInsts(tid);
507
508 if (validInsts()) {
509 // Add the current inputs to the skid buffer so they can be
510 // reprocessed when this stage unblocks.
511 skidInsert(tid);
512 }
513
514 // If we switched over to blocking, then there's a potential for
515 // an overall status change.
516 status_change = unblock(tid) || status_change || blockThisCycle;
517 }
518}
519
520template <class Impl>
521void
522DefaultRename<Impl>::renameInsts(ThreadID tid)
523{
524 // Instructions can be either in the skid buffer or the queue of
525 // instructions coming from decode, depending on the status.
526 int insts_available = renameStatus[tid] == Unblocking ?
527 skidBuffer[tid].size() : insts[tid].size();
528
529 // Check the decode queue to see if instructions are available.
530 // If there are no available instructions to rename, then do nothing.
531 if (insts_available == 0) {
532 DPRINTF(Rename, "[tid:%u]: Nothing to do, breaking out early.\n",
533 tid);
534 // Should I change status to idle?
535 ++renameIdleCycles;
536 return;
537 } else if (renameStatus[tid] == Unblocking) {
538 ++renameUnblockCycles;
539 } else if (renameStatus[tid] == Running) {
540 ++renameRunCycles;
541 }
542
543 // Will have to do a different calculation for the number of free
544 // entries.
545 int free_rob_entries = calcFreeROBEntries(tid);
546 int free_iq_entries = calcFreeIQEntries(tid);
547 int min_free_entries = free_rob_entries;
548
549 FullSource source = ROB;
550
551 if (free_iq_entries < min_free_entries) {
552 min_free_entries = free_iq_entries;
553 source = IQ;
554 }
555
556 // Check if there's any space left.
557 if (min_free_entries <= 0) {
558 DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/ "
559 "entries.\n"
560 "ROB has %i free entries.\n"
561 "IQ has %i free entries.\n",
562 tid,
563 free_rob_entries,
564 free_iq_entries);
565
566 blockThisCycle = true;
567
568 block(tid);
569
570 incrFullStat(source);
571
572 return;
573 } else if (min_free_entries < insts_available) {
574 DPRINTF(Rename, "[tid:%u]: Will have to block this cycle."
575 "%i insts available, but only %i insts can be "
576 "renamed due to ROB/IQ/LSQ limits.\n",
577 tid, insts_available, min_free_entries);
578
579 insts_available = min_free_entries;
580
581 blockThisCycle = true;
582
583 incrFullStat(source);
584 }
585
586 InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ?
587 skidBuffer[tid] : insts[tid];
588
589 DPRINTF(Rename, "[tid:%u]: %i available instructions to "
590 "send iew.\n", tid, insts_available);
591
592 DPRINTF(Rename, "[tid:%u]: %i insts pipelining from Rename | %i insts "
593 "dispatched to IQ last cycle.\n",
594 tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched);
595
596 // Handle serializing the next instruction if necessary.
597 if (serializeOnNextInst[tid]) {
598 if (emptyROB[tid] && instsInProgress[tid] == 0) {
599 // ROB already empty; no need to serialize.
600 serializeOnNextInst[tid] = false;
601 } else if (!insts_to_rename.empty()) {
602 insts_to_rename.front()->setSerializeBefore();
603 }
604 }
605
606 int renamed_insts = 0;
607
608 while (insts_available > 0 && toIEWIndex < renameWidth) {
609 DPRINTF(Rename, "[tid:%u]: Sending instructions to IEW.\n", tid);
610
611 assert(!insts_to_rename.empty());
612
613 DynInstPtr inst = insts_to_rename.front();
614
615 //For all kind of instructions, check ROB and IQ first
616 //For load instruction, check LQ size and take into account the inflight loads
617 //For store instruction, check SQ size and take into account the inflight stores
618
619 if (inst->isLoad()) {
620 if (calcFreeLQEntries(tid) <= 0) {
621 DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free LQ\n");
622 source = LQ;
623 incrFullStat(source);
624 break;
625 }
626 }
627
628 if (inst->isStore()) {
629 if (calcFreeSQEntries(tid) <= 0) {
630 DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free SQ\n");
631 source = SQ;
632 incrFullStat(source);
633 break;
634 }
635 }
636
637 insts_to_rename.pop_front();
638
639 if (renameStatus[tid] == Unblocking) {
640 DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%s from rename "
641 "skidBuffer\n", tid, inst->seqNum, inst->pcState());
642 }
643
644 if (inst->isSquashed()) {
645 DPRINTF(Rename, "[tid:%u]: instruction %i with PC %s is "
646 "squashed, skipping.\n", tid, inst->seqNum,
647 inst->pcState());
648
649 ++renameSquashedInsts;
650
651 // Decrement how many instructions are available.
652 --insts_available;
653
654 continue;
655 }
656
657 DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
658 "PC %s.\n", tid, inst->seqNum, inst->pcState());
659
660 // Check here to make sure there are enough destination registers
661 // to rename to. Otherwise block.
662 if (!renameMap[tid]->canRename(inst->numIntDestRegs(),
663 inst->numFPDestRegs(),
664 inst->numVecDestRegs(),
665 inst->numVecElemDestRegs(),
666 inst->numVecPredDestRegs(),
662 inst->numCCDestRegs())) {
663 DPRINTF(Rename, "Blocking due to lack of free "
664 "physical registers to rename to.\n");
665 blockThisCycle = true;
666 insts_to_rename.push_front(inst);
667 ++renameFullRegistersEvents;
668
669 break;
670 }
671
672 // Handle serializeAfter/serializeBefore instructions.
673 // serializeAfter marks the next instruction as serializeBefore.
674 // serializeBefore makes the instruction wait in rename until the ROB
675 // is empty.
676
677 // In this model, IPR accesses are serialize before
678 // instructions, and store conditionals are serialize after
679 // instructions. This is mainly due to lack of support for
680 // out-of-order operations of either of those classes of
681 // instructions.
682 if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
683 !inst->isSerializeHandled()) {
684 DPRINTF(Rename, "Serialize before instruction encountered.\n");
685
686 if (!inst->isTempSerializeBefore()) {
687 renamedSerializing++;
688 inst->setSerializeHandled();
689 } else {
690 renamedTempSerializing++;
691 }
692
693 // Change status over to SerializeStall so that other stages know
694 // what this is blocked on.
695 renameStatus[tid] = SerializeStall;
696
697 serializeInst[tid] = inst;
698
699 blockThisCycle = true;
700
701 break;
702 } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
703 !inst->isSerializeHandled()) {
704 DPRINTF(Rename, "Serialize after instruction encountered.\n");
705
706 renamedSerializing++;
707
708 inst->setSerializeHandled();
709
710 serializeAfter(insts_to_rename, tid);
711 }
712
713 renameSrcRegs(inst, inst->threadNumber);
714
715 renameDestRegs(inst, inst->threadNumber);
716
717 if (inst->isLoad()) {
718 loadsInProgress[tid]++;
719 }
720 if (inst->isStore()) {
721 storesInProgress[tid]++;
722 }
723 ++renamed_insts;
724 // Notify potential listeners that source and destination registers for
725 // this instruction have been renamed.
726 ppRename->notify(inst);
727
728 // Put instruction in rename queue.
729 toIEW->insts[toIEWIndex] = inst;
730 ++(toIEW->size);
731
732 // Increment which instruction we're on.
733 ++toIEWIndex;
734
735 // Decrement how many instructions are available.
736 --insts_available;
737 }
738
739 instsInProgress[tid] += renamed_insts;
740 renameRenamedInsts += renamed_insts;
741
742 // If we wrote to the time buffer, record this.
743 if (toIEWIndex) {
744 wroteToTimeBuffer = true;
745 }
746
747 // Check if there's any instructions left that haven't yet been renamed.
748 // If so then block.
749 if (insts_available) {
750 blockThisCycle = true;
751 }
752
753 if (blockThisCycle) {
754 block(tid);
755 toDecode->renameUnblock[tid] = false;
756 }
757}
758
759template<class Impl>
760void
761DefaultRename<Impl>::skidInsert(ThreadID tid)
762{
763 DynInstPtr inst = NULL;
764
765 while (!insts[tid].empty()) {
766 inst = insts[tid].front();
767
768 insts[tid].pop_front();
769
770 assert(tid == inst->threadNumber);
771
772 DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC: %s into Rename "
773 "skidBuffer\n", tid, inst->seqNum, inst->pcState());
774
775 ++renameSkidInsts;
776
777 skidBuffer[tid].push_back(inst);
778 }
779
780 if (skidBuffer[tid].size() > skidBufferMax)
781 {
782 typename InstQueue::iterator it;
783 warn("Skidbuffer contents:\n");
784 for (it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++)
785 {
786 warn("[tid:%u]: %s [sn:%i].\n", tid,
787 (*it)->staticInst->disassemble(inst->instAddr()),
788 (*it)->seqNum);
789 }
790 panic("Skidbuffer Exceeded Max Size");
791 }
792}
793
794template <class Impl>
795void
796DefaultRename<Impl>::sortInsts()
797{
798 int insts_from_decode = fromDecode->size;
799 for (int i = 0; i < insts_from_decode; ++i) {
800 const DynInstPtr &inst = fromDecode->insts[i];
801 insts[inst->threadNumber].push_back(inst);
802#if TRACING_ON
803 if (DTRACE(O3PipeView)) {
804 inst->renameTick = curTick() - inst->fetchTick;
805 }
806#endif
807 }
808}
809
810template<class Impl>
811bool
812DefaultRename<Impl>::skidsEmpty()
813{
814 list<ThreadID>::iterator threads = activeThreads->begin();
815 list<ThreadID>::iterator end = activeThreads->end();
816
817 while (threads != end) {
818 ThreadID tid = *threads++;
819
820 if (!skidBuffer[tid].empty())
821 return false;
822 }
823
824 return true;
825}
826
827template<class Impl>
828void
829DefaultRename<Impl>::updateStatus()
830{
831 bool any_unblocking = false;
832
833 list<ThreadID>::iterator threads = activeThreads->begin();
834 list<ThreadID>::iterator end = activeThreads->end();
835
836 while (threads != end) {
837 ThreadID tid = *threads++;
838
839 if (renameStatus[tid] == Unblocking) {
840 any_unblocking = true;
841 break;
842 }
843 }
844
845 // Rename will have activity if it's unblocking.
846 if (any_unblocking) {
847 if (_status == Inactive) {
848 _status = Active;
849
850 DPRINTF(Activity, "Activating stage.\n");
851
852 cpu->activateStage(O3CPU::RenameIdx);
853 }
854 } else {
855 // If it's not unblocking, then rename will not have any internal
856 // activity. Switch it to inactive.
857 if (_status == Active) {
858 _status = Inactive;
859 DPRINTF(Activity, "Deactivating stage.\n");
860
861 cpu->deactivateStage(O3CPU::RenameIdx);
862 }
863 }
864}
865
866template <class Impl>
867bool
868DefaultRename<Impl>::block(ThreadID tid)
869{
870 DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid);
871
872 // Add the current inputs onto the skid buffer, so they can be
873 // reprocessed when this stage unblocks.
874 skidInsert(tid);
875
876 // Only signal backwards to block if the previous stages do not think
877 // rename is already blocked.
878 if (renameStatus[tid] != Blocked) {
879 // If resumeUnblocking is set, we unblocked during the squash,
880 // but now we're have unblocking status. We need to tell earlier
881 // stages to block.
882 if (resumeUnblocking || renameStatus[tid] != Unblocking) {
883 toDecode->renameBlock[tid] = true;
884 toDecode->renameUnblock[tid] = false;
885 wroteToTimeBuffer = true;
886 }
887
888 // Rename can not go from SerializeStall to Blocked, otherwise
889 // it would not know to complete the serialize stall.
890 if (renameStatus[tid] != SerializeStall) {
891 // Set status to Blocked.
892 renameStatus[tid] = Blocked;
893 return true;
894 }
895 }
896
897 return false;
898}
899
900template <class Impl>
901bool
902DefaultRename<Impl>::unblock(ThreadID tid)
903{
904 DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid);
905
906 // Rename is done unblocking if the skid buffer is empty.
907 if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
908
909 DPRINTF(Rename, "[tid:%u]: Done unblocking.\n", tid);
910
911 toDecode->renameUnblock[tid] = true;
912 wroteToTimeBuffer = true;
913
914 renameStatus[tid] = Running;
915 return true;
916 }
917
918 return false;
919}
920
921template <class Impl>
922void
923DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
924{
925 typename std::list<RenameHistory>::iterator hb_it =
926 historyBuffer[tid].begin();
927
928 // After a syscall squashes everything, the history buffer may be empty
929 // but the ROB may still be squashing instructions.
930 // Go through the most recent instructions, undoing the mappings
931 // they did and freeing up the registers.
932 while (!historyBuffer[tid].empty() &&
933 hb_it->instSeqNum > squashed_seq_num) {
934 assert(hb_it != historyBuffer[tid].end());
935
936 DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
937 "number %i.\n", tid, hb_it->instSeqNum);
938
939 // Undo the rename mapping only if it was really a change.
940 // Special regs that are not really renamed (like misc regs
941 // and the zero reg) can be recognized because the new mapping
942 // is the same as the old one. While it would be merely a
943 // waste of time to update the rename table, we definitely
944 // don't want to put these on the free list.
945 if (hb_it->newPhysReg != hb_it->prevPhysReg) {
946 // Tell the rename map to set the architected register to the
947 // previous physical register that it was renamed to.
948 renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
949
950 // Put the renamed physical register back on the free list.
951 freeList->addReg(hb_it->newPhysReg);
952 }
953
954 // Notify potential listeners that the register mapping needs to be
955 // removed because the instruction it was mapped to got squashed. Note
956 // that this is done before hb_it is incremented.
957 ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum,
958 hb_it->newPhysReg));
959
960 historyBuffer[tid].erase(hb_it++);
961
962 ++renameUndoneMaps;
963 }
964
965 // Check if we need to change vector renaming mode after squashing
966 cpu->switchRenameMode(tid, freeList);
967}
968
969template<class Impl>
970void
971DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
972{
973 DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the "
974 "history buffer %u (size=%i), until [sn:%lli].\n",
975 tid, tid, historyBuffer[tid].size(), inst_seq_num);
976
977 typename std::list<RenameHistory>::iterator hb_it =
978 historyBuffer[tid].end();
979
980 --hb_it;
981
982 if (historyBuffer[tid].empty()) {
983 DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid);
984 return;
985 } else if (hb_it->instSeqNum > inst_seq_num) {
986 DPRINTF(Rename, "[tid:%u]: Old sequence number encountered. Ensure "
987 "that a syscall happened recently.\n", tid);
988 return;
989 }
990
991 // Commit all the renames up until (and including) the committed sequence
992 // number. Some or even all of the committed instructions may not have
993 // rename histories if they did not have destination registers that were
994 // renamed.
995 while (!historyBuffer[tid].empty() &&
996 hb_it != historyBuffer[tid].end() &&
997 hb_it->instSeqNum <= inst_seq_num) {
998
999 DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i (%s), "
1000 "[sn:%lli].\n",
1001 tid, hb_it->prevPhysReg->index(),
1002 hb_it->prevPhysReg->className(),
1003 hb_it->instSeqNum);
1004
1005 // Don't free special phys regs like misc and zero regs, which
1006 // can be recognized because the new mapping is the same as
1007 // the old one.
1008 if (hb_it->newPhysReg != hb_it->prevPhysReg) {
1009 freeList->addReg(hb_it->prevPhysReg);
1010 }
1011
1012 ++renameCommittedMaps;
1013
1014 historyBuffer[tid].erase(hb_it--);
1015 }
1016}
1017
1018template <class Impl>
1019inline void
1020DefaultRename<Impl>::renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
1021{
1022 ThreadContext *tc = inst->tcBase();
1023 RenameMap *map = renameMap[tid];
1024 unsigned num_src_regs = inst->numSrcRegs();
1025
1026 // Get the architectual register numbers from the source and
1027 // operands, and redirect them to the right physical register.
1028 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
1029 const RegId& src_reg = inst->srcRegIdx(src_idx);
1030 PhysRegIdPtr renamed_reg;
1031
1032 renamed_reg = map->lookup(tc->flattenRegId(src_reg));
1033 switch (src_reg.classValue()) {
1034 case IntRegClass:
1035 intRenameLookups++;
1036 break;
1037 case FloatRegClass:
1038 fpRenameLookups++;
1039 break;
1040 case VecRegClass:
1041 case VecElemClass:
1042 vecRenameLookups++;
1043 break;
667 inst->numCCDestRegs())) {
668 DPRINTF(Rename, "Blocking due to lack of free "
669 "physical registers to rename to.\n");
670 blockThisCycle = true;
671 insts_to_rename.push_front(inst);
672 ++renameFullRegistersEvents;
673
674 break;
675 }
676
677 // Handle serializeAfter/serializeBefore instructions.
678 // serializeAfter marks the next instruction as serializeBefore.
679 // serializeBefore makes the instruction wait in rename until the ROB
680 // is empty.
681
682 // In this model, IPR accesses are serialize before
683 // instructions, and store conditionals are serialize after
684 // instructions. This is mainly due to lack of support for
685 // out-of-order operations of either of those classes of
686 // instructions.
687 if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
688 !inst->isSerializeHandled()) {
689 DPRINTF(Rename, "Serialize before instruction encountered.\n");
690
691 if (!inst->isTempSerializeBefore()) {
692 renamedSerializing++;
693 inst->setSerializeHandled();
694 } else {
695 renamedTempSerializing++;
696 }
697
698 // Change status over to SerializeStall so that other stages know
699 // what this is blocked on.
700 renameStatus[tid] = SerializeStall;
701
702 serializeInst[tid] = inst;
703
704 blockThisCycle = true;
705
706 break;
707 } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
708 !inst->isSerializeHandled()) {
709 DPRINTF(Rename, "Serialize after instruction encountered.\n");
710
711 renamedSerializing++;
712
713 inst->setSerializeHandled();
714
715 serializeAfter(insts_to_rename, tid);
716 }
717
718 renameSrcRegs(inst, inst->threadNumber);
719
720 renameDestRegs(inst, inst->threadNumber);
721
722 if (inst->isLoad()) {
723 loadsInProgress[tid]++;
724 }
725 if (inst->isStore()) {
726 storesInProgress[tid]++;
727 }
728 ++renamed_insts;
729 // Notify potential listeners that source and destination registers for
730 // this instruction have been renamed.
731 ppRename->notify(inst);
732
733 // Put instruction in rename queue.
734 toIEW->insts[toIEWIndex] = inst;
735 ++(toIEW->size);
736
737 // Increment which instruction we're on.
738 ++toIEWIndex;
739
740 // Decrement how many instructions are available.
741 --insts_available;
742 }
743
744 instsInProgress[tid] += renamed_insts;
745 renameRenamedInsts += renamed_insts;
746
747 // If we wrote to the time buffer, record this.
748 if (toIEWIndex) {
749 wroteToTimeBuffer = true;
750 }
751
752 // Check if there's any instructions left that haven't yet been renamed.
753 // If so then block.
754 if (insts_available) {
755 blockThisCycle = true;
756 }
757
758 if (blockThisCycle) {
759 block(tid);
760 toDecode->renameUnblock[tid] = false;
761 }
762}
763
764template<class Impl>
765void
766DefaultRename<Impl>::skidInsert(ThreadID tid)
767{
768 DynInstPtr inst = NULL;
769
770 while (!insts[tid].empty()) {
771 inst = insts[tid].front();
772
773 insts[tid].pop_front();
774
775 assert(tid == inst->threadNumber);
776
777 DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC: %s into Rename "
778 "skidBuffer\n", tid, inst->seqNum, inst->pcState());
779
780 ++renameSkidInsts;
781
782 skidBuffer[tid].push_back(inst);
783 }
784
785 if (skidBuffer[tid].size() > skidBufferMax)
786 {
787 typename InstQueue::iterator it;
788 warn("Skidbuffer contents:\n");
789 for (it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++)
790 {
791 warn("[tid:%u]: %s [sn:%i].\n", tid,
792 (*it)->staticInst->disassemble(inst->instAddr()),
793 (*it)->seqNum);
794 }
795 panic("Skidbuffer Exceeded Max Size");
796 }
797}
798
799template <class Impl>
800void
801DefaultRename<Impl>::sortInsts()
802{
803 int insts_from_decode = fromDecode->size;
804 for (int i = 0; i < insts_from_decode; ++i) {
805 const DynInstPtr &inst = fromDecode->insts[i];
806 insts[inst->threadNumber].push_back(inst);
807#if TRACING_ON
808 if (DTRACE(O3PipeView)) {
809 inst->renameTick = curTick() - inst->fetchTick;
810 }
811#endif
812 }
813}
814
815template<class Impl>
816bool
817DefaultRename<Impl>::skidsEmpty()
818{
819 list<ThreadID>::iterator threads = activeThreads->begin();
820 list<ThreadID>::iterator end = activeThreads->end();
821
822 while (threads != end) {
823 ThreadID tid = *threads++;
824
825 if (!skidBuffer[tid].empty())
826 return false;
827 }
828
829 return true;
830}
831
832template<class Impl>
833void
834DefaultRename<Impl>::updateStatus()
835{
836 bool any_unblocking = false;
837
838 list<ThreadID>::iterator threads = activeThreads->begin();
839 list<ThreadID>::iterator end = activeThreads->end();
840
841 while (threads != end) {
842 ThreadID tid = *threads++;
843
844 if (renameStatus[tid] == Unblocking) {
845 any_unblocking = true;
846 break;
847 }
848 }
849
850 // Rename will have activity if it's unblocking.
851 if (any_unblocking) {
852 if (_status == Inactive) {
853 _status = Active;
854
855 DPRINTF(Activity, "Activating stage.\n");
856
857 cpu->activateStage(O3CPU::RenameIdx);
858 }
859 } else {
860 // If it's not unblocking, then rename will not have any internal
861 // activity. Switch it to inactive.
862 if (_status == Active) {
863 _status = Inactive;
864 DPRINTF(Activity, "Deactivating stage.\n");
865
866 cpu->deactivateStage(O3CPU::RenameIdx);
867 }
868 }
869}
870
871template <class Impl>
872bool
873DefaultRename<Impl>::block(ThreadID tid)
874{
875 DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid);
876
877 // Add the current inputs onto the skid buffer, so they can be
878 // reprocessed when this stage unblocks.
879 skidInsert(tid);
880
881 // Only signal backwards to block if the previous stages do not think
882 // rename is already blocked.
883 if (renameStatus[tid] != Blocked) {
884 // If resumeUnblocking is set, we unblocked during the squash,
885 // but now we're have unblocking status. We need to tell earlier
886 // stages to block.
887 if (resumeUnblocking || renameStatus[tid] != Unblocking) {
888 toDecode->renameBlock[tid] = true;
889 toDecode->renameUnblock[tid] = false;
890 wroteToTimeBuffer = true;
891 }
892
893 // Rename can not go from SerializeStall to Blocked, otherwise
894 // it would not know to complete the serialize stall.
895 if (renameStatus[tid] != SerializeStall) {
896 // Set status to Blocked.
897 renameStatus[tid] = Blocked;
898 return true;
899 }
900 }
901
902 return false;
903}
904
905template <class Impl>
906bool
907DefaultRename<Impl>::unblock(ThreadID tid)
908{
909 DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid);
910
911 // Rename is done unblocking if the skid buffer is empty.
912 if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
913
914 DPRINTF(Rename, "[tid:%u]: Done unblocking.\n", tid);
915
916 toDecode->renameUnblock[tid] = true;
917 wroteToTimeBuffer = true;
918
919 renameStatus[tid] = Running;
920 return true;
921 }
922
923 return false;
924}
925
926template <class Impl>
927void
928DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
929{
930 typename std::list<RenameHistory>::iterator hb_it =
931 historyBuffer[tid].begin();
932
933 // After a syscall squashes everything, the history buffer may be empty
934 // but the ROB may still be squashing instructions.
935 // Go through the most recent instructions, undoing the mappings
936 // they did and freeing up the registers.
937 while (!historyBuffer[tid].empty() &&
938 hb_it->instSeqNum > squashed_seq_num) {
939 assert(hb_it != historyBuffer[tid].end());
940
941 DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
942 "number %i.\n", tid, hb_it->instSeqNum);
943
944 // Undo the rename mapping only if it was really a change.
945 // Special regs that are not really renamed (like misc regs
946 // and the zero reg) can be recognized because the new mapping
947 // is the same as the old one. While it would be merely a
948 // waste of time to update the rename table, we definitely
949 // don't want to put these on the free list.
950 if (hb_it->newPhysReg != hb_it->prevPhysReg) {
951 // Tell the rename map to set the architected register to the
952 // previous physical register that it was renamed to.
953 renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
954
955 // Put the renamed physical register back on the free list.
956 freeList->addReg(hb_it->newPhysReg);
957 }
958
959 // Notify potential listeners that the register mapping needs to be
960 // removed because the instruction it was mapped to got squashed. Note
961 // that this is done before hb_it is incremented.
962 ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum,
963 hb_it->newPhysReg));
964
965 historyBuffer[tid].erase(hb_it++);
966
967 ++renameUndoneMaps;
968 }
969
970 // Check if we need to change vector renaming mode after squashing
971 cpu->switchRenameMode(tid, freeList);
972}
973
974template<class Impl>
975void
976DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
977{
978 DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the "
979 "history buffer %u (size=%i), until [sn:%lli].\n",
980 tid, tid, historyBuffer[tid].size(), inst_seq_num);
981
982 typename std::list<RenameHistory>::iterator hb_it =
983 historyBuffer[tid].end();
984
985 --hb_it;
986
987 if (historyBuffer[tid].empty()) {
988 DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid);
989 return;
990 } else if (hb_it->instSeqNum > inst_seq_num) {
991 DPRINTF(Rename, "[tid:%u]: Old sequence number encountered. Ensure "
992 "that a syscall happened recently.\n", tid);
993 return;
994 }
995
996 // Commit all the renames up until (and including) the committed sequence
997 // number. Some or even all of the committed instructions may not have
998 // rename histories if they did not have destination registers that were
999 // renamed.
1000 while (!historyBuffer[tid].empty() &&
1001 hb_it != historyBuffer[tid].end() &&
1002 hb_it->instSeqNum <= inst_seq_num) {
1003
1004 DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i (%s), "
1005 "[sn:%lli].\n",
1006 tid, hb_it->prevPhysReg->index(),
1007 hb_it->prevPhysReg->className(),
1008 hb_it->instSeqNum);
1009
1010 // Don't free special phys regs like misc and zero regs, which
1011 // can be recognized because the new mapping is the same as
1012 // the old one.
1013 if (hb_it->newPhysReg != hb_it->prevPhysReg) {
1014 freeList->addReg(hb_it->prevPhysReg);
1015 }
1016
1017 ++renameCommittedMaps;
1018
1019 historyBuffer[tid].erase(hb_it--);
1020 }
1021}
1022
1023template <class Impl>
1024inline void
1025DefaultRename<Impl>::renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
1026{
1027 ThreadContext *tc = inst->tcBase();
1028 RenameMap *map = renameMap[tid];
1029 unsigned num_src_regs = inst->numSrcRegs();
1030
1031 // Get the architectual register numbers from the source and
1032 // operands, and redirect them to the right physical register.
1033 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
1034 const RegId& src_reg = inst->srcRegIdx(src_idx);
1035 PhysRegIdPtr renamed_reg;
1036
1037 renamed_reg = map->lookup(tc->flattenRegId(src_reg));
1038 switch (src_reg.classValue()) {
1039 case IntRegClass:
1040 intRenameLookups++;
1041 break;
1042 case FloatRegClass:
1043 fpRenameLookups++;
1044 break;
1045 case VecRegClass:
1046 case VecElemClass:
1047 vecRenameLookups++;
1048 break;
1049 case VecPredRegClass:
1050 vecPredRenameLookups++;
1051 break;
1044 case CCRegClass:
1045 case MiscRegClass:
1046 break;
1047
1048 default:
1049 panic("Invalid register class: %d.", src_reg.classValue());
1050 }
1051
1052 DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i"
1053 ", got phys reg %i (%s)\n", tid,
1054 src_reg.className(), src_reg.index(),
1055 renamed_reg->index(),
1056 renamed_reg->className());
1057
1058 inst->renameSrcReg(src_idx, renamed_reg);
1059
1060 // See if the register is ready or not.
1061 if (scoreboard->getReg(renamed_reg)) {
1062 DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)"
1063 " is ready.\n", tid, renamed_reg->index(),
1064 renamed_reg->flatIndex(),
1065 renamed_reg->className());
1066
1067 inst->markSrcRegReady(src_idx);
1068 } else {
1069 DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)"
1070 " is not ready.\n", tid, renamed_reg->index(),
1071 renamed_reg->flatIndex(),
1072 renamed_reg->className());
1073 }
1074
1075 ++renameRenameLookups;
1076 }
1077}
1078
1079template <class Impl>
1080inline void
1081DefaultRename<Impl>::renameDestRegs(const DynInstPtr &inst, ThreadID tid)
1082{
1083 ThreadContext *tc = inst->tcBase();
1084 RenameMap *map = renameMap[tid];
1085 unsigned num_dest_regs = inst->numDestRegs();
1086
1087 // Rename the destination registers.
1088 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
1089 const RegId& dest_reg = inst->destRegIdx(dest_idx);
1090 typename RenameMap::RenameInfo rename_result;
1091
1092 RegId flat_dest_regid = tc->flattenRegId(dest_reg);
1093
1094 rename_result = map->rename(flat_dest_regid);
1095
1096 inst->flattenDestReg(dest_idx, flat_dest_regid);
1097
1098 // Mark Scoreboard entry as not ready
1099 scoreboard->unsetReg(rename_result.first);
1100
1101 DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i (%s) to physical "
1102 "reg %i (%i).\n", tid, dest_reg.index(),
1103 dest_reg.className(),
1104 rename_result.first->index(),
1105 rename_result.first->flatIndex());
1106
1107 // Record the rename information so that a history can be kept.
1108 RenameHistory hb_entry(inst->seqNum, flat_dest_regid,
1109 rename_result.first,
1110 rename_result.second);
1111
1112 historyBuffer[tid].push_front(hb_entry);
1113
1114 DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer "
1115 "(size=%i), [sn:%lli].\n",tid,
1116 historyBuffer[tid].size(),
1117 (*historyBuffer[tid].begin()).instSeqNum);
1118
1119 // Tell the instruction to rename the appropriate destination
1120 // register (dest_idx) to the new physical register
1121 // (rename_result.first), and record the previous physical
1122 // register that the same logical register was renamed to
1123 // (rename_result.second).
1124 inst->renameDestReg(dest_idx,
1125 rename_result.first,
1126 rename_result.second);
1127
1128 ++renameRenamedOperands;
1129 }
1130}
1131
1132template <class Impl>
1133inline int
1134DefaultRename<Impl>::calcFreeROBEntries(ThreadID tid)
1135{
1136 int num_free = freeEntries[tid].robEntries -
1137 (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1138
1139 //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free);
1140
1141 return num_free;
1142}
1143
1144template <class Impl>
1145inline int
1146DefaultRename<Impl>::calcFreeIQEntries(ThreadID tid)
1147{
1148 int num_free = freeEntries[tid].iqEntries -
1149 (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1150
1151 //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free);
1152
1153 return num_free;
1154}
1155
1156template <class Impl>
1157inline int
1158DefaultRename<Impl>::calcFreeLQEntries(ThreadID tid)
1159{
1160 int num_free = freeEntries[tid].lqEntries -
1161 (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
1162 DPRINTF(Rename, "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
1163 "loads dispatchedToLQ: %d\n", freeEntries[tid].lqEntries,
1164 loadsInProgress[tid], fromIEW->iewInfo[tid].dispatchedToLQ);
1165 return num_free;
1166}
1167
1168template <class Impl>
1169inline int
1170DefaultRename<Impl>::calcFreeSQEntries(ThreadID tid)
1171{
1172 int num_free = freeEntries[tid].sqEntries -
1173 (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
1174 DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, storesInProgress: %d, "
1175 "stores dispatchedToSQ: %d\n", freeEntries[tid].sqEntries,
1176 storesInProgress[tid], fromIEW->iewInfo[tid].dispatchedToSQ);
1177 return num_free;
1178}
1179
1180template <class Impl>
1181unsigned
1182DefaultRename<Impl>::validInsts()
1183{
1184 unsigned inst_count = 0;
1185
1186 for (int i=0; i<fromDecode->size; i++) {
1187 if (!fromDecode->insts[i]->isSquashed())
1188 inst_count++;
1189 }
1190
1191 return inst_count;
1192}
1193
1194template <class Impl>
1195void
1196DefaultRename<Impl>::readStallSignals(ThreadID tid)
1197{
1198 if (fromIEW->iewBlock[tid]) {
1199 stalls[tid].iew = true;
1200 }
1201
1202 if (fromIEW->iewUnblock[tid]) {
1203 assert(stalls[tid].iew);
1204 stalls[tid].iew = false;
1205 }
1206}
1207
1208template <class Impl>
1209bool
1210DefaultRename<Impl>::checkStall(ThreadID tid)
1211{
1212 bool ret_val = false;
1213
1214 if (stalls[tid].iew) {
1215 DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid);
1216 ret_val = true;
1217 } else if (calcFreeROBEntries(tid) <= 0) {
1218 DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid);
1219 ret_val = true;
1220 } else if (calcFreeIQEntries(tid) <= 0) {
1221 DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid);
1222 ret_val = true;
1223 } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) {
1224 DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid);
1225 ret_val = true;
1226 } else if (renameMap[tid]->numFreeEntries() <= 0) {
1227 DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid);
1228 ret_val = true;
1229 } else if (renameStatus[tid] == SerializeStall &&
1230 (!emptyROB[tid] || instsInProgress[tid])) {
1231 DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not "
1232 "empty.\n",
1233 tid);
1234 ret_val = true;
1235 }
1236
1237 return ret_val;
1238}
1239
1240template <class Impl>
1241void
1242DefaultRename<Impl>::readFreeEntries(ThreadID tid)
1243{
1244 if (fromIEW->iewInfo[tid].usedIQ)
1245 freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries;
1246
1247 if (fromIEW->iewInfo[tid].usedLSQ) {
1248 freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries;
1249 freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries;
1250 }
1251
1252 if (fromCommit->commitInfo[tid].usedROB) {
1253 freeEntries[tid].robEntries =
1254 fromCommit->commitInfo[tid].freeROBEntries;
1255 emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
1256 }
1257
1258 DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, "
1052 case CCRegClass:
1053 case MiscRegClass:
1054 break;
1055
1056 default:
1057 panic("Invalid register class: %d.", src_reg.classValue());
1058 }
1059
1060 DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i"
1061 ", got phys reg %i (%s)\n", tid,
1062 src_reg.className(), src_reg.index(),
1063 renamed_reg->index(),
1064 renamed_reg->className());
1065
1066 inst->renameSrcReg(src_idx, renamed_reg);
1067
1068 // See if the register is ready or not.
1069 if (scoreboard->getReg(renamed_reg)) {
1070 DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)"
1071 " is ready.\n", tid, renamed_reg->index(),
1072 renamed_reg->flatIndex(),
1073 renamed_reg->className());
1074
1075 inst->markSrcRegReady(src_idx);
1076 } else {
1077 DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)"
1078 " is not ready.\n", tid, renamed_reg->index(),
1079 renamed_reg->flatIndex(),
1080 renamed_reg->className());
1081 }
1082
1083 ++renameRenameLookups;
1084 }
1085}
1086
1087template <class Impl>
1088inline void
1089DefaultRename<Impl>::renameDestRegs(const DynInstPtr &inst, ThreadID tid)
1090{
1091 ThreadContext *tc = inst->tcBase();
1092 RenameMap *map = renameMap[tid];
1093 unsigned num_dest_regs = inst->numDestRegs();
1094
1095 // Rename the destination registers.
1096 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
1097 const RegId& dest_reg = inst->destRegIdx(dest_idx);
1098 typename RenameMap::RenameInfo rename_result;
1099
1100 RegId flat_dest_regid = tc->flattenRegId(dest_reg);
1101
1102 rename_result = map->rename(flat_dest_regid);
1103
1104 inst->flattenDestReg(dest_idx, flat_dest_regid);
1105
1106 // Mark Scoreboard entry as not ready
1107 scoreboard->unsetReg(rename_result.first);
1108
1109 DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i (%s) to physical "
1110 "reg %i (%i).\n", tid, dest_reg.index(),
1111 dest_reg.className(),
1112 rename_result.first->index(),
1113 rename_result.first->flatIndex());
1114
1115 // Record the rename information so that a history can be kept.
1116 RenameHistory hb_entry(inst->seqNum, flat_dest_regid,
1117 rename_result.first,
1118 rename_result.second);
1119
1120 historyBuffer[tid].push_front(hb_entry);
1121
1122 DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer "
1123 "(size=%i), [sn:%lli].\n",tid,
1124 historyBuffer[tid].size(),
1125 (*historyBuffer[tid].begin()).instSeqNum);
1126
1127 // Tell the instruction to rename the appropriate destination
1128 // register (dest_idx) to the new physical register
1129 // (rename_result.first), and record the previous physical
1130 // register that the same logical register was renamed to
1131 // (rename_result.second).
1132 inst->renameDestReg(dest_idx,
1133 rename_result.first,
1134 rename_result.second);
1135
1136 ++renameRenamedOperands;
1137 }
1138}
1139
1140template <class Impl>
1141inline int
1142DefaultRename<Impl>::calcFreeROBEntries(ThreadID tid)
1143{
1144 int num_free = freeEntries[tid].robEntries -
1145 (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1146
1147 //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free);
1148
1149 return num_free;
1150}
1151
1152template <class Impl>
1153inline int
1154DefaultRename<Impl>::calcFreeIQEntries(ThreadID tid)
1155{
1156 int num_free = freeEntries[tid].iqEntries -
1157 (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1158
1159 //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free);
1160
1161 return num_free;
1162}
1163
1164template <class Impl>
1165inline int
1166DefaultRename<Impl>::calcFreeLQEntries(ThreadID tid)
1167{
1168 int num_free = freeEntries[tid].lqEntries -
1169 (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
1170 DPRINTF(Rename, "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
1171 "loads dispatchedToLQ: %d\n", freeEntries[tid].lqEntries,
1172 loadsInProgress[tid], fromIEW->iewInfo[tid].dispatchedToLQ);
1173 return num_free;
1174}
1175
1176template <class Impl>
1177inline int
1178DefaultRename<Impl>::calcFreeSQEntries(ThreadID tid)
1179{
1180 int num_free = freeEntries[tid].sqEntries -
1181 (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
1182 DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, storesInProgress: %d, "
1183 "stores dispatchedToSQ: %d\n", freeEntries[tid].sqEntries,
1184 storesInProgress[tid], fromIEW->iewInfo[tid].dispatchedToSQ);
1185 return num_free;
1186}
1187
1188template <class Impl>
1189unsigned
1190DefaultRename<Impl>::validInsts()
1191{
1192 unsigned inst_count = 0;
1193
1194 for (int i=0; i<fromDecode->size; i++) {
1195 if (!fromDecode->insts[i]->isSquashed())
1196 inst_count++;
1197 }
1198
1199 return inst_count;
1200}
1201
1202template <class Impl>
1203void
1204DefaultRename<Impl>::readStallSignals(ThreadID tid)
1205{
1206 if (fromIEW->iewBlock[tid]) {
1207 stalls[tid].iew = true;
1208 }
1209
1210 if (fromIEW->iewUnblock[tid]) {
1211 assert(stalls[tid].iew);
1212 stalls[tid].iew = false;
1213 }
1214}
1215
1216template <class Impl>
1217bool
1218DefaultRename<Impl>::checkStall(ThreadID tid)
1219{
1220 bool ret_val = false;
1221
1222 if (stalls[tid].iew) {
1223 DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid);
1224 ret_val = true;
1225 } else if (calcFreeROBEntries(tid) <= 0) {
1226 DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid);
1227 ret_val = true;
1228 } else if (calcFreeIQEntries(tid) <= 0) {
1229 DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid);
1230 ret_val = true;
1231 } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) {
1232 DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid);
1233 ret_val = true;
1234 } else if (renameMap[tid]->numFreeEntries() <= 0) {
1235 DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid);
1236 ret_val = true;
1237 } else if (renameStatus[tid] == SerializeStall &&
1238 (!emptyROB[tid] || instsInProgress[tid])) {
1239 DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not "
1240 "empty.\n",
1241 tid);
1242 ret_val = true;
1243 }
1244
1245 return ret_val;
1246}
1247
1248template <class Impl>
1249void
1250DefaultRename<Impl>::readFreeEntries(ThreadID tid)
1251{
1252 if (fromIEW->iewInfo[tid].usedIQ)
1253 freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries;
1254
1255 if (fromIEW->iewInfo[tid].usedLSQ) {
1256 freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries;
1257 freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries;
1258 }
1259
1260 if (fromCommit->commitInfo[tid].usedROB) {
1261 freeEntries[tid].robEntries =
1262 fromCommit->commitInfo[tid].freeROBEntries;
1263 emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
1264 }
1265
1266 DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, "
1259 "Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i)\n",
1267 "Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i %i)\n",
1260 tid,
1261 freeEntries[tid].iqEntries,
1262 freeEntries[tid].robEntries,
1263 freeEntries[tid].lqEntries,
1264 freeEntries[tid].sqEntries,
1265 renameMap[tid]->numFreeEntries(),
1266 renameMap[tid]->numFreeIntEntries(),
1267 renameMap[tid]->numFreeFloatEntries(),
1268 renameMap[tid]->numFreeVecEntries(),
1268 tid,
1269 freeEntries[tid].iqEntries,
1270 freeEntries[tid].robEntries,
1271 freeEntries[tid].lqEntries,
1272 freeEntries[tid].sqEntries,
1273 renameMap[tid]->numFreeEntries(),
1274 renameMap[tid]->numFreeIntEntries(),
1275 renameMap[tid]->numFreeFloatEntries(),
1276 renameMap[tid]->numFreeVecEntries(),
1277 renameMap[tid]->numFreePredEntries(),
1269 renameMap[tid]->numFreeCCEntries());
1270
1271 DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n",
1272 tid, instsInProgress[tid]);
1273}
1274
1275template <class Impl>
1276bool
1277DefaultRename<Impl>::checkSignalsAndUpdate(ThreadID tid)
1278{
1279 // Check if there's a squash signal, squash if there is
1280 // Check stall signals, block if necessary.
1281 // If status was blocked
1282 // check if stall conditions have passed
1283 // if so then go to unblocking
1284 // If status was Squashing
1285 // check if squashing is not high. Switch to running this cycle.
1286 // If status was serialize stall
1287 // check if ROB is empty and no insts are in flight to the ROB
1288
1289 readFreeEntries(tid);
1290 readStallSignals(tid);
1291
1292 if (fromCommit->commitInfo[tid].squash) {
1293 DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from "
1294 "commit.\n", tid);
1295
1296 squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
1297
1298 return true;
1299 }
1300
1301 if (checkStall(tid)) {
1302 return block(tid);
1303 }
1304
1305 if (renameStatus[tid] == Blocked) {
1306 DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n",
1307 tid);
1308
1309 renameStatus[tid] = Unblocking;
1310
1311 unblock(tid);
1312
1313 return true;
1314 }
1315
1316 if (renameStatus[tid] == Squashing) {
1317 // Switch status to running if rename isn't being told to block or
1318 // squash this cycle.
1319 if (resumeSerialize) {
1320 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n",
1321 tid);
1322
1323 renameStatus[tid] = SerializeStall;
1324 return true;
1325 } else if (resumeUnblocking) {
1326 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to unblocking.\n",
1327 tid);
1328 renameStatus[tid] = Unblocking;
1329 return true;
1330 } else {
1331 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n",
1332 tid);
1333
1334 renameStatus[tid] = Running;
1335 return false;
1336 }
1337 }
1338
1339 if (renameStatus[tid] == SerializeStall) {
1340 // Stall ends once the ROB is free.
1341 DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to "
1342 "unblocking.\n", tid);
1343
1344 DynInstPtr serial_inst = serializeInst[tid];
1345
1346 renameStatus[tid] = Unblocking;
1347
1348 unblock(tid);
1349
1350 DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with "
1351 "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState());
1352
1353 // Put instruction into queue here.
1354 serial_inst->clearSerializeBefore();
1355
1356 if (!skidBuffer[tid].empty()) {
1357 skidBuffer[tid].push_front(serial_inst);
1358 } else {
1359 insts[tid].push_front(serial_inst);
1360 }
1361
1362 DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename."
1363 " Adding to front of list.\n", tid);
1364
1365 serializeInst[tid] = NULL;
1366
1367 return true;
1368 }
1369
1370 // If we've reached this point, we have not gotten any signals that
1371 // cause rename to change its status. Rename remains the same as before.
1372 return false;
1373}
1374
1375template<class Impl>
1376void
1377DefaultRename<Impl>::serializeAfter(InstQueue &inst_list, ThreadID tid)
1378{
1379 if (inst_list.empty()) {
1380 // Mark a bit to say that I must serialize on the next instruction.
1381 serializeOnNextInst[tid] = true;
1382 return;
1383 }
1384
1385 // Set the next instruction as serializing.
1386 inst_list.front()->setSerializeBefore();
1387}
1388
1389template <class Impl>
1390inline void
1391DefaultRename<Impl>::incrFullStat(const FullSource &source)
1392{
1393 switch (source) {
1394 case ROB:
1395 ++renameROBFullEvents;
1396 break;
1397 case IQ:
1398 ++renameIQFullEvents;
1399 break;
1400 case LQ:
1401 ++renameLQFullEvents;
1402 break;
1403 case SQ:
1404 ++renameSQFullEvents;
1405 break;
1406 default:
1407 panic("Rename full stall stat should be incremented for a reason!");
1408 break;
1409 }
1410}
1411
1412template <class Impl>
1413void
1414DefaultRename<Impl>::dumpHistory()
1415{
1416 typename std::list<RenameHistory>::iterator buf_it;
1417
1418 for (ThreadID tid = 0; tid < numThreads; tid++) {
1419
1420 buf_it = historyBuffer[tid].begin();
1421
1422 while (buf_it != historyBuffer[tid].end()) {
1423 cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:"
1424 " %i[%s] Old phys reg: %i[%s]\n",
1425 (*buf_it).instSeqNum,
1426 (*buf_it).archReg.className(),
1427 (*buf_it).archReg.index(),
1428 (*buf_it).newPhysReg->index(),
1429 (*buf_it).newPhysReg->className(),
1430 (*buf_it).prevPhysReg->index(),
1431 (*buf_it).prevPhysReg->className());
1432
1433 buf_it++;
1434 }
1435 }
1436}
1437
1438#endif//__CPU_O3_RENAME_IMPL_HH__
1278 renameMap[tid]->numFreeCCEntries());
1279
1280 DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n",
1281 tid, instsInProgress[tid]);
1282}
1283
1284template <class Impl>
1285bool
1286DefaultRename<Impl>::checkSignalsAndUpdate(ThreadID tid)
1287{
1288 // Check if there's a squash signal, squash if there is
1289 // Check stall signals, block if necessary.
1290 // If status was blocked
1291 // check if stall conditions have passed
1292 // if so then go to unblocking
1293 // If status was Squashing
1294 // check if squashing is not high. Switch to running this cycle.
1295 // If status was serialize stall
1296 // check if ROB is empty and no insts are in flight to the ROB
1297
1298 readFreeEntries(tid);
1299 readStallSignals(tid);
1300
1301 if (fromCommit->commitInfo[tid].squash) {
1302 DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from "
1303 "commit.\n", tid);
1304
1305 squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
1306
1307 return true;
1308 }
1309
1310 if (checkStall(tid)) {
1311 return block(tid);
1312 }
1313
1314 if (renameStatus[tid] == Blocked) {
1315 DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n",
1316 tid);
1317
1318 renameStatus[tid] = Unblocking;
1319
1320 unblock(tid);
1321
1322 return true;
1323 }
1324
1325 if (renameStatus[tid] == Squashing) {
1326 // Switch status to running if rename isn't being told to block or
1327 // squash this cycle.
1328 if (resumeSerialize) {
1329 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n",
1330 tid);
1331
1332 renameStatus[tid] = SerializeStall;
1333 return true;
1334 } else if (resumeUnblocking) {
1335 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to unblocking.\n",
1336 tid);
1337 renameStatus[tid] = Unblocking;
1338 return true;
1339 } else {
1340 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n",
1341 tid);
1342
1343 renameStatus[tid] = Running;
1344 return false;
1345 }
1346 }
1347
1348 if (renameStatus[tid] == SerializeStall) {
1349 // Stall ends once the ROB is free.
1350 DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to "
1351 "unblocking.\n", tid);
1352
1353 DynInstPtr serial_inst = serializeInst[tid];
1354
1355 renameStatus[tid] = Unblocking;
1356
1357 unblock(tid);
1358
1359 DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with "
1360 "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState());
1361
1362 // Put instruction into queue here.
1363 serial_inst->clearSerializeBefore();
1364
1365 if (!skidBuffer[tid].empty()) {
1366 skidBuffer[tid].push_front(serial_inst);
1367 } else {
1368 insts[tid].push_front(serial_inst);
1369 }
1370
1371 DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename."
1372 " Adding to front of list.\n", tid);
1373
1374 serializeInst[tid] = NULL;
1375
1376 return true;
1377 }
1378
1379 // If we've reached this point, we have not gotten any signals that
1380 // cause rename to change its status. Rename remains the same as before.
1381 return false;
1382}
1383
1384template<class Impl>
1385void
1386DefaultRename<Impl>::serializeAfter(InstQueue &inst_list, ThreadID tid)
1387{
1388 if (inst_list.empty()) {
1389 // Mark a bit to say that I must serialize on the next instruction.
1390 serializeOnNextInst[tid] = true;
1391 return;
1392 }
1393
1394 // Set the next instruction as serializing.
1395 inst_list.front()->setSerializeBefore();
1396}
1397
1398template <class Impl>
1399inline void
1400DefaultRename<Impl>::incrFullStat(const FullSource &source)
1401{
1402 switch (source) {
1403 case ROB:
1404 ++renameROBFullEvents;
1405 break;
1406 case IQ:
1407 ++renameIQFullEvents;
1408 break;
1409 case LQ:
1410 ++renameLQFullEvents;
1411 break;
1412 case SQ:
1413 ++renameSQFullEvents;
1414 break;
1415 default:
1416 panic("Rename full stall stat should be incremented for a reason!");
1417 break;
1418 }
1419}
1420
1421template <class Impl>
1422void
1423DefaultRename<Impl>::dumpHistory()
1424{
1425 typename std::list<RenameHistory>::iterator buf_it;
1426
1427 for (ThreadID tid = 0; tid < numThreads; tid++) {
1428
1429 buf_it = historyBuffer[tid].begin();
1430
1431 while (buf_it != historyBuffer[tid].end()) {
1432 cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:"
1433 " %i[%s] Old phys reg: %i[%s]\n",
1434 (*buf_it).instSeqNum,
1435 (*buf_it).archReg.className(),
1436 (*buf_it).archReg.index(),
1437 (*buf_it).newPhysReg->index(),
1438 (*buf_it).newPhysReg->className(),
1439 (*buf_it).prevPhysReg->index(),
1440 (*buf_it).prevPhysReg->className());
1441
1442 buf_it++;
1443 }
1444 }
1445}
1446
1447#endif//__CPU_O3_RENAME_IMPL_HH__