1/* 2 * Copyright (c) 2002-2005 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: Steve Reinhardt 29 */ 30 31#include "arch/utility.hh" 32#include "arch/faults.hh" 33#include "base/cprintf.hh" 34#include "base/inifile.hh" 35#include "base/loader/symtab.hh" 36#include "base/misc.hh" 37#include "base/pollevent.hh" 38#include "base/range.hh" 39#include "base/stats/events.hh" 40#include "base/trace.hh" 41#include "cpu/base.hh" 42#include "cpu/exetrace.hh" 43#include "cpu/profile.hh" 44#include "cpu/simple/base.hh" 45#include "cpu/simple_thread.hh" 46#include "cpu/smt.hh" 47#include "cpu/static_inst.hh" 48#include "cpu/thread_context.hh" 49#include "mem/packet.hh" 50#include "sim/byteswap.hh" 51#include "sim/debug.hh" 52#include "sim/host.hh" 53#include "sim/sim_events.hh" 54#include "sim/sim_object.hh" 55#include "sim/stats.hh" 56#include "sim/system.hh" 57 58#if FULL_SYSTEM 59#include "arch/kernel_stats.hh" 60#include "arch/stacktrace.hh" 61#include "arch/tlb.hh" 62#include "arch/vtophys.hh" 63#include "base/remote_gdb.hh" 64#else // !FULL_SYSTEM 65#include "mem/mem_object.hh" 66#endif // FULL_SYSTEM 67 68using namespace std; 69using namespace TheISA; 70 71BaseSimpleCPU::BaseSimpleCPU(Params *p) 72 : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL) 73{ 74#if FULL_SYSTEM 75 thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); 76#else 77 thread = new SimpleThread(this, /* thread_num */ 0, p->process, 78 /* asid */ 0); 79#endif // !FULL_SYSTEM 80 81 thread->setStatus(ThreadContext::Unallocated); 82 83 tc = thread->getTC(); 84 85 numInst = 0; 86 startNumInst = 0; 87 numLoad = 0; 88 startNumLoad = 0; 89 lastIcacheStall = 0; 90 lastDcacheStall = 0; 91 92 threadContexts.push_back(tc); 93 94 fetchOffset = 0; 95 stayAtPC = false; 96} 97 98BaseSimpleCPU::~BaseSimpleCPU() 99{ 100} 101 102void 103BaseSimpleCPU::deallocateContext(int thread_num) 104{ 105 // for now, these are equivalent 106 suspendContext(thread_num); 107} 108 109 110void 111BaseSimpleCPU::haltContext(int thread_num) 112{ 113 // for now, these are equivalent 114 suspendContext(thread_num); 115} 116 117 118void 119BaseSimpleCPU::regStats() 120{ 121 using namespace Stats; 122 123 BaseCPU::regStats(); 124 125 numInsts 126 .name(name() + ".num_insts") 127 .desc("Number of instructions executed") 128 ; 129 130 numMemRefs 131 .name(name() + ".num_refs") 132 .desc("Number of memory references") 133 ; 134 135 notIdleFraction 136 .name(name() + ".not_idle_fraction") 137 .desc("Percentage of non-idle cycles") 138 ; 139 140 idleFraction 141 .name(name() + ".idle_fraction") 142 .desc("Percentage of idle cycles") 143 ; 144 145 icacheStallCycles 146 .name(name() + ".icache_stall_cycles") 147 .desc("ICache total stall cycles") 148 .prereq(icacheStallCycles) 149 ; 150 151 dcacheStallCycles 152 .name(name() + ".dcache_stall_cycles") 153 .desc("DCache total stall cycles") 154 .prereq(dcacheStallCycles) 155 ; 156 157 icacheRetryCycles 158 .name(name() + ".icache_retry_cycles") 159 .desc("ICache total retry cycles") 160 .prereq(icacheRetryCycles) 161 ; 162 163 dcacheRetryCycles 164 .name(name() + ".dcache_retry_cycles") 165 .desc("DCache total retry cycles") 166 .prereq(dcacheRetryCycles) 167 ; 168 169 idleFraction = constant(1.0) - notIdleFraction; 170} 171 172void 173BaseSimpleCPU::resetStats() 174{ 175// startNumInst = numInst; 176 // notIdleFraction = (_status != Idle); 177} 178 179void 180BaseSimpleCPU::serialize(ostream &os) 181{ 182 BaseCPU::serialize(os); 183// SERIALIZE_SCALAR(inst); 184 nameOut(os, csprintf("%s.xc.0", name())); 185 thread->serialize(os); 186} 187 188void 189BaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 190{ 191 BaseCPU::unserialize(cp, section); 192// UNSERIALIZE_SCALAR(inst); 193 thread->unserialize(cp, csprintf("%s.xc.0", section)); 194} 195 196void 197change_thread_state(int thread_number, int activate, int priority) 198{ 199} 200 201Fault 202BaseSimpleCPU::copySrcTranslate(Addr src) 203{ 204#if 0 205 static bool no_warn = true; 206 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 207 // Only support block sizes of 64 atm. 208 assert(blk_size == 64); 209 int offset = src & (blk_size - 1); 210 211 // Make sure block doesn't span page 212 if (no_warn && 213 (src & PageMask) != ((src + blk_size) & PageMask) && 214 (src >> 40) != 0xfffffc) { 215 warn("Copied block source spans pages %x.", src); 216 no_warn = false; 217 } 218 219 memReq->reset(src & ~(blk_size - 1), blk_size); 220 221 // translate to physical address 222 Fault fault = thread->translateDataReadReq(req); 223 224 if (fault == NoFault) { 225 thread->copySrcAddr = src; 226 thread->copySrcPhysAddr = memReq->paddr + offset; 227 } else { 228 assert(!fault->isAlignmentFault()); 229 230 thread->copySrcAddr = 0; 231 thread->copySrcPhysAddr = 0; 232 } 233 return fault; 234#else 235 return NoFault; 236#endif 237} 238 239Fault 240BaseSimpleCPU::copy(Addr dest) 241{ 242#if 0 243 static bool no_warn = true; 244 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 245 // Only support block sizes of 64 atm. 246 assert(blk_size == 64); 247 uint8_t data[blk_size]; 248 //assert(thread->copySrcAddr); 249 int offset = dest & (blk_size - 1); 250 251 // Make sure block doesn't span page 252 if (no_warn && 253 (dest & PageMask) != ((dest + blk_size) & PageMask) && 254 (dest >> 40) != 0xfffffc) { 255 no_warn = false; 256 warn("Copied block destination spans pages %x. ", dest); 257 } 258 259 memReq->reset(dest & ~(blk_size -1), blk_size); 260 // translate to physical address 261 Fault fault = thread->translateDataWriteReq(req); 262 263 if (fault == NoFault) { 264 Addr dest_addr = memReq->paddr + offset; 265 // Need to read straight from memory since we have more than 8 bytes. 266 memReq->paddr = thread->copySrcPhysAddr; 267 thread->mem->read(memReq, data); 268 memReq->paddr = dest_addr; 269 thread->mem->write(memReq, data); 270 if (dcacheInterface) { 271 memReq->cmd = Copy; 272 memReq->completionEvent = NULL; 273 memReq->paddr = thread->copySrcPhysAddr; 274 memReq->dest = dest_addr; 275 memReq->size = 64; 276 memReq->time = curTick; 277 memReq->flags &= ~INST_READ; 278 dcacheInterface->access(memReq); 279 } 280 } 281 else 282 assert(!fault->isAlignmentFault()); 283 284 return fault; 285#else 286 panic("copy not implemented"); 287 return NoFault; 288#endif 289} 290 291#if FULL_SYSTEM 292Addr 293BaseSimpleCPU::dbg_vtophys(Addr addr) 294{ 295 return vtophys(tc, addr); 296} 297#endif // FULL_SYSTEM 298 299#if FULL_SYSTEM 300void 301BaseSimpleCPU::post_interrupt(int int_num, int index) 302{ 303 BaseCPU::post_interrupt(int_num, index); 304 305 if (thread->status() == ThreadContext::Suspended) { 306 DPRINTF(Quiesce,"Suspended Processor awoke\n"); 307 thread->activate(); 308 } 309} 310#endif // FULL_SYSTEM 311 312void 313BaseSimpleCPU::checkForInterrupts() 314{ 315#if FULL_SYSTEM 316 if (check_interrupts(tc)) { 317 Fault interrupt = interrupts.getInterrupt(tc); 318 319 if (interrupt != NoFault) { 320 interrupts.updateIntrInfo(tc); 321 interrupt->invoke(tc); 322 } 323 } 324#endif 325} 326 327 328Fault 329BaseSimpleCPU::setupFetchRequest(Request *req) 330{ 331 Addr threadPC = thread->readPC(); 332 333 // set up memory request for instruction fetch 334#if ISA_HAS_DELAY_SLOT 335 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC, 336 thread->readNextPC(),thread->readNextNPC()); 337#else 338 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p\n",threadPC, 339 thread->readNextPC()); 340#endif 341 342 Addr fetchPC = (threadPC & PCMask) + fetchOffset; 343 req->setVirt(0, fetchPC, sizeof(MachInst), 0, threadPC); 344 345 Fault fault = thread->translateInstReq(req); 346 347 return fault; 348} 349 350 351void 352BaseSimpleCPU::preExecute() 353{ 354 // maintain $r0 semantics 355 thread->setIntReg(ZeroReg, 0); 356#if THE_ISA == ALPHA_ISA 357 thread->setFloatReg(ZeroReg, 0.0); 358#endif // ALPHA_ISA 359 360 // keep an instruction count 361 numInst++; 362 numInsts++; 363 364 thread->funcExeInst++; 365 366 // check for instruction-count-based events 367 comInstEventQueue[0]->serviceEvents(numInst); 368 369 // decode the instruction 370 inst = gtoh(inst); 371 372 //If we're not in the middle of a macro instruction 373 if (!curMacroStaticInst) { 374 375 StaticInstPtr instPtr = NULL; 376 377 //Predecode, ie bundle up an ExtMachInst 378 //This should go away once the constructor can be set up properly 379 predecoder.setTC(thread->getTC()); 380 //If more fetch data is needed, pass it in. 381 Addr fetchPC = (thread->readPC() & PCMask) + fetchOffset; 382 //if(predecoder.needMoreBytes()) 383 predecoder.moreBytes(thread->readPC(), fetchPC, inst); 384 //else 385 // predecoder.process(); 386 387 //If an instruction is ready, decode it. Otherwise, we'll have to 388 //fetch beyond the MachInst at the current pc. 389 if (predecoder.extMachInstReady()) { 390#if THE_ISA == X86_ISA 391 thread->setNextPC(thread->readPC() + predecoder.getInstSize()); 392#endif // X86_ISA 393 stayAtPC = false; 394 instPtr = StaticInst::decode(predecoder.getExtMachInst(), 395 thread->readPC()); 396 } else { 397 stayAtPC = true; 398 fetchOffset += sizeof(MachInst); 399 } 400 401 //If we decoded an instruction and it's microcoded, start pulling 402 //out micro ops 403 if (instPtr && instPtr->isMacroop()) { 404 curMacroStaticInst = instPtr; 405 curStaticInst = curMacroStaticInst-> 406 fetchMicroop(thread->readMicroPC()); 407 } else { 408 curStaticInst = instPtr; 409 } 410 } else { 411 //Read the next micro op from the macro op 412 curStaticInst = curMacroStaticInst-> 413 fetchMicroop(thread->readMicroPC()); 414 } 415 416 //If we decoded an instruction this "tick", record information about it. 417 if(curStaticInst) 418 { 419#if TRACING_ON
| 1/* 2 * Copyright (c) 2002-2005 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: Steve Reinhardt 29 */ 30 31#include "arch/utility.hh" 32#include "arch/faults.hh" 33#include "base/cprintf.hh" 34#include "base/inifile.hh" 35#include "base/loader/symtab.hh" 36#include "base/misc.hh" 37#include "base/pollevent.hh" 38#include "base/range.hh" 39#include "base/stats/events.hh" 40#include "base/trace.hh" 41#include "cpu/base.hh" 42#include "cpu/exetrace.hh" 43#include "cpu/profile.hh" 44#include "cpu/simple/base.hh" 45#include "cpu/simple_thread.hh" 46#include "cpu/smt.hh" 47#include "cpu/static_inst.hh" 48#include "cpu/thread_context.hh" 49#include "mem/packet.hh" 50#include "sim/byteswap.hh" 51#include "sim/debug.hh" 52#include "sim/host.hh" 53#include "sim/sim_events.hh" 54#include "sim/sim_object.hh" 55#include "sim/stats.hh" 56#include "sim/system.hh" 57 58#if FULL_SYSTEM 59#include "arch/kernel_stats.hh" 60#include "arch/stacktrace.hh" 61#include "arch/tlb.hh" 62#include "arch/vtophys.hh" 63#include "base/remote_gdb.hh" 64#else // !FULL_SYSTEM 65#include "mem/mem_object.hh" 66#endif // FULL_SYSTEM 67 68using namespace std; 69using namespace TheISA; 70 71BaseSimpleCPU::BaseSimpleCPU(Params *p) 72 : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL) 73{ 74#if FULL_SYSTEM 75 thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); 76#else 77 thread = new SimpleThread(this, /* thread_num */ 0, p->process, 78 /* asid */ 0); 79#endif // !FULL_SYSTEM 80 81 thread->setStatus(ThreadContext::Unallocated); 82 83 tc = thread->getTC(); 84 85 numInst = 0; 86 startNumInst = 0; 87 numLoad = 0; 88 startNumLoad = 0; 89 lastIcacheStall = 0; 90 lastDcacheStall = 0; 91 92 threadContexts.push_back(tc); 93 94 fetchOffset = 0; 95 stayAtPC = false; 96} 97 98BaseSimpleCPU::~BaseSimpleCPU() 99{ 100} 101 102void 103BaseSimpleCPU::deallocateContext(int thread_num) 104{ 105 // for now, these are equivalent 106 suspendContext(thread_num); 107} 108 109 110void 111BaseSimpleCPU::haltContext(int thread_num) 112{ 113 // for now, these are equivalent 114 suspendContext(thread_num); 115} 116 117 118void 119BaseSimpleCPU::regStats() 120{ 121 using namespace Stats; 122 123 BaseCPU::regStats(); 124 125 numInsts 126 .name(name() + ".num_insts") 127 .desc("Number of instructions executed") 128 ; 129 130 numMemRefs 131 .name(name() + ".num_refs") 132 .desc("Number of memory references") 133 ; 134 135 notIdleFraction 136 .name(name() + ".not_idle_fraction") 137 .desc("Percentage of non-idle cycles") 138 ; 139 140 idleFraction 141 .name(name() + ".idle_fraction") 142 .desc("Percentage of idle cycles") 143 ; 144 145 icacheStallCycles 146 .name(name() + ".icache_stall_cycles") 147 .desc("ICache total stall cycles") 148 .prereq(icacheStallCycles) 149 ; 150 151 dcacheStallCycles 152 .name(name() + ".dcache_stall_cycles") 153 .desc("DCache total stall cycles") 154 .prereq(dcacheStallCycles) 155 ; 156 157 icacheRetryCycles 158 .name(name() + ".icache_retry_cycles") 159 .desc("ICache total retry cycles") 160 .prereq(icacheRetryCycles) 161 ; 162 163 dcacheRetryCycles 164 .name(name() + ".dcache_retry_cycles") 165 .desc("DCache total retry cycles") 166 .prereq(dcacheRetryCycles) 167 ; 168 169 idleFraction = constant(1.0) - notIdleFraction; 170} 171 172void 173BaseSimpleCPU::resetStats() 174{ 175// startNumInst = numInst; 176 // notIdleFraction = (_status != Idle); 177} 178 179void 180BaseSimpleCPU::serialize(ostream &os) 181{ 182 BaseCPU::serialize(os); 183// SERIALIZE_SCALAR(inst); 184 nameOut(os, csprintf("%s.xc.0", name())); 185 thread->serialize(os); 186} 187 188void 189BaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 190{ 191 BaseCPU::unserialize(cp, section); 192// UNSERIALIZE_SCALAR(inst); 193 thread->unserialize(cp, csprintf("%s.xc.0", section)); 194} 195 196void 197change_thread_state(int thread_number, int activate, int priority) 198{ 199} 200 201Fault 202BaseSimpleCPU::copySrcTranslate(Addr src) 203{ 204#if 0 205 static bool no_warn = true; 206 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 207 // Only support block sizes of 64 atm. 208 assert(blk_size == 64); 209 int offset = src & (blk_size - 1); 210 211 // Make sure block doesn't span page 212 if (no_warn && 213 (src & PageMask) != ((src + blk_size) & PageMask) && 214 (src >> 40) != 0xfffffc) { 215 warn("Copied block source spans pages %x.", src); 216 no_warn = false; 217 } 218 219 memReq->reset(src & ~(blk_size - 1), blk_size); 220 221 // translate to physical address 222 Fault fault = thread->translateDataReadReq(req); 223 224 if (fault == NoFault) { 225 thread->copySrcAddr = src; 226 thread->copySrcPhysAddr = memReq->paddr + offset; 227 } else { 228 assert(!fault->isAlignmentFault()); 229 230 thread->copySrcAddr = 0; 231 thread->copySrcPhysAddr = 0; 232 } 233 return fault; 234#else 235 return NoFault; 236#endif 237} 238 239Fault 240BaseSimpleCPU::copy(Addr dest) 241{ 242#if 0 243 static bool no_warn = true; 244 int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 245 // Only support block sizes of 64 atm. 246 assert(blk_size == 64); 247 uint8_t data[blk_size]; 248 //assert(thread->copySrcAddr); 249 int offset = dest & (blk_size - 1); 250 251 // Make sure block doesn't span page 252 if (no_warn && 253 (dest & PageMask) != ((dest + blk_size) & PageMask) && 254 (dest >> 40) != 0xfffffc) { 255 no_warn = false; 256 warn("Copied block destination spans pages %x. ", dest); 257 } 258 259 memReq->reset(dest & ~(blk_size -1), blk_size); 260 // translate to physical address 261 Fault fault = thread->translateDataWriteReq(req); 262 263 if (fault == NoFault) { 264 Addr dest_addr = memReq->paddr + offset; 265 // Need to read straight from memory since we have more than 8 bytes. 266 memReq->paddr = thread->copySrcPhysAddr; 267 thread->mem->read(memReq, data); 268 memReq->paddr = dest_addr; 269 thread->mem->write(memReq, data); 270 if (dcacheInterface) { 271 memReq->cmd = Copy; 272 memReq->completionEvent = NULL; 273 memReq->paddr = thread->copySrcPhysAddr; 274 memReq->dest = dest_addr; 275 memReq->size = 64; 276 memReq->time = curTick; 277 memReq->flags &= ~INST_READ; 278 dcacheInterface->access(memReq); 279 } 280 } 281 else 282 assert(!fault->isAlignmentFault()); 283 284 return fault; 285#else 286 panic("copy not implemented"); 287 return NoFault; 288#endif 289} 290 291#if FULL_SYSTEM 292Addr 293BaseSimpleCPU::dbg_vtophys(Addr addr) 294{ 295 return vtophys(tc, addr); 296} 297#endif // FULL_SYSTEM 298 299#if FULL_SYSTEM 300void 301BaseSimpleCPU::post_interrupt(int int_num, int index) 302{ 303 BaseCPU::post_interrupt(int_num, index); 304 305 if (thread->status() == ThreadContext::Suspended) { 306 DPRINTF(Quiesce,"Suspended Processor awoke\n"); 307 thread->activate(); 308 } 309} 310#endif // FULL_SYSTEM 311 312void 313BaseSimpleCPU::checkForInterrupts() 314{ 315#if FULL_SYSTEM 316 if (check_interrupts(tc)) { 317 Fault interrupt = interrupts.getInterrupt(tc); 318 319 if (interrupt != NoFault) { 320 interrupts.updateIntrInfo(tc); 321 interrupt->invoke(tc); 322 } 323 } 324#endif 325} 326 327 328Fault 329BaseSimpleCPU::setupFetchRequest(Request *req) 330{ 331 Addr threadPC = thread->readPC(); 332 333 // set up memory request for instruction fetch 334#if ISA_HAS_DELAY_SLOT 335 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC, 336 thread->readNextPC(),thread->readNextNPC()); 337#else 338 DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p\n",threadPC, 339 thread->readNextPC()); 340#endif 341 342 Addr fetchPC = (threadPC & PCMask) + fetchOffset; 343 req->setVirt(0, fetchPC, sizeof(MachInst), 0, threadPC); 344 345 Fault fault = thread->translateInstReq(req); 346 347 return fault; 348} 349 350 351void 352BaseSimpleCPU::preExecute() 353{ 354 // maintain $r0 semantics 355 thread->setIntReg(ZeroReg, 0); 356#if THE_ISA == ALPHA_ISA 357 thread->setFloatReg(ZeroReg, 0.0); 358#endif // ALPHA_ISA 359 360 // keep an instruction count 361 numInst++; 362 numInsts++; 363 364 thread->funcExeInst++; 365 366 // check for instruction-count-based events 367 comInstEventQueue[0]->serviceEvents(numInst); 368 369 // decode the instruction 370 inst = gtoh(inst); 371 372 //If we're not in the middle of a macro instruction 373 if (!curMacroStaticInst) { 374 375 StaticInstPtr instPtr = NULL; 376 377 //Predecode, ie bundle up an ExtMachInst 378 //This should go away once the constructor can be set up properly 379 predecoder.setTC(thread->getTC()); 380 //If more fetch data is needed, pass it in. 381 Addr fetchPC = (thread->readPC() & PCMask) + fetchOffset; 382 //if(predecoder.needMoreBytes()) 383 predecoder.moreBytes(thread->readPC(), fetchPC, inst); 384 //else 385 // predecoder.process(); 386 387 //If an instruction is ready, decode it. Otherwise, we'll have to 388 //fetch beyond the MachInst at the current pc. 389 if (predecoder.extMachInstReady()) { 390#if THE_ISA == X86_ISA 391 thread->setNextPC(thread->readPC() + predecoder.getInstSize()); 392#endif // X86_ISA 393 stayAtPC = false; 394 instPtr = StaticInst::decode(predecoder.getExtMachInst(), 395 thread->readPC()); 396 } else { 397 stayAtPC = true; 398 fetchOffset += sizeof(MachInst); 399 } 400 401 //If we decoded an instruction and it's microcoded, start pulling 402 //out micro ops 403 if (instPtr && instPtr->isMacroop()) { 404 curMacroStaticInst = instPtr; 405 curStaticInst = curMacroStaticInst-> 406 fetchMicroop(thread->readMicroPC()); 407 } else { 408 curStaticInst = instPtr; 409 } 410 } else { 411 //Read the next micro op from the macro op 412 curStaticInst = curMacroStaticInst-> 413 fetchMicroop(thread->readMicroPC()); 414 } 415 416 //If we decoded an instruction this "tick", record information about it. 417 if(curStaticInst) 418 { 419#if TRACING_ON
|