base_dyn_inst_impl.hh revision 3794:647d6bb9539a
16876Ssteve.reinhardt@amd.com/*
210089Sandreas.hansson@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
38922Swilliam.wang@arm.com * All rights reserved.
48922Swilliam.wang@arm.com *
58922Swilliam.wang@arm.com * Redistribution and use in source and binary forms, with or without
68922Swilliam.wang@arm.com * modification, are permitted provided that the following conditions are
78922Swilliam.wang@arm.com * met: redistributions of source code must retain the above copyright
88922Swilliam.wang@arm.com * notice, this list of conditions and the following disclaimer;
98922Swilliam.wang@arm.com * redistributions in binary form must reproduce the above copyright
108922Swilliam.wang@arm.com * notice, this list of conditions and the following disclaimer in the
118922Swilliam.wang@arm.com * documentation and/or other materials provided with the distribution;
128922Swilliam.wang@arm.com * neither the name of the copyright holders nor the names of its
138922Swilliam.wang@arm.com * contributors may be used to endorse or promote products derived from
146876Ssteve.reinhardt@amd.com * this software without specific prior written permission.
158717Snilay@cs.wisc.edu *
166876Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176876Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186876Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196876Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206876Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216876Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226876Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236876Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246876Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256876Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266876Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276876Ssteve.reinhardt@amd.com *
286876Ssteve.reinhardt@amd.com * Authors: Kevin Lim
296876Ssteve.reinhardt@amd.com */
306876Ssteve.reinhardt@amd.com
316876Ssteve.reinhardt@amd.com#include <iostream>
326876Ssteve.reinhardt@amd.com#include <set>
336876Ssteve.reinhardt@amd.com#include <string>
346876Ssteve.reinhardt@amd.com#include <sstream>
356876Ssteve.reinhardt@amd.com
366876Ssteve.reinhardt@amd.com#include "base/cprintf.hh"
376876Ssteve.reinhardt@amd.com#include "base/trace.hh"
386876Ssteve.reinhardt@amd.com
396876Ssteve.reinhardt@amd.com#include "sim/faults.hh"
406876Ssteve.reinhardt@amd.com#include "cpu/exetrace.hh"
416876Ssteve.reinhardt@amd.com#include "mem/request.hh"
427632SBrad.Beckmann@amd.com
438688Snilay@cs.wisc.edu#include "cpu/base_dyn_inst.hh"
449152Satgutier@umich.edu
458232Snate@binkert.org#define NOHASH
468436SBrad.Beckmann@amd.com#ifndef NOHASH
477039Snate@binkert.org
486285Snate@binkert.org#include "base/hashmap.hh"
4910525Snilay@cs.wisc.edu
5010117Snilay@cs.wisc.eduunsigned int MyHashFunc(const BaseDynInst *addr)
518923Sandreas.hansson@arm.com{
526285Snate@binkert.org    unsigned a = (unsigned)addr;
536876Ssteve.reinhardt@amd.com    unsigned hash = (((a >> 14) ^ ((a >> 2) & 0xffff))) & 0x7FFFFFFF;
5410919Sbrandon.potter@amd.com
5510919Sbrandon.potter@amd.com    return hash;
5610919Sbrandon.potter@amd.com}
5710090Snilay@cs.wisc.edu
5810090Snilay@cs.wisc.edutypedef m5::hash_map<const BaseDynInst *, const BaseDynInst *, MyHashFunc>
5910090Snilay@cs.wisc.edumy_hash_t;
6010090Snilay@cs.wisc.edu
6110919Sbrandon.potter@amd.commy_hash_t thishash;
6210913Sandreas.sandberg@arm.com#endif
636876Ssteve.reinhardt@amd.com
646876Ssteve.reinhardt@amd.comtemplate <class Impl>
656876Ssteve.reinhardt@amd.comBaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst machInst, Addr inst_PC,
668922Swilliam.wang@arm.com                               Addr pred_PC, Addr pred_NPC,
678922Swilliam.wang@arm.com                               InstSeqNum seq_num, ImplCPU *cpu)
6810090Snilay@cs.wisc.edu  : staticInst(machInst), traceData(NULL), cpu(cpu)
6910919Sbrandon.potter@amd.com{
708922Swilliam.wang@arm.com    seqNum = seq_num;
717039Snate@binkert.org
728922Swilliam.wang@arm.com    PC = inst_PC;
738922Swilliam.wang@arm.com    nextPC = PC + sizeof(TheISA::MachInst);
7410090Snilay@cs.wisc.edu    nextNPC = nextPC + sizeof(TheISA::MachInst);
7510090Snilay@cs.wisc.edu    predPC = pred_PC;
768922Swilliam.wang@arm.com    predNPC = pred_NPC;
776876Ssteve.reinhardt@amd.com    predTaken = false;
786876Ssteve.reinhardt@amd.com
797039Snate@binkert.org    initVars();
807039Snate@binkert.org}
816882SBrad.Beckmann@amd.com
826882SBrad.Beckmann@amd.comtemplate <class Impl>
836882SBrad.Beckmann@amd.comBaseDynInst<Impl>::BaseDynInst(StaticInstPtr &_staticInst)
846882SBrad.Beckmann@amd.com    : staticInst(_staticInst), traceData(NULL)
856882SBrad.Beckmann@amd.com{
869294Sandreas.hansson@arm.com    seqNum = 0;
879294Sandreas.hansson@arm.com    initVars();
886876Ssteve.reinhardt@amd.com}
8910090Snilay@cs.wisc.edu
9010090Snilay@cs.wisc.edutemplate <class Impl>
9110090Snilay@cs.wisc.eduvoid
9210090Snilay@cs.wisc.eduBaseDynInst<Impl>::initVars()
9310090Snilay@cs.wisc.edu{
9410090Snilay@cs.wisc.edu    req = NULL;
958922Swilliam.wang@arm.com    memData = NULL;
968922Swilliam.wang@arm.com    effAddr = 0;
978839Sandreas.hansson@arm.com    physEffAddr = 0;
988839Sandreas.hansson@arm.com
998922Swilliam.wang@arm.com    readyRegs = 0;
1008922Swilliam.wang@arm.com
1018922Swilliam.wang@arm.com    instResult.integer = 0;
1028922Swilliam.wang@arm.com    recordResult = true;
1039294Sandreas.hansson@arm.com
1048922Swilliam.wang@arm.com    status.reset();
1058922Swilliam.wang@arm.com
1068839Sandreas.hansson@arm.com    eaCalcDone = false;
1078922Swilliam.wang@arm.com    memOpDone = false;
1088839Sandreas.hansson@arm.com
1098922Swilliam.wang@arm.com    lqIdx = -1;
1108839Sandreas.hansson@arm.com    sqIdx = -1;
1119294Sandreas.hansson@arm.com
1129294Sandreas.hansson@arm.com    // Eventually make this a parameter.
1138922Swilliam.wang@arm.com    threadNumber = 0;
11410090Snilay@cs.wisc.edu
11510090Snilay@cs.wisc.edu    // Also make this a parameter, or perhaps get it from xc or cpu.
11610090Snilay@cs.wisc.edu    asid = 0;
11710090Snilay@cs.wisc.edu
11810090Snilay@cs.wisc.edu    // Initialize the fault to be NoFault.
11910090Snilay@cs.wisc.edu    fault = NoFault;
12010090Snilay@cs.wisc.edu
1218922Swilliam.wang@arm.com    ++instcount;
1228922Swilliam.wang@arm.com
1238922Swilliam.wang@arm.com    if (instcount > 1500) {
1248922Swilliam.wang@arm.com        cpu->dumpInsts();
1258922Swilliam.wang@arm.com#ifdef DEBUG
1268922Swilliam.wang@arm.com        dumpSNList();
1279294Sandreas.hansson@arm.com#endif
1288922Swilliam.wang@arm.com        assert(instcount <= 1500);
1298922Swilliam.wang@arm.com    }
1308922Swilliam.wang@arm.com
1318922Swilliam.wang@arm.com    DPRINTF(DynInst, "DynInst: [sn:%lli] Instruction created. Instcount=%i\n",
1327039Snate@binkert.org            seqNum, instcount);
1336876Ssteve.reinhardt@amd.com
1346882SBrad.Beckmann@amd.com#ifdef DEBUG
13510090Snilay@cs.wisc.edu    cpu->snList.insert(seqNum);
1366882SBrad.Beckmann@amd.com#endif
13710713Sandreas.hansson@arm.com}
13810713Sandreas.hansson@arm.com
1396882SBrad.Beckmann@amd.comtemplate <class Impl>
14010090Snilay@cs.wisc.eduBaseDynInst<Impl>::~BaseDynInst()
1416882SBrad.Beckmann@amd.com{
1426882SBrad.Beckmann@amd.com    if (req) {
14310090Snilay@cs.wisc.edu        delete req;
14410090Snilay@cs.wisc.edu    }
14510090Snilay@cs.wisc.edu
14610090Snilay@cs.wisc.edu    if (memData) {
14710090Snilay@cs.wisc.edu        delete [] memData;
14810090Snilay@cs.wisc.edu    }
14910090Snilay@cs.wisc.edu
15010090Snilay@cs.wisc.edu    if (traceData) {
15110090Snilay@cs.wisc.edu        delete traceData;
15210713Sandreas.hansson@arm.com    }
15310713Sandreas.hansson@arm.com
15410090Snilay@cs.wisc.edu    fault = NoFault;
15510090Snilay@cs.wisc.edu
15610090Snilay@cs.wisc.edu    --instcount;
15710090Snilay@cs.wisc.edu
15810090Snilay@cs.wisc.edu    DPRINTF(DynInst, "DynInst: [sn:%lli] Instruction destroyed. Instcount=%i\n",
15910525Snilay@cs.wisc.edu            seqNum, instcount);
16010089Sandreas.hansson@arm.com#ifdef DEBUG
16110919Sbrandon.potter@amd.com    cpu->snList.erase(seqNum);
1626882SBrad.Beckmann@amd.com#endif
16310090Snilay@cs.wisc.edu}
1646882SBrad.Beckmann@amd.com
1656882SBrad.Beckmann@amd.com#ifdef DEBUG
16610089Sandreas.hansson@arm.comtemplate <class Impl>
16710090Snilay@cs.wisc.eduvoid
16810090Snilay@cs.wisc.eduBaseDynInst<Impl>::dumpSNList()
16910919Sbrandon.potter@amd.com{
17010090Snilay@cs.wisc.edu    std::set<InstSeqNum>::iterator sn_it = cpu->snList.begin();
17110090Snilay@cs.wisc.edu
17210090Snilay@cs.wisc.edu    int count = 0;
17310919Sbrandon.potter@amd.com    while (sn_it != cpu->snList.end()) {
17410919Sbrandon.potter@amd.com        cprintf("%i: [sn:%lli] not destroyed\n", count, (*sn_it));
17510090Snilay@cs.wisc.edu        count++;
17610090Snilay@cs.wisc.edu        sn_it++;
17710090Snilay@cs.wisc.edu    }
17810090Snilay@cs.wisc.edu}
17910089Sandreas.hansson@arm.com#endif
18010089Sandreas.hansson@arm.com
18110089Sandreas.hansson@arm.comtemplate <class Impl>
1826882SBrad.Beckmann@amd.comvoid
18310090Snilay@cs.wisc.eduBaseDynInst<Impl>::prefetch(Addr addr, unsigned flags)
18410090Snilay@cs.wisc.edu{
18510090Snilay@cs.wisc.edu    // This is the "functional" implementation of prefetch.  Not much
18610090Snilay@cs.wisc.edu    // happens here since prefetches don't affect the architectural
18710090Snilay@cs.wisc.edu    // state.
18810090Snilay@cs.wisc.edu/*
1897039Snate@binkert.org    // Generate a MemReq so we can translate the effective address.
19010657Sandreas.hansson@arm.com    MemReqPtr req = new MemReq(addr, thread->getXCProxy(), 1, flags);
19110657Sandreas.hansson@arm.com    req->asid = asid;
19210657Sandreas.hansson@arm.com
19310657Sandreas.hansson@arm.com    // Prefetches never cause faults.
19410657Sandreas.hansson@arm.com    fault = NoFault;
19510089Sandreas.hansson@arm.com
19610919Sbrandon.potter@amd.com    // note this is a local, not BaseDynInst::fault
19710919Sbrandon.potter@amd.com    Fault trans_fault = cpu->translateDataReadReq(req);
1987039Snate@binkert.org
1996882SBrad.Beckmann@amd.com    if (trans_fault == NoFault && !(req->isUncacheable())) {
2006882SBrad.Beckmann@amd.com        // It's a valid address to cacheable space.  Record key MemReq
2016882SBrad.Beckmann@amd.com        // parameters so we can generate another one just like it for
2026882SBrad.Beckmann@amd.com        // the timing access without calling translate() again (which
20310090Snilay@cs.wisc.edu        // might mess up the TLB).
2046882SBrad.Beckmann@amd.com        effAddr = req->vaddr;
20510090Snilay@cs.wisc.edu        physEffAddr = req->paddr;
20610090Snilay@cs.wisc.edu        memReqFlags = req->flags;
20710090Snilay@cs.wisc.edu    } else {
20810090Snilay@cs.wisc.edu        // Bogus address (invalid or uncacheable space).  Mark it by
20910090Snilay@cs.wisc.edu        // setting the eff_addr to InvalidAddr.
21010090Snilay@cs.wisc.edu        effAddr = physEffAddr = MemReq::inval_addr;
21110412Sandreas.hansson@arm.com    }
21210412Sandreas.hansson@arm.com
21310412Sandreas.hansson@arm.com    if (traceData) {
21410412Sandreas.hansson@arm.com        traceData->setAddr(addr);
21510412Sandreas.hansson@arm.com    }
21610090Snilay@cs.wisc.edu*/
21710090Snilay@cs.wisc.edu}
21810090Snilay@cs.wisc.edu
21910090Snilay@cs.wisc.edutemplate <class Impl>
22010090Snilay@cs.wisc.eduvoid
22110090Snilay@cs.wisc.eduBaseDynInst<Impl>::writeHint(Addr addr, int size, unsigned flags)
22210090Snilay@cs.wisc.edu{
22310090Snilay@cs.wisc.edu    // Not currently supported.
22410090Snilay@cs.wisc.edu}
22510090Snilay@cs.wisc.edu
22610090Snilay@cs.wisc.edu/**
22710090Snilay@cs.wisc.edu * @todo Need to find a way to get the cache block size here.
22810090Snilay@cs.wisc.edu */
2296882SBrad.Beckmann@amd.comtemplate <class Impl>
2309662Sandreas.hansson@arm.comFault
2319662Sandreas.hansson@arm.comBaseDynInst<Impl>::copySrcTranslate(Addr src)
2326882SBrad.Beckmann@amd.com{
2336882SBrad.Beckmann@amd.com    // Not currently supported.
2346882SBrad.Beckmann@amd.com    return NoFault;
2356882SBrad.Beckmann@amd.com}
23610090Snilay@cs.wisc.edu
23710090Snilay@cs.wisc.edu/**
2386922SBrad.Beckmann@amd.com * @todo Need to find a way to get the cache block size here.
2396882SBrad.Beckmann@amd.com */
24010090Snilay@cs.wisc.edutemplate <class Impl>
24110090Snilay@cs.wisc.eduFault
24210090Snilay@cs.wisc.eduBaseDynInst<Impl>::copy(Addr dest)
24310090Snilay@cs.wisc.edu{
2449163Sandreas.hansson@arm.com    // Not currently supported.
24510919Sbrandon.potter@amd.com    return NoFault;
24610090Snilay@cs.wisc.edu}
24710919Sbrandon.potter@amd.com
2489163Sandreas.hansson@arm.comtemplate <class Impl>
2496882SBrad.Beckmann@amd.comvoid
2506882SBrad.Beckmann@amd.comBaseDynInst<Impl>::dump()
25111025Snilay@cs.wisc.edu{
2528615Snilay@cs.wisc.edu    cprintf("T%d : %#08d `", threadNumber, PC);
2537906SBrad.Beckmann@amd.com    std::cout << staticInst->disassemble(PC);
2546882SBrad.Beckmann@amd.com    cprintf("'\n");
2558615Snilay@cs.wisc.edu}
2567023SBrad.Beckmann@amd.com
2577550SBrad.Beckmann@amd.comtemplate <class Impl>
25810089Sandreas.hansson@arm.comvoid
25910089Sandreas.hansson@arm.comBaseDynInst<Impl>::dump(std::string &outstring)
2607550SBrad.Beckmann@amd.com{
26110657Sandreas.hansson@arm.com    std::ostringstream s;
26210657Sandreas.hansson@arm.com    s << "T" << threadNumber << " : 0x" << PC << " "
26310657Sandreas.hansson@arm.com      << staticInst->disassemble(PC);
26410657Sandreas.hansson@arm.com
26510089Sandreas.hansson@arm.com    outstring = s.str();
26610089Sandreas.hansson@arm.com}
2676922SBrad.Beckmann@amd.com
2686882SBrad.Beckmann@amd.comtemplate <class Impl>
2697023SBrad.Beckmann@amd.comvoid
2707910SBrad.Beckmann@amd.comBaseDynInst<Impl>::markSrcRegReady()
27110919Sbrandon.potter@amd.com{
2727910SBrad.Beckmann@amd.com    if (++readyRegs == numSrcRegs()) {
2737910SBrad.Beckmann@amd.com        status.set(CanIssue);
2747910SBrad.Beckmann@amd.com    }
2757910SBrad.Beckmann@amd.com}
2767910SBrad.Beckmann@amd.com
2777910SBrad.Beckmann@amd.comtemplate <class Impl>
27810090Snilay@cs.wisc.eduvoid
2797039Snate@binkert.orgBaseDynInst<Impl>::markSrcRegReady(RegIndex src_idx)
2807039Snate@binkert.org{
2816922SBrad.Beckmann@amd.com    _readySrcRegIdx[src_idx] = true;
2826882SBrad.Beckmann@amd.com
2836882SBrad.Beckmann@amd.com    markSrcRegReady();
2848436SBrad.Beckmann@amd.com}
28510090Snilay@cs.wisc.edu
2868436SBrad.Beckmann@amd.comtemplate <class Impl>
28710090Snilay@cs.wisc.edubool
2888436SBrad.Beckmann@amd.comBaseDynInst<Impl>::eaSrcsReady()
28910919Sbrandon.potter@amd.com{
29010919Sbrandon.potter@amd.com    // For now I am assuming that src registers 1..n-1 are the ones that the
29110919Sbrandon.potter@amd.com    // EA calc depends on.  (i.e. src reg 0 is the source of the data to be
2928436SBrad.Beckmann@amd.com    // stored)
2938436SBrad.Beckmann@amd.com
2948436SBrad.Beckmann@amd.com    for (int i = 1; i < numSrcRegs(); ++i) {
29510919Sbrandon.potter@amd.com        if (!_readySrcRegIdx[i])
29610090Snilay@cs.wisc.edu            return false;
29710090Snilay@cs.wisc.edu    }
2988436SBrad.Beckmann@amd.com
2998436SBrad.Beckmann@amd.com    return true;
3008436SBrad.Beckmann@amd.com}
30111025Snilay@cs.wisc.edu