exec_context.hh revision 12109:f29e9c5418aa
1/*
2 * Copyright (c) 2014-2016 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/reg_class.hh"
54#include "cpu/simple/base.hh"
55#include "cpu/static_inst_fwd.hh"
56#include "cpu/translation.hh"
57#include "mem/request.hh"
58
59class BaseSimpleCPU;
60
61class SimpleExecContext : public ExecContext {
62  protected:
63    typedef TheISA::MiscReg MiscReg;
64    typedef TheISA::FloatReg FloatReg;
65    typedef TheISA::FloatRegBits FloatRegBits;
66    typedef TheISA::CCReg CCReg;
67    using VecRegContainer = TheISA::VecRegContainer;
68    using VecElem = TheISA::VecElem;
69
70  public:
71    BaseSimpleCPU *cpu;
72    SimpleThread* thread;
73
74    // This is the offset from the current pc that fetch should be performed
75    Addr fetchOffset;
76    // This flag says to stay at the current pc. This is useful for
77    // instructions which go beyond MachInst boundaries.
78    bool stayAtPC;
79
80    // Branch prediction
81    TheISA::PCState predPC;
82
83    /** PER-THREAD STATS */
84
85    // Number of simulated instructions
86    Counter numInst;
87    Stats::Scalar numInsts;
88    Counter numOp;
89    Stats::Scalar numOps;
90
91    // Number of integer alu accesses
92    Stats::Scalar numIntAluAccesses;
93
94    // Number of float alu accesses
95    Stats::Scalar numFpAluAccesses;
96
97    // Number of function calls/returns
98    Stats::Scalar numCallsReturns;
99
100    // Conditional control instructions;
101    Stats::Scalar numCondCtrlInsts;
102
103    // Number of int instructions
104    Stats::Scalar numIntInsts;
105
106    // Number of float instructions
107    Stats::Scalar numFpInsts;
108
109    // Number of integer register file accesses
110    Stats::Scalar numIntRegReads;
111    Stats::Scalar numIntRegWrites;
112
113    // Number of float register file accesses
114    Stats::Scalar numFpRegReads;
115    Stats::Scalar numFpRegWrites;
116
117    // Number of vector register file accesses
118    mutable Stats::Scalar numVecRegReads;
119    Stats::Scalar numVecRegWrites;
120
121    // Number of condition code register file accesses
122    Stats::Scalar numCCRegReads;
123    Stats::Scalar numCCRegWrites;
124
125    // Number of simulated memory references
126    Stats::Scalar numMemRefs;
127    Stats::Scalar numLoadInsts;
128    Stats::Scalar numStoreInsts;
129
130    // Number of idle cycles
131    Stats::Formula numIdleCycles;
132
133    // Number of busy cycles
134    Stats::Formula numBusyCycles;
135
136    // Number of simulated loads
137    Counter numLoad;
138
139    // Number of idle cycles
140    Stats::Average notIdleFraction;
141    Stats::Formula idleFraction;
142
143    // Number of cycles stalled for I-cache responses
144    Stats::Scalar icacheStallCycles;
145    Counter lastIcacheStall;
146
147    // Number of cycles stalled for D-cache responses
148    Stats::Scalar dcacheStallCycles;
149    Counter lastDcacheStall;
150
151    /// @{
152    /// Total number of branches fetched
153    Stats::Scalar numBranches;
154    /// Number of branches predicted as taken
155    Stats::Scalar numPredictedBranches;
156    /// Number of misprediced branches
157    Stats::Scalar numBranchMispred;
158    /// @}
159
160   // Instruction mix histogram by OpClass
161   Stats::Vector statExecutedInstType;
162
163  public:
164    /** Constructor */
165    SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
166        : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
167        numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
168    { }
169
170    /** Reads an integer register. */
171    IntReg readIntRegOperand(const StaticInst *si, int idx) override
172    {
173        numIntRegReads++;
174        const RegId& reg = si->srcRegIdx(idx);
175        assert(reg.isIntReg());
176        return thread->readIntReg(reg.index());
177    }
178
179    /** Sets an integer register to a value. */
180    void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
181    {
182        numIntRegWrites++;
183        const RegId& reg = si->destRegIdx(idx);
184        assert(reg.isIntReg());
185        thread->setIntReg(reg.index(), val);
186    }
187
188    /** Reads a floating point register of single register width. */
189    FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
190    {
191        numFpRegReads++;
192        const RegId& reg = si->srcRegIdx(idx);
193        assert(reg.isFloatReg());
194        return thread->readFloatReg(reg.index());
195    }
196
197    /** Reads a floating point register in its binary format, instead
198     * of by value. */
199    FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override
200    {
201        numFpRegReads++;
202        const RegId& reg = si->srcRegIdx(idx);
203        assert(reg.isFloatReg());
204        return thread->readFloatRegBits(reg.index());
205    }
206
207    /** Sets a floating point register of single width to a value. */
208    void setFloatRegOperand(const StaticInst *si, int idx,
209                            FloatReg val) override
210    {
211        numFpRegWrites++;
212        const RegId& reg = si->destRegIdx(idx);
213        assert(reg.isFloatReg());
214        thread->setFloatReg(reg.index(), val);
215    }
216
217    /** Sets the bits of a floating point register of single width
218     * to a binary value. */
219    void setFloatRegOperandBits(const StaticInst *si, int idx,
220                                FloatRegBits val) override
221    {
222        numFpRegWrites++;
223        const RegId& reg = si->destRegIdx(idx);
224        assert(reg.isFloatReg());
225        thread->setFloatRegBits(reg.index(), val);
226    }
227
228    /** Reads a vector register. */
229    const VecRegContainer&
230    readVecRegOperand(const StaticInst *si, int idx) const override
231    {
232        numVecRegReads++;
233        const RegId& reg = si->srcRegIdx(idx);
234        assert(reg.isVecReg());
235        return thread->readVecReg(reg);
236    }
237
238    /** Reads a vector register for modification. */
239    VecRegContainer&
240    getWritableVecRegOperand(const StaticInst *si, int idx) override
241    {
242        numVecRegWrites++;
243        const RegId& reg = si->destRegIdx(idx);
244        assert(reg.isVecReg());
245        return thread->getWritableVecReg(reg);
246    }
247
248    /** Sets a vector register to a value. */
249    void setVecRegOperand(const StaticInst *si, int idx,
250                          const VecRegContainer& val) override
251    {
252        numVecRegWrites++;
253        const RegId& reg = si->destRegIdx(idx);
254        assert(reg.isVecReg());
255        thread->setVecReg(reg, val);
256    }
257
258    /** Vector Register Lane Interfaces. */
259    /** @{ */
260    /** Reads source vector lane. */
261    template <typename VecElem>
262    VecLaneT<VecElem, true>
263    readVecLaneOperand(const StaticInst *si, int idx) const
264    {
265        numVecRegReads++;
266        const RegId& reg = si->srcRegIdx(idx);
267        assert(reg.isVecReg());
268        return thread->readVecLane<VecElem>(reg);
269    }
270    /** Reads source vector 8bit operand. */
271    virtual ConstVecLane8
272    readVec8BitLaneOperand(const StaticInst *si, int idx) const
273                            override
274    { return readVecLaneOperand<uint8_t>(si, idx); }
275
276    /** Reads source vector 16bit operand. */
277    virtual ConstVecLane16
278    readVec16BitLaneOperand(const StaticInst *si, int idx) const
279                            override
280    { return readVecLaneOperand<uint16_t>(si, idx); }
281
282    /** Reads source vector 32bit operand. */
283    virtual ConstVecLane32
284    readVec32BitLaneOperand(const StaticInst *si, int idx) const
285                            override
286    { return readVecLaneOperand<uint32_t>(si, idx); }
287
288    /** Reads source vector 64bit operand. */
289    virtual ConstVecLane64
290    readVec64BitLaneOperand(const StaticInst *si, int idx) const
291                            override
292    { return readVecLaneOperand<uint64_t>(si, idx); }
293
294    /** Write a lane of the destination vector operand. */
295    template <typename LD>
296    void
297    setVecLaneOperandT(const StaticInst *si, int idx,
298            const LD& val)
299    {
300        numVecRegWrites++;
301        const RegId& reg = si->destRegIdx(idx);
302        assert(reg.isVecReg());
303        return thread->setVecLane(reg, val);
304    }
305    /** Write a lane of the destination vector operand. */
306    virtual void
307    setVecLaneOperand(const StaticInst *si, int idx,
308            const LaneData<LaneSize::Byte>& val) override
309    { return setVecLaneOperandT(si, idx, val); }
310    /** Write a lane of the destination vector operand. */
311    virtual void
312    setVecLaneOperand(const StaticInst *si, int idx,
313            const LaneData<LaneSize::TwoByte>& val) override
314    { return setVecLaneOperandT(si, idx, val); }
315    /** Write a lane of the destination vector operand. */
316    virtual void
317    setVecLaneOperand(const StaticInst *si, int idx,
318            const LaneData<LaneSize::FourByte>& val) override
319    { return setVecLaneOperandT(si, idx, val); }
320    /** Write a lane of the destination vector operand. */
321    virtual void
322    setVecLaneOperand(const StaticInst *si, int idx,
323            const LaneData<LaneSize::EightByte>& val) override
324    { return setVecLaneOperandT(si, idx, val); }
325    /** @} */
326
327    /** Reads an element of a vector register. */
328    VecElem readVecElemOperand(const StaticInst *si, int idx) const override
329    {
330        numVecRegReads++;
331        const RegId& reg = si->destRegIdx(idx);
332        assert(reg.isVecElem());
333        return thread->readVecElem(reg);
334    }
335
336    /** Sets an element of a vector register to a value. */
337    void setVecElemOperand(const StaticInst *si, int idx,
338                           const VecElem val) override
339    {
340        numVecRegWrites++;
341        const RegId& reg = si->destRegIdx(idx);
342        assert(reg.isVecElem());
343        thread->setVecElem(reg, val);
344    }
345
346    CCReg readCCRegOperand(const StaticInst *si, int idx) override
347    {
348        numCCRegReads++;
349        const RegId& reg = si->srcRegIdx(idx);
350        assert(reg.isCCReg());
351        return thread->readCCReg(reg.index());
352    }
353
354    void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
355    {
356        numCCRegWrites++;
357        const RegId& reg = si->destRegIdx(idx);
358        assert(reg.isCCReg());
359        thread->setCCReg(reg.index(), val);
360    }
361
362    MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
363    {
364        numIntRegReads++;
365        const RegId& reg = si->srcRegIdx(idx);
366        assert(reg.isMiscReg());
367        return thread->readMiscReg(reg.index());
368    }
369
370    void setMiscRegOperand(const StaticInst *si, int idx,
371                           const MiscReg &val) override
372    {
373        numIntRegWrites++;
374        const RegId& reg = si->destRegIdx(idx);
375        assert(reg.isMiscReg());
376        thread->setMiscReg(reg.index(), val);
377    }
378
379    /**
380     * Reads a miscellaneous register, handling any architectural
381     * side effects due to reading that register.
382     */
383    MiscReg readMiscReg(int misc_reg) override
384    {
385        numIntRegReads++;
386        return thread->readMiscReg(misc_reg);
387    }
388
389    /**
390     * Sets a miscellaneous register, handling any architectural
391     * side effects due to writing that register.
392     */
393    void setMiscReg(int misc_reg, const MiscReg &val) override
394    {
395        numIntRegWrites++;
396        thread->setMiscReg(misc_reg, val);
397    }
398
399    PCState pcState() const override
400    {
401        return thread->pcState();
402    }
403
404    void pcState(const PCState &val) override
405    {
406        thread->pcState(val);
407    }
408
409
410    /**
411     * Record the effective address of the instruction.
412     *
413     * @note Only valid for memory ops.
414     */
415    void setEA(Addr EA) override
416    { panic("BaseSimpleCPU::setEA() not implemented\n"); }
417
418    /**
419     * Get the effective address of the instruction.
420     *
421     * @note Only valid for memory ops.
422     */
423    Addr getEA() const override
424    { panic("BaseSimpleCPU::getEA() not implemented\n"); }
425
426    Fault readMem(Addr addr, uint8_t *data, unsigned int size,
427                  Request::Flags flags) override
428    {
429        return cpu->readMem(addr, data, size, flags);
430    }
431
432    Fault initiateMemRead(Addr addr, unsigned int size,
433                          Request::Flags flags) override
434    {
435        return cpu->initiateMemRead(addr, size, flags);
436    }
437
438    Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
439                   Request::Flags flags, uint64_t *res) override
440    {
441        return cpu->writeMem(data, size, addr, flags, res);
442    }
443
444    /**
445     * Sets the number of consecutive store conditional failures.
446     */
447    void setStCondFailures(unsigned int sc_failures) override
448    {
449        thread->setStCondFailures(sc_failures);
450    }
451
452    /**
453     * Returns the number of consecutive store conditional failures.
454     */
455    unsigned int readStCondFailures() const override
456    {
457        return thread->readStCondFailures();
458    }
459
460    /**
461     * Executes a syscall specified by the callnum.
462     */
463    void syscall(int64_t callnum, Fault *fault) override
464    {
465        if (FullSystem)
466            panic("Syscall emulation isn't available in FS mode.");
467
468        thread->syscall(callnum, fault);
469    }
470
471    /** Returns a pointer to the ThreadContext. */
472    ThreadContext *tcBase() override
473    {
474        return thread->getTC();
475    }
476
477    /**
478     * Somewhat Alpha-specific function that handles returning from an
479     * error or interrupt.
480     */
481    Fault hwrei() override
482    {
483        return thread->hwrei();
484    }
485
486    /**
487     * Check for special simulator handling of specific PAL calls.  If
488     * return value is false, actual PAL call will be suppressed.
489     */
490    bool simPalCheck(int palFunc) override
491    {
492        return thread->simPalCheck(palFunc);
493    }
494
495    bool readPredicate() override
496    {
497        return thread->readPredicate();
498    }
499
500    void setPredicate(bool val) override
501    {
502        thread->setPredicate(val);
503
504        if (cpu->traceData) {
505            cpu->traceData->setPredicate(val);
506        }
507    }
508
509    /**
510     * Invalidate a page in the DTLB <i>and</i> ITLB.
511     */
512    void demapPage(Addr vaddr, uint64_t asn) override
513    {
514        thread->demapPage(vaddr, asn);
515    }
516
517    void armMonitor(Addr address) override
518    {
519        cpu->armMonitor(thread->threadId(), address);
520    }
521
522    bool mwait(PacketPtr pkt) override
523    {
524        return cpu->mwait(thread->threadId(), pkt);
525    }
526
527    void mwaitAtomic(ThreadContext *tc) override
528    {
529        cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
530    }
531
532    AddressMonitor *getAddrMonitor() override
533    {
534        return cpu->getCpuAddrMonitor(thread->threadId());
535    }
536
537#if THE_ISA == MIPS_ISA
538    MiscReg readRegOtherThread(const RegId& reg,
539                               ThreadID tid = InvalidThreadID)
540        override
541    {
542        panic("Simple CPU models do not support multithreaded "
543              "register access.");
544    }
545
546    void setRegOtherThread(const RegId& reg, MiscReg val,
547                           ThreadID tid = InvalidThreadID) override
548    {
549        panic("Simple CPU models do not support multithreaded "
550              "register access.");
551    }
552
553#endif
554
555};
556
557#endif // __CPU_EXEC_CONTEXT_HH__
558