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} |