exec_context.hh revision 11168:f98eb2da15a4
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) 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) override
171    {
172        numIntRegWrites++;
173        thread->setIntReg(si->destRegIdx(idx), val);
174    }
175
176    /** Reads a floating point register of single register width. */
177    FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
178    {
179        numFpRegReads++;
180        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
181        return thread->readFloatReg(reg_idx);
182    }
183
184    /** Reads a floating point register in its binary format, instead
185     * of by value. */
186    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override
187    {
188        numFpRegReads++;
189        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
190        return thread->readFloatRegBits(reg_idx);
191    }
192
193    /** Sets a floating point register of single width to a value. */
194    void setFloatRegOperand(const StaticInst *si, int idx,
195                            FloatReg val) override
196    {
197        numFpRegWrites++;
198        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
199        thread->setFloatReg(reg_idx, val);
200    }
201
202    /** Sets the bits of a floating point register of single width
203     * to a binary value. */
204    void setFloatRegOperandBits(const StaticInst *si, int idx,
205                                FloatRegBits val) override
206    {
207        numFpRegWrites++;
208        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
209        thread->setFloatRegBits(reg_idx, val);
210    }
211
212    CCReg readCCRegOperand(const StaticInst *si, int idx) override
213    {
214        numCCRegReads++;
215        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
216        return thread->readCCReg(reg_idx);
217    }
218
219    void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
220    {
221        numCCRegWrites++;
222        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
223        thread->setCCReg(reg_idx, val);
224    }
225
226    MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
227    {
228        numIntRegReads++;
229        int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
230        return thread->readMiscReg(reg_idx);
231    }
232
233    void setMiscRegOperand(const StaticInst *si, int idx,
234                           const MiscReg &val) override
235    {
236        numIntRegWrites++;
237        int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
238        thread->setMiscReg(reg_idx, val);
239    }
240
241    /**
242     * Reads a miscellaneous register, handling any architectural
243     * side effects due to reading that register.
244     */
245    MiscReg readMiscReg(int misc_reg) override
246    {
247        numIntRegReads++;
248        return thread->readMiscReg(misc_reg);
249    }
250
251    /**
252     * Sets a miscellaneous register, handling any architectural
253     * side effects due to writing that register.
254     */
255    void setMiscReg(int misc_reg, const MiscReg &val) override
256    {
257        numIntRegWrites++;
258        thread->setMiscReg(misc_reg, val);
259    }
260
261    PCState pcState() const override
262    {
263        return thread->pcState();
264    }
265
266    void pcState(const PCState &val) override
267    {
268        thread->pcState(val);
269    }
270
271
272    /**
273     * Record the effective address of the instruction.
274     *
275     * @note Only valid for memory ops.
276     */
277    void setEA(Addr EA) override
278    { panic("BaseSimpleCPU::setEA() not implemented\n"); }
279
280    /**
281     * Get the effective address of the instruction.
282     *
283     * @note Only valid for memory ops.
284     */
285    Addr getEA() const override
286    { panic("BaseSimpleCPU::getEA() not implemented\n"); }
287
288    Fault readMem(Addr addr, uint8_t *data, unsigned int size,
289                  unsigned int flags) override
290    {
291        return cpu->readMem(addr, data, size, flags);
292    }
293
294    Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
295                   unsigned int flags, uint64_t *res) override
296    {
297        return cpu->writeMem(data, size, addr, flags, res);
298    }
299
300    /**
301     * Sets the number of consecutive store conditional failures.
302     */
303    void setStCondFailures(unsigned int sc_failures) override
304    {
305        thread->setStCondFailures(sc_failures);
306    }
307
308    /**
309     * Returns the number of consecutive store conditional failures.
310     */
311    unsigned int readStCondFailures() const override
312    {
313        return thread->readStCondFailures();
314    }
315
316    /**
317     * Executes a syscall specified by the callnum.
318     */
319    void syscall(int64_t callnum) override
320    {
321        if (FullSystem)
322            panic("Syscall emulation isn't available in FS mode.");
323
324        thread->syscall(callnum);
325    }
326
327    /** Returns a pointer to the ThreadContext. */
328    ThreadContext *tcBase() override
329    {
330        return thread->getTC();
331    }
332
333    /**
334     * Somewhat Alpha-specific function that handles returning from an
335     * error or interrupt.
336     */
337    Fault hwrei() override
338    {
339        return thread->hwrei();
340    }
341
342    /**
343     * Check for special simulator handling of specific PAL calls.  If
344     * return value is false, actual PAL call will be suppressed.
345     */
346    bool simPalCheck(int palFunc) override
347    {
348        return thread->simPalCheck(palFunc);
349    }
350
351    bool readPredicate() override
352    {
353        return thread->readPredicate();
354    }
355
356    void setPredicate(bool val) override
357    {
358        thread->setPredicate(val);
359
360        if (cpu->traceData) {
361            cpu->traceData->setPredicate(val);
362        }
363    }
364
365    /**
366     * Invalidate a page in the DTLB <i>and</i> ITLB.
367     */
368    void demapPage(Addr vaddr, uint64_t asn) override
369    {
370        thread->demapPage(vaddr, asn);
371    }
372
373    void armMonitor(Addr address) override
374    {
375        cpu->armMonitor(thread->threadId(), address);
376    }
377
378    bool mwait(PacketPtr pkt) override
379    {
380        return cpu->mwait(thread->threadId(), pkt);
381    }
382
383    void mwaitAtomic(ThreadContext *tc) override
384    {
385        cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
386    }
387
388    AddressMonitor *getAddrMonitor() override
389    {
390        return cpu->getCpuAddrMonitor(thread->threadId());
391    }
392
393#if THE_ISA == MIPS_ISA
394    MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
395        override
396    {
397        panic("Simple CPU models do not support multithreaded "
398              "register access.");
399    }
400
401    void setRegOtherThread(int regIdx, MiscReg val,
402                           ThreadID tid = InvalidThreadID) override
403    {
404        panic("Simple CPU models do not support multithreaded "
405              "register access.");
406    }
407
408#endif
409
410};
411
412#endif // __CPU_EXEC_CONTEXT_HH__
413