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