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