fetch_impl.hh (7720:65d338a8dba4) fetch_impl.hh (7764:03efcdc3421f)
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;

--- 303 unchanged lines hidden (view full) ---

312
313template<class Impl>
314void
315DefaultFetch<Impl>::initStage()
316{
317 // Setup PC and nextPC with initial state.
318 for (ThreadID tid = 0; tid < numThreads; tid++) {
319 pc[tid] = cpu->pcState(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;

--- 303 unchanged lines hidden (view full) ---

312
313template<class Impl>
314void
315DefaultFetch<Impl>::initStage()
316{
317 // Setup PC and nextPC with initial state.
318 for (ThreadID tid = 0; tid < numThreads; tid++) {
319 pc[tid] = cpu->pcState(tid);
320 fetchOffset[tid] = 0;
321 macroop[tid] = NULL;
320 }
321
322 for (ThreadID tid = 0; tid < numThreads; tid++) {
323
324 fetchStatus[tid] = Running;
325
326 priorityList.push_back(tid);
327

--- 201 unchanged lines hidden (view full) ---

529 ++predictedBranches;
530 }
531
532 return predict_taken;
533}
534
535template <class Impl>
536bool
322 }
323
324 for (ThreadID tid = 0; tid < numThreads; tid++) {
325
326 fetchStatus[tid] = Running;
327
328 priorityList.push_back(tid);
329

--- 201 unchanged lines hidden (view full) ---

531 ++predictedBranches;
532 }
533
534 return predict_taken;
535}
536
537template <class Impl>
538bool
537DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, ThreadID tid)
539DefaultFetch<Impl>::fetchCacheLine(Addr vaddr, Fault &ret_fault, ThreadID tid,
540 Addr pc)
538{
539 Fault fault = NoFault;
540
541 //AlphaDep
542 if (cacheBlocked) {
543 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n",
544 tid);
545 return false;
546 } else if (isSwitchedOut()) {
547 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, switched out\n",
548 tid);
549 return false;
541{
542 Fault fault = NoFault;
543
544 //AlphaDep
545 if (cacheBlocked) {
546 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n",
547 tid);
548 return false;
549 } else if (isSwitchedOut()) {
550 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, switched out\n",
551 tid);
552 return false;
550 } else if (interruptPending && !(fetch_PC & 0x3)) {
553 } else if (interruptPending && !(pc & 0x3)) {
551 // Hold off fetch from getting new instructions when:
552 // Cache is blocked, or
553 // while an interrupt is pending and we're not in PAL mode, or
554 // fetch is switched out.
555 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n",
556 tid);
557 return false;
558 }
559
554 // Hold off fetch from getting new instructions when:
555 // Cache is blocked, or
556 // while an interrupt is pending and we're not in PAL mode, or
557 // fetch is switched out.
558 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n",
559 tid);
560 return false;
561 }
562
560 // Align the fetch PC so it's at the start of a cache block.
561 Addr block_PC = icacheBlockAlignPC(fetch_PC);
563 // Align the fetch address so it's at the start of a cache block.
564 Addr block_PC = icacheBlockAlignPC(vaddr);
562
563 // If we've already got the block, no need to try to fetch it again.
564 if (cacheDataValid[tid] && block_PC == cacheDataPC[tid]) {
565 return true;
566 }
567
568 // Setup the memReq to do a read of the first instruction's address.
569 // Set the appropriate read size and flags as well.
570 // Build request here.
571 RequestPtr mem_req =
572 new Request(tid, block_PC, cacheBlkSize, Request::INST_FETCH,
565
566 // If we've already got the block, no need to try to fetch it again.
567 if (cacheDataValid[tid] && block_PC == cacheDataPC[tid]) {
568 return true;
569 }
570
571 // Setup the memReq to do a read of the first instruction's address.
572 // Set the appropriate read size and flags as well.
573 // Build request here.
574 RequestPtr mem_req =
575 new Request(tid, block_PC, cacheBlkSize, Request::INST_FETCH,
573 fetch_PC, cpu->thread[tid]->contextId(), tid);
576 pc, cpu->thread[tid]->contextId(), tid);
574
575 memReq[tid] = mem_req;
576
577 // Translate the instruction request.
578 fault = cpu->itb->translateAtomic(mem_req, cpu->thread[tid]->getTC(),
579 BaseTLB::Execute);
580
581 // In the case of faults, the fetch stage may need to stall and wait

--- 58 unchanged lines hidden (view full) ---

