exec_context.hh revision 11148:1bc3d93c7eaa
1/*
2 * Copyright (c) 2014-2015 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) 2002-2005 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 *          Andreas Sandberg
42 *          Mitch Hayenga
43 */
44
45#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
46#define __CPU_SIMPLE_EXEC_CONTEXT_HH__
47
48#include "arch/registers.hh"
49#include "base/types.hh"
50#include "config/the_isa.hh"
51#include "cpu/base.hh"
52#include "cpu/exec_context.hh"
53#include "cpu/simple/base.hh"
54#include "cpu/static_inst_fwd.hh"
55#include "cpu/translation.hh"
56
57class BaseSimpleCPU;
58
59class SimpleExecContext : public ExecContext {
60  protected:
61    typedef TheISA::MiscReg MiscReg;
62    typedef TheISA::FloatReg FloatReg;
63    typedef TheISA::FloatRegBits FloatRegBits;
64    typedef TheISA::CCReg CCReg;
65
66  public:
67    BaseSimpleCPU *cpu;
68    SimpleThread* thread;
69
70    // This is the offset from the current pc that fetch should be performed
71    Addr fetchOffset;
72    // This flag says to stay at the current pc. This is useful for
73    // instructions which go beyond MachInst boundaries.
74    bool stayAtPC;
75
76    // Branch prediction
77    TheISA::PCState predPC;
78
79    /** PER-THREAD STATS */
80
81    // Number of simulated instructions
82    Counter numInst;
83    Stats::Scalar numInsts;
84    Counter numOp;
85    Stats::Scalar numOps;
86
87    // Number of integer alu accesses
88    Stats::Scalar numIntAluAccesses;
89
90    // Number of float alu accesses
91    Stats::Scalar numFpAluAccesses;
92
93    // Number of function calls/returns
94    Stats::Scalar numCallsReturns;
95
96    // Conditional control instructions;
97    Stats::Scalar numCondCtrlInsts;
98
99    // Number of int instructions
100    Stats::Scalar numIntInsts;
101
102    // Number of float instructions
103    Stats::Scalar numFpInsts;
104
105    // Number of integer register file accesses
106    Stats::Scalar numIntRegReads;
107    Stats::Scalar numIntRegWrites;
108
109    // Number of float register file accesses
110    Stats::Scalar numFpRegReads;
111    Stats::Scalar numFpRegWrites;
112
113    // Number of condition code register file accesses
114    Stats::Scalar numCCRegReads;
115    Stats::Scalar numCCRegWrites;
116
117    // Number of simulated memory references
118    Stats::Scalar numMemRefs;
119    Stats::Scalar numLoadInsts;
120    Stats::Scalar numStoreInsts;
121
122    // Number of idle cycles
123    Stats::Formula numIdleCycles;
124
125    // Number of busy cycles
126    Stats::Formula numBusyCycles;
127
128    // Number of simulated loads
129    Counter numLoad;
130
131    // Number of idle cycles
132    Stats::Average notIdleFraction;
133    Stats::Formula idleFraction;
134
135    // Number of cycles stalled for I-cache responses
136    Stats::Scalar icacheStallCycles;
137    Counter lastIcacheStall;
138
139    // Number of cycles stalled for D-cache responses
140    Stats::Scalar dcacheStallCycles;
141    Counter lastDcacheStall;
142
143    /// @{
144    /// Total number of branches fetched
145    Stats::Scalar numBranches;
146    /// Number of branches predicted as taken
147    Stats::Scalar numPredictedBranches;
148    /// Number of misprediced branches
149    Stats::Scalar numBranchMispred;
150    /// @}
151
152   // Instruction mix histogram by OpClass
153   Stats::Vector statExecutedInstType;
154
155  public:
156    /** Constructor */
157    SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
158        : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
159        numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
160    { }
161
162    /** Reads an integer register. */
163    IntReg readIntRegOperand(const StaticInst *si, int idx) M5_ATTR_OVERRIDE
164    {
165        numIntRegReads++;
166        return thread->readIntReg(si->srcRegIdx(idx));
167    }
168
169    /** Sets an integer register to a value. */
170    void setIntRegOperand(const StaticInst *si, int idx, IntReg val)
171        M5_ATTR_OVERRIDE
172    {
173        numIntRegWrites++;
174        thread->setIntReg(si->destRegIdx(idx), val);
175    }
176
177    /** Reads a floating point register of single register width. */
178    FloatReg readFloatRegOperand(const StaticInst *si, int idx)
179        M5_ATTR_OVERRIDE
180    {
181        numFpRegReads++;
182        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
183        return thread->readFloatReg(reg_idx);
184    }
185
186    /** Reads a floating point register in its binary format, instead
187     * of by value. */
188    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
189        M5_ATTR_OVERRIDE
190    {
191        numFpRegReads++;
192        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
193        return thread->readFloatRegBits(reg_idx);
194    }
195
196    /** Sets a floating point register of single width to a value. */
197    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
198        M5_ATTR_OVERRIDE
199    {
200        numFpRegWrites++;
201        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
202        thread->setFloatReg(reg_idx, val);
203    }
204
205    /** Sets the bits of a floating point register of single width
206     * to a binary value. */
207    void setFloatRegOperandBits(const StaticInst *si, int idx,
208                                FloatRegBits val) M5_ATTR_OVERRIDE
209    {
210        numFpRegWrites++;
211        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
212        thread->setFloatRegBits(reg_idx, val);
213    }
214
215    CCReg readCCRegOperand(const StaticInst *si, int idx) M5_ATTR_OVERRIDE
216    {
217        numCCRegReads++;
218        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
219        return thread->readCCReg(reg_idx);
220    }
221
222    void setCCRegOperand(const StaticInst *si, int idx, CCReg val)
223        M5_ATTR_OVERRIDE
224    {
225        numCCRegWrites++;
226        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
227        thread->setCCReg(reg_idx, val);
228    }
229
230    MiscReg readMiscRegOperand(const StaticInst *si, int idx) M5_ATTR_OVERRIDE
231    {
232        numIntRegReads++;
233        int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
234        return thread->readMiscReg(reg_idx);
235    }
236
237    void setMiscRegOperand(const StaticInst *si, int idx, const MiscReg &val)
238        M5_ATTR_OVERRIDE
239    {
240        numIntRegWrites++;
241        int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
242        thread->setMiscReg(reg_idx, val);
243    }
244
245    /**
246     * Reads a miscellaneous register, handling any architectural
247     * side effects due to reading that register.
248     */
249    MiscReg readMiscReg(int misc_reg) M5_ATTR_OVERRIDE
250    {
251        numIntRegReads++;
252        return thread->readMiscReg(misc_reg);
253    }
254
255    /**
256     * Sets a miscellaneous register, handling any architectural
257     * side effects due to writing that register.
258     */
259    void setMiscReg(int misc_reg, const MiscReg &val) M5_ATTR_OVERRIDE
260    {
261        numIntRegWrites++;
262        thread->setMiscReg(misc_reg, val);
263    }
264
265    PCState pcState() const M5_ATTR_OVERRIDE
266    {
267        return thread->pcState();
268    }
269
270    void pcState(const PCState &val) M5_ATTR_OVERRIDE
271    {
272        thread->pcState(val);
273    }
274
275
276    /**
277     * Record the effective address of the instruction.
278     *
279     * @note Only valid for memory ops.
280     */
281    void setEA(Addr EA) M5_ATTR_OVERRIDE
282    { panic("BaseSimpleCPU::setEA() not implemented\n"); }
283
284    /**
285     * Get the effective address of the instruction.
286     *
287     * @note Only valid for memory ops.
288     */
289    Addr getEA() const M5_ATTR_OVERRIDE
290    { panic("BaseSimpleCPU::getEA() not implemented\n"); }
291
292    Fault readMem(Addr addr, uint8_t *data, unsigned int size,
293                  unsigned int flags) M5_ATTR_OVERRIDE
294    {
295        return cpu->readMem(addr, data, size, flags);
296    }
297
298    Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
299                   unsigned int flags, uint64_t *res) M5_ATTR_OVERRIDE
300    {
301        return cpu->writeMem(data, size, addr, flags, res);
302    }
303
304    /**
305     * Sets the number of consecutive store conditional failures.
306     */
307    void setStCondFailures(unsigned int sc_failures) M5_ATTR_OVERRIDE
308    {
309        thread->setStCondFailures(sc_failures);
310    }
311
312    /**
313     * Returns the number of consecutive store conditional failures.
314     */
315    unsigned int readStCondFailures() const M5_ATTR_OVERRIDE
316    {
317        return thread->readStCondFailures();
318    }
319
320    /**
321     * Executes a syscall specified by the callnum.
322     */
323    void syscall(int64_t callnum) M5_ATTR_OVERRIDE
324    {
325        if (FullSystem)
326            panic("Syscall emulation isn't available in FS mode.");
327
328        thread->syscall(callnum);
329    }
330
331    /** Returns a pointer to the ThreadContext. */
332    ThreadContext *tcBase() M5_ATTR_OVERRIDE
333    {
334        return thread->getTC();
335    }
336
337    /**
338     * Somewhat Alpha-specific function that handles returning from an
339     * error or interrupt.
340     */
341    Fault hwrei() M5_ATTR_OVERRIDE
342    {
343        return thread->hwrei();
344    }
345
346    /**
347     * Check for special simulator handling of specific PAL calls.  If
348     * return value is false, actual PAL call will be suppressed.
349     */
350    bool simPalCheck(int palFunc) M5_ATTR_OVERRIDE
351    {
352        return thread->simPalCheck(palFunc);
353    }
354
355    bool readPredicate() M5_ATTR_OVERRIDE
356    {
357        return thread->readPredicate();
358    }
359
360    void setPredicate(bool val) M5_ATTR_OVERRIDE
361    {
362        thread->setPredicate(val);
363
364        if (cpu->traceData) {
365            cpu->traceData->setPredicate(val);
366        }
367    }
368
369    /**
370     * Invalidate a page in the DTLB <i>and</i> ITLB.
371     */
372    void demapPage(Addr vaddr, uint64_t asn) M5_ATTR_OVERRIDE
373    {
374        thread->demapPage(vaddr, asn);
375    }
376
377    void armMonitor(Addr address) M5_ATTR_OVERRIDE
378    {
379        cpu->armMonitor(thread->threadId(), address);
380    }
381
382    bool mwait(PacketPtr pkt) M5_ATTR_OVERRIDE
383    {
384        return cpu->mwait(thread->threadId(), pkt);
385    }
386
387    void mwaitAtomic(ThreadContext *tc) M5_ATTR_OVERRIDE
388    {
389        cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
390    }
391
392    AddressMonitor *getAddrMonitor() M5_ATTR_OVERRIDE
393    {
394        return cpu->getCpuAddrMonitor(thread->threadId());
395    }
396
397#if THE_ISA == MIPS_ISA
398    MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
399        M5_ATTR_OVERRIDE
400    {
401        panic("Simple CPU models do not support multithreaded "
402              "register access.");
403    }
404
405    void setRegOtherThread(int regIdx, MiscReg val,
406                           ThreadID tid = InvalidThreadID) M5_ATTR_OVERRIDE
407    {
408        panic("Simple CPU models do not support multithreaded "
409              "register access.");
410    }
411
412#endif
413
414};
415
416#endif // __CPU_EXEC_CONTEXT_HH__
417