dyn_inst.hh revision 9252:f350fac86d0f
111012Sandreas.sandberg@arm.com/*
211012Sandreas.sandberg@arm.com * Copyright (c) 2010 ARM Limited
311012Sandreas.sandberg@arm.com * All rights reserved
411012Sandreas.sandberg@arm.com *
511012Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
611012Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
711012Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
811012Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
911012Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1011012Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1111012Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1211012Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1311012Sandreas.sandberg@arm.com *
1411012Sandreas.sandberg@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
1511012Sandreas.sandberg@arm.com * All rights reserved.
1611012Sandreas.sandberg@arm.com *
1711012Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1811012Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1911012Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
2011012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
2111012Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
2211012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2311012Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2411012Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2511012Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2611012Sandreas.sandberg@arm.com * this software without specific prior written permission.
2711012Sandreas.sandberg@arm.com *
2811012Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2911012Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3011012Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3111012Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3211012Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3311012Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3411012Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3511012Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3611012Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3711012Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3811012Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3911012Sandreas.sandberg@arm.com *
4011012Sandreas.sandberg@arm.com * Authors: Kevin Lim
4111012Sandreas.sandberg@arm.com */
4211012Sandreas.sandberg@arm.com
4311012Sandreas.sandberg@arm.com#ifndef __CPU_O3_DYN_INST_HH__
4411012Sandreas.sandberg@arm.com#define __CPU_O3_DYN_INST_HH__
4511012Sandreas.sandberg@arm.com
4611012Sandreas.sandberg@arm.com#include "arch/isa_traits.hh"
4711012Sandreas.sandberg@arm.com#include "config/the_isa.hh"
4811012Sandreas.sandberg@arm.com#include "cpu/o3/cpu.hh"
4911012Sandreas.sandberg@arm.com#include "cpu/o3/isa_specific.hh"
5011012Sandreas.sandberg@arm.com#include "cpu/base_dyn_inst.hh"
5111012Sandreas.sandberg@arm.com#include "cpu/inst_seq.hh"
5211012Sandreas.sandberg@arm.com
5311012Sandreas.sandberg@arm.comclass Packet;
5411012Sandreas.sandberg@arm.com
5511012Sandreas.sandberg@arm.com/**
5611012Sandreas.sandberg@arm.com * Mostly implementation & ISA specific AlphaDynInst. As with most
5711012Sandreas.sandberg@arm.com * other classes in the new CPU model, it is templated on the Impl to
5811012Sandreas.sandberg@arm.com * allow for passing in of all types, such as the CPU type and the ISA
5911012Sandreas.sandberg@arm.com * type. The AlphaDynInst serves as the primary interface to the CPU
6011012Sandreas.sandberg@arm.com * for instructions that are executing.
6111012Sandreas.sandberg@arm.com */
6211012Sandreas.sandberg@arm.comtemplate <class Impl>
6311012Sandreas.sandberg@arm.comclass BaseO3DynInst : public BaseDynInst<Impl>
6411012Sandreas.sandberg@arm.com{
6511012Sandreas.sandberg@arm.com  public:
6611012Sandreas.sandberg@arm.com    /** Typedef for the CPU. */
6711012Sandreas.sandberg@arm.com    typedef typename Impl::O3CPU O3CPU;
6811012Sandreas.sandberg@arm.com
6911012Sandreas.sandberg@arm.com    /** Binary machine instruction type. */
7011012Sandreas.sandberg@arm.com    typedef TheISA::MachInst MachInst;
7111012Sandreas.sandberg@arm.com    /** Extended machine instruction type. */
7211012Sandreas.sandberg@arm.com    typedef TheISA::ExtMachInst ExtMachInst;
7311012Sandreas.sandberg@arm.com    /** Logical register index type. */
7411012Sandreas.sandberg@arm.com    typedef TheISA::RegIndex RegIndex;
7511012Sandreas.sandberg@arm.com    /** Integer register index type. */
7611012Sandreas.sandberg@arm.com    typedef TheISA::IntReg   IntReg;
7711012Sandreas.sandberg@arm.com    typedef TheISA::FloatReg FloatReg;
7811012Sandreas.sandberg@arm.com    typedef TheISA::FloatRegBits FloatRegBits;
7911012Sandreas.sandberg@arm.com    /** Misc register index type. */
8011012Sandreas.sandberg@arm.com    typedef TheISA::MiscReg  MiscReg;
8111012Sandreas.sandberg@arm.com
8211012Sandreas.sandberg@arm.com    enum {
8311012Sandreas.sandberg@arm.com        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        //< Max source regs
8411012Sandreas.sandberg@arm.com        MaxInstDestRegs = TheISA::MaxInstDestRegs       //< Max dest regs
8511012Sandreas.sandberg@arm.com    };
8611012Sandreas.sandberg@arm.com
8711012Sandreas.sandberg@arm.com  public:
8811012Sandreas.sandberg@arm.com    /** BaseDynInst constructor given a binary instruction. */
8911012Sandreas.sandberg@arm.com    BaseO3DynInst(StaticInstPtr staticInst, StaticInstPtr macroop,
9011012Sandreas.sandberg@arm.com                  TheISA::PCState pc, TheISA::PCState predPC,
9111012Sandreas.sandberg@arm.com                  InstSeqNum seq_num, O3CPU *cpu);
9211012Sandreas.sandberg@arm.com
9311012Sandreas.sandberg@arm.com    /** BaseDynInst constructor given a static inst pointer. */
9411012Sandreas.sandberg@arm.com    BaseO3DynInst(StaticInstPtr _staticInst, StaticInstPtr _macroop);
9511012Sandreas.sandberg@arm.com
9611012Sandreas.sandberg@arm.com    ~BaseO3DynInst();
9711012Sandreas.sandberg@arm.com
9811012Sandreas.sandberg@arm.com    /** Executes the instruction.*/
9911012Sandreas.sandberg@arm.com    Fault execute();
10011012Sandreas.sandberg@arm.com
10111012Sandreas.sandberg@arm.com    /** Initiates the access.  Only valid for memory operations. */
10211012Sandreas.sandberg@arm.com    Fault initiateAcc();
10311012Sandreas.sandberg@arm.com
10411012Sandreas.sandberg@arm.com    /** Completes the access.  Only valid for memory operations. */
10511012Sandreas.sandberg@arm.com    Fault completeAcc(PacketPtr pkt);
10611012Sandreas.sandberg@arm.com
10711012Sandreas.sandberg@arm.com  private:
10811012Sandreas.sandberg@arm.com    /** Initializes variables. */
10911012Sandreas.sandberg@arm.com    void initVars();
11011012Sandreas.sandberg@arm.com
11111012Sandreas.sandberg@arm.com  protected:
11211012Sandreas.sandberg@arm.com    /** Values to be written to the destination misc. registers. */
11311012Sandreas.sandberg@arm.com    MiscReg _destMiscRegVal[TheISA::MaxMiscDestRegs];
11411012Sandreas.sandberg@arm.com
11511012Sandreas.sandberg@arm.com    /** Indexes of the destination misc. registers. They are needed to defer
11611012Sandreas.sandberg@arm.com     * the write accesses to the misc. registers until the commit stage, when
11711012Sandreas.sandberg@arm.com     * the instruction is out of its speculative state.
11811012Sandreas.sandberg@arm.com     */
11911012Sandreas.sandberg@arm.com    short _destMiscRegIdx[TheISA::MaxMiscDestRegs];
12011012Sandreas.sandberg@arm.com
12111012Sandreas.sandberg@arm.com    /** Number of destination misc. registers. */
12211012Sandreas.sandberg@arm.com    uint8_t _numDestMiscRegs;
12311012Sandreas.sandberg@arm.com
12411012Sandreas.sandberg@arm.com
12511012Sandreas.sandberg@arm.com  public:
12611012Sandreas.sandberg@arm.com#if TRACING_ON
12711012Sandreas.sandberg@arm.com    /** Tick records used for the pipeline activity viewer. */
12811012Sandreas.sandberg@arm.com    Tick fetchTick;	     // instruction fetch is completed.
12911012Sandreas.sandberg@arm.com    int32_t decodeTick;  // instruction enters decode phase
13011012Sandreas.sandberg@arm.com    int32_t renameTick;  // instruction enters rename phase
13111012Sandreas.sandberg@arm.com    int32_t dispatchTick;
13211012Sandreas.sandberg@arm.com    int32_t issueTick;
13311012Sandreas.sandberg@arm.com    int32_t completeTick;
13411012Sandreas.sandberg@arm.com    int32_t commitTick;
13511012Sandreas.sandberg@arm.com#endif
13611012Sandreas.sandberg@arm.com
13711012Sandreas.sandberg@arm.com    /** Reads a misc. register, including any side-effects the read
13811012Sandreas.sandberg@arm.com     * might have as defined by the architecture.
13911012Sandreas.sandberg@arm.com     */
14011012Sandreas.sandberg@arm.com    MiscReg readMiscReg(int misc_reg)
14111012Sandreas.sandberg@arm.com    {
14211012Sandreas.sandberg@arm.com        return this->cpu->readMiscReg(misc_reg, this->threadNumber);
14311012Sandreas.sandberg@arm.com    }
14411012Sandreas.sandberg@arm.com
14511012Sandreas.sandberg@arm.com    /** Sets a misc. register, including any side-effects the write
14611012Sandreas.sandberg@arm.com     * might have as defined by the architecture.
14711012Sandreas.sandberg@arm.com     */
14811012Sandreas.sandberg@arm.com    void setMiscReg(int misc_reg, const MiscReg &val)
14911012Sandreas.sandberg@arm.com    {
15011012Sandreas.sandberg@arm.com        /** Writes to misc. registers are recorded and deferred until the
15111012Sandreas.sandberg@arm.com         * commit stage, when updateMiscRegs() is called.
15211012Sandreas.sandberg@arm.com         */
15311012Sandreas.sandberg@arm.com        assert(_numDestMiscRegs < TheISA::MaxMiscDestRegs);
15411012Sandreas.sandberg@arm.com        _destMiscRegIdx[_numDestMiscRegs] = misc_reg;
15511012Sandreas.sandberg@arm.com        _destMiscRegVal[_numDestMiscRegs] = val;
15611012Sandreas.sandberg@arm.com        _numDestMiscRegs++;
15711012Sandreas.sandberg@arm.com    }
15811012Sandreas.sandberg@arm.com
15911012Sandreas.sandberg@arm.com    /** Reads a misc. register, including any side-effects the read
16011012Sandreas.sandberg@arm.com     * might have as defined by the architecture.
16111012Sandreas.sandberg@arm.com     */
16211012Sandreas.sandberg@arm.com    TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
16311012Sandreas.sandberg@arm.com    {
16411012Sandreas.sandberg@arm.com        return this->cpu->readMiscReg(
16511012Sandreas.sandberg@arm.com                si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
16611012Sandreas.sandberg@arm.com                this->threadNumber);
16711012Sandreas.sandberg@arm.com    }
16811012Sandreas.sandberg@arm.com
16911012Sandreas.sandberg@arm.com    /** Sets a misc. register, including any side-effects the write
17011012Sandreas.sandberg@arm.com     * might have as defined by the architecture.
17111012Sandreas.sandberg@arm.com     */
17211012Sandreas.sandberg@arm.com    void setMiscRegOperand(const StaticInst *si, int idx,
17311012Sandreas.sandberg@arm.com                                     const MiscReg &val)
17411012Sandreas.sandberg@arm.com    {
17511012Sandreas.sandberg@arm.com        int misc_reg = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
17611012Sandreas.sandberg@arm.com        setMiscReg(misc_reg, val);
17711012Sandreas.sandberg@arm.com    }
17811012Sandreas.sandberg@arm.com
17911012Sandreas.sandberg@arm.com    /** Called at the commit stage to update the misc. registers. */
18011012Sandreas.sandberg@arm.com    void updateMiscRegs()
18111012Sandreas.sandberg@arm.com    {
18211012Sandreas.sandberg@arm.com        // @todo: Pretty convoluted way to avoid squashing from happening when
18311012Sandreas.sandberg@arm.com        // using the TC during an instruction's execution (specifically for
18411012Sandreas.sandberg@arm.com        // instructions that have side-effects that use the TC).  Fix this.
18511012Sandreas.sandberg@arm.com        // See cpu/o3/dyn_inst_impl.hh.
18611012Sandreas.sandberg@arm.com        bool in_syscall = this->thread->inSyscall;
18711012Sandreas.sandberg@arm.com        this->thread->inSyscall = true;
18811012Sandreas.sandberg@arm.com
18911012Sandreas.sandberg@arm.com        for (int i = 0; i < _numDestMiscRegs; i++)
19011012Sandreas.sandberg@arm.com            this->cpu->setMiscReg(
19111012Sandreas.sandberg@arm.com                _destMiscRegIdx[i], _destMiscRegVal[i], this->threadNumber);
19211012Sandreas.sandberg@arm.com
19311012Sandreas.sandberg@arm.com        this->thread->inSyscall = in_syscall;
19411012Sandreas.sandberg@arm.com    }
19511012Sandreas.sandberg@arm.com
19611012Sandreas.sandberg@arm.com    void forwardOldRegs()
19711012Sandreas.sandberg@arm.com    {
19811012Sandreas.sandberg@arm.com
19911012Sandreas.sandberg@arm.com        for (int idx = 0; idx < this->numDestRegs(); idx++) {
20011012Sandreas.sandberg@arm.com            PhysRegIndex prev_phys_reg = this->prevDestRegIdx(idx);
20111012Sandreas.sandberg@arm.com            TheISA::RegIndex original_dest_reg = this->staticInst->destRegIdx(idx);
20211012Sandreas.sandberg@arm.com            if (original_dest_reg <  TheISA::FP_Base_DepTag)
20311012Sandreas.sandberg@arm.com                this->setIntRegOperand(this->staticInst.get(), idx, this->cpu->readIntReg(prev_phys_reg));
20411012Sandreas.sandberg@arm.com            else if (original_dest_reg < TheISA::Ctrl_Base_DepTag)
20511012Sandreas.sandberg@arm.com                this->setFloatRegOperandBits(this->staticInst.get(), idx, this->cpu->readFloatRegBits(prev_phys_reg));
20611012Sandreas.sandberg@arm.com        }
20711012Sandreas.sandberg@arm.com    }
20811012Sandreas.sandberg@arm.com    /** Calls hardware return from error interrupt. */
20911012Sandreas.sandberg@arm.com    Fault hwrei();
21011012Sandreas.sandberg@arm.com    /** Traps to handle specified fault. */
21111012Sandreas.sandberg@arm.com    void trap(Fault fault);
21211012Sandreas.sandberg@arm.com    bool simPalCheck(int palFunc);
21311012Sandreas.sandberg@arm.com
21411012Sandreas.sandberg@arm.com    /** Emulates a syscall. */
21511012Sandreas.sandberg@arm.com    void syscall(int64_t callnum);
21611012Sandreas.sandberg@arm.com
21711012Sandreas.sandberg@arm.com  public:
21811012Sandreas.sandberg@arm.com
21911012Sandreas.sandberg@arm.com    // The register accessor methods provide the index of the
22011012Sandreas.sandberg@arm.com    // instruction's operand (e.g., 0 or 1), not the architectural
22111012Sandreas.sandberg@arm.com    // register index, to simplify the implementation of register
22211012Sandreas.sandberg@arm.com    // renaming.  We find the architectural register index by indexing
22311012Sandreas.sandberg@arm.com    // into the instruction's own operand index table.  Note that a
22411012Sandreas.sandberg@arm.com    // raw pointer to the StaticInst is provided instead of a
22511012Sandreas.sandberg@arm.com    // ref-counted StaticInstPtr to redice overhead.  This is fine as
22611012Sandreas.sandberg@arm.com    // long as these methods don't copy the pointer into any long-term
22711012Sandreas.sandberg@arm.com    // storage (which is pretty hard to imagine they would have reason
22811012Sandreas.sandberg@arm.com    // to do).
22911012Sandreas.sandberg@arm.com
23011012Sandreas.sandberg@arm.com    uint64_t readIntRegOperand(const StaticInst *si, int idx)
23111012Sandreas.sandberg@arm.com    {
23211012Sandreas.sandberg@arm.com        return this->cpu->readIntReg(this->_srcRegIdx[idx]);
23311012Sandreas.sandberg@arm.com    }
23411012Sandreas.sandberg@arm.com
23511012Sandreas.sandberg@arm.com    FloatReg readFloatRegOperand(const StaticInst *si, int idx)
23611012Sandreas.sandberg@arm.com    {
23711012Sandreas.sandberg@arm.com        return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
23811012Sandreas.sandberg@arm.com    }
23911012Sandreas.sandberg@arm.com
24011012Sandreas.sandberg@arm.com    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
24111012Sandreas.sandberg@arm.com    {
24211012Sandreas.sandberg@arm.com        return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
24311012Sandreas.sandberg@arm.com    }
24411012Sandreas.sandberg@arm.com
24511012Sandreas.sandberg@arm.com    /** @todo: Make results into arrays so they can handle multiple dest
24611012Sandreas.sandberg@arm.com     *  registers.
24711012Sandreas.sandberg@arm.com     */
24811012Sandreas.sandberg@arm.com    void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
24911012Sandreas.sandberg@arm.com    {
25011012Sandreas.sandberg@arm.com        this->cpu->setIntReg(this->_destRegIdx[idx], val);
25111012Sandreas.sandberg@arm.com        BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
25211012Sandreas.sandberg@arm.com    }
25311012Sandreas.sandberg@arm.com
25411012Sandreas.sandberg@arm.com    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
25511012Sandreas.sandberg@arm.com    {
25611012Sandreas.sandberg@arm.com        this->cpu->setFloatReg(this->_destRegIdx[idx], val);
25711012Sandreas.sandberg@arm.com        BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
25811012Sandreas.sandberg@arm.com    }
25911012Sandreas.sandberg@arm.com
26011012Sandreas.sandberg@arm.com    void setFloatRegOperandBits(const StaticInst *si, int idx,
26111012Sandreas.sandberg@arm.com                                FloatRegBits val)
26211012Sandreas.sandberg@arm.com    {
26311012Sandreas.sandberg@arm.com        this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
26411012Sandreas.sandberg@arm.com        BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
26511012Sandreas.sandberg@arm.com    }
26611012Sandreas.sandberg@arm.com
26711012Sandreas.sandberg@arm.com#if THE_ISA == MIPS_ISA
26811012Sandreas.sandberg@arm.com    uint64_t readRegOtherThread(int misc_reg)
26911012Sandreas.sandberg@arm.com    {
27011012Sandreas.sandberg@arm.com        panic("MIPS MT not defined for O3 CPU.\n");
27111012Sandreas.sandberg@arm.com        return 0;
27211012Sandreas.sandberg@arm.com    }
27311012Sandreas.sandberg@arm.com
27411012Sandreas.sandberg@arm.com    void setRegOtherThread(int misc_reg, const TheISA::MiscReg &val)
27511012Sandreas.sandberg@arm.com    {
27611012Sandreas.sandberg@arm.com        panic("MIPS MT not defined for O3 CPU.\n");
27711012Sandreas.sandberg@arm.com    }
27811012Sandreas.sandberg@arm.com#endif
27911012Sandreas.sandberg@arm.com
28011012Sandreas.sandberg@arm.com  public:
28111012Sandreas.sandberg@arm.com    /** Calculates EA part of a memory instruction. Currently unused,
28211012Sandreas.sandberg@arm.com     * though it may be useful in the future if we want to split
28311012Sandreas.sandberg@arm.com     * memory operations into EA calculation and memory access parts.
28411012Sandreas.sandberg@arm.com     */
28511012Sandreas.sandberg@arm.com    Fault calcEA()
28611012Sandreas.sandberg@arm.com    {
28711012Sandreas.sandberg@arm.com        return this->staticInst->eaCompInst()->execute(this, this->traceData);
28811012Sandreas.sandberg@arm.com    }
28911012Sandreas.sandberg@arm.com
29011012Sandreas.sandberg@arm.com    /** Does the memory access part of a memory instruction. Currently unused,
29111012Sandreas.sandberg@arm.com     * though it may be useful in the future if we want to split
29211012Sandreas.sandberg@arm.com     * memory operations into EA calculation and memory access parts.
29311012Sandreas.sandberg@arm.com     */
29411012Sandreas.sandberg@arm.com    Fault memAccess()
29511012Sandreas.sandberg@arm.com    {
29611012Sandreas.sandberg@arm.com        return this->staticInst->memAccInst()->execute(this, this->traceData);
29711012Sandreas.sandberg@arm.com    }
29811012Sandreas.sandberg@arm.com};
29911012Sandreas.sandberg@arm.com
30011012Sandreas.sandberg@arm.com#endif // __CPU_O3_ALPHA_DYN_INST_HH__
30111012Sandreas.sandberg@arm.com
30211012Sandreas.sandberg@arm.com