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