base_dyn_inst_impl.hh revision 5375
11060SN/A/*
22702SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan
31060SN/A * All rights reserved.
41060SN/A *
51060SN/A * Redistribution and use in source and binary forms, with or without
61060SN/A * modification, are permitted provided that the following conditions are
71060SN/A * met: redistributions of source code must retain the above copyright
81060SN/A * notice, this list of conditions and the following disclaimer;
91060SN/A * redistributions in binary form must reproduce the above copyright
101060SN/A * notice, this list of conditions and the following disclaimer in the
111060SN/A * documentation and/or other materials provided with the distribution;
121060SN/A * neither the name of the copyright holders nor the names of its
131060SN/A * contributors may be used to endorse or promote products derived from
141060SN/A * this software without specific prior written permission.
151060SN/A *
161060SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665SN/A *
282665SN/A * Authors: Kevin Lim
291060SN/A */
301060SN/A
311060SN/A#include <iostream>
322292SN/A#include <set>
331060SN/A#include <string>
341060SN/A#include <sstream>
351060SN/A
361060SN/A#include "base/cprintf.hh"
371061SN/A#include "base/trace.hh"
381060SN/A
392980Sgblack@eecs.umich.edu#include "sim/faults.hh"
401060SN/A#include "cpu/exetrace.hh"
412669SN/A#include "mem/request.hh"
421060SN/A
431060SN/A#include "cpu/base_dyn_inst.hh"
441060SN/A
451060SN/A#define NOHASH
461060SN/A#ifndef NOHASH
471060SN/A
481060SN/A#include "base/hashmap.hh"
491060SN/A
501060SN/Aunsigned int MyHashFunc(const BaseDynInst *addr)
511060SN/A{
522292SN/A    unsigned a = (unsigned)addr;
532292SN/A    unsigned hash = (((a >> 14) ^ ((a >> 2) & 0xffff))) & 0x7FFFFFFF;
541060SN/A
552292SN/A    return hash;
561060SN/A}
571060SN/A
582292SN/Atypedef m5::hash_map<const BaseDynInst *, const BaseDynInst *, MyHashFunc>
592292SN/Amy_hash_t;
602292SN/A
611060SN/Amy_hash_t thishash;
621060SN/A#endif
631060SN/A
641061SN/Atemplate <class Impl>
654636Sgblack@eecs.umich.eduBaseDynInst<Impl>::BaseDynInst(StaticInstPtr _staticInst,
663801Sgblack@eecs.umich.edu                               Addr inst_PC, Addr inst_NPC,
674636Sgblack@eecs.umich.edu                               Addr inst_MicroPC,
683794Sgblack@eecs.umich.edu                               Addr pred_PC, Addr pred_NPC,
694636Sgblack@eecs.umich.edu                               Addr pred_MicroPC,
703794Sgblack@eecs.umich.edu                               InstSeqNum seq_num, ImplCPU *cpu)
714636Sgblack@eecs.umich.edu  : staticInst(_staticInst), traceData(NULL), cpu(cpu)
721060SN/A{
731464SN/A    seqNum = seq_num;
741061SN/A
754636Sgblack@eecs.umich.edu    bool nextIsMicro =
764654Sgblack@eecs.umich.edu        staticInst->isMicroop() && !staticInst->isLastMicroop();
774636Sgblack@eecs.umich.edu
781464SN/A    PC = inst_PC;
794636Sgblack@eecs.umich.edu    microPC = inst_MicroPC;
804636Sgblack@eecs.umich.edu    if (nextIsMicro) {
814636Sgblack@eecs.umich.edu        nextPC = inst_PC;
824636Sgblack@eecs.umich.edu        nextNPC = inst_NPC;
834636Sgblack@eecs.umich.edu        nextMicroPC = microPC + 1;
844636Sgblack@eecs.umich.edu    } else {
854636Sgblack@eecs.umich.edu        nextPC = inst_NPC;
864636Sgblack@eecs.umich.edu        nextNPC = nextPC + sizeof(TheISA::MachInst);
874636Sgblack@eecs.umich.edu        nextMicroPC = 0;
884636Sgblack@eecs.umich.edu    }
891464SN/A    predPC = pred_PC;
903794Sgblack@eecs.umich.edu    predNPC = pred_NPC;
914636Sgblack@eecs.umich.edu    predMicroPC = pred_MicroPC;
924636Sgblack@eecs.umich.edu    predTaken = false;
934636Sgblack@eecs.umich.edu
944636Sgblack@eecs.umich.edu    initVars();
954636Sgblack@eecs.umich.edu}
964636Sgblack@eecs.umich.edu
974636Sgblack@eecs.umich.edutemplate <class Impl>
984636Sgblack@eecs.umich.eduBaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst inst,
994636Sgblack@eecs.umich.edu                               Addr inst_PC, Addr inst_NPC,
1004636Sgblack@eecs.umich.edu                               Addr inst_MicroPC,
1014636Sgblack@eecs.umich.edu                               Addr pred_PC, Addr pred_NPC,
1024636Sgblack@eecs.umich.edu                               Addr pred_MicroPC,
1034636Sgblack@eecs.umich.edu                               InstSeqNum seq_num, ImplCPU *cpu)
1044654Sgblack@eecs.umich.edu  : staticInst(inst, inst_PC), traceData(NULL), cpu(cpu)
1054636Sgblack@eecs.umich.edu{
1064636Sgblack@eecs.umich.edu    seqNum = seq_num;
1074636Sgblack@eecs.umich.edu
1084636Sgblack@eecs.umich.edu    bool nextIsMicro =
1094654Sgblack@eecs.umich.edu        staticInst->isMicroop() && !staticInst->isLastMicroop();
1104636Sgblack@eecs.umich.edu
1114636Sgblack@eecs.umich.edu    PC = inst_PC;
1124636Sgblack@eecs.umich.edu    microPC = inst_MicroPC;
1134636Sgblack@eecs.umich.edu    if (nextIsMicro) {
1144636Sgblack@eecs.umich.edu        nextPC = inst_PC;
1154636Sgblack@eecs.umich.edu        nextNPC = inst_NPC;
1164636Sgblack@eecs.umich.edu        nextMicroPC = microPC + 1;
1174636Sgblack@eecs.umich.edu    } else {
1184636Sgblack@eecs.umich.edu        nextPC = inst_NPC;
1194636Sgblack@eecs.umich.edu        nextNPC = nextPC + sizeof(TheISA::MachInst);
1204636Sgblack@eecs.umich.edu        nextMicroPC = 0;
1214636Sgblack@eecs.umich.edu    }
1224636Sgblack@eecs.umich.edu    predPC = pred_PC;
1234636Sgblack@eecs.umich.edu    predNPC = pred_NPC;
1244636Sgblack@eecs.umich.edu    predMicroPC = pred_MicroPC;
1253794Sgblack@eecs.umich.edu    predTaken = false;
1261464SN/A
1271464SN/A    initVars();
1281464SN/A}
1291464SN/A
1301464SN/Atemplate <class Impl>
1312107SN/ABaseDynInst<Impl>::BaseDynInst(StaticInstPtr &_staticInst)
1321464SN/A    : staticInst(_staticInst), traceData(NULL)
1331464SN/A{
1342292SN/A    seqNum = 0;
1351464SN/A    initVars();
1361464SN/A}
1371464SN/A
1381464SN/Atemplate <class Impl>
1391464SN/Avoid
1401464SN/ABaseDynInst<Impl>::initVars()
1411464SN/A{
1422678SN/A    memData = NULL;
1432669SN/A    effAddr = 0;
1444032Sktlim@umich.edu    effAddrValid = false;
1452669SN/A    physEffAddr = 0;
1461060SN/A
1474032Sktlim@umich.edu    isUncacheable = false;
1484032Sktlim@umich.edu    reqMade = false;
1491060SN/A    readyRegs = 0;
1501060SN/A
1512702SN/A    instResult.integer = 0;
1523326Sktlim@umich.edu    recordResult = true;
1532702SN/A
1542731SN/A    status.reset();
1552731SN/A
1561464SN/A    eaCalcDone = false;
1572292SN/A    memOpDone = false;
1582731SN/A
1592292SN/A    lqIdx = -1;
1602292SN/A    sqIdx = -1;
1612292SN/A
1621060SN/A    // Eventually make this a parameter.
1631060SN/A    threadNumber = 0;
1641464SN/A
1651060SN/A    // Also make this a parameter, or perhaps get it from xc or cpu.
1661060SN/A    asid = 0;
1671060SN/A
1682698SN/A    // Initialize the fault to be NoFault.
1692292SN/A    fault = NoFault;
1701060SN/A
1711060SN/A    ++instcount;
1721060SN/A
1732292SN/A    if (instcount > 1500) {
1745375Svilas.sridharan@gmail.com#ifdef DEBUG
1752292SN/A        cpu->dumpInsts();
1762292SN/A        dumpSNList();
1772292SN/A#endif
1782292SN/A        assert(instcount <= 1500);
1792292SN/A    }
1802292SN/A
1812292SN/A    DPRINTF(DynInst, "DynInst: [sn:%lli] Instruction created. Instcount=%i\n",
1822292SN/A            seqNum, instcount);
1832292SN/A
1842292SN/A#ifdef DEBUG
1852292SN/A    cpu->snList.insert(seqNum);
1862292SN/A#endif
1871060SN/A}
1881060SN/A
1891061SN/Atemplate <class Impl>
1901060SN/ABaseDynInst<Impl>::~BaseDynInst()
1911060SN/A{
1922678SN/A    if (memData) {
1932678SN/A        delete [] memData;
1942292SN/A    }
1952292SN/A
1962292SN/A    if (traceData) {
1972292SN/A        delete traceData;
1982292SN/A    }
1992292SN/A
2002348SN/A    fault = NoFault;
2012348SN/A
2021060SN/A    --instcount;
2032292SN/A
2042292SN/A    DPRINTF(DynInst, "DynInst: [sn:%lli] Instruction destroyed. Instcount=%i\n",
2052292SN/A            seqNum, instcount);
2062292SN/A#ifdef DEBUG
2072292SN/A    cpu->snList.erase(seqNum);
2082292SN/A#endif
2091060SN/A}
2101464SN/A
2112292SN/A#ifdef DEBUG
2122292SN/Atemplate <class Impl>
2132292SN/Avoid
2142292SN/ABaseDynInst<Impl>::dumpSNList()
2152292SN/A{
2162292SN/A    std::set<InstSeqNum>::iterator sn_it = cpu->snList.begin();
2172292SN/A
2182292SN/A    int count = 0;
2192292SN/A    while (sn_it != cpu->snList.end()) {
2202292SN/A        cprintf("%i: [sn:%lli] not destroyed\n", count, (*sn_it));
2212292SN/A        count++;
2222292SN/A        sn_it++;
2232292SN/A    }
2242292SN/A}
2252292SN/A#endif
2262292SN/A
2271061SN/Atemplate <class Impl>
2281060SN/Avoid
2291060SN/ABaseDynInst<Impl>::prefetch(Addr addr, unsigned flags)
2301060SN/A{
2311060SN/A    // This is the "functional" implementation of prefetch.  Not much
2321060SN/A    // happens here since prefetches don't affect the architectural
2331060SN/A    // state.
2342669SN/A/*
2351060SN/A    // Generate a MemReq so we can translate the effective address.
2362292SN/A    MemReqPtr req = new MemReq(addr, thread->getXCProxy(), 1, flags);
2371060SN/A    req->asid = asid;
2381060SN/A
2391060SN/A    // Prefetches never cause faults.
2402090SN/A    fault = NoFault;
2411060SN/A
2421060SN/A    // note this is a local, not BaseDynInst::fault
2432292SN/A    Fault trans_fault = cpu->translateDataReadReq(req);
2441060SN/A
2453172Sstever@eecs.umich.edu    if (trans_fault == NoFault && !(req->isUncacheable())) {
2461060SN/A        // It's a valid address to cacheable space.  Record key MemReq
2471060SN/A        // parameters so we can generate another one just like it for
2481060SN/A        // the timing access without calling translate() again (which
2491060SN/A        // might mess up the TLB).
2501060SN/A        effAddr = req->vaddr;
2511060SN/A        physEffAddr = req->paddr;
2521060SN/A        memReqFlags = req->flags;
2531060SN/A    } else {
2541060SN/A        // Bogus address (invalid or uncacheable space).  Mark it by
2551060SN/A        // setting the eff_addr to InvalidAddr.
2561060SN/A        effAddr = physEffAddr = MemReq::inval_addr;
2571060SN/A    }
2581060SN/A
2591060SN/A    if (traceData) {
2601060SN/A        traceData->setAddr(addr);
2611060SN/A    }
2622669SN/A*/
2631060SN/A}
2641060SN/A
2651061SN/Atemplate <class Impl>
2661060SN/Avoid
2671060SN/ABaseDynInst<Impl>::writeHint(Addr addr, int size, unsigned flags)
2681060SN/A{
2692702SN/A    // Not currently supported.
2701060SN/A}
2711060SN/A
2721060SN/A/**
2731060SN/A * @todo Need to find a way to get the cache block size here.
2741060SN/A */
2751061SN/Atemplate <class Impl>
2762132SN/AFault
2771060SN/ABaseDynInst<Impl>::copySrcTranslate(Addr src)
2781060SN/A{
2792702SN/A    // Not currently supported.
2802669SN/A    return NoFault;
2811060SN/A}
2821060SN/A
2831060SN/A/**
2841060SN/A * @todo Need to find a way to get the cache block size here.
2851060SN/A */
2861061SN/Atemplate <class Impl>
2872132SN/AFault
2881060SN/ABaseDynInst<Impl>::copy(Addr dest)
2891060SN/A{
2902702SN/A    // Not currently supported.
2912669SN/A    return NoFault;
2921060SN/A}
2931060SN/A
2941061SN/Atemplate <class Impl>
2951060SN/Avoid
2961060SN/ABaseDynInst<Impl>::dump()
2971060SN/A{
2981060SN/A    cprintf("T%d : %#08d `", threadNumber, PC);
2992980Sgblack@eecs.umich.edu    std::cout << staticInst->disassemble(PC);
3001060SN/A    cprintf("'\n");
3011060SN/A}
3021060SN/A
3031061SN/Atemplate <class Impl>
3041060SN/Avoid
3051060SN/ABaseDynInst<Impl>::dump(std::string &outstring)
3061060SN/A{
3071060SN/A    std::ostringstream s;
3081060SN/A    s << "T" << threadNumber << " : 0x" << PC << " "
3091060SN/A      << staticInst->disassemble(PC);
3101060SN/A
3111060SN/A    outstring = s.str();
3121060SN/A}
3131060SN/A
3141464SN/Atemplate <class Impl>
3152292SN/Avoid
3162292SN/ABaseDynInst<Impl>::markSrcRegReady()
3172292SN/A{
3182292SN/A    if (++readyRegs == numSrcRegs()) {
3194032Sktlim@umich.edu        setCanIssue();
3202292SN/A    }
3212292SN/A}
3222292SN/A
3232292SN/Atemplate <class Impl>
3242292SN/Avoid
3252292SN/ABaseDynInst<Impl>::markSrcRegReady(RegIndex src_idx)
3262292SN/A{
3272292SN/A    _readySrcRegIdx[src_idx] = true;
3282292SN/A
3292731SN/A    markSrcRegReady();
3302292SN/A}
3312292SN/A
3322292SN/Atemplate <class Impl>
3331464SN/Abool
3341464SN/ABaseDynInst<Impl>::eaSrcsReady()
3351464SN/A{
3361464SN/A    // For now I am assuming that src registers 1..n-1 are the ones that the
3371464SN/A    // EA calc depends on.  (i.e. src reg 0 is the source of the data to be
3381464SN/A    // stored)
3391464SN/A
3402292SN/A    for (int i = 1; i < numSrcRegs(); ++i) {
3411464SN/A        if (!_readySrcRegIdx[i])
3421464SN/A            return false;
3431464SN/A    }
3441464SN/A
3451464SN/A    return true;
3461464SN/A}
347