fetch_impl.hh (3961:42374ae36922) | fetch_impl.hh (3968:0a08763926a1) |
---|---|
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; --- 327 unchanged lines hidden (view full) --- 336 337 memReq[tid] = NULL; 338 339 // Create space to store a cache line. 340 cacheData[tid] = new uint8_t[cacheBlkSize]; 341 cacheDataPC[tid] = 0; 342 cacheDataValid[tid] = false; 343 | 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; --- 327 unchanged lines hidden (view full) --- 336 337 memReq[tid] = NULL; 338 339 // Create space to store a cache line. 340 cacheData[tid] = new uint8_t[cacheBlkSize]; 341 cacheDataPC[tid] = 0; 342 cacheDataValid[tid] = false; 343 |
344 delaySlotInfo[tid].branchSeqNum = -1; 345 delaySlotInfo[tid].numInsts = 0; 346 delaySlotInfo[tid].targetAddr = 0; 347 delaySlotInfo[tid].targetReady = false; 348 | |
349 stalls[tid].decode = false; 350 stalls[tid].rename = false; 351 stalls[tid].iew = false; 352 stalls[tid].commit = false; 353 } 354} 355 356template<class Impl> --- 77 unchanged lines hidden (view full) --- 434 stalls[i].decode = 0; 435 stalls[i].rename = 0; 436 stalls[i].iew = 0; 437 stalls[i].commit = 0; 438 PC[i] = cpu->readPC(i); 439 nextPC[i] = cpu->readNextPC(i); 440#if ISA_HAS_DELAY_SLOT 441 nextNPC[i] = cpu->readNextNPC(i); | 344 stalls[tid].decode = false; 345 stalls[tid].rename = false; 346 stalls[tid].iew = false; 347 stalls[tid].commit = false; 348 } 349} 350 351template<class Impl> --- 77 unchanged lines hidden (view full) --- 429 stalls[i].decode = 0; 430 stalls[i].rename = 0; 431 stalls[i].iew = 0; 432 stalls[i].commit = 0; 433 PC[i] = cpu->readPC(i); 434 nextPC[i] = cpu->readNextPC(i); 435#if ISA_HAS_DELAY_SLOT 436 nextNPC[i] = cpu->readNextNPC(i); |
442 delaySlotInfo[i].branchSeqNum = -1; 443 delaySlotInfo[i].numInsts = 0; 444 delaySlotInfo[i].targetAddr = 0; 445 delaySlotInfo[i].targetReady = false; | 437#else 438 nextNPC[i] = nextPC[i] + sizeof(TheISA::MachInst); |
446#endif 447 fetchStatus[i] = Running; 448 } 449 numInst = 0; 450 wroteToTimeBuffer = false; 451 _status = Inactive; 452 switchedOut = false; 453 interruptPending = false; --- 42 unchanged lines hidden (view full) --- 496 Addr &next_NPC) 497{ 498 // Do branch prediction check here. 499 // A bit of a misnomer...next_PC is actually the current PC until 500 // this function updates it. 501 bool predict_taken; 502 503 if (!inst->isControl()) { | 439#endif 440 fetchStatus[i] = Running; 441 } 442 numInst = 0; 443 wroteToTimeBuffer = false; 444 _status = Inactive; 445 switchedOut = false; 446 interruptPending = false; --- 42 unchanged lines hidden (view full) --- 489 Addr &next_NPC) 490{ 491 // Do branch prediction check here. 492 // A bit of a misnomer...next_PC is actually the current PC until 493 // this function updates it. 494 bool predict_taken; 495 496 if (!inst->isControl()) { |
504#if ISA_HAS_DELAY_SLOT | |
505 next_PC = next_NPC; 506 next_NPC = next_NPC + instSize; 507 inst->setPredTarg(next_PC, next_NPC); | 497 next_PC = next_NPC; 498 next_NPC = next_NPC + instSize; 499 inst->setPredTarg(next_PC, next_NPC); |
508#else 509 next_PC = next_PC + instSize; 510 inst->setPredTarg(next_PC, next_PC + sizeof(TheISA::MachInst)); 511#endif | |
512 inst->setPredTaken(false); 513 return false; 514 } 515 516 int tid = inst->threadNumber; | 500 inst->setPredTaken(false); 501 return false; 502 } 503 504 int tid = inst->threadNumber; |
517#if ISA_HAS_DELAY_SLOT | |
518 Addr pred_PC = next_PC; 519 predict_taken = branchPred.predict(inst, pred_PC, tid); 520 | 505 Addr pred_PC = next_PC; 506 predict_taken = branchPred.predict(inst, pred_PC, tid); 507 |
521 if (predict_taken) { 522 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be taken.\n", tid); | 508/* if (predict_taken) { 509 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be taken to %#x.\n", 510 tid, pred_PC); |
523 } else { 524 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be not taken.\n", tid); | 511 } else { 512 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be not taken.\n", tid); |
525 } | 513 }*/ |
526 | 514 |
515#if ISA_HAS_DELAY_SLOT |
|
527 next_PC = next_NPC; | 516 next_PC = next_NPC; |
528 if (predict_taken) { | 517 if (predict_taken) |
529 next_NPC = pred_PC; | 518 next_NPC = pred_PC; |
530 // Update delay slot info 531 ++delaySlotInfo[tid].numInsts; 532 delaySlotInfo[tid].targetAddr = pred_PC; 533 DPRINTF(Fetch, "[tid:%i]: %i delay slot inst(s) to process.\n", tid, 534 delaySlotInfo[tid].numInsts); 535 } else { 536 next_NPC = next_NPC + instSize; 537 } | 519 else 520 next_NPC += instSize; |
538#else | 521#else |
539 predict_taken = branchPred.predict(inst, next_PC, tid); | 522 if (predict_taken) 523 next_PC = pred_PC; 524 else 525 next_PC += instSize; 526 next_NPC = next_PC + instSize; |
540#endif | 527#endif |
541 DPRINTF(Fetch, "[tid:%i]: Branch predicted to go to %#x and then %#x.\n", 542 tid, next_PC, next_NPC); | 528/* DPRINTF(Fetch, "[tid:%i]: Branch predicted to go to %#x and then %#x.\n", 529 tid, next_PC, next_NPC);*/ |
543 inst->setPredTarg(next_PC, next_NPC); 544 inst->setPredTaken(predict_taken); 545 546 ++fetchedBranches; 547 548 if (predict_taken) { 549 ++predictedBranches; 550 } --- 148 unchanged lines hidden (view full) --- 699DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC, const Addr &new_NPC, 700 const InstSeqNum &seq_num, 701 unsigned tid) 702{ 703 DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid); 704 705 doSquash(new_PC, new_NPC, tid); 706 | 530 inst->setPredTarg(next_PC, next_NPC); 531 inst->setPredTaken(predict_taken); 532 533 ++fetchedBranches; 534 535 if (predict_taken) { 536 ++predictedBranches; 537 } --- 148 unchanged lines hidden (view full) --- 686DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC, const Addr &new_NPC, 687 const InstSeqNum &seq_num, 688 unsigned tid) 689{ 690 DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid); 691 692 doSquash(new_PC, new_NPC, tid); 693 |
707#if ISA_HAS_DELAY_SLOT 708 if (seq_num <= delaySlotInfo[tid].branchSeqNum) { 709 delaySlotInfo[tid].numInsts = 0; 710 delaySlotInfo[tid].targetAddr = 0; 711 delaySlotInfo[tid].targetReady = false; 712 } 713#endif 714 | |
715 // Tell the CPU to remove any instructions that are in flight between 716 // fetch and decode. 717 cpu->removeInstsUntil(seq_num, tid); 718} 719 720template<class Impl> 721bool 722DefaultFetch<Impl>::checkStall(unsigned tid) const --- 66 unchanged lines hidden (view full) --- 789 const InstSeqNum &seq_num, 790 bool squash_delay_slot, unsigned tid) 791{ 792 DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid); 793 794 doSquash(new_PC, new_NPC, tid); 795 796#if ISA_HAS_DELAY_SLOT | 694 // Tell the CPU to remove any instructions that are in flight between 695 // fetch and decode. 696 cpu->removeInstsUntil(seq_num, tid); 697} 698 699template<class Impl> 700bool 701DefaultFetch<Impl>::checkStall(unsigned tid) const --- 66 unchanged lines hidden (view full) --- 768 const InstSeqNum &seq_num, 769 bool squash_delay_slot, unsigned tid) 770{ 771 DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid); 772 773 doSquash(new_PC, new_NPC, tid); 774 775#if ISA_HAS_DELAY_SLOT |
797 if (seq_num <= delaySlotInfo[tid].branchSeqNum) { 798 delaySlotInfo[tid].numInsts = 0; 799 delaySlotInfo[tid].targetAddr = 0; 800 delaySlotInfo[tid].targetReady = false; 801 } 802 | |
803 // Tell the CPU to remove any instructions that are not in the ROB. 804 cpu->removeInstsNotInROB(tid, squash_delay_slot, seq_num); 805#else 806 // Tell the CPU to remove any instructions that are not in the ROB. 807 cpu->removeInstsNotInROB(tid, true, 0); 808#endif 809} 810 --- 161 unchanged lines hidden (view full) --- 972 973 if (fetchStatus[tid] != Squashing) { 974 975#if ISA_HAS_DELAY_SLOT 976 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].bdelayDoneSeqNum; 977#else 978 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum; 979#endif | 776 // Tell the CPU to remove any instructions that are not in the ROB. 777 cpu->removeInstsNotInROB(tid, squash_delay_slot, seq_num); 778#else 779 // Tell the CPU to remove any instructions that are not in the ROB. 780 cpu->removeInstsNotInROB(tid, true, 0); 781#endif 782} 783 --- 161 unchanged lines hidden (view full) --- 945 946 if (fetchStatus[tid] != Squashing) { 947 948#if ISA_HAS_DELAY_SLOT 949 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].bdelayDoneSeqNum; 950#else 951 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum; 952#endif |
953 DPRINTF(Fetch, "Squashing from decode with PC = %#x, NPC = %#x\n", 954 fromDecode->decodeInfo[tid].nextPC, 955 fromDecode->decodeInfo[tid].nextNPC); |
|
980 // Squash unless we're already squashing 981 squashFromDecode(fromDecode->decodeInfo[tid].nextPC, 982 fromDecode->decodeInfo[tid].nextNPC, 983 doneSeqNum, 984 tid); 985 986 return true; 987 } --- 131 unchanged lines hidden (view full) --- 1119 numInst < fetchWidth && 1120 !predicted_branch; 1121 ++numInst) { 1122 1123 // If we're branching after this instruction, quite fetching 1124 // from the same block then. 1125 predicted_branch = 1126 (fetch_PC + sizeof(TheISA::MachInst) != fetch_NPC); | 956 // Squash unless we're already squashing 957 squashFromDecode(fromDecode->decodeInfo[tid].nextPC, 958 fromDecode->decodeInfo[tid].nextNPC, 959 doneSeqNum, 960 tid); 961 962 return true; 963 } --- 131 unchanged lines hidden (view full) --- 1095 numInst < fetchWidth && 1096 !predicted_branch; 1097 ++numInst) { 1098 1099 // If we're branching after this instruction, quite fetching 1100 // from the same block then. 1101 predicted_branch = 1102 (fetch_PC + sizeof(TheISA::MachInst) != fetch_NPC); |
1103 if (predicted_branch) { 1104 DPRINTF(Fetch, "Branch detected with PC = %#x, NPC = %#x\n", 1105 fetch_PC, fetch_NPC); 1106 } |
|
1127 | 1107 |
1108 |
|
1128 // Get a sequence number. 1129 inst_seq = cpu->getAndIncrementInstSeq(); 1130 1131 // Make sure this is a valid index. 1132 assert(offset <= cacheBlkSize - instSize); 1133 1134 // Get the instruction from the array of the cache line. 1135 inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *> --- 17 unchanged lines hidden (view full) --- 1153 instruction->setASID(tid); 1154 1155 instruction->setThreadState(cpu->thread[tid]); 1156 1157 DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created " 1158 "[sn:%lli]\n", 1159 tid, instruction->readPC(), inst_seq); 1160 | 1109 // Get a sequence number. 1110 inst_seq = cpu->getAndIncrementInstSeq(); 1111 1112 // Make sure this is a valid index. 1113 assert(offset <= cacheBlkSize - instSize); 1114 1115 // Get the instruction from the array of the cache line. 1116 inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *> --- 17 unchanged lines hidden (view full) --- 1134 instruction->setASID(tid); 1135 1136 instruction->setThreadState(cpu->thread[tid]); 1137 1138 DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created " 1139 "[sn:%lli]\n", 1140 tid, instruction->readPC(), inst_seq); 1141 |
1161 DPRINTF(Fetch, "[tid:%i]: MachInst is %#x\n", tid, ext_inst); | 1142 //DPRINTF(Fetch, "[tid:%i]: MachInst is %#x\n", tid, ext_inst); |
1162 1163 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", 1164 tid, instruction->staticInst->disassemble(fetch_PC)); 1165 1166 instruction->traceData = 1167 Trace::getInstRecord(curTick, cpu->tcBase(tid), 1168 instruction->staticInst, 1169 instruction->readPC()); 1170 1171 lookupAndUpdateNextPC(instruction, next_PC, next_NPC); | 1143 1144 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", 1145 tid, instruction->staticInst->disassemble(fetch_PC)); 1146 1147 instruction->traceData = 1148 Trace::getInstRecord(curTick, cpu->tcBase(tid), 1149 instruction->staticInst, 1150 instruction->readPC()); 1151 1152 lookupAndUpdateNextPC(instruction, next_PC, next_NPC); |
1153 predicted_branch |= (next_PC != fetch_NPC); |
|
1172 1173 // Add instruction to the CPU's list of instructions. 1174 instruction->setInstListIt(cpu->addInst(instruction)); 1175 1176 // Write the instruction to the first slot in the queue 1177 // that heads to decode. 1178 toDecode->insts[numInst] = instruction; 1179 --- 32 unchanged lines hidden (view full) --- 1212 1213 if (numInst > 0) { 1214 wroteToTimeBuffer = true; 1215 } 1216 1217 // Now that fetching is completed, update the PC to signify what the next 1218 // cycle will be. 1219 if (fault == NoFault) { | 1154 1155 // Add instruction to the CPU's list of instructions. 1156 instruction->setInstListIt(cpu->addInst(instruction)); 1157 1158 // Write the instruction to the first slot in the queue 1159 // that heads to decode. 1160 toDecode->insts[numInst] = instruction; 1161 --- 32 unchanged lines hidden (view full) --- 1194 1195 if (numInst > 0) { 1196 wroteToTimeBuffer = true; 1197 } 1198 1199 // Now that fetching is completed, update the PC to signify what the next 1200 // cycle will be. 1201 if (fault == NoFault) { |
1202 PC[tid] = next_PC; 1203 nextPC[tid] = next_NPC; 1204 nextNPC[tid] = next_NPC + instSize; |
|
1220#if ISA_HAS_DELAY_SLOT | 1205#if ISA_HAS_DELAY_SLOT |
1221 if (delaySlotInfo[tid].targetReady && 1222 delaySlotInfo[tid].numInsts == 0) { 1223 // Set PC to target 1224 PC[tid] = next_PC; 1225 nextPC[tid] = next_NPC; 1226 nextNPC[tid] = next_NPC + instSize; 1227 1228 delaySlotInfo[tid].targetReady = false; 1229 } else { 1230 PC[tid] = next_PC; 1231 nextPC[tid] = next_NPC; 1232 nextNPC[tid] = next_NPC + instSize; 1233 } 1234 | |
1235 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]); 1236#else | 1206 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]); 1207#else |
1237 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC); 1238 PC[tid] = next_PC; 1239 nextPC[tid] = next_PC + instSize; | 1208 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, next_PC); |
1240#endif 1241 } else { 1242 // We shouldn't be in an icache miss and also have a fault (an ITB 1243 // miss) 1244 if (fetchStatus[tid] == IcacheWaitResponse) { 1245 panic("Fetch should have exited prior to this!"); 1246 } 1247 --- 212 unchanged lines hidden --- | 1209#endif 1210 } else { 1211 // We shouldn't be in an icache miss and also have a fault (an ITB 1212 // miss) 1213 if (fetchStatus[tid] == IcacheWaitResponse) { 1214 panic("Fetch should have exited prior to this!"); 1215 } 1216 --- 212 unchanged lines hidden --- |