dyn_inst.hh revision 7720:65d338a8dba4
1/*
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Kevin Lim
29 */
30
31#ifndef __CPU_O3_DYN_INST_HH__
32#define __CPU_O3_DYN_INST_HH__
33
34#include "arch/isa_traits.hh"
35#include "config/the_isa.hh"
36#include "cpu/base_dyn_inst.hh"
37#include "cpu/inst_seq.hh"
38#include "cpu/o3/cpu.hh"
39#include "cpu/o3/isa_specific.hh"
40
41class Packet;
42
43/**
44 * Mostly implementation & ISA specific AlphaDynInst. As with most
45 * other classes in the new CPU model, it is templated on the Impl to
46 * allow for passing in of all types, such as the CPU type and the ISA
47 * type. The AlphaDynInst serves as the primary interface to the CPU
48 * for instructions that are executing.
49 */
50template <class Impl>
51class BaseO3DynInst : public BaseDynInst<Impl>
52{
53  public:
54    /** Typedef for the CPU. */
55    typedef typename Impl::O3CPU O3CPU;
56
57    /** Binary machine instruction type. */
58    typedef TheISA::MachInst MachInst;
59    /** Extended machine instruction type. */
60    typedef TheISA::ExtMachInst ExtMachInst;
61    /** Logical register index type. */
62    typedef TheISA::RegIndex RegIndex;
63    /** Integer register index type. */
64    typedef TheISA::IntReg   IntReg;
65    typedef TheISA::FloatReg FloatReg;
66    typedef TheISA::FloatRegBits FloatRegBits;
67    /** Misc register index type. */
68    typedef TheISA::MiscReg  MiscReg;
69
70    enum {
71        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        //< Max source regs
72        MaxInstDestRegs = TheISA::MaxInstDestRegs,      //< Max dest regs
73    };
74
75  public:
76    /** BaseDynInst constructor given a binary instruction. */
77    BaseO3DynInst(StaticInstPtr staticInst,
78                  TheISA::PCState pc, TheISA::PCState predPC,
79                  InstSeqNum seq_num, O3CPU *cpu);
80
81    /** BaseDynInst constructor given a binary instruction. */
82    BaseO3DynInst(ExtMachInst inst,
83                  TheISA::PCState pc, TheISA::PCState predPC,
84                  InstSeqNum seq_num, O3CPU *cpu);
85
86    /** BaseDynInst constructor given a static inst pointer. */
87    BaseO3DynInst(StaticInstPtr &_staticInst);
88
89    /** Executes the instruction.*/
90    Fault execute();
91
92    /** Initiates the access.  Only valid for memory operations. */
93    Fault initiateAcc();
94
95    /** Completes the access.  Only valid for memory operations. */
96    Fault completeAcc(PacketPtr pkt);
97
98  private:
99    /** Initializes variables. */
100    void initVars();
101
102  public:
103    /** Reads a miscellaneous register. */
104    MiscReg readMiscRegNoEffect(int misc_reg)
105    {
106        return this->cpu->readMiscRegNoEffect(misc_reg, this->threadNumber);
107    }
108
109    /** Reads a misc. register, including any side-effects the read
110     * might have as defined by the architecture.
111     */
112    MiscReg readMiscReg(int misc_reg)
113    {
114        return this->cpu->readMiscReg(misc_reg, this->threadNumber);
115    }
116
117    /** Sets a misc. register. */
118    void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
119    {
120        this->instResult.integer = val;
121        return this->cpu->setMiscRegNoEffect(misc_reg, val, this->threadNumber);
122    }
123
124    /** Sets a misc. register, including any side-effects the write
125     * might have as defined by the architecture.
126     */
127    void setMiscReg(int misc_reg, const MiscReg &val)
128    {
129        return this->cpu->setMiscReg(misc_reg, val,
130                                               this->threadNumber);
131    }
132
133    /** Reads a miscellaneous register. */
134    TheISA::MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
135    {
136        return this->cpu->readMiscRegNoEffect(
137                si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
138                this->threadNumber);
139    }
140
141    /** Reads a misc. register, including any side-effects the read
142     * might have as defined by the architecture.
143     */
144    TheISA::MiscReg readMiscRegOperand(const StaticInst *si, int idx)
145    {
146        return this->cpu->readMiscReg(
147                si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
148                this->threadNumber);
149    }
150
151    /** Sets a misc. register. */
152    void setMiscRegOperandNoEffect(const StaticInst * si, int idx, const MiscReg &val)
153    {
154        this->instResult.integer = val;
155        return this->cpu->setMiscRegNoEffect(
156                si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
157                val, this->threadNumber);
158    }
159
160    /** Sets a misc. register, including any side-effects the write
161     * might have as defined by the architecture.
162     */
163    void setMiscRegOperand(const StaticInst *si, int idx,
164                                     const MiscReg &val)
165    {
166        return this->cpu->setMiscReg(
167                si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag,
168                val, this->threadNumber);
169    }
170
171#if FULL_SYSTEM
172    /** Calls hardware return from error interrupt. */
173    Fault hwrei();
174    /** Traps to handle specified fault. */
175    void trap(Fault fault);
176    bool simPalCheck(int palFunc);
177#else
178    /** Calls a syscall. */
179    void syscall(int64_t callnum);
180#endif
181
182  public:
183
184    // The register accessor methods provide the index of the
185    // instruction's operand (e.g., 0 or 1), not the architectural
186    // register index, to simplify the implementation of register
187    // renaming.  We find the architectural register index by indexing
188    // into the instruction's own operand index table.  Note that a
189    // raw pointer to the StaticInst is provided instead of a
190    // ref-counted StaticInstPtr to redice overhead.  This is fine as
191    // long as these methods don't copy the pointer into any long-term
192    // storage (which is pretty hard to imagine they would have reason
193    // to do).
194
195    uint64_t readIntRegOperand(const StaticInst *si, int idx)
196    {
197        return this->cpu->readIntReg(this->_srcRegIdx[idx]);
198    }
199
200    FloatReg readFloatRegOperand(const StaticInst *si, int idx)
201    {
202        return this->cpu->readFloatReg(this->_srcRegIdx[idx]);
203    }
204
205    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
206    {
207        return this->cpu->readFloatRegBits(this->_srcRegIdx[idx]);
208    }
209
210    /** @todo: Make results into arrays so they can handle multiple dest
211     *  registers.
212     */
213    void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
214    {
215        this->cpu->setIntReg(this->_destRegIdx[idx], val);
216        BaseDynInst<Impl>::setIntRegOperand(si, idx, val);
217    }
218
219    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
220    {
221        this->cpu->setFloatReg(this->_destRegIdx[idx], val);
222        BaseDynInst<Impl>::setFloatRegOperand(si, idx, val);
223    }
224
225    void setFloatRegOperandBits(const StaticInst *si, int idx,
226                                FloatRegBits val)
227    {
228        this->cpu->setFloatRegBits(this->_destRegIdx[idx], val);
229        BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val);
230    }
231
232#if THE_ISA == MIPS_ISA
233    uint64_t readRegOtherThread(int misc_reg)
234    {
235        panic("MIPS MT not defined for O3 CPU.\n");
236        return 0;
237    }
238
239    void setRegOtherThread(int misc_reg, const TheISA::MiscReg &val)
240    {
241        panic("MIPS MT not defined for O3 CPU.\n");
242    }
243#endif
244
245  public:
246    /** Calculates EA part of a memory instruction. Currently unused,
247     * though it may be useful in the future if we want to split
248     * memory operations into EA calculation and memory access parts.
249     */
250    Fault calcEA()
251    {
252        return this->staticInst->eaCompInst()->execute(this, this->traceData);
253    }
254
255    /** Does the memory access part of a memory instruction. Currently unused,
256     * though it may be useful in the future if we want to split
257     * memory operations into EA calculation and memory access parts.
258     */
259    Fault memAccess()
260    {
261        return this->staticInst->memAccInst()->execute(this, this->traceData);
262    }
263};
264
265#endif // __CPU_O3_ALPHA_DYN_INST_HH__
266
267