lsq_impl.hh (2980:eab855f06b79) lsq_impl.hh (3014:b4309193255a)
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 panic("O3CPU doesn't expect recvFunctional callback!");
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);
67 return true;
68}
69
70template <class Impl>
71void
72LSQ<Impl>::DcachePort::recvRetry()
73{
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 panic("O3CPU doesn't expect recvFunctional callback!");
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);
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 }
74 lsq->thread[lsq->retryTid].recvRetry();
75 // Speculatively clear the retry Tid. This will get set again if
76 // the LSQUnit was unable to complete its access.
77 lsq->retryTid = -1;
78}
79
80template <class Impl>
81LSQ<Impl>::LSQ(Params *params)
82 : dcachePort(this), LQEntries(params->LQEntries),
83 SQEntries(params->SQEntries), numThreads(params->numberOfThreads),
84 retryTid(-1)
85{
86 DPRINTF(LSQ, "Creating LSQ object.\n");
87
88 //**********************************************/
89 //************ Handle SMT Parameters ***********/
90 //**********************************************/
91 std::string policy = params->smtLSQPolicy;
92
93 //Convert string to lowercase
94 std::transform(policy.begin(), policy.end(), policy.begin(),
95 (int(*)(int)) tolower);
96
97 //Figure out fetch policy
98 if (policy == "dynamic") {
99 lsqPolicy = Dynamic;
100
101 maxLQEntries = LQEntries;
102 maxSQEntries = SQEntries;
103
104 DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
105
106 } else if (policy == "partitioned") {
107 lsqPolicy = Partitioned;
108
109 //@todo:make work if part_amt doesnt divide evenly.
110 maxLQEntries = LQEntries / numThreads;
111 maxSQEntries = SQEntries / numThreads;
112
113 DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
114 "%i entries per LQ | %i entries per SQ",
115 maxLQEntries,maxSQEntries);
116
117 } else if (policy == "threshold") {
118 lsqPolicy = Threshold;
119
120 assert(params->smtLSQThreshold > LQEntries);
121 assert(params->smtLSQThreshold > SQEntries);
122
123 //Divide up by threshold amount
124 //@todo: Should threads check the max and the total
125 //amount of the LSQ
126 maxLQEntries = params->smtLSQThreshold;
127 maxSQEntries = params->smtLSQThreshold;
128
129 DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
130 "%i entries per LQ | %i entries per SQ",
131 maxLQEntries,maxSQEntries);
132
133 } else {
134 assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
135 "Partitioned, Threshold}");
136 }
137
138 //Initialize LSQs
139 for (int tid=0; tid < numThreads; tid++) {
140 thread[tid].init(params, this, maxLQEntries, maxSQEntries, tid);
141 thread[tid].setDcachePort(&dcachePort);
142 }
143}
144
145
146template<class Impl>
147std::string
148LSQ<Impl>::name() const
149{
150 return iewStage->name() + ".lsq";
151}
152
153template<class Impl>
154void
155LSQ<Impl>::regStats()
156{
157 //Initialize LSQs
158 for (int tid=0; tid < numThreads; tid++) {
159 thread[tid].regStats();
160 }
161}
162
163template<class Impl>
164void
165LSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
166{
167 activeThreads = at_ptr;
168 assert(activeThreads != 0);
169}
170
171template<class Impl>
172void
173LSQ<Impl>::setCPU(O3CPU *cpu_ptr)
174{
175 cpu = cpu_ptr;
176
177 dcachePort.setName(name());
178
179 for (int tid=0; tid < numThreads; tid++) {
180 thread[tid].setCPU(cpu_ptr);
181 }
182}
183
184template<class Impl>
185void
186LSQ<Impl>::setIEW(IEW *iew_ptr)
187{
188 iewStage = iew_ptr;
189
190 for (int tid=0; tid < numThreads; tid++) {
191 thread[tid].setIEW(iew_ptr);
192 }
193}
194
195template <class Impl>
196void
197LSQ<Impl>::switchOut()
198{
199 for (int tid = 0; tid < numThreads; tid++) {
200 thread[tid].switchOut();
201 }
202}
203
204template <class Impl>
205void
206LSQ<Impl>::takeOverFrom()
207{
208 for (int tid = 0; tid < numThreads; tid++) {
209 thread[tid].takeOverFrom();
210 }
211}
212
213template <class Impl>
214int
215LSQ<Impl>::entryAmount(int num_threads)
216{
217 if (lsqPolicy == Partitioned) {
218 return LQEntries / num_threads;
219 } else {
220 return 0;
221 }
222}
223
224template <class Impl>
225void
226LSQ<Impl>::resetEntries()
227{
228 if (lsqPolicy != Dynamic || numThreads > 1) {
229 int active_threads = (*activeThreads).size();
230
231 std::list<unsigned>::iterator threads = (*activeThreads).begin();
232 std::list<unsigned>::iterator list_end = (*activeThreads).end();
233
234 int maxEntries;
235
236 if (lsqPolicy == Partitioned) {
237 maxEntries = LQEntries / active_threads;
238 } else if (lsqPolicy == Threshold && active_threads == 1) {
239 maxEntries = LQEntries;
240 } else {
241 maxEntries = LQEntries;
242 }
243
244 while (threads != list_end) {
245 resizeEntries(maxEntries,*threads++);
246 }
247 }
248}
249
250template<class Impl>
251void
252LSQ<Impl>::removeEntries(unsigned tid)
253{
254 thread[tid].clearLQ();
255 thread[tid].clearSQ();
256}
257
258template<class Impl>
259void
260LSQ<Impl>::resizeEntries(unsigned size,unsigned tid)
261{
262 thread[tid].resizeLQ(size);
263 thread[tid].resizeSQ(size);
264}
265
266template<class Impl>
267void
268LSQ<Impl>::tick()
269{
270 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
271
272 while (active_threads != (*activeThreads).end()) {
273 unsigned tid = *active_threads++;
274
275 thread[tid].tick();
276 }
277}
278
279template<class Impl>
280void
281LSQ<Impl>::insertLoad(DynInstPtr &load_inst)
282{
283 unsigned tid = load_inst->threadNumber;
284
285 thread[tid].insertLoad(load_inst);
286}
287
288template<class Impl>
289void
290LSQ<Impl>::insertStore(DynInstPtr &store_inst)
291{
292 unsigned tid = store_inst->threadNumber;
293
294 thread[tid].insertStore(store_inst);
295}
296
297template<class Impl>
298Fault
299LSQ<Impl>::executeLoad(DynInstPtr &inst)
300{
301 unsigned tid = inst->threadNumber;
302
303 return thread[tid].executeLoad(inst);
304}
305
306template<class Impl>
307Fault
308LSQ<Impl>::executeStore(DynInstPtr &inst)
309{
310 unsigned tid = inst->threadNumber;
311
312 return thread[tid].executeStore(inst);
313}
314
315template<class Impl>
316void
317LSQ<Impl>::writebackStores()
318{
319 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
320
321 while (active_threads != (*activeThreads).end()) {
322 unsigned tid = *active_threads++;
323
324 if (numStoresToWB(tid) > 0) {
325 DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
326 "available for Writeback.\n", tid, numStoresToWB(tid));
327 }
328
329 thread[tid].writebackStores();
330 }
331}
332
333template<class Impl>
334bool
335LSQ<Impl>::violation()
336{
337 /* Answers: Does Anybody Have a Violation?*/
338 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
339
340 while (active_threads != (*activeThreads).end()) {
341 unsigned tid = *active_threads++;
342 if (thread[tid].violation())
343 return true;
344 }
345
346 return false;
347}
348
349template<class Impl>
350int
351LSQ<Impl>::getCount()
352{
353 unsigned total = 0;
354
355 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
356
357 while (active_threads != (*activeThreads).end()) {
358 unsigned tid = *active_threads++;
359 total += getCount(tid);
360 }
361
362 return total;
363}
364
365template<class Impl>
366int
367LSQ<Impl>::numLoads()
368{
369 unsigned total = 0;
370
371 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
372
373 while (active_threads != (*activeThreads).end()) {
374 unsigned tid = *active_threads++;
375 total += numLoads(tid);
376 }
377
378 return total;
379}
380
381template<class Impl>
382int
383LSQ<Impl>::numStores()
384{
385 unsigned total = 0;
386
387 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
388
389 while (active_threads != (*activeThreads).end()) {
390 unsigned tid = *active_threads++;
391 total += thread[tid].numStores();
392 }
393
394 return total;
395}
396
397template<class Impl>
398int
399LSQ<Impl>::numLoadsReady()
400{
401 unsigned total = 0;
402
403 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
404
405 while (active_threads != (*activeThreads).end()) {
406 unsigned tid = *active_threads++;
407 total += thread[tid].numLoadsReady();
408 }
409
410 return total;
411}
412
413template<class Impl>
414unsigned
415LSQ<Impl>::numFreeEntries()
416{
417 unsigned total = 0;
418
419 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
420
421 while (active_threads != (*activeThreads).end()) {
422 unsigned tid = *active_threads++;
423 total += thread[tid].numFreeEntries();
424 }
425
426 return total;
427}
428
429template<class Impl>
430unsigned
431LSQ<Impl>::numFreeEntries(unsigned tid)
432{
433 //if( lsqPolicy == Dynamic )
434 //return numFreeEntries();
435 //else
436 return thread[tid].numFreeEntries();
437}
438
439template<class Impl>
440bool
441LSQ<Impl>::isFull()
442{
443 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
444
445 while (active_threads != (*activeThreads).end()) {
446 unsigned tid = *active_threads++;
447 if (! (thread[tid].lqFull() || thread[tid].sqFull()) )
448 return false;
449 }
450
451 return true;
452}
453
454template<class Impl>
455bool
456LSQ<Impl>::isFull(unsigned tid)
457{
458 //@todo: Change to Calculate All Entries for
459 //Dynamic Policy
460 if( lsqPolicy == Dynamic )
461 return isFull();
462 else
463 return thread[tid].lqFull() || thread[tid].sqFull();
464}
465
466template<class Impl>
467bool
468LSQ<Impl>::lqFull()
469{
470 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
471
472 while (active_threads != (*activeThreads).end()) {
473 unsigned tid = *active_threads++;
474 if (!thread[tid].lqFull())
475 return false;
476 }
477
478 return true;
479}
480
481template<class Impl>
482bool
483LSQ<Impl>::lqFull(unsigned tid)
484{
485 //@todo: Change to Calculate All Entries for
486 //Dynamic Policy
487 if( lsqPolicy == Dynamic )
488 return lqFull();
489 else
490 return thread[tid].lqFull();
491}
492
493template<class Impl>
494bool
495LSQ<Impl>::sqFull()
496{
497 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
498
499 while (active_threads != (*activeThreads).end()) {
500 unsigned tid = *active_threads++;
501 if (!sqFull(tid))
502 return false;
503 }
504
505 return true;
506}
507
508template<class Impl>
509bool
510LSQ<Impl>::sqFull(unsigned tid)
511{
512 //@todo: Change to Calculate All Entries for
513 //Dynamic Policy
514 if( lsqPolicy == Dynamic )
515 return sqFull();
516 else
517 return thread[tid].sqFull();
518}
519
520template<class Impl>
521bool
522LSQ<Impl>::isStalled()
523{
524 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
525
526 while (active_threads != (*activeThreads).end()) {
527 unsigned tid = *active_threads++;
528 if (!thread[tid].isStalled())
529 return false;
530 }
531
532 return true;
533}
534
535template<class Impl>
536bool
537LSQ<Impl>::isStalled(unsigned tid)
538{
539 if( lsqPolicy == Dynamic )
540 return isStalled();
541 else
542 return thread[tid].isStalled();
543}
544
545template<class Impl>
546bool
547LSQ<Impl>::hasStoresToWB()
548{
549 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
550
551 if ((*activeThreads).empty())
552 return false;
553
554 while (active_threads != (*activeThreads).end()) {
555 unsigned tid = *active_threads++;
556 if (!hasStoresToWB(tid))
557 return false;
558 }
559
560 return true;
561}
562
563template<class Impl>
564bool
565LSQ<Impl>::willWB()
566{
567 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
568
569 while (active_threads != (*activeThreads).end()) {
570 unsigned tid = *active_threads++;
571 if (!willWB(tid))
572 return false;
573 }
574
575 return true;
576}
577
578template<class Impl>
579void
580LSQ<Impl>::dumpInsts()
581{
582 std::list<unsigned>::iterator active_threads = (*activeThreads).begin();
583
584 while (active_threads != (*activeThreads).end()) {
585 unsigned tid = *active_threads++;
586 thread[tid].dumpInsts();
587 }
588}
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}