dyn_inst.hh revision 10935
17119Sgblack@eecs.umich.edu/* 27119Sgblack@eecs.umich.edu * Copyright (c) 2010 ARM Limited 37119Sgblack@eecs.umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc. 47119Sgblack@eecs.umich.edu * All rights reserved 57119Sgblack@eecs.umich.edu * 67119Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 77119Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 87119Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 97119Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 107119Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 117119Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 127119Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 137119Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 147119Sgblack@eecs.umich.edu * 157119Sgblack@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan 167119Sgblack@eecs.umich.edu * All rights reserved. 177119Sgblack@eecs.umich.edu * 187119Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 197119Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 207119Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 217119Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 227119Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 237119Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 247119Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 257119Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 267119Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 277119Sgblack@eecs.umich.edu * this software without specific prior written permission. 287119Sgblack@eecs.umich.edu * 297119Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 307119Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 317119Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 327119Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 337119Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 347119Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 357119Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 367119Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 377119Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 387119Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 397119Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 407119Sgblack@eecs.umich.edu * 417119Sgblack@eecs.umich.edu * Authors: Kevin Lim 427119Sgblack@eecs.umich.edu */ 437119Sgblack@eecs.umich.edu 447119Sgblack@eecs.umich.edu#ifndef __CPU_O3_DYN_INST_HH__ 457119Sgblack@eecs.umich.edu#define __CPU_O3_DYN_INST_HH__ 467119Sgblack@eecs.umich.edu 477119Sgblack@eecs.umich.edu#include <array> 487119Sgblack@eecs.umich.edu 497119Sgblack@eecs.umich.edu#include "arch/isa_traits.hh" 507119Sgblack@eecs.umich.edu#include "config/the_isa.hh" 517119Sgblack@eecs.umich.edu#include "cpu/o3/cpu.hh" 527119Sgblack@eecs.umich.edu#include "cpu/o3/isa_specific.hh" 537119Sgblack@eecs.umich.edu#include "cpu/base_dyn_inst.hh" 547119Sgblack@eecs.umich.edu#include "cpu/inst_seq.hh" 557119Sgblack@eecs.umich.edu#include "cpu/reg_class.hh" 567128Sgblack@eecs.umich.edu 577128Sgblack@eecs.umich.educlass Packet; 587128Sgblack@eecs.umich.edu 597128Sgblack@eecs.umich.edutemplate <class Impl> 607128Sgblack@eecs.umich.educlass BaseO3DynInst : public BaseDynInst<Impl> 617128Sgblack@eecs.umich.edu{ 627119Sgblack@eecs.umich.edu public: 637119Sgblack@eecs.umich.edu /** Typedef for the CPU. */ 647119Sgblack@eecs.umich.edu typedef typename Impl::O3CPU O3CPU; 657119Sgblack@eecs.umich.edu 667119Sgblack@eecs.umich.edu /** Binary machine instruction type. */ 677132Sgblack@eecs.umich.edu typedef TheISA::MachInst MachInst; 687132Sgblack@eecs.umich.edu /** Extended machine instruction type. */ 697132Sgblack@eecs.umich.edu typedef TheISA::ExtMachInst ExtMachInst; 707132Sgblack@eecs.umich.edu /** Logical register index type. */ 717119Sgblack@eecs.umich.edu typedef TheISA::RegIndex RegIndex; 727119Sgblack@eecs.umich.edu /** Integer register index type. */ 737119Sgblack@eecs.umich.edu typedef TheISA::IntReg IntReg; 747119Sgblack@eecs.umich.edu typedef TheISA::FloatReg FloatReg; 757119Sgblack@eecs.umich.edu typedef TheISA::FloatRegBits FloatRegBits; 767119Sgblack@eecs.umich.edu typedef TheISA::CCReg CCReg; 777244Sgblack@eecs.umich.edu 787244Sgblack@eecs.umich.edu /** Misc register index type. */ 797119Sgblack@eecs.umich.edu typedef TheISA::MiscReg MiscReg; 807119Sgblack@eecs.umich.edu 817119Sgblack@eecs.umich.edu enum { 827119Sgblack@eecs.umich.edu MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs 837119Sgblack@eecs.umich.edu MaxInstDestRegs = TheISA::MaxInstDestRegs //< Max dest regs 847119Sgblack@eecs.umich.edu }; 857119Sgblack@eecs.umich.edu 867119Sgblack@eecs.umich.edu public: 877119Sgblack@eecs.umich.edu /** BaseDynInst constructor given a binary instruction. */ 887119Sgblack@eecs.umich.edu BaseO3DynInst(const StaticInstPtr &staticInst, const StaticInstPtr ¯oop, 897119Sgblack@eecs.umich.edu TheISA::PCState pc, TheISA::PCState predPC, 907119Sgblack@eecs.umich.edu InstSeqNum seq_num, O3CPU *cpu); 917119Sgblack@eecs.umich.edu 927119Sgblack@eecs.umich.edu /** BaseDynInst constructor given a static inst pointer. */ 937119Sgblack@eecs.umich.edu BaseO3DynInst(const StaticInstPtr &_staticInst, 947192Sgblack@eecs.umich.edu const StaticInstPtr &_macroop); 957192Sgblack@eecs.umich.edu 967192Sgblack@eecs.umich.edu ~BaseO3DynInst(); 977192Sgblack@eecs.umich.edu 987192Sgblack@eecs.umich.edu /** Executes the instruction.*/ 997192Sgblack@eecs.umich.edu Fault execute(); 1007192Sgblack@eecs.umich.edu 1017192Sgblack@eecs.umich.edu /** Initiates the access. Only valid for memory operations. */ 1027244Sgblack@eecs.umich.edu Fault initiateAcc(); 1037244Sgblack@eecs.umich.edu 1047244Sgblack@eecs.umich.edu /** Completes the access. Only valid for memory operations. */ 1057244Sgblack@eecs.umich.edu Fault completeAcc(PacketPtr pkt); 1067244Sgblack@eecs.umich.edu 1077192Sgblack@eecs.umich.edu private: 1087119Sgblack@eecs.umich.edu /** Initializes variables. */ 1097119Sgblack@eecs.umich.edu void initVars(); 1107132Sgblack@eecs.umich.edu 1117119Sgblack@eecs.umich.edu protected: 1127192Sgblack@eecs.umich.edu /** Values to be written to the destination misc. registers. */ 1137119Sgblack@eecs.umich.edu std::array<MiscReg, TheISA::MaxMiscDestRegs> _destMiscRegVal; 1147119Sgblack@eecs.umich.edu 1157192Sgblack@eecs.umich.edu /** Indexes of the destination misc. registers. They are needed to defer 1167119Sgblack@eecs.umich.edu * the write accesses to the misc. registers until the commit stage, when 1177119Sgblack@eecs.umich.edu * the instruction is out of its speculative state. 1187119Sgblack@eecs.umich.edu */ 1197119Sgblack@eecs.umich.edu std::array<short, TheISA::MaxMiscDestRegs> _destMiscRegIdx; 1207119Sgblack@eecs.umich.edu 1217119Sgblack@eecs.umich.edu /** Number of destination misc. registers. */ 1227119Sgblack@eecs.umich.edu uint8_t _numDestMiscRegs; 1237119Sgblack@eecs.umich.edu 1247119Sgblack@eecs.umich.edu 1257119Sgblack@eecs.umich.edu public: 1267119Sgblack@eecs.umich.edu#if TRACING_ON 1277119Sgblack@eecs.umich.edu /** Tick records used for the pipeline activity viewer. */ 1287119Sgblack@eecs.umich.edu Tick fetchTick; // instruction fetch is completed. 1297119Sgblack@eecs.umich.edu int32_t decodeTick; // instruction enters decode phase 1307119Sgblack@eecs.umich.edu int32_t renameTick; // instruction enters rename phase 1317119Sgblack@eecs.umich.edu int32_t dispatchTick; 1327192Sgblack@eecs.umich.edu int32_t issueTick; 1337192Sgblack@eecs.umich.edu int32_t completeTick; 1347192Sgblack@eecs.umich.edu int32_t commitTick; 1357192Sgblack@eecs.umich.edu int32_t storeTick; 1367192Sgblack@eecs.umich.edu#endif 1377192Sgblack@eecs.umich.edu 1387192Sgblack@eecs.umich.edu /** Reads a misc. register, including any side-effects the read 1397192Sgblack@eecs.umich.edu * might have as defined by the architecture. 1407192Sgblack@eecs.umich.edu */ 1417192Sgblack@eecs.umich.edu MiscReg readMiscReg(int misc_reg) 1427119Sgblack@eecs.umich.edu { 1437119Sgblack@eecs.umich.edu return this->cpu->readMiscReg(misc_reg, this->threadNumber); 1447132Sgblack@eecs.umich.edu } 1457119Sgblack@eecs.umich.edu 1467192Sgblack@eecs.umich.edu /** Sets a misc. register, including any side-effects the write 1477119Sgblack@eecs.umich.edu * might have as defined by the architecture. 1487244Sgblack@eecs.umich.edu */ 1497128Sgblack@eecs.umich.edu void setMiscReg(int misc_reg, const MiscReg &val) 1507128Sgblack@eecs.umich.edu { 1517128Sgblack@eecs.umich.edu /** Writes to misc. registers are recorded and deferred until the 1527128Sgblack@eecs.umich.edu * commit stage, when updateMiscRegs() is called. First, check if 1537128Sgblack@eecs.umich.edu * the misc reg has been written before and update its value to be 1547128Sgblack@eecs.umich.edu * committed instead of making a new entry. If not, make a new 1557128Sgblack@eecs.umich.edu * entry and record the write. 1567128Sgblack@eecs.umich.edu */ 1577128Sgblack@eecs.umich.edu for (int idx = 0; idx < _numDestMiscRegs; idx++) { 1587128Sgblack@eecs.umich.edu if (_destMiscRegIdx[idx] == misc_reg) { 1597128Sgblack@eecs.umich.edu _destMiscRegVal[idx] = val; 1607128Sgblack@eecs.umich.edu return; 1617128Sgblack@eecs.umich.edu } 1627128Sgblack@eecs.umich.edu } 1637128Sgblack@eecs.umich.edu 1647128Sgblack@eecs.umich.edu assert(_numDestMiscRegs < TheISA::MaxMiscDestRegs); 1657128Sgblack@eecs.umich.edu _destMiscRegIdx[_numDestMiscRegs] = misc_reg; 1667128Sgblack@eecs.umich.edu _destMiscRegVal[_numDestMiscRegs] = val; 1677244Sgblack@eecs.umich.edu _numDestMiscRegs++; 1687244Sgblack@eecs.umich.edu } 1697244Sgblack@eecs.umich.edu 1707244Sgblack@eecs.umich.edu /** Reads a misc. register, including any side-effects the read 1717244Sgblack@eecs.umich.edu * might have as defined by the architecture. 1727128Sgblack@eecs.umich.edu */ 1737128Sgblack@eecs.umich.edu TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx) 1747132Sgblack@eecs.umich.edu { 1757128Sgblack@eecs.umich.edu return this->cpu->readMiscReg( 1767244Sgblack@eecs.umich.edu si->srcRegIdx(idx) - TheISA::Misc_Reg_Base, 1777128Sgblack@eecs.umich.edu this->threadNumber); 1787128Sgblack@eecs.umich.edu } 1797128Sgblack@eecs.umich.edu 1807128Sgblack@eecs.umich.edu /** Sets a misc. register, including any side-effects the write 1817128Sgblack@eecs.umich.edu * might have as defined by the architecture. 1827128Sgblack@eecs.umich.edu */ 1837128Sgblack@eecs.umich.edu void setMiscRegOperand(const StaticInst *si, int idx, 1847128Sgblack@eecs.umich.edu const MiscReg &val) 1857128Sgblack@eecs.umich.edu { 1867128Sgblack@eecs.umich.edu int misc_reg = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; 1877128Sgblack@eecs.umich.edu setMiscReg(misc_reg, val); 1887128Sgblack@eecs.umich.edu } 1897128Sgblack@eecs.umich.edu 1907128Sgblack@eecs.umich.edu /** Called at the commit stage to update the misc. registers. */ 1917128Sgblack@eecs.umich.edu void updateMiscRegs() 1927128Sgblack@eecs.umich.edu { 1937128Sgblack@eecs.umich.edu // @todo: Pretty convoluted way to avoid squashing from happening when 1947128Sgblack@eecs.umich.edu // using the TC during an instruction's execution (specifically for 1957128Sgblack@eecs.umich.edu // instructions that have side-effects that use the TC). Fix this. 1967128Sgblack@eecs.umich.edu // See cpu/o3/dyn_inst_impl.hh. 1977128Sgblack@eecs.umich.edu bool no_squash_from_TC = this->thread->noSquashFromTC; 1987128Sgblack@eecs.umich.edu this->thread->noSquashFromTC = true; 1997128Sgblack@eecs.umich.edu 2007132Sgblack@eecs.umich.edu for (int i = 0; i < _numDestMiscRegs; i++) 2017128Sgblack@eecs.umich.edu this->cpu->setMiscReg( 2027128Sgblack@eecs.umich.edu _destMiscRegIdx[i], _destMiscRegVal[i], this->threadNumber); 2037128Sgblack@eecs.umich.edu 2047119Sgblack@eecs.umich.edu this->thread->noSquashFromTC = no_squash_from_TC; 2057119Sgblack@eecs.umich.edu } 2067119Sgblack@eecs.umich.edu 2077119Sgblack@eecs.umich.edu void forwardOldRegs() 2087119Sgblack@eecs.umich.edu { 2097119Sgblack@eecs.umich.edu 2107119Sgblack@eecs.umich.edu for (int idx = 0; idx < this->numDestRegs(); idx++) { 2117119Sgblack@eecs.umich.edu PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx); 2127119Sgblack@eecs.umich.edu TheISA::RegIndex original_dest_reg = 2137119Sgblack@eecs.umich.edu this->staticInst->destRegIdx(idx); 2147119Sgblack@eecs.umich.edu switch (regIdxToClass(original_dest_reg)) { 2157119Sgblack@eecs.umich.edu case IntRegClass: 2167119Sgblack@eecs.umich.edu this->setIntRegOperand(this->staticInst.get(), idx, 2177119Sgblack@eecs.umich.edu this->cpu->readIntReg(prev_phys_reg)); 2187128Sgblack@eecs.umich.edu break; 2197128Sgblack@eecs.umich.edu case FloatRegClass: 2207128Sgblack@eecs.umich.edu this->setFloatRegOperandBits(this->staticInst.get(), idx, 2217128Sgblack@eecs.umich.edu this->cpu->readFloatRegBits(prev_phys_reg)); 2227128Sgblack@eecs.umich.edu break; 2237128Sgblack@eecs.umich.edu case CCRegClass: 2247128Sgblack@eecs.umich.edu this->setCCRegOperand(this->staticInst.get(), idx, 2257128Sgblack@eecs.umich.edu this->cpu->readCCReg(prev_phys_reg)); 2267128Sgblack@eecs.umich.edu break; 2277128Sgblack@eecs.umich.edu case MiscRegClass: 2287128Sgblack@eecs.umich.edu // no need to forward misc reg values 2297128Sgblack@eecs.umich.edu break; 2307128Sgblack@eecs.umich.edu } 2317128Sgblack@eecs.umich.edu } 2327192Sgblack@eecs.umich.edu } 2337192Sgblack@eecs.umich.edu /** Calls hardware return from error interrupt. */ 2347192Sgblack@eecs.umich.edu Fault hwrei(); 2357192Sgblack@eecs.umich.edu /** Traps to handle specified fault. */ 2367192Sgblack@eecs.umich.edu void trap(const Fault &fault); 2377192Sgblack@eecs.umich.edu bool simPalCheck(int palFunc); 2387119Sgblack@eecs.umich.edu 2397119Sgblack@eecs.umich.edu /** Emulates a syscall. */ 2407119Sgblack@eecs.umich.edu void syscall(int64_t callnum); 2417119Sgblack@eecs.umich.edu 2427119Sgblack@eecs.umich.edu public: 2437119Sgblack@eecs.umich.edu 2447119Sgblack@eecs.umich.edu // The register accessor methods provide the index of the 2457119Sgblack@eecs.umich.edu // instruction's operand (e.g., 0 or 1), not the architectural 2467119Sgblack@eecs.umich.edu // register index, to simplify the implementation of register 2477119Sgblack@eecs.umich.edu // renaming. We find the architectural register index by indexing 2487128Sgblack@eecs.umich.edu // into the instruction's own operand index table. Note that a 2497128Sgblack@eecs.umich.edu // raw pointer to the StaticInst is provided instead of a 2507192Sgblack@eecs.umich.edu // ref-counted StaticInstPtr to redice overhead. This is fine as 2517192Sgblack@eecs.umich.edu // long as these methods don't copy the pointer into any long-term 2527192Sgblack@eecs.umich.edu // storage (which is pretty hard to imagine they would have reason 2537192Sgblack@eecs.umich.edu // to do). 2547244Sgblack@eecs.umich.edu 2557244Sgblack@eecs.umich.edu IntReg readIntRegOperand(const StaticInst *si, int idx) 2567244Sgblack@eecs.umich.edu { 2577244Sgblack@eecs.umich.edu return this->cpu->readIntReg(this->_srcRegIdx[idx]); 2587244Sgblack@eecs.umich.edu } 2597119Sgblack@eecs.umich.edu 260 FloatReg readFloatRegOperand(const StaticInst *si, int idx) 261 { 262 return this->cpu->readFloatReg(this->_srcRegIdx[idx]); 263 } 264 265 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) 266 { 267 return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]); 268 } 269 270 CCReg readCCRegOperand(const StaticInst *si, int idx) 271 { 272 return this->cpu->readCCReg(this->_srcRegIdx[idx]); 273 } 274 275 /** @todo: Make results into arrays so they can handle multiple dest 276 * registers. 277 */ 278 void setIntRegOperand(const StaticInst *si, int idx, IntReg val) 279 { 280 this->cpu->setIntReg(this->_destRegIdx[idx], val); 281 BaseDynInst<Impl>::setIntRegOperand(si, idx, val); 282 } 283 284 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 285 { 286 this->cpu->setFloatReg(this->_destRegIdx[idx], val); 287 BaseDynInst<Impl>::setFloatRegOperand(si, idx, val); 288 } 289 290 void setFloatRegOperandBits(const StaticInst *si, int idx, 291 FloatRegBits val) 292 { 293 this->cpu->setFloatRegBits(this->_destRegIdx[idx], val); 294 BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val); 295 } 296 297 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) 298 { 299 this->cpu->setCCReg(this->_destRegIdx[idx], val); 300 BaseDynInst<Impl>::setCCRegOperand(si, idx, val); 301 } 302 303#if THE_ISA == MIPS_ISA 304 MiscReg readRegOtherThread(int misc_reg, ThreadID tid) 305 { 306 panic("MIPS MT not defined for O3 CPU.\n"); 307 return 0; 308 } 309 310 void setRegOtherThread(int misc_reg, MiscReg val, ThreadID tid) 311 { 312 panic("MIPS MT not defined for O3 CPU.\n"); 313 } 314#endif 315 316 public: 317 /** Calculates EA part of a memory instruction. Currently unused, 318 * though it may be useful in the future if we want to split 319 * memory operations into EA calculation and memory access parts. 320 */ 321 Fault calcEA() 322 { 323 return this->staticInst->eaCompInst()->execute(this, this->traceData); 324 } 325 326 /** Does the memory access part of a memory instruction. Currently unused, 327 * though it may be useful in the future if we want to split 328 * memory operations into EA calculation and memory access parts. 329 */ 330 Fault memAccess() 331 { 332 return this->staticInst->memAccInst()->execute(this, this->traceData); 333 } 334}; 335 336#endif // __CPU_O3_ALPHA_DYN_INST_HH__ 337 338