640template <class Impl>
641inline void
642DefaultFetch<Impl>::doSquash(const TheISA::PCState &newPC, ThreadID tid)
643{
644 DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %s.\n",
645 tid, newPC);
646
647 pc[tid] = newPC;
577
578 memReq[tid] = mem_req;
579
580 // Translate the instruction request.
581 fault = cpu->itb->translateAtomic(mem_req, cpu->thread[tid]->getTC(),
582 BaseTLB::Execute);
583
584 // In the case of faults, the fetch stage may need to stall and wait

--- 58 unchanged lines hidden (view full) ---

643template <class Impl>
644inline void
645DefaultFetch<Impl>::doSquash(const TheISA::PCState &newPC, ThreadID tid)
646{
647 DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %s.\n",
648 tid, newPC);
649
650 pc[tid] = newPC;
651 fetchOffset[tid] = 0;
652 macroop[tid] = NULL;
653 predecoder.reset();
648
649 // Clear the icache miss if it's outstanding.
650 if (fetchStatus[tid] == IcacheWaitResponse) {
651 DPRINTF(Fetch, "[tid:%i]: Squashing outstanding Icache miss.\n",
652 tid);
653 memReq[tid] = NULL;
654 }
655

--- 297 unchanged lines hidden (view full) ---

953 }
954
955 // If we've reached this point, we have not gotten any signals that
956 // cause fetch to change its status. Fetch remains the same as before.
957 return false;
958}
959
960template<class Impl>
654
655 // Clear the icache miss if it's outstanding.
656 if (fetchStatus[tid] == IcacheWaitResponse) {
657 DPRINTF(Fetch, "[tid:%i]: Squashing outstanding Icache miss.\n",
658 tid);
659 memReq[tid] = NULL;
660 }
661

--- 297 unchanged lines hidden (view full) ---

