base.cc revision 7897:d9e8b1fd1a9f
16019Shines@cs.fsu.edu/*
26019Shines@cs.fsu.edu * Copyright (c) 2010 ARM Limited
36019Shines@cs.fsu.edu * All rights reserved
46019Shines@cs.fsu.edu *
56019Shines@cs.fsu.edu * The license below extends only to copyright in the software and shall
66019Shines@cs.fsu.edu * not be construed as granting a license to any other intellectual
76019Shines@cs.fsu.edu * property including but not limited to intellectual property relating
86019Shines@cs.fsu.edu * to a hardware implementation of the functionality of the software
96019Shines@cs.fsu.edu * licensed hereunder.  You may use the software subject to the license
106019Shines@cs.fsu.edu * terms below provided that you ensure that this notice is replicated
116019Shines@cs.fsu.edu * unmodified and in its entirety in all distributions of the software,
126019Shines@cs.fsu.edu * modified or unmodified, in source code or in binary form.
136019Shines@cs.fsu.edu *
146019Shines@cs.fsu.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
156019Shines@cs.fsu.edu * All rights reserved.
166019Shines@cs.fsu.edu *
176019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without
186019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are
196019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright
206019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer;
216019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright
226019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the
236019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution;
246019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its
256019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from
266019Shines@cs.fsu.edu * this software without specific prior written permission.
276019Shines@cs.fsu.edu *
286019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
296019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
306019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
316019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
326019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
336019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
346019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
356019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
366019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
376019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
386019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
396019Shines@cs.fsu.edu *
406019Shines@cs.fsu.edu * Authors: Steve Reinhardt
416019Shines@cs.fsu.edu */
426019Shines@cs.fsu.edu
436019Shines@cs.fsu.edu#include "arch/faults.hh"
446019Shines@cs.fsu.edu#include "arch/utility.hh"
456019Shines@cs.fsu.edu#include "base/cp_annotate.hh"
466019Shines@cs.fsu.edu#include "base/cprintf.hh"
476019Shines@cs.fsu.edu#include "base/inifile.hh"
486019Shines@cs.fsu.edu#include "base/loader/symtab.hh"
496019Shines@cs.fsu.edu#include "base/misc.hh"
506019Shines@cs.fsu.edu#include "base/pollevent.hh"
516019Shines@cs.fsu.edu#include "base/range.hh"
526019Shines@cs.fsu.edu#include "base/trace.hh"
536019Shines@cs.fsu.edu#include "base/types.hh"
546019Shines@cs.fsu.edu#include "config/the_isa.hh"
556019Shines@cs.fsu.edu#include "cpu/base.hh"
566019Shines@cs.fsu.edu#include "cpu/exetrace.hh"
576019Shines@cs.fsu.edu#include "cpu/profile.hh"
586019Shines@cs.fsu.edu#include "cpu/simple/base.hh"
596019Shines@cs.fsu.edu#include "cpu/simple_thread.hh"
606019Shines@cs.fsu.edu#include "cpu/smt.hh"
616019Shines@cs.fsu.edu#include "cpu/static_inst.hh"
626019Shines@cs.fsu.edu#include "cpu/thread_context.hh"
636019Shines@cs.fsu.edu#include "mem/packet.hh"
646019Shines@cs.fsu.edu#include "mem/request.hh"
656019Shines@cs.fsu.edu#include "params/BaseSimpleCPU.hh"
666019Shines@cs.fsu.edu#include "sim/byteswap.hh"
676019Shines@cs.fsu.edu#include "sim/debug.hh"
686019Shines@cs.fsu.edu#include "sim/sim_events.hh"
696019Shines@cs.fsu.edu#include "sim/sim_object.hh"
706019Shines@cs.fsu.edu#include "sim/stats.hh"
716019Shines@cs.fsu.edu#include "sim/system.hh"
726019Shines@cs.fsu.edu
736019Shines@cs.fsu.edu#if FULL_SYSTEM
746019Shines@cs.fsu.edu#include "arch/kernel_stats.hh"
756019Shines@cs.fsu.edu#include "arch/stacktrace.hh"
766019Shines@cs.fsu.edu#include "arch/tlb.hh"
776019Shines@cs.fsu.edu#include "arch/vtophys.hh"
786019Shines@cs.fsu.edu#else // !FULL_SYSTEM
796019Shines@cs.fsu.edu#include "mem/mem_object.hh"
806019Shines@cs.fsu.edu#endif // FULL_SYSTEM
816019Shines@cs.fsu.edu
826019Shines@cs.fsu.eduusing namespace std;
836019Shines@cs.fsu.eduusing namespace TheISA;
846019Shines@cs.fsu.edu
856019Shines@cs.fsu.eduBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
866019Shines@cs.fsu.edu    : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
876019Shines@cs.fsu.edu{
886019Shines@cs.fsu.edu#if FULL_SYSTEM
896019Shines@cs.fsu.edu    thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
906019Shines@cs.fsu.edu#else
916019Shines@cs.fsu.edu    thread = new SimpleThread(this, /* thread_num */ 0, p->workload[0],
926019Shines@cs.fsu.edu            p->itb, p->dtb);
936019Shines@cs.fsu.edu#endif // !FULL_SYSTEM
946019Shines@cs.fsu.edu
956019Shines@cs.fsu.edu    thread->setStatus(ThreadContext::Halted);
966019Shines@cs.fsu.edu
976019Shines@cs.fsu.edu    tc = thread->getTC();
986019Shines@cs.fsu.edu
996019Shines@cs.fsu.edu    numInst = 0;
1006019Shines@cs.fsu.edu    startNumInst = 0;
1016019Shines@cs.fsu.edu    numLoad = 0;
1026019Shines@cs.fsu.edu    startNumLoad = 0;
1036019Shines@cs.fsu.edu    lastIcacheStall = 0;
1046019Shines@cs.fsu.edu    lastDcacheStall = 0;
1056019Shines@cs.fsu.edu
1066019Shines@cs.fsu.edu    threadContexts.push_back(tc);
1076019Shines@cs.fsu.edu
1086019Shines@cs.fsu.edu
1096019Shines@cs.fsu.edu    fetchOffset = 0;
1106019Shines@cs.fsu.edu    stayAtPC = false;
1116019Shines@cs.fsu.edu}
1126019Shines@cs.fsu.edu
1136019Shines@cs.fsu.eduBaseSimpleCPU::~BaseSimpleCPU()
1146019Shines@cs.fsu.edu{
1156019Shines@cs.fsu.edu}
1166019Shines@cs.fsu.edu
1176019Shines@cs.fsu.eduvoid
1186019Shines@cs.fsu.eduBaseSimpleCPU::deallocateContext(int thread_num)
1196019Shines@cs.fsu.edu{
1206019Shines@cs.fsu.edu    // for now, these are equivalent
1216019Shines@cs.fsu.edu    suspendContext(thread_num);
1226019Shines@cs.fsu.edu}
1236019Shines@cs.fsu.edu
1246019Shines@cs.fsu.edu
1256019Shines@cs.fsu.eduvoid
1266019Shines@cs.fsu.eduBaseSimpleCPU::haltContext(int thread_num)
1276019Shines@cs.fsu.edu{
1286019Shines@cs.fsu.edu    // for now, these are equivalent
1296019Shines@cs.fsu.edu    suspendContext(thread_num);
1306019Shines@cs.fsu.edu}
1316019Shines@cs.fsu.edu
1326019Shines@cs.fsu.edu
1336019Shines@cs.fsu.eduvoid
1346019Shines@cs.fsu.eduBaseSimpleCPU::regStats()
1356019Shines@cs.fsu.edu{
1366019Shines@cs.fsu.edu    using namespace Stats;
1376019Shines@cs.fsu.edu
1386019Shines@cs.fsu.edu    BaseCPU::regStats();
1396019Shines@cs.fsu.edu
1406019Shines@cs.fsu.edu    numInsts
1416019Shines@cs.fsu.edu        .name(name() + ".num_insts")
1426019Shines@cs.fsu.edu        .desc("Number of instructions executed")
1436019Shines@cs.fsu.edu        ;
1446019Shines@cs.fsu.edu
1456019Shines@cs.fsu.edu    numIntAluAccesses
1466019Shines@cs.fsu.edu        .name(name() + ".num_int_alu_accesses")
1476019Shines@cs.fsu.edu        .desc("Number of integer alu accesses")
1486019Shines@cs.fsu.edu        ;
1496019Shines@cs.fsu.edu
1506019Shines@cs.fsu.edu    numFpAluAccesses
1516019Shines@cs.fsu.edu        .name(name() + ".num_fp_alu_accesses")
1526019Shines@cs.fsu.edu        .desc("Number of float alu accesses")
1536019Shines@cs.fsu.edu        ;
1546019Shines@cs.fsu.edu
1556019Shines@cs.fsu.edu    numCallsReturns
1566019Shines@cs.fsu.edu        .name(name() + ".num_func_calls")
1576019Shines@cs.fsu.edu        .desc("number of times a function call or return occured")
1586019Shines@cs.fsu.edu        ;
1596019Shines@cs.fsu.edu
1606019Shines@cs.fsu.edu    numCondCtrlInsts
1616019Shines@cs.fsu.edu        .name(name() + ".num_conditional_control_insts")
1626019Shines@cs.fsu.edu        .desc("number of instructions that are conditional controls")
1636019Shines@cs.fsu.edu        ;
1646019Shines@cs.fsu.edu
1656019Shines@cs.fsu.edu    numIntInsts
1666019Shines@cs.fsu.edu        .name(name() + ".num_int_insts")
1676019Shines@cs.fsu.edu        .desc("number of integer instructions")
1686019Shines@cs.fsu.edu        ;
1696019Shines@cs.fsu.edu
1706019Shines@cs.fsu.edu    numFpInsts
1716019Shines@cs.fsu.edu        .name(name() + ".num_fp_insts")
1726019Shines@cs.fsu.edu        .desc("number of float instructions")
1736019Shines@cs.fsu.edu        ;
1746019Shines@cs.fsu.edu
1756019Shines@cs.fsu.edu    numIntRegReads
1766019Shines@cs.fsu.edu        .name(name() + ".num_int_register_reads")
1776019Shines@cs.fsu.edu        .desc("number of times the integer registers were read")
1786019Shines@cs.fsu.edu        ;
1796019Shines@cs.fsu.edu
1806019Shines@cs.fsu.edu    numIntRegWrites
1816019Shines@cs.fsu.edu        .name(name() + ".num_int_register_writes")
1826019Shines@cs.fsu.edu        .desc("number of times the integer registers were written")
1836019Shines@cs.fsu.edu        ;
1846019Shines@cs.fsu.edu
1856019Shines@cs.fsu.edu    numFpRegReads
1866019Shines@cs.fsu.edu        .name(name() + ".num_fp_register_reads")
1876019Shines@cs.fsu.edu        .desc("number of times the floating registers were read")
1886019Shines@cs.fsu.edu        ;
1896019Shines@cs.fsu.edu
1906019Shines@cs.fsu.edu    numFpRegWrites
1916019Shines@cs.fsu.edu        .name(name() + ".num_fp_register_writes")
1926019Shines@cs.fsu.edu        .desc("number of times the floating registers were written")
1936019Shines@cs.fsu.edu        ;
1946019Shines@cs.fsu.edu
1956019Shines@cs.fsu.edu    numMemRefs
1966019Shines@cs.fsu.edu        .name(name()+".num_mem_refs")
1976019Shines@cs.fsu.edu        .desc("number of memory refs")
1986019Shines@cs.fsu.edu        ;
1996019Shines@cs.fsu.edu
2006019Shines@cs.fsu.edu    numStoreInsts
2016019Shines@cs.fsu.edu        .name(name() + ".num_store_insts")
2026019Shines@cs.fsu.edu        .desc("Number of store instructions")
2036019Shines@cs.fsu.edu        ;
2046019Shines@cs.fsu.edu
2056019Shines@cs.fsu.edu    numLoadInsts
2066019Shines@cs.fsu.edu        .name(name() + ".num_load_insts")
2076019Shines@cs.fsu.edu        .desc("Number of load instructions")
2086019Shines@cs.fsu.edu        ;
2096019Shines@cs.fsu.edu
2106019Shines@cs.fsu.edu    notIdleFraction
2116019Shines@cs.fsu.edu        .name(name() + ".not_idle_fraction")
2126019Shines@cs.fsu.edu        .desc("Percentage of non-idle cycles")
2136019Shines@cs.fsu.edu        ;
2146019Shines@cs.fsu.edu
2156019Shines@cs.fsu.edu    idleFraction
2166019Shines@cs.fsu.edu        .name(name() + ".idle_fraction")
2176019Shines@cs.fsu.edu        .desc("Percentage of idle cycles")
2186019Shines@cs.fsu.edu        ;
2196019Shines@cs.fsu.edu
2206019Shines@cs.fsu.edu    numBusyCycles
2216019Shines@cs.fsu.edu        .name(name() + ".num_busy_cycles")
2226019Shines@cs.fsu.edu        .desc("Number of busy cycles")
2236019Shines@cs.fsu.edu        ;
2246019Shines@cs.fsu.edu
2256019Shines@cs.fsu.edu    numIdleCycles
2266019Shines@cs.fsu.edu        .name(name()+".num_idle_cycles")
2276019Shines@cs.fsu.edu        .desc("Number of idle cycles")
2286019Shines@cs.fsu.edu        ;
2296019Shines@cs.fsu.edu
2306019Shines@cs.fsu.edu    icacheStallCycles
2316019Shines@cs.fsu.edu        .name(name() + ".icache_stall_cycles")
2326019Shines@cs.fsu.edu        .desc("ICache total stall cycles")
2336019Shines@cs.fsu.edu        .prereq(icacheStallCycles)
2346019Shines@cs.fsu.edu        ;
2356019Shines@cs.fsu.edu
2366019Shines@cs.fsu.edu    dcacheStallCycles
2376019Shines@cs.fsu.edu        .name(name() + ".dcache_stall_cycles")
2386019Shines@cs.fsu.edu        .desc("DCache total stall cycles")
2396019Shines@cs.fsu.edu        .prereq(dcacheStallCycles)
2406019Shines@cs.fsu.edu        ;
2416019Shines@cs.fsu.edu
2426019Shines@cs.fsu.edu    icacheRetryCycles
2436019Shines@cs.fsu.edu        .name(name() + ".icache_retry_cycles")
2446019Shines@cs.fsu.edu        .desc("ICache total retry cycles")
2456019Shines@cs.fsu.edu        .prereq(icacheRetryCycles)
2466019Shines@cs.fsu.edu        ;
2476019Shines@cs.fsu.edu
2486019Shines@cs.fsu.edu    dcacheRetryCycles
2496019Shines@cs.fsu.edu        .name(name() + ".dcache_retry_cycles")
2506019Shines@cs.fsu.edu        .desc("DCache total retry cycles")
2516019Shines@cs.fsu.edu        .prereq(dcacheRetryCycles)
2526019Shines@cs.fsu.edu        ;
2536019Shines@cs.fsu.edu
2546019Shines@cs.fsu.edu    idleFraction = constant(1.0) - notIdleFraction;
2556019Shines@cs.fsu.edu    numIdleCycles = idleFraction * numCycles;
2566019Shines@cs.fsu.edu    numBusyCycles = (notIdleFraction)*numCycles;
2576019Shines@cs.fsu.edu}
2586019Shines@cs.fsu.edu
2596019Shines@cs.fsu.eduvoid
2606019Shines@cs.fsu.eduBaseSimpleCPU::resetStats()
2616019Shines@cs.fsu.edu{
2626019Shines@cs.fsu.edu//    startNumInst = numInst;
2636019Shines@cs.fsu.edu     notIdleFraction = (_status != Idle);
2646019Shines@cs.fsu.edu}
2656019Shines@cs.fsu.edu
2666019Shines@cs.fsu.eduvoid
2676019Shines@cs.fsu.eduBaseSimpleCPU::serialize(ostream &os)
2686019Shines@cs.fsu.edu{
2696019Shines@cs.fsu.edu    SERIALIZE_ENUM(_status);
2706019Shines@cs.fsu.edu    BaseCPU::serialize(os);
2716019Shines@cs.fsu.edu//    SERIALIZE_SCALAR(inst);
2726019Shines@cs.fsu.edu    nameOut(os, csprintf("%s.xc.0", name()));
2736019Shines@cs.fsu.edu    thread->serialize(os);
2746019Shines@cs.fsu.edu}
2756019Shines@cs.fsu.edu
2766019Shines@cs.fsu.eduvoid
2776019Shines@cs.fsu.eduBaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
2786019Shines@cs.fsu.edu{
2796019Shines@cs.fsu.edu    UNSERIALIZE_ENUM(_status);
2806019Shines@cs.fsu.edu    BaseCPU::unserialize(cp, section);
2816019Shines@cs.fsu.edu//    UNSERIALIZE_SCALAR(inst);
2826019Shines@cs.fsu.edu    thread->unserialize(cp, csprintf("%s.xc.0", section));
2836019Shines@cs.fsu.edu}
2846019Shines@cs.fsu.edu
2856019Shines@cs.fsu.eduvoid
2866019Shines@cs.fsu.educhange_thread_state(ThreadID tid, int activate, int priority)
2876019Shines@cs.fsu.edu{
2886019Shines@cs.fsu.edu}
2896019Shines@cs.fsu.edu
2906019Shines@cs.fsu.edu#if FULL_SYSTEM
2916019Shines@cs.fsu.eduAddr
2926019Shines@cs.fsu.eduBaseSimpleCPU::dbg_vtophys(Addr addr)
2936019Shines@cs.fsu.edu{
2946019Shines@cs.fsu.edu    return vtophys(tc, addr);
2956019Shines@cs.fsu.edu}
2966019Shines@cs.fsu.edu#endif // FULL_SYSTEM
2976019Shines@cs.fsu.edu
2986019Shines@cs.fsu.edu#if FULL_SYSTEM
2996019Shines@cs.fsu.eduvoid
3006019Shines@cs.fsu.eduBaseSimpleCPU::wakeup()
3016019Shines@cs.fsu.edu{
3026019Shines@cs.fsu.edu    if (thread->status() != ThreadContext::Suspended)
3036019Shines@cs.fsu.edu        return;
3046019Shines@cs.fsu.edu
3056019Shines@cs.fsu.edu    DPRINTF(Quiesce,"Suspended Processor awoke\n");
3066019Shines@cs.fsu.edu    thread->activate();
3076019Shines@cs.fsu.edu}
3086019Shines@cs.fsu.edu#endif // FULL_SYSTEM
3096019Shines@cs.fsu.edu
3106019Shines@cs.fsu.eduvoid
3116019Shines@cs.fsu.eduBaseSimpleCPU::checkForInterrupts()
3126019Shines@cs.fsu.edu{
3136019Shines@cs.fsu.edu#if FULL_SYSTEM
3146019Shines@cs.fsu.edu    if (checkInterrupts(tc)) {
3156019Shines@cs.fsu.edu        Fault interrupt = interrupts->getInterrupt(tc);
3166019Shines@cs.fsu.edu
3176019Shines@cs.fsu.edu        if (interrupt != NoFault) {
3186019Shines@cs.fsu.edu            fetchOffset = 0;
3196019Shines@cs.fsu.edu            interrupts->updateIntrInfo(tc);
3206019Shines@cs.fsu.edu            interrupt->invoke(tc);
3216019Shines@cs.fsu.edu            predecoder.reset();
3226019Shines@cs.fsu.edu        }
3236019Shines@cs.fsu.edu    }
3246019Shines@cs.fsu.edu#endif
3256019Shines@cs.fsu.edu}
3266019Shines@cs.fsu.edu
3276019Shines@cs.fsu.edu
3286019Shines@cs.fsu.eduvoid
3296019Shines@cs.fsu.eduBaseSimpleCPU::setupFetchRequest(Request *req)
3306019Shines@cs.fsu.edu{
3316019Shines@cs.fsu.edu    Addr instAddr = thread->instAddr();
3326019Shines@cs.fsu.edu
3336019Shines@cs.fsu.edu    // set up memory request for instruction fetch
3346019Shines@cs.fsu.edu    DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr);
3356019Shines@cs.fsu.edu
3366019Shines@cs.fsu.edu    Addr fetchPC = (instAddr & PCMask) + fetchOffset;
3376019Shines@cs.fsu.edu    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instAddr);
3386019Shines@cs.fsu.edu}
3396019Shines@cs.fsu.edu
3406019Shines@cs.fsu.edu
3416019Shines@cs.fsu.eduvoid
3426019Shines@cs.fsu.eduBaseSimpleCPU::preExecute()
3436019Shines@cs.fsu.edu{
3446019Shines@cs.fsu.edu    // maintain $r0 semantics
3456019Shines@cs.fsu.edu    thread->setIntReg(ZeroReg, 0);
3466019Shines@cs.fsu.edu#if THE_ISA == ALPHA_ISA
3476019Shines@cs.fsu.edu    thread->setFloatReg(ZeroReg, 0.0);
3486019Shines@cs.fsu.edu#endif // ALPHA_ISA
3496019Shines@cs.fsu.edu
3506019Shines@cs.fsu.edu    // check for instruction-count-based events
3516019Shines@cs.fsu.edu    comInstEventQueue[0]->serviceEvents(numInst);
3526019Shines@cs.fsu.edu    system->instEventQueue.serviceEvents(system->totalNumInsts);
3536019Shines@cs.fsu.edu
3546019Shines@cs.fsu.edu    // decode the instruction
3556019Shines@cs.fsu.edu    inst = gtoh(inst);
3566019Shines@cs.fsu.edu
3576019Shines@cs.fsu.edu    TheISA::PCState pcState = thread->pcState();
3586019Shines@cs.fsu.edu
3596019Shines@cs.fsu.edu    if (isRomMicroPC(pcState.microPC())) {
3606019Shines@cs.fsu.edu        stayAtPC = false;
3616019Shines@cs.fsu.edu        curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
3626019Shines@cs.fsu.edu                                                  curMacroStaticInst);
3636019Shines@cs.fsu.edu    } else if (!curMacroStaticInst) {
3646019Shines@cs.fsu.edu        //We're not in the middle of a macro instruction
365        StaticInstPtr instPtr = NULL;
366
367        //Predecode, ie bundle up an ExtMachInst
368        //This should go away once the constructor can be set up properly
369        predecoder.setTC(thread->getTC());
370        //If more fetch data is needed, pass it in.
371        Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
372        //if(predecoder.needMoreBytes())
373            predecoder.moreBytes(pcState, fetchPC, inst);
374        //else
375        //    predecoder.process();
376
377        //If an instruction is ready, decode it. Otherwise, we'll have to
378        //fetch beyond the MachInst at the current pc.
379        if (predecoder.extMachInstReady()) {
380            stayAtPC = false;
381            ExtMachInst machInst = predecoder.getExtMachInst(pcState);
382            thread->pcState(pcState);
383            instPtr = StaticInst::decode(machInst, pcState.instAddr());
384        } else {
385            stayAtPC = true;
386            fetchOffset += sizeof(MachInst);
387        }
388
389        //If we decoded an instruction and it's microcoded, start pulling
390        //out micro ops
391        if (instPtr && instPtr->isMacroop()) {
392            curMacroStaticInst = instPtr;
393            curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
394        } else {
395            curStaticInst = instPtr;
396        }
397    } else {
398        //Read the next micro op from the macro op
399        curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
400    }
401
402    //If we decoded an instruction this "tick", record information about it.
403    if(curStaticInst)
404    {
405#if TRACING_ON
406        traceData = tracer->getInstRecord(curTick(), tc,
407                curStaticInst, thread->pcState(), curMacroStaticInst);
408
409        DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
410                curStaticInst->getName(), curStaticInst->machInst);
411#endif // TRACING_ON
412    }
413}
414
415void
416BaseSimpleCPU::postExecute()
417{
418    assert(curStaticInst);
419
420    TheISA::PCState pc = tc->pcState();
421    Addr instAddr = pc.instAddr();
422#if FULL_SYSTEM
423    if (thread->profile) {
424        bool usermode = TheISA::inUserMode(tc);
425        thread->profilePC = usermode ? 1 : instAddr;
426        ProfileNode *node = thread->profile->consume(tc, curStaticInst);
427        if (node)
428            thread->profileNode = node;
429    }
430#endif
431
432    if (curStaticInst->isMemRef()) {
433        numMemRefs++;
434    }
435
436    if (curStaticInst->isLoad()) {
437        ++numLoad;
438        comLoadEventQueue[0]->serviceEvents(numLoad);
439    }
440
441    if (CPA::available()) {
442        CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr());
443    }
444
445    /* Power model statistics */
446    //integer alu accesses
447    if (curStaticInst->isInteger()){
448        numIntAluAccesses++;
449        numIntInsts++;
450    }
451
452    //float alu accesses
453    if (curStaticInst->isFloating()){
454        numFpAluAccesses++;
455        numFpInsts++;
456    }
457
458    //number of function calls/returns to get window accesses
459    if (curStaticInst->isCall() || curStaticInst->isReturn()){
460        numCallsReturns++;
461    }
462
463    //the number of branch predictions that will be made
464    if (curStaticInst->isCondCtrl()){
465        numCondCtrlInsts++;
466    }
467
468    //result bus acceses
469    if (curStaticInst->isLoad()){
470        numLoadInsts++;
471    }
472
473    if (curStaticInst->isStore()){
474        numStoreInsts++;
475    }
476    /* End power model statistics */
477
478    traceFunctions(instAddr);
479
480    if (traceData) {
481        traceData->dump();
482        delete traceData;
483        traceData = NULL;
484    }
485}
486
487
488void
489BaseSimpleCPU::advancePC(Fault fault)
490{
491    //Since we're moving to a new pc, zero out the offset
492    fetchOffset = 0;
493    if (fault != NoFault) {
494        curMacroStaticInst = StaticInst::nullStaticInstPtr;
495        fault->invoke(tc, curStaticInst);
496        predecoder.reset();
497    } else {
498        if (curStaticInst) {
499            if (curStaticInst->isLastMicroop())
500                curMacroStaticInst = StaticInst::nullStaticInstPtr;
501            TheISA::PCState pcState = thread->pcState();
502            TheISA::advancePC(pcState, curStaticInst);
503            thread->pcState(pcState);
504        }
505    }
506}
507
508/*Fault
509BaseSimpleCPU::CacheOp(uint8_t Op, Addr EffAddr)
510{
511    // translate to physical address
512    Fault fault = NoFault;
513    int CacheID = Op & 0x3; // Lower 3 bits identify Cache
514    int CacheOP = Op >> 2; // Upper 3 bits identify Cache Operation
515    if(CacheID > 1)
516      {
517        warn("CacheOps not implemented for secondary/tertiary caches\n");
518      }
519    else
520      {
521        switch(CacheOP)
522          { // Fill Packet Type
523          case 0: warn("Invalidate Cache Op\n");
524            break;
525          case 1: warn("Index Load Tag Cache Op\n");
526            break;
527          case 2: warn("Index Store Tag Cache Op\n");
528            break;
529          case 4: warn("Hit Invalidate Cache Op\n");
530            break;
531          case 5: warn("Fill/Hit Writeback Invalidate Cache Op\n");
532            break;
533          case 6: warn("Hit Writeback\n");
534            break;
535          case 7: warn("Fetch & Lock Cache Op\n");
536            break;
537          default: warn("Unimplemented Cache Op\n");
538          }
539      }
540    return fault;
541}*/
542