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