lsq_impl.hh (3184:8edaf4539e05) lsq_impl.hh (3310:21adbb41a37e)
1/*
2 * Copyright (c) 2005-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Korey Sewell
29 */
30
31#include <algorithm>
32#include <list>
33#include <string>
34
35#include "cpu/o3/lsq.hh"
36
37template <class Impl>
38Tick
39LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
40{
41 panic("O3CPU model does not work with atomic mode!");
42 return curTick;
43}
44
45template <class Impl>
46void
47LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
48{
49 warn("O3CPU doesn't update things on a recvFunctional.");
50}
51
52template <class Impl>
53void
54LSQ<Impl>::DcachePort::recvStatusChange(Status status)
55{
56 if (status == RangeChange)
57 return;
58
59 panic("O3CPU doesn't expect recvStatusChange callback!");
60}
61
62template <class Impl>
63bool
64LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
65{
1/*
2 * Copyright (c) 2005-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Korey Sewell
29 */
30
31#include <algorithm>
32#include <list>
33#include <string>
34
35#include "cpu/o3/lsq.hh"
36
37template <class Impl>
38Tick
39LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
40{
41 panic("O3CPU model does not work with atomic mode!");
42 return curTick;
43}
44
45template <class Impl>
46void
47LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
48{
49 warn("O3CPU doesn't update things on a recvFunctional.");
50}
51
52template <class Impl>
53void
54LSQ<Impl>::DcachePort::recvStatusChange(Status status)
55{
56 if (status == RangeChange)
57 return;
58
59 panic("O3CPU doesn't expect recvStatusChange callback!");
60}
61
62template <class Impl>
63bool
64LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
65{
66 lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt);
66 if (pkt->isResponse()) {
67 lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt);
68 }
69 else {
70 //else it is a coherence request, maybe you need to do something
71 warn("Recieved a coherence request (Invalidate??), 03CPU doesn't"
72 "update LSQ for these\n");
73 }
67 return true;
68}
69
70template <class Impl>
71void
72LSQ<Impl>::DcachePort::recvRetry()
73{
74 if (lsq->retryTid == -1)
75 {
76 //Squashed, so drop it
77 return;
78 }
79 lsq->thread[lsq->retryTid].recvRetry();
80 // Speculatively clear the retry Tid. This will get set again if
81 // the LSQUnit was unable to complete its access.
82 lsq->retryTid = -1;
83}
84
85template <class Impl>
86LSQ<Impl>::LSQ(Params *params)
87 : dcachePort(this), LQEntries(params->LQEntries),
88 SQEntries(params->SQEntries), numThreads(params->numberOfThreads),
89 retryTid(-1)
90{
91 DPRINTF(LSQ, "Creating LSQ object.\n");
92
93 //**********************************************/
94 //************ Handle SMT Parameters ***********/
95 //**********************************************/
96 std::string policy = params->smtLSQPolicy;
97
98 //Convert string to lowercase
99 std::transform(policy.begin(), policy.end(), policy.begin(),
100 (int(*)(int)) tolower);
101
102 //Figure out fetch policy
103 if (policy == "dynamic") {
104 lsqPolicy = Dynamic;
105
106 maxLQEntries = LQEntries;
107 maxSQEntries = SQEntries;
108
109 DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
110
111 } else if (policy == "partitioned") {
112 lsqPolicy = Partitioned;
113
114 //@todo:make work if part_amt doesnt divide evenly.
115 maxLQEntries = LQEntries / numThreads;
116 maxSQEntries = SQEntries / numThreads;
117
118 DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
119 "%i entries per LQ | %i entries per SQ",
120 maxLQEntries,maxSQEntries);
121
122 } else if (policy == "threshold") {
123 lsqPolicy = Threshold;
124
125 assert(params->smtLSQThreshold > LQEntries);
126 assert(params->smtLSQThreshold > SQEntries);
127
128 //Divide up by threshold amount
129 //@todo: Should threads check the max and the total
130 //amount of the LSQ
131 maxLQEntries = params->smtLSQThreshold;
132 maxSQEntries = params->smtLSQThreshold;
133
134 DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
135 "%i entries per LQ | %i entries per SQ",
136 maxLQEntries,maxSQEntries);
137
138 } else {
139 assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
140 "Partitioned, Threshold}");
141 }
142
143 //Initialize LSQs
144 for (int tid=0; tid < numThreads; tid++) {
145 thread[tid].init(params, this, maxLQEntries, maxSQEntries, tid);
146 thread[tid].setDcachePort(&dcachePort);
147 }
148}
149
150
151template<class Impl>
152std::string
153LSQ<Impl>::name() const
154{
155 return iewStage->name() + ".lsq";
156}
157
158template<class Impl>
159void
160LSQ<Impl>::regStats()
161{
162 //Initialize LSQs
163 for (int tid=0; tid < numThreads; tid++) {
164 thread[tid].regStats();
165 }
166}
167
168template<class Impl>
169void
170LSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
171{
172 activeThreads = at_ptr;
173 assert(activeThreads != 0);
174}
175
176template<class Impl>
177void
178LSQ<Impl>::setCPU(O3CPU *cpu_ptr)
179{
180 cpu = cpu_ptr;
181
182 dcachePort.setName(name());
183
184 for (int tid=0; tid < numThreads; tid++) {
185 thread[tid].setCPU(cpu_ptr);
186 }
187}
188
189template<class Impl>
190void
191LSQ<Impl>::setIEW(IEW *iew_ptr)
192{
193 iewStage = iew_ptr;
194
195 for (int tid=0; tid < numThreads; tid++) {
196 thread[tid].setIEW(iew_ptr);
197 }
198}
199
200template <class Impl>
201void
202LSQ<Impl>::switchOut()
203{
204 for (int tid = 0; tid < numThreads; tid++) {
205 thread[tid].switchOut();
206 }
207}
208
209template <class Impl>
210void
211LSQ<Impl>::takeOverFrom()
212{
213 for (int tid = 0; tid < numThreads; tid++) {
214 thread[tid].takeOverFrom();
215 }
216}
217
218template <class Impl>
219int
220LSQ<Impl>::entryAmount(int num_threads)
221{
222 if (lsqPolicy == Partitioned) {
223 return LQEntries / num_threads;
224 } else {
225 return 0;
226 }
227}
228
229template <class Impl>
230void
231LSQ<Impl>::resetEntries()
232{
233 if (lsqPolicy != Dynamic || numThreads > 1) {
234 int active_threads = (*activeThreads).size();
235
236 std::list<unsigned>::iterator threads = (*activeThreads).begin();
237 std::list<unsigned>::iterator list_end = (*activeThreads).end();
238
239 int maxEntries;
240
241 if (lsqPolicy == Partitioned) {
242 maxEntries = LQEntries / active_threads;
243 } else if (lsqPolicy == Threshold && active_threads == 1) {
244 maxEntries = LQEntries;
245 } else {
246 maxEntries = LQEntries;
247 }
248
249 while (threads != list_end) {
250 resizeEntries(maxEntries,*threads++);
251 }
252 }
253}
254
255template<class Impl>
256void
257LSQ<Impl>::removeEntries(unsigned tid)
258{
259 thread[tid].clearLQ();
260 thread[tid].clearSQ();
261}
262
263template<class Impl>
264void
265LSQ<Impl>::resizeEntries(unsigned size,unsigned tid)
266{
267 thread[tid].resizeLQ(size);
268 thread[tid].resizeSQ(size);
269}
270
271template<class Impl>
272void
273LSQ<Impl>::tick()
274{
275 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
276
277 while (active_threads != (*activeThreads).end()) {
278 unsigned tid = *active_threads++;
279
280 thread[tid].tick();
281 }
282}
283
284template<class Impl>
285void
286LSQ<Impl>::insertLoad(DynInstPtr &load_inst)
287{
288 unsigned tid = load_inst->threadNumber;
289
290 thread[tid].insertLoad(load_inst);
291}
292
293template<class Impl>
294void
295LSQ<Impl>::insertStore(DynInstPtr &store_inst)
296{
297 unsigned tid = store_inst->threadNumber;
298
299 thread[tid].insertStore(store_inst);
300}
301
302template<class Impl>
303Fault
304LSQ<Impl>::executeLoad(DynInstPtr &inst)
305{
306 unsigned tid = inst->threadNumber;
307
308 return thread[tid].executeLoad(inst);
309}
310
311template<class Impl>
312Fault
313LSQ<Impl>::executeStore(DynInstPtr &inst)
314{
315 unsigned tid = inst->threadNumber;
316
317 return thread[tid].executeStore(inst);
318}
319
320template<class Impl>
321void
322LSQ<Impl>::writebackStores()
323{
324 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
325
326 while (active_threads != (*activeThreads).end()) {
327 unsigned tid = *active_threads++;
328
329 if (numStoresToWB(tid) > 0) {
330 DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
331 "available for Writeback.\n", tid, numStoresToWB(tid));
332 }
333
334 thread[tid].writebackStores();
335 }
336}
337
338template<class Impl>
339bool
340LSQ<Impl>::violation()
341{
342 /* Answers: Does Anybody Have a Violation?*/
343 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
344
345 while (active_threads != (*activeThreads).end()) {
346 unsigned tid = *active_threads++;
347 if (thread[tid].violation())
348 return true;
349 }
350
351 return false;
352}
353
354template<class Impl>
355int
356LSQ<Impl>::getCount()
357{
358 unsigned total = 0;
359
360 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
361
362 while (active_threads != (*activeThreads).end()) {
363 unsigned tid = *active_threads++;
364 total += getCount(tid);
365 }
366
367 return total;
368}
369
370template<class Impl>
371int
372LSQ<Impl>::numLoads()
373{
374 unsigned total = 0;
375
376 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
377
378 while (active_threads != (*activeThreads).end()) {
379 unsigned tid = *active_threads++;
380 total += numLoads(tid);
381 }
382
383 return total;
384}
385
386template<class Impl>
387int
388LSQ<Impl>::numStores()
389{
390 unsigned total = 0;
391
392 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
393
394 while (active_threads != (*activeThreads).end()) {
395 unsigned tid = *active_threads++;
396 total += thread[tid].numStores();
397 }
398
399 return total;
400}
401
402template<class Impl>
403int
404LSQ<Impl>::numLoadsReady()
405{
406 unsigned total = 0;
407
408 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
409
410 while (active_threads != (*activeThreads).end()) {
411 unsigned tid = *active_threads++;
412 total += thread[tid].numLoadsReady();
413 }
414
415 return total;
416}
417
418template<class Impl>
419unsigned
420LSQ<Impl>::numFreeEntries()
421{
422 unsigned total = 0;
423
424 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
425
426 while (active_threads != (*activeThreads).end()) {
427 unsigned tid = *active_threads++;
428 total += thread[tid].numFreeEntries();
429 }
430
431 return total;
432}
433
434template<class Impl>
435unsigned
436LSQ<Impl>::numFreeEntries(unsigned tid)
437{
438 //if( lsqPolicy == Dynamic )
439 //return numFreeEntries();
440 //else
441 return thread[tid].numFreeEntries();
442}
443
444template<class Impl>
445bool
446LSQ<Impl>::isFull()
447{
448 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
449
450 while (active_threads != (*activeThreads).end()) {
451 unsigned tid = *active_threads++;
452 if (! (thread[tid].lqFull() || thread[tid].sqFull()) )
453 return false;
454 }
455
456 return true;
457}
458
459template<class Impl>
460bool
461LSQ<Impl>::isFull(unsigned tid)
462{
463 //@todo: Change to Calculate All Entries for
464 //Dynamic Policy
465 if( lsqPolicy == Dynamic )
466 return isFull();
467 else
468 return thread[tid].lqFull() || thread[tid].sqFull();
469}
470
471template<class Impl>
472bool
473LSQ<Impl>::lqFull()
474{
475 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
476
477 while (active_threads != (*activeThreads).end()) {
478 unsigned tid = *active_threads++;
479 if (!thread[tid].lqFull())
480 return false;
481 }
482
483 return true;
484}
485
486template<class Impl>
487bool
488LSQ<Impl>::lqFull(unsigned tid)
489{
490 //@todo: Change to Calculate All Entries for
491 //Dynamic Policy
492 if( lsqPolicy == Dynamic )
493 return lqFull();
494 else
495 return thread[tid].lqFull();
496}
497
498template<class Impl>
499bool
500LSQ<Impl>::sqFull()
501{
502 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
503
504 while (active_threads != (*activeThreads).end()) {
505 unsigned tid = *active_threads++;
506 if (!sqFull(tid))
507 return false;
508 }
509
510 return true;
511}
512
513template<class Impl>
514bool
515LSQ<Impl>::sqFull(unsigned tid)
516{
517 //@todo: Change to Calculate All Entries for
518 //Dynamic Policy
519 if( lsqPolicy == Dynamic )
520 return sqFull();
521 else
522 return thread[tid].sqFull();
523}
524
525template<class Impl>
526bool
527LSQ<Impl>::isStalled()
528{
529 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
530
531 while (active_threads != (*activeThreads).end()) {
532 unsigned tid = *active_threads++;
533 if (!thread[tid].isStalled())
534 return false;
535 }
536
537 return true;
538}
539
540template<class Impl>
541bool
542LSQ<Impl>::isStalled(unsigned tid)
543{
544 if( lsqPolicy == Dynamic )
545 return isStalled();
546 else
547 return thread[tid].isStalled();
548}
549
550template<class Impl>
551bool
552LSQ<Impl>::hasStoresToWB()
553{
554 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
555
556 if ((*activeThreads).empty())
557 return false;
558
559 while (active_threads != (*activeThreads).end()) {
560 unsigned tid = *active_threads++;
561 if (!hasStoresToWB(tid))
562 return false;
563 }
564
565 return true;
566}
567
568template<class Impl>
569bool
570LSQ<Impl>::willWB()
571{
572 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
573
574 while (active_threads != (*activeThreads).end()) {
575 unsigned tid = *active_threads++;
576 if (!willWB(tid))
577 return false;
578 }
579
580 return true;
581}
582
583template<class Impl>
584void
585LSQ<Impl>::dumpInsts()
586{
587 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
588
589 while (active_threads != (*activeThreads).end()) {
590 unsigned tid = *active_threads++;
591 thread[tid].dumpInsts();
592 }
593}
74 return true;
75}
76
77template <class Impl>
78void
79LSQ<Impl>::DcachePort::recvRetry()
80{
81 if (lsq->retryTid == -1)
82 {
83 //Squashed, so drop it
84 return;
85 }
86 lsq->thread[lsq->retryTid].recvRetry();
87 // Speculatively clear the retry Tid. This will get set again if
88 // the LSQUnit was unable to complete its access.
89 lsq->retryTid = -1;
90}
91
92template <class Impl>
93LSQ<Impl>::LSQ(Params *params)
94 : dcachePort(this), LQEntries(params->LQEntries),
95 SQEntries(params->SQEntries), numThreads(params->numberOfThreads),
96 retryTid(-1)
97{
98 DPRINTF(LSQ, "Creating LSQ object.\n");
99
100 //**********************************************/
101 //************ Handle SMT Parameters ***********/
102 //**********************************************/
103 std::string policy = params->smtLSQPolicy;
104
105 //Convert string to lowercase
106 std::transform(policy.begin(), policy.end(), policy.begin(),
107 (int(*)(int)) tolower);
108
109 //Figure out fetch policy
110 if (policy == "dynamic") {
111 lsqPolicy = Dynamic;
112
113 maxLQEntries = LQEntries;
114 maxSQEntries = SQEntries;
115
116 DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
117
118 } else if (policy == "partitioned") {
119 lsqPolicy = Partitioned;
120
121 //@todo:make work if part_amt doesnt divide evenly.
122 maxLQEntries = LQEntries / numThreads;
123 maxSQEntries = SQEntries / numThreads;
124
125 DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
126 "%i entries per LQ | %i entries per SQ",
127 maxLQEntries,maxSQEntries);
128
129 } else if (policy == "threshold") {
130 lsqPolicy = Threshold;
131
132 assert(params->smtLSQThreshold > LQEntries);
133 assert(params->smtLSQThreshold > SQEntries);
134
135 //Divide up by threshold amount
136 //@todo: Should threads check the max and the total
137 //amount of the LSQ
138 maxLQEntries = params->smtLSQThreshold;
139 maxSQEntries = params->smtLSQThreshold;
140
141 DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
142 "%i entries per LQ | %i entries per SQ",
143 maxLQEntries,maxSQEntries);
144
145 } else {
146 assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
147 "Partitioned, Threshold}");
148 }
149
150 //Initialize LSQs
151 for (int tid=0; tid < numThreads; tid++) {
152 thread[tid].init(params, this, maxLQEntries, maxSQEntries, tid);
153 thread[tid].setDcachePort(&dcachePort);
154 }
155}
156
157
158template<class Impl>
159std::string
160LSQ<Impl>::name() const
161{
162 return iewStage->name() + ".lsq";
163}
164
165template<class Impl>
166void
167LSQ<Impl>::regStats()
168{
169 //Initialize LSQs
170 for (int tid=0; tid < numThreads; tid++) {
171 thread[tid].regStats();
172 }
173}
174
175template<class Impl>
176void
177LSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
178{
179 activeThreads = at_ptr;
180 assert(activeThreads != 0);
181}
182
183template<class Impl>
184void
185LSQ<Impl>::setCPU(O3CPU *cpu_ptr)
186{
187 cpu = cpu_ptr;
188
189 dcachePort.setName(name());
190
191 for (int tid=0; tid < numThreads; tid++) {
192 thread[tid].setCPU(cpu_ptr);
193 }
194}
195
196template<class Impl>
197void
198LSQ<Impl>::setIEW(IEW *iew_ptr)
199{
200 iewStage = iew_ptr;
201
202 for (int tid=0; tid < numThreads; tid++) {
203 thread[tid].setIEW(iew_ptr);
204 }
205}
206
207template <class Impl>
208void
209LSQ<Impl>::switchOut()
210{
211 for (int tid = 0; tid < numThreads; tid++) {
212 thread[tid].switchOut();
213 }
214}
215
216template <class Impl>
217void
218LSQ<Impl>::takeOverFrom()
219{
220 for (int tid = 0; tid < numThreads; tid++) {
221 thread[tid].takeOverFrom();
222 }
223}
224
225template <class Impl>
226int
227LSQ<Impl>::entryAmount(int num_threads)
228{
229 if (lsqPolicy == Partitioned) {
230 return LQEntries / num_threads;
231 } else {
232 return 0;
233 }
234}
235
236template <class Impl>
237void
238LSQ<Impl>::resetEntries()
239{
240 if (lsqPolicy != Dynamic || numThreads > 1) {
241 int active_threads = (*activeThreads).size();
242
243 std::list<unsigned>::iterator threads = (*activeThreads).begin();
244 std::list<unsigned>::iterator list_end = (*activeThreads).end();
245
246 int maxEntries;
247
248 if (lsqPolicy == Partitioned) {
249 maxEntries = LQEntries / active_threads;
250 } else if (lsqPolicy == Threshold && active_threads == 1) {
251 maxEntries = LQEntries;
252 } else {
253 maxEntries = LQEntries;
254 }
255
256 while (threads != list_end) {
257 resizeEntries(maxEntries,*threads++);
258 }
259 }
260}
261
262template<class Impl>
263void
264LSQ<Impl>::removeEntries(unsigned tid)
265{
266 thread[tid].clearLQ();
267 thread[tid].clearSQ();
268}
269
270template<class Impl>
271void
272LSQ<Impl>::resizeEntries(unsigned size,unsigned tid)
273{
274 thread[tid].resizeLQ(size);
275 thread[tid].resizeSQ(size);
276}
277
278template<class Impl>
279void
280LSQ<Impl>::tick()
281{
282 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
283
284 while (active_threads != (*activeThreads).end()) {
285 unsigned tid = *active_threads++;
286
287 thread[tid].tick();
288 }
289}
290
291template<class Impl>
292void
293LSQ<Impl>::insertLoad(DynInstPtr &load_inst)
294{
295 unsigned tid = load_inst->threadNumber;
296
297 thread[tid].insertLoad(load_inst);
298}
299
300template<class Impl>
301void
302LSQ<Impl>::insertStore(DynInstPtr &store_inst)
303{
304 unsigned tid = store_inst->threadNumber;
305
306 thread[tid].insertStore(store_inst);
307}
308
309template<class Impl>
310Fault
311LSQ<Impl>::executeLoad(DynInstPtr &inst)
312{
313 unsigned tid = inst->threadNumber;
314
315 return thread[tid].executeLoad(inst);
316}
317
318template<class Impl>
319Fault
320LSQ<Impl>::executeStore(DynInstPtr &inst)
321{
322 unsigned tid = inst->threadNumber;
323
324 return thread[tid].executeStore(inst);
325}
326
327template<class Impl>
328void
329LSQ<Impl>::writebackStores()
330{
331 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
332
333 while (active_threads != (*activeThreads).end()) {
334 unsigned tid = *active_threads++;
335
336 if (numStoresToWB(tid) > 0) {
337 DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
338 "available for Writeback.\n", tid, numStoresToWB(tid));
339 }
340
341 thread[tid].writebackStores();
342 }
343}
344
345template<class Impl>
346bool
347LSQ<Impl>::violation()
348{
349 /* Answers: Does Anybody Have a Violation?*/
350 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
351
352 while (active_threads != (*activeThreads).end()) {
353 unsigned tid = *active_threads++;
354 if (thread[tid].violation())
355 return true;
356 }
357
358 return false;
359}
360
361template<class Impl>
362int
363LSQ<Impl>::getCount()
364{
365 unsigned total = 0;
366
367 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
368
369 while (active_threads != (*activeThreads).end()) {
370 unsigned tid = *active_threads++;
371 total += getCount(tid);
372 }
373
374 return total;
375}
376
377template<class Impl>
378int
379LSQ<Impl>::numLoads()
380{
381 unsigned total = 0;
382
383 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
384
385 while (active_threads != (*activeThreads).end()) {
386 unsigned tid = *active_threads++;
387 total += numLoads(tid);
388 }
389
390 return total;
391}
392
393template<class Impl>
394int
395LSQ<Impl>::numStores()
396{
397 unsigned total = 0;
398
399 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
400
401 while (active_threads != (*activeThreads).end()) {
402 unsigned tid = *active_threads++;
403 total += thread[tid].numStores();
404 }
405
406 return total;
407}
408
409template<class Impl>
410int
411LSQ<Impl>::numLoadsReady()
412{
413 unsigned total = 0;
414
415 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
416
417 while (active_threads != (*activeThreads).end()) {
418 unsigned tid = *active_threads++;
419 total += thread[tid].numLoadsReady();
420 }
421
422 return total;
423}
424
425template<class Impl>
426unsigned
427LSQ<Impl>::numFreeEntries()
428{
429 unsigned total = 0;
430
431 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
432
433 while (active_threads != (*activeThreads).end()) {
434 unsigned tid = *active_threads++;
435 total += thread[tid].numFreeEntries();
436 }
437
438 return total;
439}
440
441template<class Impl>
442unsigned
443LSQ<Impl>::numFreeEntries(unsigned tid)
444{
445 //if( lsqPolicy == Dynamic )
446 //return numFreeEntries();
447 //else
448 return thread[tid].numFreeEntries();
449}
450
451template<class Impl>
452bool
453LSQ<Impl>::isFull()
454{
455 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
456
457 while (active_threads != (*activeThreads).end()) {
458 unsigned tid = *active_threads++;
459 if (! (thread[tid].lqFull() || thread[tid].sqFull()) )
460 return false;
461 }
462
463 return true;
464}
465
466template<class Impl>
467bool
468LSQ<Impl>::isFull(unsigned tid)
469{
470 //@todo: Change to Calculate All Entries for
471 //Dynamic Policy
472 if( lsqPolicy == Dynamic )
473 return isFull();
474 else
475 return thread[tid].lqFull() || thread[tid].sqFull();
476}
477
478template<class Impl>
479bool
480LSQ<Impl>::lqFull()
481{
482 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
483
484 while (active_threads != (*activeThreads).end()) {
485 unsigned tid = *active_threads++;
486 if (!thread[tid].lqFull())
487 return false;
488 }
489
490 return true;
491}
492
493template<class Impl>
494bool
495LSQ<Impl>::lqFull(unsigned tid)
496{
497 //@todo: Change to Calculate All Entries for
498 //Dynamic Policy
499 if( lsqPolicy == Dynamic )
500 return lqFull();
501 else
502 return thread[tid].lqFull();
503}
504
505template<class Impl>
506bool
507LSQ<Impl>::sqFull()
508{
509 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
510
511 while (active_threads != (*activeThreads).end()) {
512 unsigned tid = *active_threads++;
513 if (!sqFull(tid))
514 return false;
515 }
516
517 return true;
518}
519
520template<class Impl>
521bool
522LSQ<Impl>::sqFull(unsigned tid)
523{
524 //@todo: Change to Calculate All Entries for
525 //Dynamic Policy
526 if( lsqPolicy == Dynamic )
527 return sqFull();
528 else
529 return thread[tid].sqFull();
530}
531
532template<class Impl>
533bool
534LSQ<Impl>::isStalled()
535{
536 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
537
538 while (active_threads != (*activeThreads).end()) {
539 unsigned tid = *active_threads++;
540 if (!thread[tid].isStalled())
541 return false;
542 }
543
544 return true;
545}
546
547template<class Impl>
548bool
549LSQ<Impl>::isStalled(unsigned tid)
550{
551 if( lsqPolicy == Dynamic )
552 return isStalled();
553 else
554 return thread[tid].isStalled();
555}
556
557template<class Impl>
558bool
559LSQ<Impl>::hasStoresToWB()
560{
561 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
562
563 if ((*activeThreads).empty())
564 return false;
565
566 while (active_threads != (*activeThreads).end()) {
567 unsigned tid = *active_threads++;
568 if (!hasStoresToWB(tid))
569 return false;
570 }
571
572 return true;
573}
574
575template<class Impl>
576bool
577LSQ<Impl>::willWB()
578{
579 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
580
581 while (active_threads != (*activeThreads).end()) {
582 unsigned tid = *active_threads++;
583 if (!willWB(tid))
584 return false;
585 }
586
587 return true;
588}
589
590template<class Impl>
591void
592LSQ<Impl>::dumpInsts()
593{
594 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
595
596 while (active_threads != (*activeThreads).end()) {
597 unsigned tid = *active_threads++;
598 thread[tid].dumpInsts();
599 }
600}