base_dyn_inst.hh revision 2695
11060SN/A/* 21762SN/A * Copyright (c) 2004-2005 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. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 291060SN/A */ 301060SN/A 311464SN/A#ifndef __CPU_BASE_DYN_INST_HH__ 321464SN/A#define __CPU_BASE_DYN_INST_HH__ 331060SN/A 342292SN/A#include <list> 351464SN/A#include <string> 361060SN/A 372669Sktlim@umich.edu#include "arch/faults.hh" 381060SN/A#include "base/fast_alloc.hh" 391060SN/A#include "base/trace.hh" 401858SN/A#include "config/full_system.hh" 411464SN/A#include "cpu/exetrace.hh" 421464SN/A#include "cpu/inst_seq.hh" 432669Sktlim@umich.edu#include "cpu/op_class.hh" 441060SN/A#include "cpu/static_inst.hh" 452669Sktlim@umich.edu#include "mem/packet.hh" 462292SN/A#include "sim/system.hh" 472292SN/A/* 481717SN/A#include "encumbered/cpu/full/bpred_update.hh" 491717SN/A#include "encumbered/cpu/full/spec_memory.hh" 501717SN/A#include "encumbered/cpu/full/spec_state.hh" 511717SN/A#include "encumbered/mem/functional/main.hh" 522292SN/A*/ 531060SN/A 541060SN/A/** 551060SN/A * @file 561060SN/A * Defines a dynamic instruction context. 571060SN/A */ 581060SN/A 591061SN/A// Forward declaration. 601061SN/Aclass StaticInstPtr; 611060SN/A 621060SN/Atemplate <class Impl> 631061SN/Aclass BaseDynInst : public FastAlloc, public RefCounted 641060SN/A{ 651060SN/A public: 661060SN/A // Typedef for the CPU. 671060SN/A typedef typename Impl::FullCPU FullCPU; 682292SN/A typedef typename FullCPU::ImplState ImplState; 691060SN/A 702292SN/A // Binary machine instruction type. 712107SN/A typedef TheISA::MachInst MachInst; 722292SN/A // Extended machine instruction type 732292SN/A typedef TheISA::ExtMachInst ExtMachInst; 742292SN/A // Logical register index type. 752107SN/A typedef TheISA::RegIndex RegIndex; 762690Sktlim@umich.edu // Integer register type. 772107SN/A typedef TheISA::IntReg IntReg; 782690Sktlim@umich.edu // Floating point register type. 792690Sktlim@umich.edu typedef TheISA::FloatReg FloatReg; 801060SN/A 812292SN/A // The DynInstPtr type. 822292SN/A typedef typename Impl::DynInstPtr DynInstPtr; 832292SN/A 842292SN/A // The list of instructions iterator type. 852292SN/A typedef typename std::list<DynInstPtr>::iterator ListIt; 862292SN/A 871060SN/A enum { 882292SN/A MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs 892292SN/A MaxInstDestRegs = TheISA::MaxInstDestRegs, /// Max dest regs 901060SN/A }; 911060SN/A 922292SN/A /** The StaticInst used by this BaseDynInst. */ 932107SN/A StaticInstPtr staticInst; 941060SN/A 951060SN/A //////////////////////////////////////////// 961060SN/A // 971060SN/A // INSTRUCTION EXECUTION 981060SN/A // 991060SN/A //////////////////////////////////////////// 1002292SN/A /** InstRecord that tracks this instructions. */ 1011060SN/A Trace::InstRecord *traceData; 1021060SN/A 1032292SN/A /** 1042292SN/A * Does a read to a given address. 1052292SN/A * @param addr The address to read. 1062292SN/A * @param data The read's data is written into this parameter. 1072292SN/A * @param flags The request's flags. 1082292SN/A * @return Returns any fault due to the read. 1092292SN/A */ 1101060SN/A template <class T> 1112132SN/A Fault read(Addr addr, T &data, unsigned flags); 1121060SN/A 1132292SN/A /** 1142292SN/A * Does a write to a given address. 1152292SN/A * @param data The data to be written. 1162292SN/A * @param addr The address to write to. 1172292SN/A * @param flags The request's flags. 1182292SN/A * @param res The result of the write (for load locked/store conditionals). 1192292SN/A * @return Returns any fault due to the write. 1202292SN/A */ 1211060SN/A template <class T> 1222132SN/A Fault write(T data, Addr addr, unsigned flags, 1231060SN/A uint64_t *res); 1241060SN/A 1251060SN/A void prefetch(Addr addr, unsigned flags); 1261060SN/A void writeHint(Addr addr, int size, unsigned flags); 1272132SN/A Fault copySrcTranslate(Addr src); 1282132SN/A Fault copy(Addr dest); 1291060SN/A 1301684SN/A /** @todo: Consider making this private. */ 1311060SN/A public: 1321060SN/A /** The sequence number of the instruction. */ 1331060SN/A InstSeqNum seqNum; 1341060SN/A 1352292SN/A /** Is the instruction in the IQ */ 1362292SN/A bool iqEntry; 1372292SN/A 1382292SN/A /** Is the instruction in the ROB */ 1392292SN/A bool robEntry; 1402292SN/A 1412292SN/A /** Is the instruction in the LSQ */ 1422292SN/A bool lsqEntry; 1431060SN/A 1441464SN/A /** Is the instruction completed. */ 1451464SN/A bool completed; 1461464SN/A 1472308SN/A /** Is the instruction's result ready. */ 1482308SN/A bool resultReady; 1492308SN/A 1501060SN/A /** Can this instruction issue. */ 1511060SN/A bool canIssue; 1521060SN/A 1531060SN/A /** Has this instruction issued. */ 1541060SN/A bool issued; 1551060SN/A 1561060SN/A /** Has this instruction executed (or made it through execute) yet. */ 1571060SN/A bool executed; 1581060SN/A 1591060SN/A /** Can this instruction commit. */ 1601060SN/A bool canCommit; 1611060SN/A 1622292SN/A /** Is this instruction committed. */ 1632292SN/A bool committed; 1642292SN/A 1651060SN/A /** Is this instruction squashed. */ 1661060SN/A bool squashed; 1671060SN/A 1681060SN/A /** Is this instruction squashed in the instruction queue. */ 1691060SN/A bool squashedInIQ; 1701060SN/A 1712292SN/A /** Is this instruction squashed in the instruction queue. */ 1722292SN/A bool squashedInLSQ; 1732292SN/A 1742292SN/A /** Is this instruction squashed in the instruction queue. */ 1752292SN/A bool squashedInROB; 1762292SN/A 1771060SN/A /** Is this a recover instruction. */ 1781060SN/A bool recoverInst; 1791060SN/A 1801060SN/A /** Is this a thread blocking instruction. */ 1811060SN/A bool blockingInst; /* this inst has called thread_block() */ 1821060SN/A 1831060SN/A /** Is this a thread syncrhonization instruction. */ 1841060SN/A bool threadsyncWait; 1851060SN/A 1861060SN/A /** The thread this instruction is from. */ 1871060SN/A short threadNumber; 1881060SN/A 1891060SN/A /** data address space ID, for loads & stores. */ 1901060SN/A short asid; 1911060SN/A 1922292SN/A /** How many source registers are ready. */ 1932292SN/A unsigned readyRegs; 1942292SN/A 1951060SN/A /** Pointer to the FullCPU object. */ 1961060SN/A FullCPU *cpu; 1971060SN/A 1982680Sktlim@umich.edu /** Pointer to the thread state. */ 1992292SN/A ImplState *thread; 2001060SN/A 2011060SN/A /** The kind of fault this instruction has generated. */ 2022132SN/A Fault fault; 2031060SN/A 2042292SN/A /** The memory request. */ 2052669Sktlim@umich.edu// MemReqPtr req; 2062669Sktlim@umich.edu Request *req; 2072669Sktlim@umich.edu// Packet pkt; 2082669Sktlim@umich.edu 2092669Sktlim@umich.edu uint8_t *memData; 2102292SN/A 2111060SN/A /** The effective virtual address (lds & stores only). */ 2121060SN/A Addr effAddr; 2131060SN/A 2141060SN/A /** The effective physical address. */ 2151060SN/A Addr physEffAddr; 2161060SN/A 2171060SN/A /** Effective virtual address for a copy source. */ 2181060SN/A Addr copySrcEffAddr; 2191060SN/A 2201060SN/A /** Effective physical address for a copy source. */ 2211060SN/A Addr copySrcPhysEffAddr; 2221060SN/A 2231060SN/A /** The memory request flags (from translation). */ 2241060SN/A unsigned memReqFlags; 2251060SN/A 2261060SN/A /** The size of the data to be stored. */ 2271060SN/A int storeSize; 2281060SN/A 2291060SN/A /** The data to be stored. */ 2301060SN/A IntReg storeData; 2311060SN/A 2321464SN/A union Result { 2331464SN/A uint64_t integer; 2341464SN/A float fp; 2351464SN/A double dbl; 2361464SN/A }; 2371060SN/A 2381464SN/A /** The result of the instruction; assumes for now that there's only one 2391464SN/A * destination register. 2401464SN/A */ 2411464SN/A Result instResult; 2421060SN/A 2431060SN/A /** PC of this instruction. */ 2441060SN/A Addr PC; 2451060SN/A 2461060SN/A /** Next non-speculative PC. It is not filled in at fetch, but rather 2471060SN/A * once the target of the branch is truly known (either decode or 2481060SN/A * execute). 2491060SN/A */ 2501060SN/A Addr nextPC; 2511060SN/A 2521060SN/A /** Predicted next PC. */ 2531060SN/A Addr predPC; 2541060SN/A 2551060SN/A /** Count of total number of dynamic instructions. */ 2561060SN/A static int instcount; 2571060SN/A 2582292SN/A#ifdef DEBUG 2592292SN/A void dumpSNList(); 2602292SN/A#endif 2612292SN/A 2622292SN/A /** Whether or not the source register is ready. 2632292SN/A * @todo: Not sure this should be here vs the derived class. 2641060SN/A */ 2651060SN/A bool _readySrcRegIdx[MaxInstSrcRegs]; 2661060SN/A 2671060SN/A public: 2682292SN/A /** BaseDynInst constructor given a binary instruction. 2692292SN/A * @param inst The binary instruction. 2702292SN/A * @param PC The PC of the instruction. 2712292SN/A * @param pred_PC The predicted next PC. 2722292SN/A * @param seq_num The sequence number of the instruction. 2732292SN/A * @param cpu Pointer to the instruction's CPU. 2742292SN/A */ 2752292SN/A BaseDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num, 2761060SN/A FullCPU *cpu); 2771060SN/A 2782292SN/A /** BaseDynInst constructor given a StaticInst pointer. 2792292SN/A * @param _staticInst The StaticInst for this BaseDynInst. 2802292SN/A */ 2812107SN/A BaseDynInst(StaticInstPtr &_staticInst); 2821060SN/A 2831060SN/A /** BaseDynInst destructor. */ 2841060SN/A ~BaseDynInst(); 2851060SN/A 2861464SN/A private: 2871684SN/A /** Function to initialize variables in the constructors. */ 2881464SN/A void initVars(); 2891060SN/A 2901464SN/A public: 2912292SN/A /** 2922292SN/A * @todo: Make this function work; currently it is a dummy function. 2932292SN/A * @param fault Last fault. 2942292SN/A * @param cmd Last command. 2952292SN/A * @param addr Virtual address of access. 2962292SN/A * @param p Memory accessed. 2972292SN/A * @param nbytes Access size. 2982292SN/A */ 2992669Sktlim@umich.edu// void 3002669Sktlim@umich.edu// trace_mem(Fault fault, 3012669Sktlim@umich.edu// MemCmd cmd, 3022669Sktlim@umich.edu// Addr addr, 3032669Sktlim@umich.edu// void *p, 3042669Sktlim@umich.edu// int nbytes); 3051060SN/A 3061060SN/A /** Dumps out contents of this BaseDynInst. */ 3071060SN/A void dump(); 3081060SN/A 3091060SN/A /** Dumps out contents of this BaseDynInst into given string. */ 3101060SN/A void dump(std::string &outstring); 3111060SN/A 3121060SN/A /** Returns the fault type. */ 3132132SN/A Fault getFault() { return fault; } 3141060SN/A 3151060SN/A /** Checks whether or not this instruction has had its branch target 3161060SN/A * calculated yet. For now it is not utilized and is hacked to be 3171060SN/A * always false. 3182292SN/A * @todo: Actually use this instruction. 3191060SN/A */ 3201060SN/A bool doneTargCalc() { return false; } 3211060SN/A 3221684SN/A /** Returns the next PC. This could be the speculative next PC if it is 3231684SN/A * called prior to the actual branch target being calculated. 3241684SN/A */ 3251060SN/A Addr readNextPC() { return nextPC; } 3261060SN/A 3271060SN/A /** Set the predicted target of this current instruction. */ 3281060SN/A void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; } 3291060SN/A 3301060SN/A /** Returns the predicted target of the branch. */ 3311060SN/A Addr readPredTarg() { return predPC; } 3321060SN/A 3331060SN/A /** Returns whether the instruction was predicted taken or not. */ 3342292SN/A bool predTaken() { return predPC != (PC + sizeof(MachInst)); } 3351060SN/A 3361060SN/A /** Returns whether the instruction mispredicted. */ 3372292SN/A bool mispredicted() { return predPC != nextPC; } 3381060SN/A 3391060SN/A // 3401060SN/A // Instruction types. Forward checks to StaticInst object. 3411060SN/A // 3421060SN/A bool isNop() const { return staticInst->isNop(); } 3431060SN/A bool isMemRef() const { return staticInst->isMemRef(); } 3441060SN/A bool isLoad() const { return staticInst->isLoad(); } 3451060SN/A bool isStore() const { return staticInst->isStore(); } 3462336SN/A bool isStoreConditional() const 3472336SN/A { return staticInst->isStoreConditional(); } 3481060SN/A bool isInstPrefetch() const { return staticInst->isInstPrefetch(); } 3491060SN/A bool isDataPrefetch() const { return staticInst->isDataPrefetch(); } 3501060SN/A bool isCopy() const { return staticInst->isCopy(); } 3511060SN/A bool isInteger() const { return staticInst->isInteger(); } 3521060SN/A bool isFloating() const { return staticInst->isFloating(); } 3531060SN/A bool isControl() const { return staticInst->isControl(); } 3541060SN/A bool isCall() const { return staticInst->isCall(); } 3551060SN/A bool isReturn() const { return staticInst->isReturn(); } 3561060SN/A bool isDirectCtrl() const { return staticInst->isDirectCtrl(); } 3571060SN/A bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); } 3581060SN/A bool isCondCtrl() const { return staticInst->isCondCtrl(); } 3591060SN/A bool isUncondCtrl() const { return staticInst->isUncondCtrl(); } 3601060SN/A bool isThreadSync() const { return staticInst->isThreadSync(); } 3611060SN/A bool isSerializing() const { return staticInst->isSerializing(); } 3622292SN/A bool isSerializeBefore() const 3632292SN/A { return staticInst->isSerializeBefore() || serializeBefore; } 3642292SN/A bool isSerializeAfter() const 3652292SN/A { return staticInst->isSerializeAfter() || serializeAfter; } 3661060SN/A bool isMemBarrier() const { return staticInst->isMemBarrier(); } 3671060SN/A bool isWriteBarrier() const { return staticInst->isWriteBarrier(); } 3681060SN/A bool isNonSpeculative() const { return staticInst->isNonSpeculative(); } 3692292SN/A bool isQuiesce() const { return staticInst->isQuiesce(); } 3702336SN/A bool isIprAccess() const { return staticInst->isIprAccess(); } 3712308SN/A bool isUnverifiable() const { return staticInst->isUnverifiable(); } 3722292SN/A 3732292SN/A /** Temporarily sets this instruction as a serialize before instruction. */ 3742292SN/A void setSerializeBefore() { serializeBefore = true; } 3752292SN/A 3762292SN/A /** Clears the serializeBefore part of this instruction. */ 3772292SN/A void clearSerializeBefore() { serializeBefore = false; } 3782292SN/A 3792292SN/A /** Checks if this serializeBefore is only temporarily set. */ 3802292SN/A bool isTempSerializeBefore() { return serializeBefore; } 3812292SN/A 3822292SN/A /** Tracks if instruction has been externally set as serializeBefore. */ 3832292SN/A bool serializeBefore; 3842292SN/A 3852292SN/A /** Temporarily sets this instruction as a serialize after instruction. */ 3862292SN/A void setSerializeAfter() { serializeAfter = true; } 3872292SN/A 3882292SN/A /** Clears the serializeAfter part of this instruction.*/ 3892292SN/A void clearSerializeAfter() { serializeAfter = false; } 3902292SN/A 3912292SN/A /** Checks if this serializeAfter is only temporarily set. */ 3922292SN/A bool isTempSerializeAfter() { return serializeAfter; } 3932292SN/A 3942292SN/A /** Tracks if instruction has been externally set as serializeAfter. */ 3952292SN/A bool serializeAfter; 3962292SN/A 3972292SN/A /** Checks if the serialization part of this instruction has been 3982292SN/A * handled. This does not apply to the temporary serializing 3992292SN/A * state; it only applies to this instruction's own permanent 4002292SN/A * serializing state. 4012292SN/A */ 4022292SN/A bool isSerializeHandled() { return serializeHandled; } 4032292SN/A 4042292SN/A /** Sets the serialization part of this instruction as handled. */ 4052292SN/A void setSerializeHandled() { serializeHandled = true; } 4062292SN/A 4072292SN/A /** Whether or not the serialization of this instruction has been handled. */ 4082292SN/A bool serializeHandled; 4091060SN/A 4101464SN/A /** Returns the opclass of this instruction. */ 4111464SN/A OpClass opClass() const { return staticInst->opClass(); } 4121464SN/A 4131464SN/A /** Returns the branch target address. */ 4141464SN/A Addr branchTarget() const { return staticInst->branchTarget(PC); } 4151464SN/A 4162292SN/A /** Returns the number of source registers. */ 4172292SN/A int8_t numSrcRegs() const { return staticInst->numSrcRegs(); } 4181684SN/A 4192292SN/A /** Returns the number of destination registers. */ 4201060SN/A int8_t numDestRegs() const { return staticInst->numDestRegs(); } 4211060SN/A 4221060SN/A // the following are used to track physical register usage 4231060SN/A // for machines with separate int & FP reg files 4241060SN/A int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } 4251060SN/A int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } 4261060SN/A 4271060SN/A /** Returns the logical register index of the i'th destination register. */ 4282292SN/A RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); } 4291060SN/A 4301060SN/A /** Returns the logical register index of the i'th source register. */ 4312292SN/A RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } 4321060SN/A 4331684SN/A /** Returns the result of an integer instruction. */ 4341464SN/A uint64_t readIntResult() { return instResult.integer; } 4351684SN/A 4361684SN/A /** Returns the result of a floating point instruction. */ 4371464SN/A float readFloatResult() { return instResult.fp; } 4381684SN/A 4391684SN/A /** Returns the result of a floating point (double) instruction. */ 4401464SN/A double readDoubleResult() { return instResult.dbl; } 4411060SN/A 4422308SN/A void setIntReg(const StaticInst *si, int idx, uint64_t val) 4431060SN/A { 4442308SN/A instResult.integer = val; 4451060SN/A } 4461060SN/A 4472690Sktlim@umich.edu void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) 4482690Sktlim@umich.edu { 4492690Sktlim@umich.edu if (width == 32) 4502690Sktlim@umich.edu instResult.fp = val; 4512690Sktlim@umich.edu else if (width == 64) 4522690Sktlim@umich.edu instResult.dbl = val; 4532690Sktlim@umich.edu else 4542690Sktlim@umich.edu panic("Unsupported width!"); 4552690Sktlim@umich.edu } 4562690Sktlim@umich.edu 4572690Sktlim@umich.edu void setFloatReg(const StaticInst *si, int idx, FloatReg val) 4581060SN/A { 4592308SN/A instResult.fp = val; 4602308SN/A } 4611060SN/A 4622690Sktlim@umich.edu void setFloatRegBits(const StaticInst *si, int idx, uint64_t val, int width) 4632308SN/A { 4642690Sktlim@umich.edu instResult.integer = val; 4652308SN/A } 4661060SN/A 4672690Sktlim@umich.edu void setFloatRegBits(const StaticInst *si, int idx, uint64_t val) 4682308SN/A { 4692308SN/A instResult.integer = val; 4701060SN/A } 4711060SN/A 4722190SN/A /** Records that one of the source registers is ready. */ 4732292SN/A void markSrcRegReady(); 4742190SN/A 4752331SN/A /** Marks a specific register as ready. */ 4762292SN/A void markSrcRegReady(RegIndex src_idx); 4772190SN/A 4781684SN/A /** Returns if a source register is ready. */ 4791464SN/A bool isReadySrcRegIdx(int idx) const 4801464SN/A { 4811464SN/A return this->_readySrcRegIdx[idx]; 4821464SN/A } 4831464SN/A 4841684SN/A /** Sets this instruction as completed. */ 4851464SN/A void setCompleted() { completed = true; } 4861464SN/A 4872292SN/A /** Returns whether or not this instruction is completed. */ 4881464SN/A bool isCompleted() const { return completed; } 4891464SN/A 4902308SN/A void setResultReady() { resultReady = true; } 4912308SN/A 4922308SN/A bool isResultReady() const { return resultReady; } 4932308SN/A 4941060SN/A /** Sets this instruction as ready to issue. */ 4951060SN/A void setCanIssue() { canIssue = true; } 4961060SN/A 4971060SN/A /** Returns whether or not this instruction is ready to issue. */ 4981060SN/A bool readyToIssue() const { return canIssue; } 4991060SN/A 5001060SN/A /** Sets this instruction as issued from the IQ. */ 5011060SN/A void setIssued() { issued = true; } 5021060SN/A 5031060SN/A /** Returns whether or not this instruction has issued. */ 5041464SN/A bool isIssued() const { return issued; } 5051060SN/A 5061060SN/A /** Sets this instruction as executed. */ 5071060SN/A void setExecuted() { executed = true; } 5081060SN/A 5091060SN/A /** Returns whether or not this instruction has executed. */ 5101464SN/A bool isExecuted() const { return executed; } 5111060SN/A 5121060SN/A /** Sets this instruction as ready to commit. */ 5131060SN/A void setCanCommit() { canCommit = true; } 5141060SN/A 5151061SN/A /** Clears this instruction as being ready to commit. */ 5161061SN/A void clearCanCommit() { canCommit = false; } 5171061SN/A 5181060SN/A /** Returns whether or not this instruction is ready to commit. */ 5191060SN/A bool readyToCommit() const { return canCommit; } 5201060SN/A 5212292SN/A /** Sets this instruction as committed. */ 5222292SN/A void setCommitted() { committed = true; } 5232292SN/A 5242292SN/A /** Returns whether or not this instruction is committed. */ 5252292SN/A bool isCommitted() const { return committed; } 5262292SN/A 5271060SN/A /** Sets this instruction as squashed. */ 5281060SN/A void setSquashed() { squashed = true; } 5291060SN/A 5301060SN/A /** Returns whether or not this instruction is squashed. */ 5311060SN/A bool isSquashed() const { return squashed; } 5321060SN/A 5332292SN/A //Instruction Queue Entry 5342292SN/A //----------------------- 5352292SN/A /** Sets this instruction as a entry the IQ. */ 5362292SN/A void setInIQ() { iqEntry = true; } 5372292SN/A 5382292SN/A /** Sets this instruction as a entry the IQ. */ 5392292SN/A void removeInIQ() { iqEntry = false; } 5402292SN/A 5411060SN/A /** Sets this instruction as squashed in the IQ. */ 5422292SN/A void setSquashedInIQ() { squashedInIQ = true; squashed = true;} 5431060SN/A 5441060SN/A /** Returns whether or not this instruction is squashed in the IQ. */ 5451464SN/A bool isSquashedInIQ() const { return squashedInIQ; } 5461060SN/A 5472292SN/A /** Returns whether or not this instruction has issued. */ 5482292SN/A bool isInIQ() const { return iqEntry; } 5492292SN/A 5502292SN/A 5512292SN/A //Load / Store Queue Functions 5522292SN/A //----------------------- 5532292SN/A /** Sets this instruction as a entry the LSQ. */ 5542292SN/A void setInLSQ() { lsqEntry = true; } 5552292SN/A 5562292SN/A /** Sets this instruction as a entry the LSQ. */ 5572292SN/A void removeInLSQ() { lsqEntry = false; } 5582292SN/A 5592292SN/A /** Sets this instruction as squashed in the LSQ. */ 5602292SN/A void setSquashedInLSQ() { squashedInLSQ = true;} 5612292SN/A 5622292SN/A /** Returns whether or not this instruction is squashed in the LSQ. */ 5632292SN/A bool isSquashedInLSQ() const { return squashedInLSQ; } 5642292SN/A 5652292SN/A /** Returns whether or not this instruction is in the LSQ. */ 5662292SN/A bool isInLSQ() const { return lsqEntry; } 5672292SN/A 5682292SN/A 5692292SN/A //Reorder Buffer Functions 5702292SN/A //----------------------- 5712292SN/A /** Sets this instruction as a entry the ROB. */ 5722292SN/A void setInROB() { robEntry = true; } 5732292SN/A 5742292SN/A /** Sets this instruction as a entry the ROB. */ 5752292SN/A void removeInROB() { robEntry = false; } 5762292SN/A 5772292SN/A /** Sets this instruction as squashed in the ROB. */ 5782292SN/A void setSquashedInROB() { squashedInROB = true; } 5792292SN/A 5802292SN/A /** Returns whether or not this instruction is squashed in the ROB. */ 5812292SN/A bool isSquashedInROB() const { return squashedInROB; } 5822292SN/A 5832292SN/A /** Returns whether or not this instruction is in the ROB. */ 5842292SN/A bool isInROB() const { return robEntry; } 5852292SN/A 5861060SN/A /** Read the PC of this instruction. */ 5871464SN/A const Addr readPC() const { return PC; } 5881060SN/A 5891060SN/A /** Set the next PC of this instruction (its actual target). */ 5902308SN/A void setNextPC(uint64_t val) 5912308SN/A { 5922308SN/A nextPC = val; 5932308SN/A// instResult.integer = val; 5942308SN/A } 5952190SN/A 5962292SN/A void setASID(short addr_space_id) { asid = addr_space_id; } 5972292SN/A 5982292SN/A void setThread(unsigned tid) { threadNumber = tid; } 5992292SN/A 6002292SN/A void setState(ImplState *state) { thread = state; } 6011060SN/A 6022680Sktlim@umich.edu /** Returns the thread context. 6031684SN/A */ 6042680Sktlim@umich.edu ThreadContext *tcBase() { return thread->getTC(); } 6051464SN/A 6061464SN/A private: 6071684SN/A /** Instruction effective address. 6081684SN/A * @todo: Consider if this is necessary or not. 6091684SN/A */ 6101464SN/A Addr instEffAddr; 6112292SN/A 6121684SN/A /** Whether or not the effective address calculation is completed. 6131684SN/A * @todo: Consider if this is necessary or not. 6141684SN/A */ 6151464SN/A bool eaCalcDone; 6161464SN/A 6171464SN/A public: 6181684SN/A /** Sets the effective address. */ 6191464SN/A void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; } 6201684SN/A 6211684SN/A /** Returns the effective address. */ 6221464SN/A const Addr &getEA() const { return instEffAddr; } 6231684SN/A 6241684SN/A /** Returns whether or not the eff. addr. calculation has been completed. */ 6251464SN/A bool doneEACalc() { return eaCalcDone; } 6261684SN/A 6271684SN/A /** Returns whether or not the eff. addr. source registers are ready. */ 6281464SN/A bool eaSrcsReady(); 6291681SN/A 6302292SN/A /** Whether or not the memory operation is done. */ 6312292SN/A bool memOpDone; 6322292SN/A 6331681SN/A public: 6341684SN/A /** Load queue index. */ 6351681SN/A int16_t lqIdx; 6361684SN/A 6371684SN/A /** Store queue index. */ 6381681SN/A int16_t sqIdx; 6392292SN/A 6402292SN/A bool reachedCommit; 6412292SN/A 6422292SN/A /** Iterator pointing to this BaseDynInst in the list of all insts. */ 6432292SN/A ListIt instListIt; 6442292SN/A 6452292SN/A /** Returns iterator to this instruction in the list of all insts. */ 6462292SN/A ListIt &getInstListIt() { return instListIt; } 6472292SN/A 6482292SN/A /** Sets iterator for this instruction in the list of all insts. */ 6492292SN/A void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 6501060SN/A}; 6511060SN/A 6521060SN/Atemplate<class Impl> 6531060SN/Atemplate<class T> 6542132SN/Ainline Fault 6551060SN/ABaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) 6561060SN/A{ 6572695Sktlim@umich.edu // Sometimes reads will get retried, so they may come through here 6582695Sktlim@umich.edu // twice. 6592695Sktlim@umich.edu if (!req) { 6602695Sktlim@umich.edu req = new Request(); 6612695Sktlim@umich.edu req->setVirt(asid, addr, sizeof(T), flags, this->PC); 6622695Sktlim@umich.edu req->setThreadContext(thread->readCpuId(), threadNumber); 6632695Sktlim@umich.edu } else { 6642695Sktlim@umich.edu assert(addr == req->getVaddr()); 6652292SN/A } 6662292SN/A 6672669Sktlim@umich.edu if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() > 6682292SN/A TheISA::VMPageSize) { 6692292SN/A return TheISA::genAlignmentFault(); 6702292SN/A } 6711060SN/A 6722690Sktlim@umich.edu fault = cpu->translateDataReadReq(req, thread); 6731060SN/A 6742678Sktlim@umich.edu if (fault == NoFault) { 6752678Sktlim@umich.edu effAddr = req->getVaddr(); 6762678Sktlim@umich.edu physEffAddr = req->getPaddr(); 6772678Sktlim@umich.edu memReqFlags = req->getFlags(); 6781060SN/A 6792690Sktlim@umich.edu#if 0 6802292SN/A if (cpu->system->memctrl->badaddr(physEffAddr)) { 6812292SN/A fault = TheISA::genMachineCheckFault(); 6822292SN/A data = (T)-1; 6832292SN/A this->setExecuted(); 6842292SN/A } else { 6852292SN/A fault = cpu->read(req, data, lqIdx); 6862292SN/A } 6872292SN/A#else 6881681SN/A fault = cpu->read(req, data, lqIdx); 6892632Sstever@eecs.umich.edu#endif 6901684SN/A } else { 6911060SN/A // Return a fixed value to keep simulation deterministic even 6921060SN/A // along misspeculated paths. 6931060SN/A data = (T)-1; 6942292SN/A 6952292SN/A // Commit will have to clean up whatever happened. Set this 6962292SN/A // instruction as executed. 6972292SN/A this->setExecuted(); 6981060SN/A } 6991060SN/A 7001060SN/A if (traceData) { 7011060SN/A traceData->setAddr(addr); 7021060SN/A traceData->setData(data); 7031060SN/A } 7041060SN/A 7051060SN/A return fault; 7061060SN/A} 7071060SN/A 7081060SN/Atemplate<class Impl> 7091060SN/Atemplate<class T> 7102132SN/Ainline Fault 7111060SN/ABaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) 7121060SN/A{ 7131060SN/A if (traceData) { 7141060SN/A traceData->setAddr(addr); 7151060SN/A traceData->setData(data); 7161060SN/A } 7171060SN/A 7182695Sktlim@umich.edu assert(req == NULL); 7192695Sktlim@umich.edu 7202669Sktlim@umich.edu req = new Request(); 7212669Sktlim@umich.edu req->setVirt(asid, addr, sizeof(T), flags, this->PC); 7222683Sktlim@umich.edu req->setThreadContext(thread->readCpuId(), threadNumber); 7231060SN/A 7242669Sktlim@umich.edu if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() > 7252292SN/A TheISA::VMPageSize) { 7262292SN/A return TheISA::genAlignmentFault(); 7272292SN/A } 7281060SN/A 7292690Sktlim@umich.edu fault = cpu->translateDataWriteReq(req, thread); 7301060SN/A 7312090SN/A if (fault == NoFault) { 7322678Sktlim@umich.edu effAddr = req->getVaddr(); 7332678Sktlim@umich.edu physEffAddr = req->getPaddr(); 7342678Sktlim@umich.edu memReqFlags = req->getFlags(); 7352690Sktlim@umich.edu#if 0 7362292SN/A if (cpu->system->memctrl->badaddr(physEffAddr)) { 7372292SN/A fault = TheISA::genMachineCheckFault(); 7382292SN/A } else { 7392292SN/A fault = cpu->write(req, data, sqIdx); 7402292SN/A } 7412292SN/A#else 7421681SN/A fault = cpu->write(req, data, sqIdx); 7432632Sstever@eecs.umich.edu#endif 7441060SN/A } 7451060SN/A 7461060SN/A if (res) { 7471060SN/A // always return some result to keep misspeculated paths 7481060SN/A // (which will ignore faults) deterministic 7492669Sktlim@umich.edu *res = (fault == NoFault) ? req->getScResult() : 0; 7501060SN/A } 7511060SN/A 7521060SN/A return fault; 7531060SN/A} 7541060SN/A 7551464SN/A#endif // __CPU_BASE_DYN_INST_HH__ 756