dyn_inst_impl.hh revision 9252
1/*
2 * Copyright (c) 2010-2011 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2004-2006 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Kevin Lim
41 */
42
43#include "base/cp_annotate.hh"
44#include "cpu/o3/dyn_inst.hh"
45#include "sim/full_system.hh"
46#include "debug/O3PipeView.hh"
47
48template <class Impl>
49BaseO3DynInst<Impl>::BaseO3DynInst(StaticInstPtr staticInst,
50                                   StaticInstPtr macroop,
51                                   TheISA::PCState pc, TheISA::PCState predPC,
52                                   InstSeqNum seq_num, O3CPU *cpu)
53    : BaseDynInst<Impl>(staticInst, macroop, pc, predPC, seq_num, cpu)
54{
55    initVars();
56}
57
58template <class Impl>
59BaseO3DynInst<Impl>::BaseO3DynInst(StaticInstPtr _staticInst,
60                                   StaticInstPtr _macroop)
61    : BaseDynInst<Impl>(_staticInst, _macroop)
62{
63    initVars();
64}
65
66template <class Impl>BaseO3DynInst<Impl>::~BaseO3DynInst()
67{
68#if TRACING_ON
69    Tick val, fetch = this->fetchTick;
70    // Print info needed by the pipeline activity viewer.
71    DPRINTFR(O3PipeView, "O3PipeView:fetch:%llu:0x%08llx:%d:%llu:%s\n",
72             fetch,
73             this->instAddr(),
74             this->microPC(),
75             this->seqNum,
76             this->staticInst->disassemble(this->instAddr()));
77    val = (this->decodeTick == -1) ? 0 : fetch + this->decodeTick;
78    DPRINTFR(O3PipeView, "O3PipeView:decode:%llu\n", val);
79    val = (this->renameTick == -1) ? 0 : fetch + this->renameTick;
80    DPRINTFR(O3PipeView, "O3PipeView:rename:%llu\n", val);
81    val = (this->dispatchTick == -1) ? 0 : fetch + this->dispatchTick;
82    DPRINTFR(O3PipeView, "O3PipeView:dispatch:%llu\n", val);
83    val = (this->issueTick == -1) ? 0 : fetch + this->issueTick;
84    DPRINTFR(O3PipeView, "O3PipeView:issue:%llu\n", val);
85    val = (this->completeTick == -1) ? 0 : fetch + this->completeTick;
86    DPRINTFR(O3PipeView, "O3PipeView:complete:%llu\n", val);
87    val = (this->commitTick == -1) ? 0 : fetch + this->commitTick;
88    DPRINTFR(O3PipeView, "O3PipeView:retire:%llu\n", val);
89#endif
90};
91
92
93template <class Impl>
94void
95BaseO3DynInst<Impl>::initVars()
96{
97    // Make sure to have the renamed register entries set to the same
98    // as the normal register entries.  It will allow the IQ to work
99    // without any modifications.
100    for (int i = 0; i < this->staticInst->numDestRegs(); i++) {
101        this->_destRegIdx[i] = this->staticInst->destRegIdx(i);
102    }
103
104    for (int i = 0; i < this->staticInst->numSrcRegs(); i++) {
105        this->_srcRegIdx[i] = this->staticInst->srcRegIdx(i);
106    }
107
108    this->_readySrcRegIdx.reset();
109
110    _numDestMiscRegs = 0;
111
112#if TRACING_ON
113    // Value -1 indicates that particular phase
114    // hasn't happened (yet).
115    fetchTick = -1;
116    decodeTick = -1;
117    renameTick = -1;
118    dispatchTick = -1;
119    issueTick = -1;
120    completeTick = -1;
121    commitTick = -1;
122#endif
123}
124
125template <class Impl>
126Fault
127BaseO3DynInst<Impl>::execute()
128{
129    // @todo: Pretty convoluted way to avoid squashing from happening
130    // when using the TC during an instruction's execution
131    // (specifically for instructions that have side-effects that use
132    // the TC).  Fix this.
133    bool in_syscall = this->thread->inSyscall;
134    this->thread->inSyscall = true;
135
136    this->fault = this->staticInst->execute(this, this->traceData);
137
138    this->thread->inSyscall = in_syscall;
139
140    return this->fault;
141}
142
143template <class Impl>
144Fault
145BaseO3DynInst<Impl>::initiateAcc()
146{
147    // @todo: Pretty convoluted way to avoid squashing from happening
148    // when using the TC during an instruction's execution
149    // (specifically for instructions that have side-effects that use
150    // the TC).  Fix this.
151    bool in_syscall = this->thread->inSyscall;
152    this->thread->inSyscall = true;
153
154    this->fault = this->staticInst->initiateAcc(this, this->traceData);
155
156    this->thread->inSyscall = in_syscall;
157
158    return this->fault;
159}
160
161template <class Impl>
162Fault
163BaseO3DynInst<Impl>::completeAcc(PacketPtr pkt)
164{
165    // @todo: Pretty convoluted way to avoid squashing from happening
166    // when using the TC during an instruction's execution
167    // (specifically for instructions that have side-effects that use
168    // the TC).  Fix this.
169    bool in_syscall = this->thread->inSyscall;
170    this->thread->inSyscall = true;
171
172    if (this->cpu->checker) {
173        if (this->isStoreConditional()) {
174            this->reqToVerify->setExtraData(pkt->req->getExtraData());
175        }
176    }
177
178    this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
179
180    this->thread->inSyscall = in_syscall;
181
182    return this->fault;
183}
184
185template <class Impl>
186Fault
187BaseO3DynInst<Impl>::hwrei()
188{
189#if THE_ISA == ALPHA_ISA
190    // Can only do a hwrei when in pal mode.
191    if (!(this->instAddr() & 0x3))
192        return new AlphaISA::UnimplementedOpcodeFault;
193
194    // Set the next PC based on the value of the EXC_ADDR IPR.
195    AlphaISA::PCState pc = this->pcState();
196    pc.npc(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
197                                          this->threadNumber));
198    this->pcState(pc);
199    if (CPA::available()) {
200        ThreadContext *tc = this->cpu->tcBase(this->threadNumber);
201        CPA::cpa()->swAutoBegin(tc, this->nextInstAddr());
202    }
203
204    // Tell CPU to clear any state it needs to if a hwrei is taken.
205    this->cpu->hwrei(this->threadNumber);
206#else
207
208#endif
209    // FIXME: XXX check for interrupts? XXX
210    return NoFault;
211}
212
213template <class Impl>
214void
215BaseO3DynInst<Impl>::trap(Fault fault)
216{
217    this->cpu->trap(fault, this->threadNumber, this->staticInst);
218}
219
220template <class Impl>
221bool
222BaseO3DynInst<Impl>::simPalCheck(int palFunc)
223{
224#if THE_ISA != ALPHA_ISA
225    panic("simPalCheck called, but PAL only exists in Alpha!\n");
226#endif
227    return this->cpu->simPalCheck(palFunc, this->threadNumber);
228}
229
230template <class Impl>
231void
232BaseO3DynInst<Impl>::syscall(int64_t callnum)
233{
234    if (FullSystem)
235        panic("Syscall emulation isn't available in FS mode.\n");
236
237    // HACK: check CPU's nextPC before and after syscall. If it
238    // changes, update this instruction's nextPC because the syscall
239    // must have changed the nextPC.
240    TheISA::PCState curPC = this->cpu->pcState(this->threadNumber);
241    this->cpu->syscall(callnum, this->threadNumber);
242    TheISA::PCState newPC = this->cpu->pcState(this->threadNumber);
243    if (!(curPC == newPC)) {
244        this->pcState(newPC);
245    }
246}
247
248