fetch_impl.hh (3070:0ca43be10749) | fetch_impl.hh (3093:b09c33e66bce) |
---|---|
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; --- 325 unchanged lines hidden (view full) --- 334template<class Impl> 335void 336DefaultFetch<Impl>::initStage() 337{ 338 // Setup PC and nextPC with initial state. 339 for (int tid = 0; tid < numThreads; tid++) { 340 PC[tid] = cpu->readPC(tid); 341 nextPC[tid] = cpu->readNextPC(tid); | 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; --- 325 unchanged lines hidden (view full) --- 334template<class Impl> 335void 336DefaultFetch<Impl>::initStage() 337{ 338 // Setup PC and nextPC with initial state. 339 for (int tid = 0; tid < numThreads; tid++) { 340 PC[tid] = cpu->readPC(tid); 341 nextPC[tid] = cpu->readNextPC(tid); |
342#if THE_ISA != ALPHA_ISA | 342#if ISA_HAS_DELAY_SLOT |
343 nextNPC[tid] = cpu->readNextNPC(tid); 344#endif 345 } 346} 347 348template<class Impl> 349void 350DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt) --- 73 unchanged lines hidden (view full) --- 424 // Reset all state 425 for (int i = 0; i < Impl::MaxThreads; ++i) { 426 stalls[i].decode = 0; 427 stalls[i].rename = 0; 428 stalls[i].iew = 0; 429 stalls[i].commit = 0; 430 PC[i] = cpu->readPC(i); 431 nextPC[i] = cpu->readNextPC(i); | 343 nextNPC[tid] = cpu->readNextNPC(tid); 344#endif 345 } 346} 347 348template<class Impl> 349void 350DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt) --- 73 unchanged lines hidden (view full) --- 424 // Reset all state 425 for (int i = 0; i < Impl::MaxThreads; ++i) { 426 stalls[i].decode = 0; 427 stalls[i].rename = 0; 428 stalls[i].iew = 0; 429 stalls[i].commit = 0; 430 PC[i] = cpu->readPC(i); 431 nextPC[i] = cpu->readNextPC(i); |
432#if THE_ISA != ALPHA_ISA | 432#if ISA_HAS_DELAY_SLOT |
433 nextNPC[i] = cpu->readNextNPC(i); 434 delaySlotInfo[i].branchSeqNum = -1; 435 delaySlotInfo[i].numInsts = 0; 436 delaySlotInfo[i].targetAddr = 0; 437 delaySlotInfo[i].targetReady = false; 438#endif 439 fetchStatus[i] = Running; 440 } --- 46 unchanged lines hidden (view full) --- 487 Addr &next_NPC) 488{ 489 // Do branch prediction check here. 490 // A bit of a misnomer...next_PC is actually the current PC until 491 // this function updates it. 492 bool predict_taken; 493 494 if (!inst->isControl()) { | 433 nextNPC[i] = cpu->readNextNPC(i); 434 delaySlotInfo[i].branchSeqNum = -1; 435 delaySlotInfo[i].numInsts = 0; 436 delaySlotInfo[i].targetAddr = 0; 437 delaySlotInfo[i].targetReady = false; 438#endif 439 fetchStatus[i] = Running; 440 } --- 46 unchanged lines hidden (view full) --- 487 Addr &next_NPC) 488{ 489 // Do branch prediction check here. 490 // A bit of a misnomer...next_PC is actually the current PC until 491 // this function updates it. 492 bool predict_taken; 493 494 if (!inst->isControl()) { |
495#if THE_ISA == ALPHA_ISA 496 next_PC = next_PC + instSize; 497 inst->setPredTarg(next_PC); 498#else | 495#if ISA_HAS_DELAY_SLOT |
499 Addr cur_PC = next_PC; 500 next_PC = cur_PC + instSize; //next_NPC; 501 next_NPC = cur_PC + (2 * instSize);//next_NPC + instSize; 502 inst->setPredTarg(next_NPC); | 496 Addr cur_PC = next_PC; 497 next_PC = cur_PC + instSize; //next_NPC; 498 next_NPC = cur_PC + (2 * instSize);//next_NPC + instSize; 499 inst->setPredTarg(next_NPC); |
500#else 501 next_PC = next_PC + instSize; 502 inst->setPredTarg(next_PC); |
|
503#endif 504 return false; 505 } 506 507 int tid = inst->threadNumber; | 503#endif 504 return false; 505 } 506 507 int tid = inst->threadNumber; |
508#if THE_ISA == ALPHA_ISA 509 predict_taken = branchPred.predict(inst, next_PC, tid); 510#else | 508#if ISA_HAS_DELAY_SLOT |
511 Addr pred_PC = next_PC; 512 predict_taken = branchPred.predict(inst, pred_PC, tid); 513 514 if (predict_taken) { 515 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be true.\n", tid); 516 } else { 517 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be false.\n", tid); 518 } --- 15 unchanged lines hidden (view full) --- 534 } else { 535 next_PC = next_NPC; 536 // No need to declare a delay slot here since 537 // there is no for the pred. target to jump 538 } 539 540 next_NPC = next_NPC + instSize; 541 } | 509 Addr pred_PC = next_PC; 510 predict_taken = branchPred.predict(inst, pred_PC, tid); 511 512 if (predict_taken) { 513 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be true.\n", tid); 514 } else { 515 DPRINTF(Fetch, "[tid:%i]: Branch predicted to be false.\n", tid); 516 } --- 15 unchanged lines hidden (view full) --- 532 } else { 533 next_PC = next_NPC; 534 // No need to declare a delay slot here since 535 // there is no for the pred. target to jump 536 } 537 538 next_NPC = next_NPC + instSize; 539 } |
540#else 541 predict_taken = branchPred.predict(inst, next_PC, tid); |
|
542#endif 543 544 ++fetchedBranches; 545 546 if (predict_taken) { 547 ++predictedBranches; 548 } 549 --- 137 unchanged lines hidden (view full) --- 687DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC, 688 const InstSeqNum &seq_num, 689 unsigned tid) 690{ 691 DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid); 692 693 doSquash(new_PC, tid); 694 | 542#endif 543 544 ++fetchedBranches; 545 546 if (predict_taken) { 547 ++predictedBranches; 548 } 549 --- 137 unchanged lines hidden (view full) --- 687DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC, 688 const InstSeqNum &seq_num, 689 unsigned tid) 690{ 691 DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid); 692 693 doSquash(new_PC, tid); 694 |
695#if THE_ISA != ALPHA_ISA | 695#if ISA_HAS_DELAY_SLOT |
696 if (seq_num <= delaySlotInfo[tid].branchSeqNum) { 697 delaySlotInfo[tid].numInsts = 0; 698 delaySlotInfo[tid].targetAddr = 0; 699 delaySlotInfo[tid].targetReady = false; 700 } 701#endif 702 703 // Tell the CPU to remove any instructions that are in flight between --- 71 unchanged lines hidden (view full) --- 775void 776DefaultFetch<Impl>::squash(const Addr &new_PC, const InstSeqNum &seq_num, 777 bool squash_delay_slot, unsigned tid) 778{ 779 DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid); 780 781 doSquash(new_PC, tid); 782 | 696 if (seq_num <= delaySlotInfo[tid].branchSeqNum) { 697 delaySlotInfo[tid].numInsts = 0; 698 delaySlotInfo[tid].targetAddr = 0; 699 delaySlotInfo[tid].targetReady = false; 700 } 701#endif 702 703 // Tell the CPU to remove any instructions that are in flight between --- 71 unchanged lines hidden (view full) --- 775void 776DefaultFetch<Impl>::squash(const Addr &new_PC, const InstSeqNum &seq_num, 777 bool squash_delay_slot, unsigned tid) 778{ 779 DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid); 780 781 doSquash(new_PC, tid); 782 |
783#if THE_ISA == ALPHA_ISA 784 // Tell the CPU to remove any instructions that are not in the ROB. 785 cpu->removeInstsNotInROB(tid, true, 0); 786#else | 783#if ISA_HAS_DELAY_SLOT |
787 if (seq_num <= delaySlotInfo[tid].branchSeqNum) { 788 delaySlotInfo[tid].numInsts = 0; 789 delaySlotInfo[tid].targetAddr = 0; 790 delaySlotInfo[tid].targetReady = false; 791 } 792 793 // Tell the CPU to remove any instructions that are not in the ROB. 794 cpu->removeInstsNotInROB(tid, squash_delay_slot, seq_num); | 784 if (seq_num <= delaySlotInfo[tid].branchSeqNum) { 785 delaySlotInfo[tid].numInsts = 0; 786 delaySlotInfo[tid].targetAddr = 0; 787 delaySlotInfo[tid].targetReady = false; 788 } 789 790 // Tell the CPU to remove any instructions that are not in the ROB. 791 cpu->removeInstsNotInROB(tid, squash_delay_slot, seq_num); |
792#else 793 // Tell the CPU to remove any instructions that are not in the ROB. 794 cpu->removeInstsNotInROB(tid, true, 0); |
|
795#endif 796} 797 798template <class Impl> 799void 800DefaultFetch<Impl>::tick() 801{ 802 std::list<unsigned>::iterator threads = (*activeThreads).begin(); --- 93 unchanged lines hidden (view full) --- 896 } 897 898 // Check squash signals from commit. 899 if (fromCommit->commitInfo[tid].squash) { 900 901 DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash " 902 "from commit.\n",tid); 903 | 795#endif 796} 797 798template <class Impl> 799void 800DefaultFetch<Impl>::tick() 801{ 802 std::list<unsigned>::iterator threads = (*activeThreads).begin(); --- 93 unchanged lines hidden (view full) --- 896 } 897 898 // Check squash signals from commit. 899 if (fromCommit->commitInfo[tid].squash) { 900 901 DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash " 902 "from commit.\n",tid); 903 |
904#if THE_ISA == ALPHA_ISA 905 InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].doneSeqNum; | 904#if ISA_HAS_DELAY_SLOT 905 InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].bdelayDoneSeqNum; |
906#else | 906#else |
907 InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].bdelayDoneSeqNum; | 907 InstSeqNum doneSeqNum = fromCommit->commitInfo[tid].doneSeqNum; |
908#endif 909 // In any case, squash. 910 squash(fromCommit->commitInfo[tid].nextPC, 911 doneSeqNum, 912 fromCommit->commitInfo[tid].squashDelaySlot, 913 tid); 914 915 // Also check if there's a mispredict that happened. --- 37 unchanged lines hidden (view full) --- 953 tid); 954 } else { 955 branchPred.squash(fromDecode->decodeInfo[tid].doneSeqNum, 956 tid); 957 } 958 959 if (fetchStatus[tid] != Squashing) { 960 | 908#endif 909 // In any case, squash. 910 squash(fromCommit->commitInfo[tid].nextPC, 911 doneSeqNum, 912 fromCommit->commitInfo[tid].squashDelaySlot, 913 tid); 914 915 // Also check if there's a mispredict that happened. --- 37 unchanged lines hidden (view full) --- 953 tid); 954 } else { 955 branchPred.squash(fromDecode->decodeInfo[tid].doneSeqNum, 956 tid); 957 } 958 959 if (fetchStatus[tid] != Squashing) { 960 |
961#if THE_ISA == ALPHA_ISA 962 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum; 963#else | 961#if ISA_HAS_DELAY_SLOT |
964 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].bdelayDoneSeqNum; | 962 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].bdelayDoneSeqNum; |
963#else 964 InstSeqNum doneSeqNum = fromDecode->decodeInfo[tid].doneSeqNum; |
|
965#endif 966 // Squash unless we're already squashing 967 squashFromDecode(fromDecode->decodeInfo[tid].nextPC, 968 doneSeqNum, 969 tid); 970 971 return true; 972 } --- 151 unchanged lines hidden (view full) --- 1124 DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created " 1125 "[sn:%lli]\n", 1126 tid, instruction->readPC(), inst_seq); 1127 1128 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", 1129 tid, instruction->staticInst->disassemble(fetch_PC)); 1130 1131 instruction->traceData = | 965#endif 966 // Squash unless we're already squashing 967 squashFromDecode(fromDecode->decodeInfo[tid].nextPC, 968 doneSeqNum, 969 tid); 970 971 return true; 972 } --- 151 unchanged lines hidden (view full) --- 1124 DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x created " 1125 "[sn:%lli]\n", 1126 tid, instruction->readPC(), inst_seq); 1127 1128 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", 1129 tid, instruction->staticInst->disassemble(fetch_PC)); 1130 1131 instruction->traceData = |
1132 Trace::getInstRecord(curTick, cpu->tcBase(tid), | 1132 Trace::getInstRecord(curTick, cpu->tcBase(tid), cpu, |
1133 instruction->staticInst, | 1133 instruction->staticInst, |
1134 instruction->readPC()); | 1134 instruction->readPC(),tid); |
1135 1136 predicted_branch = lookupAndUpdateNextPC(instruction, next_PC, 1137 next_NPC); 1138 1139 // Add instruction to the CPU's list of instructions. 1140 instruction->setInstListIt(cpu->addInst(instruction)); 1141 1142 // Write the instruction to the first slot in the queue --- 14 unchanged lines hidden (view full) --- 1157 fetchStatus[tid] = QuiescePending; 1158 ++numInst; 1159 status_change = true; 1160 break; 1161 } 1162 1163 offset += instSize; 1164 | 1135 1136 predicted_branch = lookupAndUpdateNextPC(instruction, next_PC, 1137 next_NPC); 1138 1139 // Add instruction to the CPU's list of instructions. 1140 instruction->setInstListIt(cpu->addInst(instruction)); 1141 1142 // Write the instruction to the first slot in the queue --- 14 unchanged lines hidden (view full) --- 1157 fetchStatus[tid] = QuiescePending; 1158 ++numInst; 1159 status_change = true; 1160 break; 1161 } 1162 1163 offset += instSize; 1164 |
1165#if THE_ISA != ALPHA_ISA | 1165#if ISA_HAS_DELAY_SLOT |
1166 if (predicted_branch) { 1167 delaySlotInfo[tid].branchSeqNum = inst_seq; 1168 1169 DPRINTF(Fetch, "[tid:%i]: Delay slot branch set to [sn:%i]\n", 1170 tid, inst_seq); 1171 continue; 1172 } else if (delaySlotInfo[tid].numInsts > 0) { 1173 --delaySlotInfo[tid].numInsts; --- 26 unchanged lines hidden (view full) --- 1200 1201 if (numInst > 0) { 1202 wroteToTimeBuffer = true; 1203 } 1204 1205 // Now that fetching is completed, update the PC to signify what the next 1206 // cycle will be. 1207 if (fault == NoFault) { | 1166 if (predicted_branch) { 1167 delaySlotInfo[tid].branchSeqNum = inst_seq; 1168 1169 DPRINTF(Fetch, "[tid:%i]: Delay slot branch set to [sn:%i]\n", 1170 tid, inst_seq); 1171 continue; 1172 } else if (delaySlotInfo[tid].numInsts > 0) { 1173 --delaySlotInfo[tid].numInsts; --- 26 unchanged lines hidden (view full) --- 1200 1201 if (numInst > 0) { 1202 wroteToTimeBuffer = true; 1203 } 1204 1205 // Now that fetching is completed, update the PC to signify what the next 1206 // cycle will be. 1207 if (fault == NoFault) { |
1208#if THE_ISA == ALPHA_ISA 1209 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC); 1210 PC[tid] = next_PC; 1211 nextPC[tid] = next_PC + instSize; 1212#else | 1208#if ISA_HAS_DELAY_SLOT |
1213 if (delaySlotInfo[tid].targetReady && 1214 delaySlotInfo[tid].numInsts == 0) { 1215 // Set PC to target 1216 PC[tid] = delaySlotInfo[tid].targetAddr; //next_PC 1217 nextPC[tid] = next_PC + instSize; //next_NPC 1218 nextNPC[tid] = next_PC + (2 * instSize); 1219 1220 delaySlotInfo[tid].targetReady = false; 1221 } else { 1222 PC[tid] = next_PC; 1223 nextPC[tid] = next_NPC; 1224 nextNPC[tid] = next_NPC + instSize; 1225 } 1226 1227 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]); | 1209 if (delaySlotInfo[tid].targetReady && 1210 delaySlotInfo[tid].numInsts == 0) { 1211 // Set PC to target 1212 PC[tid] = delaySlotInfo[tid].targetAddr; //next_PC 1213 nextPC[tid] = next_PC + instSize; //next_NPC 1214 nextNPC[tid] = next_PC + (2 * instSize); 1215 1216 delaySlotInfo[tid].targetReady = false; 1217 } else { 1218 PC[tid] = next_PC; 1219 nextPC[tid] = next_NPC; 1220 nextNPC[tid] = next_NPC + instSize; 1221 } 1222 1223 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, PC[tid]); |
1224#else 1225 DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n",tid, next_PC); 1226 PC[tid] = next_PC; 1227 nextPC[tid] = next_PC + instSize; |
|
1228#endif 1229 } else { 1230 // We shouldn't be in an icache miss and also have a fault (an ITB 1231 // miss) 1232 if (fetchStatus[tid] == IcacheWaitResponse) { 1233 panic("Fetch should have exited prior to this!"); 1234 } 1235 --- 209 unchanged lines hidden --- | 1228#endif 1229 } else { 1230 // We shouldn't be in an icache miss and also have a fault (an ITB 1231 // miss) 1232 if (fetchStatus[tid] == IcacheWaitResponse) { 1233 panic("Fetch should have exited prior to this!"); 1234 } 1235 --- 209 unchanged lines hidden --- |