base.cc revision 4156
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are
711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright
811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer;
911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright
1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the
1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution;
1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its
1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
1411308Santhony.gutierrez@amd.com * this software without specific prior written permission.
1511308Santhony.gutierrez@amd.com *
1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711308Santhony.gutierrez@amd.com *
2811308Santhony.gutierrez@amd.com * Authors: Steve Reinhardt
2911308Santhony.gutierrez@amd.com */
3011308Santhony.gutierrez@amd.com
3111308Santhony.gutierrez@amd.com#include "arch/utility.hh"
3211308Santhony.gutierrez@amd.com#include "arch/faults.hh"
3311308Santhony.gutierrez@amd.com#include "base/cprintf.hh"
3411308Santhony.gutierrez@amd.com#include "base/inifile.hh"
3511308Santhony.gutierrez@amd.com#include "base/loader/symtab.hh"
3611308Santhony.gutierrez@amd.com#include "base/misc.hh"
3711308Santhony.gutierrez@amd.com#include "base/pollevent.hh"
3811308Santhony.gutierrez@amd.com#include "base/range.hh"
3911308Santhony.gutierrez@amd.com#include "base/stats/events.hh"
4011308Santhony.gutierrez@amd.com#include "base/trace.hh"
4111308Santhony.gutierrez@amd.com#include "cpu/base.hh"
4211308Santhony.gutierrez@amd.com#include "cpu/exetrace.hh"
4311308Santhony.gutierrez@amd.com#include "cpu/profile.hh"
4411308Santhony.gutierrez@amd.com#include "cpu/simple/base.hh"
4511308Santhony.gutierrez@amd.com#include "cpu/simple_thread.hh"
4611308Santhony.gutierrez@amd.com#include "cpu/smt.hh"
4711308Santhony.gutierrez@amd.com#include "cpu/static_inst.hh"
4811308Santhony.gutierrez@amd.com#include "cpu/thread_context.hh"
4911308Santhony.gutierrez@amd.com#include "mem/packet.hh"
5011308Santhony.gutierrez@amd.com#include "sim/builder.hh"
5111308Santhony.gutierrez@amd.com#include "sim/byteswap.hh"
5211308Santhony.gutierrez@amd.com#include "sim/debug.hh"
5311308Santhony.gutierrez@amd.com#include "sim/host.hh"
5411308Santhony.gutierrez@amd.com#include "sim/sim_events.hh"
5511308Santhony.gutierrez@amd.com#include "sim/sim_object.hh"
5611308Santhony.gutierrez@amd.com#include "sim/stats.hh"
5711308Santhony.gutierrez@amd.com#include "sim/system.hh"
5811308Santhony.gutierrez@amd.com
5911308Santhony.gutierrez@amd.com#if FULL_SYSTEM
6011308Santhony.gutierrez@amd.com#include "arch/kernel_stats.hh"
6111308Santhony.gutierrez@amd.com#include "arch/stacktrace.hh"
6211308Santhony.gutierrez@amd.com#include "arch/tlb.hh"
6311308Santhony.gutierrez@amd.com#include "arch/vtophys.hh"
6411308Santhony.gutierrez@amd.com#include "base/remote_gdb.hh"
6511308Santhony.gutierrez@amd.com#else // !FULL_SYSTEM
6611308Santhony.gutierrez@amd.com#include "mem/mem_object.hh"
6711308Santhony.gutierrez@amd.com#endif // FULL_SYSTEM
6811308Santhony.gutierrez@amd.com
6911308Santhony.gutierrez@amd.comusing namespace std;
7011308Santhony.gutierrez@amd.comusing namespace TheISA;
7111308Santhony.gutierrez@amd.com
7211308Santhony.gutierrez@amd.comBaseSimpleCPU::BaseSimpleCPU(Params *p)
7311308Santhony.gutierrez@amd.com    : BaseCPU(p), thread(NULL)
7411308Santhony.gutierrez@amd.com{
7511308Santhony.gutierrez@amd.com#if FULL_SYSTEM
7611308Santhony.gutierrez@amd.com    thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
7711308Santhony.gutierrez@amd.com#else
7811308Santhony.gutierrez@amd.com    thread = new SimpleThread(this, /* thread_num */ 0, p->process,
7911308Santhony.gutierrez@amd.com            /* asid */ 0);
8011308Santhony.gutierrez@amd.com#endif // !FULL_SYSTEM
8111308Santhony.gutierrez@amd.com
8211308Santhony.gutierrez@amd.com    thread->setStatus(ThreadContext::Suspended);
8311308Santhony.gutierrez@amd.com
8411308Santhony.gutierrez@amd.com    tc = thread->getTC();
8511308Santhony.gutierrez@amd.com
8611308Santhony.gutierrez@amd.com    numInst = 0;
8711308Santhony.gutierrez@amd.com    startNumInst = 0;
8811308Santhony.gutierrez@amd.com    numLoad = 0;
8911308Santhony.gutierrez@amd.com    startNumLoad = 0;
9011308Santhony.gutierrez@amd.com    lastIcacheStall = 0;
9111308Santhony.gutierrez@amd.com    lastDcacheStall = 0;
9211308Santhony.gutierrez@amd.com
9311308Santhony.gutierrez@amd.com    threadContexts.push_back(tc);
9411308Santhony.gutierrez@amd.com}
9511308Santhony.gutierrez@amd.com
9611308Santhony.gutierrez@amd.comBaseSimpleCPU::~BaseSimpleCPU()
9711308Santhony.gutierrez@amd.com{
9811308Santhony.gutierrez@amd.com}
9911308Santhony.gutierrez@amd.com
10011308Santhony.gutierrez@amd.comvoid
10111308Santhony.gutierrez@amd.comBaseSimpleCPU::deallocateContext(int thread_num)
10211308Santhony.gutierrez@amd.com{
10311308Santhony.gutierrez@amd.com    // for now, these are equivalent
10411308Santhony.gutierrez@amd.com    suspendContext(thread_num);
10511308Santhony.gutierrez@amd.com}
10611308Santhony.gutierrez@amd.com
10711308Santhony.gutierrez@amd.com
10811308Santhony.gutierrez@amd.comvoid
10911308Santhony.gutierrez@amd.comBaseSimpleCPU::haltContext(int thread_num)
11011308Santhony.gutierrez@amd.com{
11111308Santhony.gutierrez@amd.com    // for now, these are equivalent
11211308Santhony.gutierrez@amd.com    suspendContext(thread_num);
11311308Santhony.gutierrez@amd.com}
11411308Santhony.gutierrez@amd.com
11511308Santhony.gutierrez@amd.com
11611308Santhony.gutierrez@amd.comvoid
11711308Santhony.gutierrez@amd.comBaseSimpleCPU::regStats()
11811308Santhony.gutierrez@amd.com{
11911308Santhony.gutierrez@amd.com    using namespace Stats;
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.com    BaseCPU::regStats();
12211308Santhony.gutierrez@amd.com
12311308Santhony.gutierrez@amd.com    numInsts
12411308Santhony.gutierrez@amd.com        .name(name() + ".num_insts")
12511308Santhony.gutierrez@amd.com        .desc("Number of instructions executed")
12611308Santhony.gutierrez@amd.com        ;
12711308Santhony.gutierrez@amd.com
12811308Santhony.gutierrez@amd.com    numMemRefs
12911308Santhony.gutierrez@amd.com        .name(name() + ".num_refs")
13011308Santhony.gutierrez@amd.com        .desc("Number of memory references")
13111308Santhony.gutierrez@amd.com        ;
13211308Santhony.gutierrez@amd.com
13311308Santhony.gutierrez@amd.com    notIdleFraction
13411308Santhony.gutierrez@amd.com        .name(name() + ".not_idle_fraction")
13511308Santhony.gutierrez@amd.com        .desc("Percentage of non-idle cycles")
13611308Santhony.gutierrez@amd.com        ;
13711308Santhony.gutierrez@amd.com
13811308Santhony.gutierrez@amd.com    idleFraction
13911308Santhony.gutierrez@amd.com        .name(name() + ".idle_fraction")
14011308Santhony.gutierrez@amd.com        .desc("Percentage of idle cycles")
14111308Santhony.gutierrez@amd.com        ;
14211308Santhony.gutierrez@amd.com
14311308Santhony.gutierrez@amd.com    icacheStallCycles
14411308Santhony.gutierrez@amd.com        .name(name() + ".icache_stall_cycles")
14511308Santhony.gutierrez@amd.com        .desc("ICache total stall cycles")
14611308Santhony.gutierrez@amd.com        .prereq(icacheStallCycles)
14711308Santhony.gutierrez@amd.com        ;
14811308Santhony.gutierrez@amd.com
14911308Santhony.gutierrez@amd.com    dcacheStallCycles
15011308Santhony.gutierrez@amd.com        .name(name() + ".dcache_stall_cycles")
15111308Santhony.gutierrez@amd.com        .desc("DCache total stall cycles")
15211308Santhony.gutierrez@amd.com        .prereq(dcacheStallCycles)
15311308Santhony.gutierrez@amd.com        ;
15411308Santhony.gutierrez@amd.com
15511308Santhony.gutierrez@amd.com    icacheRetryCycles
15611308Santhony.gutierrez@amd.com        .name(name() + ".icache_retry_cycles")
15711308Santhony.gutierrez@amd.com        .desc("ICache total retry cycles")
15811308Santhony.gutierrez@amd.com        .prereq(icacheRetryCycles)
15911308Santhony.gutierrez@amd.com        ;
16011308Santhony.gutierrez@amd.com
16111308Santhony.gutierrez@amd.com    dcacheRetryCycles
16211308Santhony.gutierrez@amd.com        .name(name() + ".dcache_retry_cycles")
16311308Santhony.gutierrez@amd.com        .desc("DCache total retry cycles")
16411308Santhony.gutierrez@amd.com        .prereq(dcacheRetryCycles)
16511308Santhony.gutierrez@amd.com        ;
16611308Santhony.gutierrez@amd.com
16711308Santhony.gutierrez@amd.com    idleFraction = constant(1.0) - notIdleFraction;
16811308Santhony.gutierrez@amd.com}
16911308Santhony.gutierrez@amd.com
17011308Santhony.gutierrez@amd.comvoid
17111308Santhony.gutierrez@amd.comBaseSimpleCPU::resetStats()
17211308Santhony.gutierrez@amd.com{
17311308Santhony.gutierrez@amd.com//    startNumInst = numInst;
17411308Santhony.gutierrez@amd.com    // notIdleFraction = (_status != Idle);
17511308Santhony.gutierrez@amd.com}
17611308Santhony.gutierrez@amd.com
17711308Santhony.gutierrez@amd.comvoid
17811308Santhony.gutierrez@amd.comBaseSimpleCPU::serialize(ostream &os)
17911308Santhony.gutierrez@amd.com{
18011308Santhony.gutierrez@amd.com    BaseCPU::serialize(os);
18111308Santhony.gutierrez@amd.com//    SERIALIZE_SCALAR(inst);
18211308Santhony.gutierrez@amd.com    nameOut(os, csprintf("%s.xc.0", name()));
18311308Santhony.gutierrez@amd.com    thread->serialize(os);
18411308Santhony.gutierrez@amd.com}
18511308Santhony.gutierrez@amd.com
18611308Santhony.gutierrez@amd.comvoid
18711308Santhony.gutierrez@amd.comBaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
18811308Santhony.gutierrez@amd.com{
18911308Santhony.gutierrez@amd.com    BaseCPU::unserialize(cp, section);
19011308Santhony.gutierrez@amd.com//    UNSERIALIZE_SCALAR(inst);
19111308Santhony.gutierrez@amd.com    thread->unserialize(cp, csprintf("%s.xc.0", section));
19211308Santhony.gutierrez@amd.com}
19311308Santhony.gutierrez@amd.com
19411308Santhony.gutierrez@amd.comvoid
19511308Santhony.gutierrez@amd.comchange_thread_state(int thread_number, int activate, int priority)
19611308Santhony.gutierrez@amd.com{
19711308Santhony.gutierrez@amd.com}
19811308Santhony.gutierrez@amd.com
19911308Santhony.gutierrez@amd.comFault
20011308Santhony.gutierrez@amd.comBaseSimpleCPU::copySrcTranslate(Addr src)
20111308Santhony.gutierrez@amd.com{
20211308Santhony.gutierrez@amd.com#if 0
20311308Santhony.gutierrez@amd.com    static bool no_warn = true;
20411308Santhony.gutierrez@amd.com    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
20511308Santhony.gutierrez@amd.com    // Only support block sizes of 64 atm.
20611308Santhony.gutierrez@amd.com    assert(blk_size == 64);
20711308Santhony.gutierrez@amd.com    int offset = src & (blk_size - 1);
20811308Santhony.gutierrez@amd.com
20911308Santhony.gutierrez@amd.com    // Make sure block doesn't span page
21011308Santhony.gutierrez@amd.com    if (no_warn &&
21111308Santhony.gutierrez@amd.com        (src & PageMask) != ((src + blk_size) & PageMask) &&
21211308Santhony.gutierrez@amd.com        (src >> 40) != 0xfffffc) {
21311308Santhony.gutierrez@amd.com        warn("Copied block source spans pages %x.", src);
21411308Santhony.gutierrez@amd.com        no_warn = false;
21511308Santhony.gutierrez@amd.com    }
21611308Santhony.gutierrez@amd.com
21711308Santhony.gutierrez@amd.com    memReq->reset(src & ~(blk_size - 1), blk_size);
21811308Santhony.gutierrez@amd.com
21911308Santhony.gutierrez@amd.com    // translate to physical address
22011308Santhony.gutierrez@amd.com    Fault fault = thread->translateDataReadReq(req);
22111308Santhony.gutierrez@amd.com
22211308Santhony.gutierrez@amd.com    if (fault == NoFault) {
22311308Santhony.gutierrez@amd.com        thread->copySrcAddr = src;
22411308Santhony.gutierrez@amd.com        thread->copySrcPhysAddr = memReq->paddr + offset;
22511308Santhony.gutierrez@amd.com    } else {
22611308Santhony.gutierrez@amd.com        assert(!fault->isAlignmentFault());
22711308Santhony.gutierrez@amd.com
22811308Santhony.gutierrez@amd.com        thread->copySrcAddr = 0;
22911308Santhony.gutierrez@amd.com        thread->copySrcPhysAddr = 0;
23011308Santhony.gutierrez@amd.com    }
23111308Santhony.gutierrez@amd.com    return fault;
23211308Santhony.gutierrez@amd.com#else
23311308Santhony.gutierrez@amd.com    return NoFault;
23411308Santhony.gutierrez@amd.com#endif
23511308Santhony.gutierrez@amd.com}
23611308Santhony.gutierrez@amd.com
23711308Santhony.gutierrez@amd.comFault
23811308Santhony.gutierrez@amd.comBaseSimpleCPU::copy(Addr dest)
23911308Santhony.gutierrez@amd.com{
24011308Santhony.gutierrez@amd.com#if 0
24111308Santhony.gutierrez@amd.com    static bool no_warn = true;
24211308Santhony.gutierrez@amd.com    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
24311308Santhony.gutierrez@amd.com    // Only support block sizes of 64 atm.
24411308Santhony.gutierrez@amd.com    assert(blk_size == 64);
24511308Santhony.gutierrez@amd.com    uint8_t data[blk_size];
24611308Santhony.gutierrez@amd.com    //assert(thread->copySrcAddr);
24711308Santhony.gutierrez@amd.com    int offset = dest & (blk_size - 1);
24811308Santhony.gutierrez@amd.com
24911308Santhony.gutierrez@amd.com    // Make sure block doesn't span page
25011308Santhony.gutierrez@amd.com    if (no_warn &&
25111308Santhony.gutierrez@amd.com        (dest & PageMask) != ((dest + blk_size) & PageMask) &&
25211308Santhony.gutierrez@amd.com        (dest >> 40) != 0xfffffc) {
25311308Santhony.gutierrez@amd.com        no_warn = false;
25411308Santhony.gutierrez@amd.com        warn("Copied block destination spans pages %x. ", dest);
25511308Santhony.gutierrez@amd.com    }
25611308Santhony.gutierrez@amd.com
25711308Santhony.gutierrez@amd.com    memReq->reset(dest & ~(blk_size -1), blk_size);
25811308Santhony.gutierrez@amd.com    // translate to physical address
25911308Santhony.gutierrez@amd.com    Fault fault = thread->translateDataWriteReq(req);
26011308Santhony.gutierrez@amd.com
26111308Santhony.gutierrez@amd.com    if (fault == NoFault) {
26211308Santhony.gutierrez@amd.com        Addr dest_addr = memReq->paddr + offset;
26311308Santhony.gutierrez@amd.com        // Need to read straight from memory since we have more than 8 bytes.
26411308Santhony.gutierrez@amd.com        memReq->paddr = thread->copySrcPhysAddr;
26511308Santhony.gutierrez@amd.com        thread->mem->read(memReq, data);
26611308Santhony.gutierrez@amd.com        memReq->paddr = dest_addr;
26711308Santhony.gutierrez@amd.com        thread->mem->write(memReq, data);
26811308Santhony.gutierrez@amd.com        if (dcacheInterface) {
26911308Santhony.gutierrez@amd.com            memReq->cmd = Copy;
27011308Santhony.gutierrez@amd.com            memReq->completionEvent = NULL;
27111308Santhony.gutierrez@amd.com            memReq->paddr = thread->copySrcPhysAddr;
27211308Santhony.gutierrez@amd.com            memReq->dest = dest_addr;
27311308Santhony.gutierrez@amd.com            memReq->size = 64;
27411308Santhony.gutierrez@amd.com            memReq->time = curTick;
27511308Santhony.gutierrez@amd.com            memReq->flags &= ~INST_READ;
27611308Santhony.gutierrez@amd.com            dcacheInterface->access(memReq);
27711308Santhony.gutierrez@amd.com        }
27811308Santhony.gutierrez@amd.com    }
27911308Santhony.gutierrez@amd.com    else
28011308Santhony.gutierrez@amd.com        assert(!fault->isAlignmentFault());
28111308Santhony.gutierrez@amd.com
28211308Santhony.gutierrez@amd.com    return fault;
28311308Santhony.gutierrez@amd.com#else
28411308Santhony.gutierrez@amd.com    panic("copy not implemented");
28511308Santhony.gutierrez@amd.com    return NoFault;
28611308Santhony.gutierrez@amd.com#endif
28711308Santhony.gutierrez@amd.com}
28811308Santhony.gutierrez@amd.com
28911308Santhony.gutierrez@amd.com#if FULL_SYSTEM
29011308Santhony.gutierrez@amd.comAddr
29111308Santhony.gutierrez@amd.comBaseSimpleCPU::dbg_vtophys(Addr addr)
29211308Santhony.gutierrez@amd.com{
29311308Santhony.gutierrez@amd.com    return vtophys(tc, addr);
29411308Santhony.gutierrez@amd.com}
29511308Santhony.gutierrez@amd.com#endif // FULL_SYSTEM
29611308Santhony.gutierrez@amd.com
29711308Santhony.gutierrez@amd.com#if FULL_SYSTEM
29811308Santhony.gutierrez@amd.comvoid
29911308Santhony.gutierrez@amd.comBaseSimpleCPU::post_interrupt(int int_num, int index)
30011308Santhony.gutierrez@amd.com{
30111308Santhony.gutierrez@amd.com    BaseCPU::post_interrupt(int_num, index);
30211308Santhony.gutierrez@amd.com
30311308Santhony.gutierrez@amd.com    if (thread->status() == ThreadContext::Suspended) {
30411308Santhony.gutierrez@amd.com                DPRINTF(IPI,"Suspended Processor awoke\n");
30511308Santhony.gutierrez@amd.com        thread->activate();
30611308Santhony.gutierrez@amd.com    }
30711308Santhony.gutierrez@amd.com}
30811308Santhony.gutierrez@amd.com#endif // FULL_SYSTEM
30911308Santhony.gutierrez@amd.com
31011308Santhony.gutierrez@amd.comvoid
31111308Santhony.gutierrez@amd.comBaseSimpleCPU::checkForInterrupts()
31211308Santhony.gutierrez@amd.com{
31311308Santhony.gutierrez@amd.com#if FULL_SYSTEM
31411308Santhony.gutierrez@amd.com    if (check_interrupts(tc)) {
31511308Santhony.gutierrez@amd.com        Fault interrupt = interrupts.getInterrupt(tc);
31611308Santhony.gutierrez@amd.com
31711308Santhony.gutierrez@amd.com        if (interrupt != NoFault) {
31811308Santhony.gutierrez@amd.com            interrupts.updateIntrInfo(tc);
31911308Santhony.gutierrez@amd.com            interrupt->invoke(tc);
32011308Santhony.gutierrez@amd.com        }
32111308Santhony.gutierrez@amd.com    }
32211308Santhony.gutierrez@amd.com#endif
32311308Santhony.gutierrez@amd.com}
32411308Santhony.gutierrez@amd.com
32511308Santhony.gutierrez@amd.com
32611308Santhony.gutierrez@amd.comFault
32711308Santhony.gutierrez@amd.comBaseSimpleCPU::setupFetchRequest(Request *req)
32811308Santhony.gutierrez@amd.com{
32911308Santhony.gutierrez@amd.com    // set up memory request for instruction fetch
33011308Santhony.gutierrez@amd.com#if ISA_HAS_DELAY_SLOT
33111308Santhony.gutierrez@amd.com    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(),
33211308Santhony.gutierrez@amd.com            thread->readNextPC(),thread->readNextNPC());
33311308Santhony.gutierrez@amd.com#else
33411308Santhony.gutierrez@amd.com    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p",thread->readPC(),
33511308Santhony.gutierrez@amd.com            thread->readNextPC());
33611308Santhony.gutierrez@amd.com#endif
33711308Santhony.gutierrez@amd.com
33811308Santhony.gutierrez@amd.com    req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst),
33911308Santhony.gutierrez@amd.com                 (FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0,
34011308Santhony.gutierrez@amd.com                 thread->readPC());
34111308Santhony.gutierrez@amd.com
34211308Santhony.gutierrez@amd.com    Fault fault = thread->translateInstReq(req);
34311308Santhony.gutierrez@amd.com
34411308Santhony.gutierrez@amd.com    return fault;
34511308Santhony.gutierrez@amd.com}
34611955Sgabeblack@google.com
34711308Santhony.gutierrez@amd.com
34811308Santhony.gutierrez@amd.comvoid
34911308Santhony.gutierrez@amd.comBaseSimpleCPU::preExecute()
35011308Santhony.gutierrez@amd.com{
35111308Santhony.gutierrez@amd.com    // maintain $r0 semantics
35211308Santhony.gutierrez@amd.com    thread->setIntReg(ZeroReg, 0);
35311308Santhony.gutierrez@amd.com#if THE_ISA == ALPHA_ISA
35411308Santhony.gutierrez@amd.com    thread->setFloatReg(ZeroReg, 0.0);
35511308Santhony.gutierrez@amd.com#endif // ALPHA_ISA
35611308Santhony.gutierrez@amd.com
35711308Santhony.gutierrez@amd.com    // keep an instruction count
35811308Santhony.gutierrez@amd.com    numInst++;
35911308Santhony.gutierrez@amd.com    numInsts++;
36011308Santhony.gutierrez@amd.com
36111308Santhony.gutierrez@amd.com    thread->funcExeInst++;
36211308Santhony.gutierrez@amd.com
36311308Santhony.gutierrez@amd.com    // check for instruction-count-based events
36411308Santhony.gutierrez@amd.com    comInstEventQueue[0]->serviceEvents(numInst);
36511308Santhony.gutierrez@amd.com
36611308Santhony.gutierrez@amd.com    // decode the instruction
36711308Santhony.gutierrez@amd.com    inst = gtoh(inst);
36811308Santhony.gutierrez@amd.com    //If we're not in the middle of a macro instruction
36911308Santhony.gutierrez@amd.com    if (!curMacroStaticInst) {
37011308Santhony.gutierrez@amd.com#if THE_ISA == ALPHA_ISA
37111308Santhony.gutierrez@amd.com        StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC()));
37211308Santhony.gutierrez@amd.com#elif THE_ISA == SPARC_ISA
37311308Santhony.gutierrez@amd.com        StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
37411308Santhony.gutierrez@amd.com#elif THE_ISA == X86_ISA
37511308Santhony.gutierrez@amd.com        StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
37611308Santhony.gutierrez@amd.com#elif THE_ISA == MIPS_ISA
37711308Santhony.gutierrez@amd.com        //Mips doesn't do anything in it's MakeExtMI function right now,
37811308Santhony.gutierrez@amd.com        //so it won't be called.
37911308Santhony.gutierrez@amd.com        StaticInstPtr instPtr = StaticInst::decode(inst);
38011308Santhony.gutierrez@amd.com#endif
38111308Santhony.gutierrez@amd.com        if (instPtr->isMacroOp()) {
38211308Santhony.gutierrez@amd.com            curMacroStaticInst = instPtr;
38311308Santhony.gutierrez@amd.com            curStaticInst = curMacroStaticInst->
38411308Santhony.gutierrez@amd.com                fetchMicroOp(thread->readMicroPC());
38511308Santhony.gutierrez@amd.com        } else {
38611308Santhony.gutierrez@amd.com            curStaticInst = instPtr;
38711308Santhony.gutierrez@amd.com        }
38811308Santhony.gutierrez@amd.com    } else {
38911308Santhony.gutierrez@amd.com        //Read the next micro op from the macro op
39011308Santhony.gutierrez@amd.com        curStaticInst = curMacroStaticInst->
39111308Santhony.gutierrez@amd.com            fetchMicroOp(thread->readMicroPC());
39211308Santhony.gutierrez@amd.com    }
39311308Santhony.gutierrez@amd.com
39411308Santhony.gutierrez@amd.com
39511308Santhony.gutierrez@amd.com    traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
39611308Santhony.gutierrez@amd.com                                     thread->readPC());
39711308Santhony.gutierrez@amd.com
39811308Santhony.gutierrez@amd.com    DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
39911308Santhony.gutierrez@amd.com            curStaticInst->getName(), curStaticInst->getOpcode(),
40011308Santhony.gutierrez@amd.com            curStaticInst->machInst);
40111308Santhony.gutierrez@amd.com
40211308Santhony.gutierrez@amd.com#if FULL_SYSTEM
40311308Santhony.gutierrez@amd.com    thread->setInst(inst);
40411308Santhony.gutierrez@amd.com#endif // FULL_SYSTEM
40511308Santhony.gutierrez@amd.com}
40611308Santhony.gutierrez@amd.com
40711308Santhony.gutierrez@amd.comvoid
40811308Santhony.gutierrez@amd.comBaseSimpleCPU::postExecute()
40911308Santhony.gutierrez@amd.com{
41011308Santhony.gutierrez@amd.com#if FULL_SYSTEM
41111308Santhony.gutierrez@amd.com    if (thread->profile) {
41211308Santhony.gutierrez@amd.com        bool usermode = TheISA::inUserMode(tc);
41311308Santhony.gutierrez@amd.com        thread->profilePC = usermode ? 1 : thread->readPC();
41411308Santhony.gutierrez@amd.com        ProfileNode *node = thread->profile->consume(tc, inst);
41511308Santhony.gutierrez@amd.com        if (node)
41611308Santhony.gutierrez@amd.com            thread->profileNode = node;
41711308Santhony.gutierrez@amd.com    }
41811308Santhony.gutierrez@amd.com#endif
41911308Santhony.gutierrez@amd.com
42011308Santhony.gutierrez@amd.com    if (curStaticInst->isMemRef()) {
42111308Santhony.gutierrez@amd.com        numMemRefs++;
42211308Santhony.gutierrez@amd.com    }
42311308Santhony.gutierrez@amd.com
42411308Santhony.gutierrez@amd.com    if (curStaticInst->isLoad()) {
42511308Santhony.gutierrez@amd.com        ++numLoad;
42611308Santhony.gutierrez@amd.com        comLoadEventQueue[0]->serviceEvents(numLoad);
42711308Santhony.gutierrez@amd.com    }
42811308Santhony.gutierrez@amd.com
42911308Santhony.gutierrez@amd.com    traceFunctions(thread->readPC());
43011308Santhony.gutierrez@amd.com
43111308Santhony.gutierrez@amd.com    if (traceData) {
43211308Santhony.gutierrez@amd.com        traceData->dump();
43311308Santhony.gutierrez@amd.com        delete traceData;
43411308Santhony.gutierrez@amd.com        traceData = NULL;
43511308Santhony.gutierrez@amd.com    }
43611308Santhony.gutierrez@amd.com}
43711308Santhony.gutierrez@amd.com
43811308Santhony.gutierrez@amd.com
43911308Santhony.gutierrez@amd.comvoid
44011308Santhony.gutierrez@amd.comBaseSimpleCPU::advancePC(Fault fault)
44111308Santhony.gutierrez@amd.com{
44211308Santhony.gutierrez@amd.com    if (fault != NoFault) {
44311308Santhony.gutierrez@amd.com        curMacroStaticInst = StaticInst::nullStaticInstPtr;
44411308Santhony.gutierrez@amd.com        fault->invoke(tc);
44511308Santhony.gutierrez@amd.com        thread->setMicroPC(0);
44611308Santhony.gutierrez@amd.com        thread->setNextMicroPC(1);
44711308Santhony.gutierrez@amd.com    } else {
44811308Santhony.gutierrez@amd.com        //If we're at the last micro op for this instruction
44911308Santhony.gutierrez@amd.com        if (curStaticInst->isLastMicroOp()) {
45011308Santhony.gutierrez@amd.com            //We should be working with a macro op
45111308Santhony.gutierrez@amd.com            assert(curMacroStaticInst);
45211308Santhony.gutierrez@amd.com            //Close out this macro op, and clean up the
45311308Santhony.gutierrez@amd.com            //microcode state
45411308Santhony.gutierrez@amd.com            curMacroStaticInst = StaticInst::nullStaticInstPtr;
45511308Santhony.gutierrez@amd.com            thread->setMicroPC(0);
45611308Santhony.gutierrez@amd.com            thread->setNextMicroPC(1);
45711308Santhony.gutierrez@amd.com        }
45811308Santhony.gutierrez@amd.com        //If we're still in a macro op
45911308Santhony.gutierrez@amd.com        if (curMacroStaticInst) {
46011308Santhony.gutierrez@amd.com            //Advance the micro pc
46111308Santhony.gutierrez@amd.com            thread->setMicroPC(thread->readNextMicroPC());
46211308Santhony.gutierrez@amd.com            //Advance the "next" micro pc. Note that there are no delay
46311308Santhony.gutierrez@amd.com            //slots, and micro ops are "word" addressed.
46411308Santhony.gutierrez@amd.com            thread->setNextMicroPC(thread->readNextMicroPC() + 1);
46511308Santhony.gutierrez@amd.com        } else {
46611308Santhony.gutierrez@amd.com            // go to the next instruction
46711308Santhony.gutierrez@amd.com            thread->setPC(thread->readNextPC());
46811308Santhony.gutierrez@amd.com#if ISA_HAS_DELAY_SLOT
46911308Santhony.gutierrez@amd.com            thread->setNextPC(thread->readNextNPC());
47011308Santhony.gutierrez@amd.com            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
47111308Santhony.gutierrez@amd.com            assert(thread->readNextPC() != thread->readNextNPC());
47211308Santhony.gutierrez@amd.com#else
47311308Santhony.gutierrez@amd.com            thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
47411308Santhony.gutierrez@amd.com#endif
47511308Santhony.gutierrez@amd.com        }
47611308Santhony.gutierrez@amd.com    }
47711308Santhony.gutierrez@amd.com
47811308Santhony.gutierrez@amd.com#if FULL_SYSTEM
47911308Santhony.gutierrez@amd.com    Addr oldpc;
48011308Santhony.gutierrez@amd.com    do {
48111308Santhony.gutierrez@amd.com        oldpc = thread->readPC();
48211308Santhony.gutierrez@amd.com        system->pcEventQueue.service(tc);
48311308Santhony.gutierrez@amd.com    } while (oldpc != thread->readPC());
48411308Santhony.gutierrez@amd.com#endif
48511308Santhony.gutierrez@amd.com}
48611308Santhony.gutierrez@amd.com
48711308Santhony.gutierrez@amd.com