exec_context.hh revision 11303:f694764d656d
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 initiateMemRead(Addr addr, unsigned int size,
295                          unsigned int flags) override
296    {
297        return cpu->initiateMemRead(addr, size, flags);
298    }
299
300    Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
301                   unsigned int flags, uint64_t *res) override
302    {
303        return cpu->writeMem(data, size, addr, flags, res);
304    }
305
306    /**
307     * Sets the number of consecutive store conditional failures.
308     */
309    void setStCondFailures(unsigned int sc_failures) override
310    {
311        thread->setStCondFailures(sc_failures);
312    }
313
314    /**
315     * Returns the number of consecutive store conditional failures.
316     */
317    unsigned int readStCondFailures() const override
318    {
319        return thread->readStCondFailures();
320    }
321
322    /**
323     * Executes a syscall specified by the callnum.
324     */
325    void syscall(int64_t callnum) override
326    {
327        if (FullSystem)
328            panic("Syscall emulation isn't available in FS mode.");
329
330        thread->syscall(callnum);
331    }
332
333    /** Returns a pointer to the ThreadContext. */
334    ThreadContext *tcBase() override
335    {
336        return thread->getTC();
337    }
338
339    /**
340     * Somewhat Alpha-specific function that handles returning from an
341     * error or interrupt.
342     */
343    Fault hwrei() override
344    {
345        return thread->hwrei();
346    }
347
348    /**
349     * Check for special simulator handling of specific PAL calls.  If
350     * return value is false, actual PAL call will be suppressed.
351     */
352    bool simPalCheck(int palFunc) override
353    {
354        return thread->simPalCheck(palFunc);
355    }
356
357    bool readPredicate() override
358    {
359        return thread->readPredicate();
360    }
361
362    void setPredicate(bool val) override
363    {
364        thread->setPredicate(val);
365
366        if (cpu->traceData) {
367            cpu->traceData->setPredicate(val);
368        }
369    }
370
371    /**
372     * Invalidate a page in the DTLB <i>and</i> ITLB.
373     */
374    void demapPage(Addr vaddr, uint64_t asn) override
375    {
376        thread->demapPage(vaddr, asn);
377    }
378
379    void armMonitor(Addr address) override
380    {
381        cpu->armMonitor(thread->threadId(), address);
382    }
383
384    bool mwait(PacketPtr pkt) override
385    {
386        return cpu->mwait(thread->threadId(), pkt);
387    }
388
389    void mwaitAtomic(ThreadContext *tc) override
390    {
391        cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
392    }
393
394    AddressMonitor *getAddrMonitor() override
395    {
396        return cpu->getCpuAddrMonitor(thread->threadId());
397    }
398
399#if THE_ISA == MIPS_ISA
400    MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
401        override
402    {
403        panic("Simple CPU models do not support multithreaded "
404              "register access.");
405    }
406
407    void setRegOtherThread(int regIdx, MiscReg val,
408                           ThreadID tid = InvalidThreadID) override
409    {
410        panic("Simple CPU models do not support multithreaded "
411              "register access.");
412    }
413
414#endif
415
416};
417
418#endif // __CPU_EXEC_CONTEXT_HH__
419