959 }
960
961 // If we've reached this point, we have not gotten any signals that
962 // cause fetch to change its status. Fetch remains the same as before.
963 return false;
964}
965
966template<class Impl>
967typename Impl::DynInstPtr
968DefaultFetch<Impl>::buildInst(ThreadID tid, StaticInstPtr staticInst,
969 StaticInstPtr curMacroop, TheISA::PCState thisPC,
970 TheISA::PCState nextPC, bool trace)
971{
972 // Get a sequence number.
973 InstSeqNum seq = cpu->getAndIncrementInstSeq();
974
975 // Create a new DynInst from the instruction fetched.
976 DynInstPtr instruction =
977 new DynInst(staticInst, thisPC, nextPC, seq, cpu);
978 instruction->setTid(tid);
979
980 instruction->setASID(tid);
981
982 instruction->setThreadState(cpu->thread[tid]);
983
984 DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x (%d) created "
985 "[sn:%lli]\n", tid, thisPC.instAddr(),
986 thisPC.microPC(), seq);
987
988 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", tid,
989 instruction->staticInst->
990 disassemble(thisPC.instAddr()));
991
992#if TRACING_ON
993 if (trace) {
994 instruction->traceData =
995 cpu->getTracer()->getInstRecord(curTick, cpu->tcBase(tid),
996 instruction->staticInst, thisPC, curMacroop);
997 }
998#else
999 instruction->traceData = NULL;
1000#endif
1001
1002 // Add instruction to the CPU's list of instructions.
1003 instruction->setInstListIt(cpu->addInst(instruction));
1004
1005 // Write the instruction to the first slot in the queue
1006 // that heads to decode.
1007 assert(numInst < fetchWidth);
1008 toDecode->insts[toDecode->size++] = instruction;
1009
1010 return instruction;
1011}
1012
1013template<class Impl>
961void
962DefaultFetch<Impl>::fetch(bool &status_change)
963{
964 //////////////////////////////////////////
965 // Start actual fetch
966 //////////////////////////////////////////
967 ThreadID tid = getFetchingThread(fetchPolicy);
968
969 if (tid == InvalidThreadID || drainPending) {
970 DPRINTF(Fetch,"There are no more threads available to fetch from.\n");
971
972 // Breaks looping condition in tick()
973 threadFetched = numFetchingThreads;
974 return;
975 }
976
977 DPRINTF(Fetch, "Attempting to fetch from [tid:%i]\n", tid);
978
979 // The current PC.
1014void
1015DefaultFetch<Impl>::fetch(bool &status_change)
1016{
1017 //////////////////////////////////////////
1018 // Start actual fetch
1019 //////////////////////////////////////////
1020 ThreadID tid = getFetchingThread(fetchPolicy);
1021
1022 if (tid == InvalidThreadID || drainPending) {
1023 DPRINTF(Fetch,"There are no more threads available to fetch from.\n");
1024
1025 // Breaks looping condition in tick()
1026 threadFetched = numFetchingThreads;
1027 return;
1028 }
1029
1030 DPRINTF(Fetch, "Attempting to fetch from [tid:%i]\n", tid);
1031
1032 // The current PC.
980 TheISA::PCState fetchPC = pc[tid];
1033 TheISA::PCState thisPC = pc[tid];
981
982 // Fault code for memory access.
983 Fault fault = NoFault;
984
1034
1035 // Fault code for memory access.
1036 Fault fault = NoFault;
1037
1038 Addr pcOffset = fetchOffset[tid];
1039 Addr fetchAddr = (thisPC.instAddr() + pcOffset) & BaseCPU::PCMask;
1040
985 // If returning from the delay of a cache miss, then update the status
986 // to running, otherwise do the cache access. Possibly move this up
987 // to tick() function.
988 if (fetchStatus[tid] == IcacheAccessComplete) {
1041 // If returning from the delay of a cache miss, then update the status
1042 // to running, otherwise do the cache access. Possibly move this up
1043 // to tick() function.
1044 if (fetchStatus[tid] == IcacheAccessComplete) {
989 DPRINTF(Fetch, "[tid:%i]: Icache miss is complete.\n",
990 tid);
1045 DPRINTF(Fetch, "[tid:%i]: Icache miss is complete.\n",tid);
991
992 fetchStatus[tid] = Running;
993 status_change = true;
994 } else if (fetchStatus[tid] == Running) {
995 DPRINTF(Fetch, "[tid:%i]: Attempting to translate and read "
1046
1047 fetchStatus[tid] = Running;
1048 status_change = true;
1049 } else if (fetchStatus[tid] == Running) {
1050 DPRINTF(Fetch, "[tid:%i]: Attempting to translate and read "
996 "instruction, starting at PC %s.\n", tid, fetchPC);
1051 "instruction, starting at PC %#x.\n", tid, fetchAddr);
997
1052
998 bool fetch_success = fetchCacheLine(fetchPC.instAddr(), fault, tid);
1053 bool fetch_success = fetchCacheLine(fetchAddr, fault, tid,
1054 thisPC.instAddr());
999 if (!fetch_success) {
1000 if (cacheBlocked) {
1001 ++icacheStallCycles;
1002 } else {
1003 ++fetchMiscStallCycles;
1004 }
1005 return;
1006 }

--- 21 unchanged lines hidden (view full) ---

1028
1029 // If we had a stall due to an icache miss, then return.
1030 if (fetchStatus[tid] == IcacheWaitResponse) {
1031 ++icacheStallCycles;
1032 status_change = true;
1033 return;
1034 }
1035
1055 if (!fetch_success) {
1056 if (cacheBlocked) {
1057 ++icacheStallCycles;
1058 } else {
1059 ++fetchMiscStallCycles;
1060 }
1061 return;
1062 }

--- 21 unchanged lines hidden (view full) ---

1084
1085 // If we had a stall due to an icache miss, then return.
1086 if (fetchStatus[tid] == IcacheWaitResponse) {
1087 ++icacheStallCycles;
1088 status_change = true;
1089 return;
1090 }
1091
1036 TheISA::PCState nextPC = fetchPC;
1092 TheISA::PCState nextPC = thisPC;
1037
1093
1038 InstSeqNum inst_seq;
1039 MachInst inst;
1040 ExtMachInst ext_inst;
1041
1042 StaticInstPtr staticInst = NULL;
1094 StaticInstPtr staticInst = NULL;
1043 StaticInstPtr macroop = NULL;
1095 StaticInstPtr curMacroop = macroop[tid];
1044
1045 if (fault == NoFault) {
1096
1097 if (fault == NoFault) {
1046 //XXX Masking out pal mode bit. This will break x86. Alpha needs
1047 //to pull the pal mode bit ouf ot the instruction address.
1048 unsigned offset = (fetchPC.instAddr() & ~1) - cacheDataPC[tid];
1049 assert(offset < cacheBlkSize);
1050
1051 // If the read of the first instruction was successful, then grab the
1052 // instructions from the rest of the cache line and put them into the
1053 // queue heading to decode.
1054
1098
1099 // If the read of the first instruction was successful, then grab the
1100 // instructions from the rest of the cache line and put them into the
1101 // queue heading to decode.
1102
1055 DPRINTF(Fetch, "[tid:%i]: Adding instructions to queue to "
1056 "decode.\n",tid);
1103 DPRINTF(Fetch,
1104 "[tid:%i]: Adding instructions to queue to decode.\n", tid);
1057
1058 // Need to keep track of whether or not a predicted branch
1059 // ended this fetch block.
1105
1106 // Need to keep track of whether or not a predicted branch
1107 // ended this fetch block.
1060 bool predicted_branch = false;
1108 bool predictedBranch = false;
1061
1109
1062 while (offset < cacheBlkSize &&
1063 numInst < fetchWidth &&
1064 !predicted_branch) {
1110 TheISA::MachInst *cacheInsts =
1111 reinterpret_cast<TheISA::MachInst *>(cacheData[tid]);
1065
1112
1066 // Make sure this is a valid index.
1067 assert(offset <= cacheBlkSize - instSize);
1113 const unsigned numInsts = cacheBlkSize / instSize;
1114 unsigned blkOffset = (fetchAddr - cacheDataPC[tid]) / instSize;
1068
1115
1069 if (!macroop) {
1070 // Get the instruction from the array of the cache line.
1071 inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
1072 (&cacheData[tid][offset]));
1116 // Loop through instruction memory from the cache.
1117 while (blkOffset < numInsts &&
1118 numInst < fetchWidth &&
1119 !predictedBranch) {
1073
1120
1121 // If we need to process more memory, do it now.
1122 if (!curMacroop && !predecoder.extMachInstReady()) {
1123 if (ISA_HAS_DELAY_SLOT && pcOffset == 0) {
1124 // Walk past any annulled delay slot instructions.
1125 Addr pcAddr = thisPC.instAddr() & BaseCPU::PCMask;
1126 while (fetchAddr != pcAddr && blkOffset < numInsts) {
1127 blkOffset++;
1128 fetchAddr += instSize;
1129 }
1130 if (blkOffset >= numInsts)
1131 break;
1132 }
1133 MachInst inst = TheISA::gtoh(cacheInsts[blkOffset]);
1134
1074 predecoder.setTC(cpu->thread[tid]->getTC());
1135 predecoder.setTC(cpu->thread[tid]->getTC());
1075 predecoder.moreBytes(fetchPC, fetchPC.instAddr(), inst);
1136 predecoder.moreBytes(thisPC, fetchAddr, inst);
1076
1137
1077 ext_inst = predecoder.getExtMachInst(fetchPC);
1078 staticInst = StaticInstPtr(ext_inst, fetchPC.instAddr());
1079 if (staticInst->isMacroop())
1080 macroop = staticInst;
1138 if (predecoder.needMoreBytes()) {
1139 blkOffset++;
1140 fetchAddr += instSize;
1141 pcOffset += instSize;
1142 }
1081 }
1143 }
1144
1145 // Extract as many instructions and/or microops as we can from
1146 // the memory we've processed so far.
1082 do {
1147 do {
1083 if (macroop) {
1084 staticInst = macroop->fetchMicroop(fetchPC.microPC());
1085 if (staticInst->isLastMicroop())
1086 macroop = NULL;
1087 }
1148 if (!curMacroop) {
1149 if (predecoder.extMachInstReady()) {
1150 ExtMachInst extMachInst;
1088
1151
1089 // Get a sequence number.
1090 inst_seq = cpu->getAndIncrementInstSeq();
1152 extMachInst = predecoder.getExtMachInst(thisPC);
1153 pcOffset = 0;
1154 staticInst = StaticInstPtr(extMachInst,
1155 thisPC.instAddr());
1091
1156
1092 // Create a new DynInst from the instruction fetched.
1093 DynInstPtr instruction = new DynInst(staticInst,
1094 fetchPC, nextPC,
1095 inst_seq, cpu);
1096 instruction->setTid(tid);
1157 // Increment stat of fetched instructions.
1158 ++fetchedInsts;
1097
1159
1098 instruction->setASID(tid);
1160 if (staticInst->isMacroop())
1161 curMacroop = staticInst;
1162 } else {
1163 // We need more bytes for this instruction.
1164 break;
1165 }
1166 }
1167 if (curMacroop) {
1168 staticInst = curMacroop->fetchMicroop(thisPC.microPC());
1169 if (staticInst->isLastMicroop())
1170 curMacroop = NULL;
1171 }
1099
1172
1100 instruction->setThreadState(cpu->thread[tid]);
1173 DynInstPtr instruction =
1174 buildInst(tid, staticInst, curMacroop,
1175 thisPC, nextPC, true);
1101
1176
1102 DPRINTF(Fetch, "[tid:%i]: Instruction PC %s (%d) created "
1103 "[sn:%lli]\n", tid, instruction->pcState(),
1104 instruction->microPC(), inst_seq);
1177 numInst++;
1105
1178
1106 //DPRINTF(Fetch, "[tid:%i]: MachInst is %#x\n", tid, ext_inst);
1179 nextPC = thisPC;
1107
1180
1108 DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", tid,
1109 instruction->staticInst->
1110 disassemble(fetchPC.instAddr()));
1111
1112#if TRACING_ON
1113 instruction->traceData =
1114 cpu->getTracer()->getInstRecord(curTick, cpu->tcBase(tid),
1115 instruction->staticInst, fetchPC, macroop);
1116#else
1117 instruction->traceData = NULL;
1118#endif
1119
1120 // If we're branching after this instruction, quite fetching
1121 // from the same block then.
1181 // If we're branching after this instruction, quite fetching
1182 // from the same block then.
1122 predicted_branch = fetchPC.branching();
1123 predicted_branch |=
1183 predictedBranch |= thisPC.branching();
1184 predictedBranch |=
1124 lookupAndUpdateNextPC(instruction, nextPC);
1185 lookupAndUpdateNextPC(instruction, nextPC);
1125 if (predicted_branch) {
1126 DPRINTF(Fetch, "Branch detected with PC = %s\n", fetchPC);
1186 if (predictedBranch) {
1187 DPRINTF(Fetch, "Branch detected with PC = %s\n", thisPC);
1127 }
1128
1188 }
1189
1129 // Add instruction to the CPU's list of instructions.
1130 instruction->setInstListIt(cpu->addInst(instruction));
1131
1132 // Write the instruction to the first slot in the queue
1133 // that heads to decode.
1134 toDecode->insts[numInst] = instruction;
1135
1136 toDecode->size++;
1137
1138 // Increment stat of fetched instructions.
1139 ++fetchedInsts;
1140
1141 // Move to the next instruction, unless we have a branch.
1190 // Move to the next instruction, unless we have a branch.
1142 fetchPC = nextPC;
1191 thisPC = nextPC;
1143
1144 if (instruction->isQuiesce()) {
1192
1193 if (instruction->isQuiesce()) {
1145 DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!",
1146 curTick);
1194 DPRINTF(Fetch,
1195 "Quiesce instruction encountered, halting fetch!");
1147 fetchStatus[tid] = QuiescePending;
1196 fetchStatus[tid] = QuiescePending;
1148 ++numInst;
1149 status_change = true;
1150 break;
1151 }
1197 status_change = true;
1198 break;
1199 }
1152
1153 ++numInst;
1154 } while (staticInst->isMicroop() &&
1155 !staticInst->isLastMicroop() &&
1200 } while ((curMacroop || predecoder.extMachInstReady()) &&
1156 numInst < fetchWidth);
1201 numInst < fetchWidth);
1157 //XXX Masking out pal mode bit.
1158 offset = (fetchPC.instAddr() & ~1) - cacheDataPC[tid];
1159 }
1160
1202 }
1203
1161 if (predicted_branch) {
1204 if (predictedBranch) {
1162 DPRINTF(Fetch, "[tid:%i]: Done fetching, predicted branch "
1163 "instruction encountered.\n", tid);
1164 } else if (numInst >= fetchWidth) {
1165 DPRINTF(Fetch, "[tid:%i]: Done fetching, reached fetch bandwidth "
1166 "for this cycle.\n", tid);
1205 DPRINTF(Fetch, "[tid:%i]: Done fetching, predicted branch "
1206 "instruction encountered.\n", tid);
1207 } else if (numInst >= fetchWidth) {
1208 DPRINTF(Fetch, "[tid:%i]: Done fetching, reached fetch bandwidth "
1209 "for this cycle.\n", tid);
1167 } else if (offset >= cacheBlkSize) {
1210 } else if (blkOffset >= cacheBlkSize) {
1168 DPRINTF(Fetch, "[tid:%i]: Done fetching, reached the end of cache "
1169 "block.\n", tid);
1170 }
1171 }
1172
1211 DPRINTF(Fetch, "[tid:%i]: Done fetching, reached the end of cache "
1212 "block.\n", tid);
1213 }
1214 }
1215
1216 macroop[tid] = curMacroop;
1217 fetchOffset[tid] = pcOffset;
1218
1173 if (numInst > 0) {
1174 wroteToTimeBuffer = true;
1175 }
1176
1177 // Now that fetching is completed, update the PC to signify what the next
1178 // cycle will be.
1179 if (fault == NoFault) {
1180 pc[tid] = nextPC;
1181 DPRINTF(Fetch, "[tid:%i]: Setting PC to %s.\n", tid, nextPC);
1182 } else {
1183 // We shouldn't be in an icache miss and also have a fault (an ITB
1184 // miss)
1185 if (fetchStatus[tid] == IcacheWaitResponse) {
1186 panic("Fetch should have exited prior to this!");
1187 }
1188
1189 // Send the fault to commit. This thread will not do anything
1190 // until commit handles the fault. The only other way it can
1219 if (numInst > 0) {
1220 wroteToTimeBuffer = true;
1221 }
1222
1223 // Now that fetching is completed, update the PC to signify what the next
1224 // cycle will be.
1225 if (fault == NoFault) {
1226 pc[tid] = nextPC;
1227 DPRINTF(Fetch, "[tid:%i]: Setting PC to %s.\n", tid, nextPC);
1228 } else {
1229 // We shouldn't be in an icache miss and also have a fault (an ITB
1230 // miss)
1231 if (fetchStatus[tid] == IcacheWaitResponse) {
1232 panic("Fetch should have exited prior to this!");
1233 }
1234
1235 // Send the fault to commit. This thread will not do anything
1236 // until commit handles the fault. The only other way it can
1191 // wake up is if a squash comes along and changes the PC.
1192 assert(numInst < fetchWidth);
1193 // Get a sequence number.
1194 inst_seq = cpu->getAndIncrementInstSeq();
1195 // We will use a nop in order to carry the fault.
1196 ext_inst = TheISA::NoopMachInst;
1237 // wake up is if a squash comes along and changes the PC. Send the
1238 // fault on a dummy nop.
1239 staticInst = StaticInstPtr(TheISA::NoopMachInst, thisPC.instAddr());
1197
1240
1198 // Create a new DynInst from the dummy nop.
1199 DynInstPtr instruction = new DynInst(ext_inst, fetchPC, nextPC,
1200 inst_seq, cpu);
1201 TheISA::advancePC(nextPC, instruction->staticInst);
1202 instruction->setPredTarg(nextPC);
1203 instruction->setTid(tid);
1241 DynInstPtr instruction =
1242 buildInst(tid, staticInst, NULL, thisPC, nextPC, false);
1204
1243
1205 instruction->setASID(tid);
1206
1207 instruction->setThreadState(cpu->thread[tid]);
1208
1209 instruction->traceData = NULL;
1210
1211 instruction->setInstListIt(cpu->addInst(instruction));
1212
1244 TheISA::advancePC(nextPC, staticInst);
1245 instruction->setPredTarg(nextPC);
1213 instruction->fault = fault;
1214
1246 instruction->fault = fault;
1247
1215 toDecode->insts[numInst] = instruction;
1216 toDecode->size++;
1217
1218 wroteToTimeBuffer = true;
1219
1220 DPRINTF(Fetch, "[tid:%i]: Blocked, need to handle the trap.\n",tid);
1221
1222 fetchStatus[tid] = TrapPending;
1223 status_change = true;
1224
1225 DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %s",
1248 DPRINTF(Fetch, "[tid:%i]: Blocked, need to handle the trap.\n",tid);
1249
1250 fetchStatus[tid] = TrapPending;
1251 status_change = true;
1252
1253 DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %s",
1226 tid, fault->name(), pc[tid]);
1254 tid, fault->name(), thisPC);
1227 }
1228}
1229
1230template<class Impl>
1231void
1232DefaultFetch<Impl>::recvRetry()
1233{
1234 if (retryPkt != NULL) {

--- 169 unchanged lines hidden ---
1255 }
1256}
1257
1258template<class Impl>
1259void
1260DefaultFetch<Impl>::recvRetry()
1261{
1262 if (retryPkt != NULL) {

--- 169 unchanged lines hidden ---