base_dyn_inst_impl.hh revision 7599
12SN/A/*
21762SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim
292665Ssaidi@eecs.umich.edu */
302SN/A
312SN/A#include <iostream>
321717SN/A#include <set>
331717SN/A#include <string>
342SN/A#include <sstream>
352SN/A
362SN/A#include "base/cprintf.hh"
374182Sgblack@eecs.umich.edu#include "base/trace.hh"
385664Sgblack@eecs.umich.edu#include "config/the_isa.hh"
39707SN/A#include "cpu/base_dyn_inst.hh"
401858SN/A#include "cpu/exetrace.hh"
4156SN/A#include "mem/request.hh"
424776Sgblack@eecs.umich.edu#include "sim/faults.hh"
432856Srdreslin@umich.edu
442SN/A#define NOHASH
453520Sgblack@eecs.umich.edu#ifndef NOHASH
463520Sgblack@eecs.umich.edu
473520Sgblack@eecs.umich.edu#include "base/hashmap.hh"
483520Sgblack@eecs.umich.edu
495529Snate@binkert.orgunsigned int MyHashFunc(const BaseDynInst *addr)
502190SN/A{
512315SN/A    unsigned a = (unsigned)addr;
522680Sktlim@umich.edu    unsigned hash = (((a >> 14) ^ ((a >> 2) & 0xffff))) & 0x7FFFFFFF;
532SN/A
542856Srdreslin@umich.edu    return hash;
552SN/A}
564182Sgblack@eecs.umich.edu
574182Sgblack@eecs.umich.edutypedef m5::hash_map<const BaseDynInst *, const BaseDynInst *, MyHashFunc>
584182Sgblack@eecs.umich.edumy_hash_t;
594182Sgblack@eecs.umich.edu
604182Sgblack@eecs.umich.edumy_hash_t thishash;
612356SN/A#endif
622356SN/A
632356SN/Atemplate <class Impl>
642356SN/ABaseDynInst<Impl>::BaseDynInst(StaticInstPtr _staticInst,
652356SN/A                               Addr inst_PC, Addr inst_NPC,
662356SN/A                               Addr inst_MicroPC,
672356SN/A                               Addr pred_PC, Addr pred_NPC,
682356SN/A                               Addr pred_MicroPC,
695606Snate@binkert.org                               InstSeqNum seq_num, ImplCPU *cpu)
702356SN/A  : staticInst(_staticInst), traceData(NULL), cpu(cpu)
712356SN/A{
722356SN/A    seqNum = seq_num;
735336Shines@cs.fsu.edu
742356SN/A    bool nextIsMicro =
752356SN/A        staticInst->isMicroop() && !staticInst->isLastMicroop();
762856Srdreslin@umich.edu
772SN/A    PC = inst_PC;
781634SN/A    microPC = inst_MicroPC;
791634SN/A    if (nextIsMicro) {
801695SN/A        nextPC = inst_PC;
813814Ssaidi@eecs.umich.edu        nextNPC = inst_NPC;
823814Ssaidi@eecs.umich.edu        nextMicroPC = microPC + 1;
835712Shsul@eecs.umich.edu    } else {
845712Shsul@eecs.umich.edu        nextPC = inst_NPC;
855712Shsul@eecs.umich.edu        nextNPC = nextPC + sizeof(TheISA::MachInst);
865712Shsul@eecs.umich.edu        nextMicroPC = 0;
875712Shsul@eecs.umich.edu    }
881634SN/A    predPC = pred_PC;
891634SN/A    predNPC = pred_NPC;
905712Shsul@eecs.umich.edu    predMicroPC = pred_MicroPC;
915712Shsul@eecs.umich.edu    predTaken = false;
925712Shsul@eecs.umich.edu
932359SN/A    initVars();
941695SN/A}
955100Ssaidi@eecs.umich.edu
961695SN/Atemplate <class Impl>
975099Ssaidi@eecs.umich.eduBaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst inst,
983814Ssaidi@eecs.umich.edu                               Addr inst_PC, Addr inst_NPC,
993814Ssaidi@eecs.umich.edu                               Addr inst_MicroPC,
1001634SN/A                               Addr pred_PC, Addr pred_NPC,
1013495Sktlim@umich.edu                               Addr pred_MicroPC,
1023495Sktlim@umich.edu                               InstSeqNum seq_num, ImplCPU *cpu)
1033495Sktlim@umich.edu  : staticInst(inst, inst_PC), traceData(NULL), cpu(cpu)
1043495Sktlim@umich.edu{
1053495Sktlim@umich.edu    seqNum = seq_num;
1063495Sktlim@umich.edu
1073495Sktlim@umich.edu    bool nextIsMicro =
1083495Sktlim@umich.edu        staticInst->isMicroop() && !staticInst->isLastMicroop();
1093495Sktlim@umich.edu
1103495Sktlim@umich.edu    PC = inst_PC;
1113495Sktlim@umich.edu    microPC = inst_MicroPC;
1123495Sktlim@umich.edu    if (nextIsMicro) {
1133495Sktlim@umich.edu        nextPC = inst_PC;
1143495Sktlim@umich.edu        nextNPC = inst_NPC;
1155664Sgblack@eecs.umich.edu        nextMicroPC = microPC + 1;
1165664Sgblack@eecs.umich.edu    } else {
1171858SN/A        nextPC = inst_NPC;
1182SN/A        nextNPC = nextPC + sizeof(TheISA::MachInst);
1195704Snate@binkert.org        nextMicroPC = 0;
1202SN/A    }
1212SN/A    predPC = pred_PC;
1225645Sgblack@eecs.umich.edu    predNPC = pred_NPC;
1235645Sgblack@eecs.umich.edu    predMicroPC = pred_MicroPC;
1245645Sgblack@eecs.umich.edu    predTaken = false;
1255647Sgblack@eecs.umich.edu
1265645Sgblack@eecs.umich.edu    initVars();
1275645Sgblack@eecs.umich.edu}
1285704Snate@binkert.org
1295704Snate@binkert.orgtemplate <class Impl>
1305704Snate@binkert.orgBaseDynInst<Impl>::BaseDynInst(StaticInstPtr &_staticInst)
1312SN/A    : staticInst(_staticInst), traceData(NULL)
1325704Snate@binkert.org{
1335704Snate@binkert.org    seqNum = 0;
1345704Snate@binkert.org    initVars();
1355704Snate@binkert.org}
1365704Snate@binkert.org
1371917SN/Atemplate <class Impl>
1381917SN/Avoid
1391917SN/ABaseDynInst<Impl>::initVars()
1401917SN/A{
1411917SN/A    memData = NULL;
1425536Srstrong@hp.com    effAddr = 0;
1431917SN/A    effAddrValid = false;
1441917SN/A    physEffAddr = 0;
1455536Srstrong@hp.com
1461917SN/A    isUncacheable = false;
1471917SN/A    reqMade = false;
1481917SN/A    readyRegs = 0;
1492SN/A
1502SN/A    instResult.integer = 0;
1512SN/A    recordResult = true;
1522680Sktlim@umich.edu
1534182Sgblack@eecs.umich.edu    status.reset();
1542SN/A
1554776Sgblack@eecs.umich.edu    eaCalcDone = false;
1564776Sgblack@eecs.umich.edu    memOpDone = false;
1572SN/A    predicate = true;
158393SN/A
1594776Sgblack@eecs.umich.edu    lqIdx = -1;
1604776Sgblack@eecs.umich.edu    sqIdx = -1;
1614776Sgblack@eecs.umich.edu
162393SN/A    // Eventually make this a parameter.
163393SN/A    threadNumber = 0;
164393SN/A
165393SN/A    // Also make this a parameter, or perhaps get it from xc or cpu.
166393SN/A    asid = 0;
167393SN/A
168393SN/A    // Initialize the fault to be NoFault.
169393SN/A    fault = NoFault;
170393SN/A
171393SN/A#ifndef NDEBUG
172393SN/A    ++cpu->instcount;
173393SN/A
174393SN/A    if (cpu->instcount > 1500) {
1752SN/A#ifdef DEBUG
1764000Ssaidi@eecs.umich.edu        cpu->dumpInsts();
1774000Ssaidi@eecs.umich.edu        dumpSNList();
1784000Ssaidi@eecs.umich.edu#endif
1794000Ssaidi@eecs.umich.edu        assert(cpu->instcount <= 1500);
1804000Ssaidi@eecs.umich.edu    }
1814000Ssaidi@eecs.umich.edu
1822SN/A    DPRINTF(DynInst,
1835529Snate@binkert.org        "DynInst: [sn:%lli] Instruction created. Instcount for %s = %i\n",
1845529Snate@binkert.org        seqNum, cpu->name(), cpu->instcount);
1855529Snate@binkert.org#endif
1861400SN/A
1871191SN/A#ifdef DEBUG
1882SN/A    cpu->snList.insert(seqNum);
1891129SN/A#endif
1901917SN/A}
1912SN/A
1922SN/Atemplate <class Impl>
1932103SN/ABaseDynInst<Impl>::~BaseDynInst()
1942103SN/A{
1952680Sktlim@umich.edu    if (memData) {
196180SN/A        delete [] memData;
1971492SN/A    }
1981492SN/A
1992798Sktlim@umich.edu    if (traceData) {
200180SN/A        delete traceData;
201180SN/A    }
202180SN/A
2034192Sktlim@umich.edu    fault = NoFault;
204180SN/A
205124SN/A#ifndef NDEBUG
206124SN/A    --cpu->instcount;
207124SN/A
208124SN/A    DPRINTF(DynInst,
2092SN/A        "DynInst: [sn:%lli] Instruction destroyed. Instcount for %s = %i\n",
2102SN/A        seqNum, cpu->name(), cpu->instcount);
2115529Snate@binkert.org#endif
2125529Snate@binkert.org#ifdef DEBUG
213124SN/A    cpu->snList.erase(seqNum);
214124SN/A#endif
215124SN/A}
216124SN/A
217124SN/A#ifdef DEBUG
218503SN/Atemplate <class Impl>
2192SN/Avoid
220124SN/ABaseDynInst<Impl>::dumpSNList()
221124SN/A{
222124SN/A    std::set<InstSeqNum>::iterator sn_it = cpu->snList.begin();
223124SN/A
224124SN/A    int count = 0;
225124SN/A    while (sn_it != cpu->snList.end()) {
226124SN/A        cprintf("%i: [sn:%lli] not destroyed\n", count, (*sn_it));
2272SN/A        count++;
228921SN/A        sn_it++;
2293661Srdreslin@umich.edu    }
2303661Srdreslin@umich.edu}
2312378SN/A#endif
232921SN/A
233921SN/Atemplate <class Impl>
234921SN/Avoid
235921SN/ABaseDynInst<Impl>::prefetch(Addr addr, unsigned flags)
236921SN/A{
237921SN/A    // This is the "functional" implementation of prefetch.  Not much
238921SN/A    // happens here since prefetches don't affect the architectural
239921SN/A    // state.
240921SN/A/*
241921SN/A    // Generate a MemReq so we can translate the effective address.
242921SN/A    MemReqPtr req = new MemReq(addr, thread->getXCProxy(), 1, flags);
243921SN/A    req->asid = asid;
244921SN/A
2452SN/A    // Prefetches never cause faults.
2462SN/A    fault = NoFault;
247124SN/A
248124SN/A    // note this is a local, not BaseDynInst::fault
249124SN/A    Fault trans_fault = cpu->translateDataReadReq(req);
250124SN/A
2512SN/A    if (trans_fault == NoFault && !(req->isUncacheable())) {
2522SN/A        // It's a valid address to cacheable space.  Record key MemReq
253707SN/A        // parameters so we can generate another one just like it for
254707SN/A        // the timing access without calling translate() again (which
2551191SN/A        // might mess up the TLB).
2561191SN/A        effAddr = req->vaddr;
2571191SN/A        physEffAddr = req->paddr;
2581191SN/A        memReqFlags = req->flags;
2591191SN/A    } else {
2601191SN/A        // Bogus address (invalid or uncacheable space).  Mark it by
2611191SN/A        // setting the eff_addr to InvalidAddr.
2621191SN/A        effAddr = physEffAddr = MemReq::inval_addr;
2631191SN/A    }
2641191SN/A
2651191SN/A    if (traceData) {
2661191SN/A        traceData->setAddr(addr);
2671191SN/A    }
2681191SN/A*/
2691191SN/A}
2701191SN/A
2711191SN/Atemplate <class Impl>
2722SN/Avoid
2732SN/ABaseDynInst<Impl>::writeHint(Addr addr, int size, unsigned flags)
2742SN/A{
2752SN/A    // Not currently supported.
2762SN/A}
277707SN/A
278707SN/A/**
279707SN/A * @todo Need to find a way to get the cache block size here.
280707SN/A */
281707SN/Atemplate <class Impl>
282707SN/AFault
283707SN/ABaseDynInst<Impl>::copySrcTranslate(Addr src)
284707SN/A{
285707SN/A    // Not currently supported.
286707SN/A    return NoFault;
287707SN/A}
288707SN/A
289707SN/A/**
290729SN/A * @todo Need to find a way to get the cache block size here.
2912SN/A */
2922SN/Atemplate <class Impl>
2931717SN/AFault
294BaseDynInst<Impl>::copy(Addr dest)
295{
296    // Not currently supported.
297    return NoFault;
298}
299
300template <class Impl>
301void
302BaseDynInst<Impl>::dump()
303{
304    cprintf("T%d : %#08d `", threadNumber, PC);
305    std::cout << staticInst->disassemble(PC);
306    cprintf("'\n");
307}
308
309template <class Impl>
310void
311BaseDynInst<Impl>::dump(std::string &outstring)
312{
313    std::ostringstream s;
314    s << "T" << threadNumber << " : 0x" << PC << " "
315      << staticInst->disassemble(PC);
316
317    outstring = s.str();
318}
319
320template <class Impl>
321void
322BaseDynInst<Impl>::markSrcRegReady()
323{
324    DPRINTF(IQ, "[sn:%lli] has %d ready out of %d sources. RTI %d)\n",
325            seqNum, readyRegs+1, numSrcRegs(), readyToIssue());
326    if (++readyRegs == numSrcRegs()) {
327        setCanIssue();
328    }
329}
330
331template <class Impl>
332void
333BaseDynInst<Impl>::markSrcRegReady(RegIndex src_idx)
334{
335    _readySrcRegIdx[src_idx] = true;
336
337    markSrcRegReady();
338}
339
340template <class Impl>
341bool
342BaseDynInst<Impl>::eaSrcsReady()
343{
344    // For now I am assuming that src registers 1..n-1 are the ones that the
345    // EA calc depends on.  (i.e. src reg 0 is the source of the data to be
346    // stored)
347
348    for (int i = 1; i < numSrcRegs(); ++i) {
349        if (!_readySrcRegIdx[i])
350            return false;
351    }
352
353    return true;
354}
355