| /* | |
| * Copyright (c) 2011 ARM Limited | |
| * All rights reserved. | |
| * | |
| * The license below extends only to copyright in the software and shall | |
| * not be construed as granting a license to any other intellectual | |
| * property including but not limited to intellectual property relating | |
| * to a hardware implementation of the functionality of the software | |
| * licensed hereunder. You may use the software subject to the license | |
| * terms below provided that you ensure that this notice is replicated | |
| * unmodified and in its entirety in all distributions of the software, | |
| * modified or unmodified, in source code or in binary form. | |
| * | |
| * Copyright (c) 2004-2006 The Regents of The University of Michigan | |
| * All rights reserved. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are | |
| * met: redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer; | |
| * redistributions in binary form must reproduce the above copyright | |
| * notice, this list of conditions and the following disclaimer in the | |
| * documentation and/or other materials provided with the distribution; | |
| * neither the name of the copyright holders nor the names of its | |
| * contributors may be used to endorse or promote products derived from | |
| * this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| * | |
| * Authors: Kevin Lim | |
| */ | |
| #ifndef __CPU_BASE_DYN_INST_IMPL_HH__ | |
| #define __CPU_BASE_DYN_INST_IMPL_HH__ | |
| #include <iostream> | |
| #include <set> | |
| #include <sstream> | |
| #include <string> | |
| #include "base/cprintf.hh" | |
| #include "base/trace.hh" | |
| #include "config/the_isa.hh" | |
| #include "cpu/base_dyn_inst.hh" | |
| #include "cpu/exetrace.hh" | |
| #include "debug/DynInst.hh" | |
| #include "debug/IQ.hh" | |
| #include "mem/request.hh" | |
| #include "sim/faults.hh" | |
| template <class Impl> | |
| BaseDynInst<Impl>::BaseDynInst(const StaticInstPtr &_staticInst, | |
| const StaticInstPtr &_macroop, | |
| TheISA::PCState _pc, TheISA::PCState _predPC, | |
| InstSeqNum seq_num, ImplCPU *cpu) | |
| : staticInst(_staticInst), cpu(cpu), traceData(NULL), macroop(_macroop) | |
| { | |
| seqNum = seq_num; | |
| pc = _pc; | |
| predPC = _predPC; | |
| initVars(); | |
| } | |
| template <class Impl> | |
| BaseDynInst<Impl>::BaseDynInst(const StaticInstPtr &_staticInst, | |
| const StaticInstPtr &_macroop) | |
| : staticInst(_staticInst), traceData(NULL), macroop(_macroop) | |
| { | |
| seqNum = 0; | |
| initVars(); | |
| } | |
| template <class Impl> | |
| void | |
| BaseDynInst<Impl>::initVars() | |
| { | |
| memData = NULL; | |
| effAddr = 0; | |
| physEffAddr = 0; | |
| readyRegs = 0; | |
| memReqFlags = 0; | |
| status.reset(); | |
| instFlags.reset(); | |
| instFlags[RecordResult] = true; | |
| instFlags[Predicate] = true; | |
| lqIdx = -1; | |
| sqIdx = -1; | |
| // Eventually make this a parameter. | |
| threadNumber = 0; | |
| // Also make this a parameter, or perhaps get it from xc or cpu. | |
| asid = 0; | |
| // Initialize the fault to be NoFault. | |
| fault = NoFault; | |
| #ifndef NDEBUG | |
| ++cpu->instcount; | |
| if (cpu->instcount > 1500) { | |
| #ifdef DEBUG | |
| cpu->dumpInsts(); | |
| dumpSNList(); | |
| #endif | |
| assert(cpu->instcount <= 1500); | |
| } | |
| DPRINTF(DynInst, | |
| "DynInst: [sn:%lli] Instruction created. Instcount for %s = %i\n", | |
| seqNum, cpu->name(), cpu->instcount); | |
| #endif | |
| #ifdef DEBUG | |
| cpu->snList.insert(seqNum); | |
| #endif | |
| reqToVerify = NULL; | |
| } | |
| template <class Impl> | |
| BaseDynInst<Impl>::~BaseDynInst() | |
| { | |
| if (memData) { | |
| delete [] memData; | |
| } | |
| if (traceData) { | |
| delete traceData; | |
| } | |
| fault = NoFault; | |
| #ifndef NDEBUG | |
| --cpu->instcount; | |
| DPRINTF(DynInst, | |
| "DynInst: [sn:%lli] Instruction destroyed. Instcount for %s = %i\n", | |
| seqNum, cpu->name(), cpu->instcount); | |
| #endif | |
| #ifdef DEBUG | |
| cpu->snList.erase(seqNum); | |
| #endif | |
| if (reqToVerify) | |
| delete reqToVerify; | |
| } | |
| #ifdef DEBUG | |
| template <class Impl> | |
| void | |
| BaseDynInst<Impl>::dumpSNList() | |
| { | |
| std::set<InstSeqNum>::iterator sn_it = cpu->snList.begin(); | |
| int count = 0; | |
| while (sn_it != cpu->snList.end()) { | |
| cprintf("%i: [sn:%lli] not destroyed\n", count, (*sn_it)); | |
| count++; | |
| sn_it++; | |
| } | |
| } | |
| #endif | |
| template <class Impl> | |
| void | |
| BaseDynInst<Impl>::dump() | |
| { | |
| cprintf("T%d : %#08d `", threadNumber, pc.instAddr()); | |
| std::cout << staticInst->disassemble(pc.instAddr()); | |
| cprintf("'\n"); | |
| } | |
| template <class Impl> | |
| void | |
| BaseDynInst<Impl>::dump(std::string &outstring) | |
| { | |
| std::ostringstream s; | |
| s << "T" << threadNumber << " : 0x" << pc.instAddr() << " " | |
| << staticInst->disassemble(pc.instAddr()); | |
| outstring = s.str(); | |
| } | |
| template <class Impl> | |
| void | |
| BaseDynInst<Impl>::markSrcRegReady() | |
| { | |
| DPRINTF(IQ, "[sn:%lli] has %d ready out of %d sources. RTI %d)\n", | |
| seqNum, readyRegs+1, numSrcRegs(), readyToIssue()); | |
| if (++readyRegs == numSrcRegs()) { | |
| setCanIssue(); | |
| } | |
| } | |
| template <class Impl> | |
| void | |
| BaseDynInst<Impl>::markSrcRegReady(RegIndex src_idx) | |
| { | |
| _readySrcRegIdx[src_idx] = true; | |
| markSrcRegReady(); | |
| } | |
| template <class Impl> | |
| bool | |
| BaseDynInst<Impl>::eaSrcsReady() | |
| { | |
| // For now I am assuming that src registers 1..n-1 are the ones that the | |
| // EA calc depends on. (i.e. src reg 0 is the source of the data to be | |
| // stored) | |
| for (int i = 1; i < numSrcRegs(); ++i) { | |
| if (!_readySrcRegIdx[i]) | |
| return false; | |
| } | |
| return true; | |
| } | |
| #endif//__CPU_BASE_DYN_INST_IMPL_HH__ |