exec_context.hh revision 13611
15222Sksewell@umich.edu/*
25268Sksewell@umich.edu * Copyright (c) 2014-2017 ARM Limited
35254Sksewell@umich.edu * All rights reserved
45254Sksewell@umich.edu *
55222Sksewell@umich.edu * The license below extends only to copyright in the software and shall
65254Sksewell@umich.edu * not be construed as granting a license to any other intellectual
75254Sksewell@umich.edu * property including but not limited to intellectual property relating
85254Sksewell@umich.edu * to a hardware implementation of the functionality of the software
95254Sksewell@umich.edu * licensed hereunder.  You may use the software subject to the license
105254Sksewell@umich.edu * terms below provided that you ensure that this notice is replicated
115254Sksewell@umich.edu * unmodified and in its entirety in all distributions of the software,
125254Sksewell@umich.edu * modified or unmodified, in source code or in binary form.
135254Sksewell@umich.edu *
145254Sksewell@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
155254Sksewell@umich.edu * All rights reserved.
165222Sksewell@umich.edu *
175254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
185254Sksewell@umich.edu * modification, are permitted provided that the following conditions are
195254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
205254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
215254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
225254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
235254Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
245254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
255254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
265254Sksewell@umich.edu * this software without specific prior written permission.
275254Sksewell@umich.edu *
285222Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
295268Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
305268Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
315268Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
325222Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
335222Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
345222Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
355222Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
365222Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3712334Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
388763Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
398763Sgblack@eecs.umich.edu *
405222Sksewell@umich.edu * Authors: Kevin Lim
415222Sksewell@umich.edu *          Andreas Sandberg
425222Sksewell@umich.edu *          Mitch Hayenga
436378Sgblack@eecs.umich.edu */
446378Sgblack@eecs.umich.edu
456378Sgblack@eecs.umich.edu#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
465222Sksewell@umich.edu#define __CPU_SIMPLE_EXEC_CONTEXT_HH__
476378Sgblack@eecs.umich.edu
486378Sgblack@eecs.umich.edu#include "arch/registers.hh"
496378Sgblack@eecs.umich.edu#include "base/types.hh"
506378Sgblack@eecs.umich.edu#include "config/the_isa.hh"
516378Sgblack@eecs.umich.edu#include "cpu/base.hh"
526378Sgblack@eecs.umich.edu#include "cpu/exec_context.hh"
535222Sksewell@umich.edu#include "cpu/reg_class.hh"
546378Sgblack@eecs.umich.edu#include "cpu/simple/base.hh"
555222Sksewell@umich.edu#include "cpu/static_inst_fwd.hh"
566378Sgblack@eecs.umich.edu#include "cpu/translation.hh"
576378Sgblack@eecs.umich.edu#include "mem/request.hh"
586378Sgblack@eecs.umich.edu
596378Sgblack@eecs.umich.educlass BaseSimpleCPU;
606378Sgblack@eecs.umich.edu
615222Sksewell@umich.educlass SimpleExecContext : public ExecContext {
626378Sgblack@eecs.umich.edu  protected:
636378Sgblack@eecs.umich.edu    typedef TheISA::CCReg CCReg;
646378Sgblack@eecs.umich.edu    using VecRegContainer = TheISA::VecRegContainer;
656378Sgblack@eecs.umich.edu    using VecElem = TheISA::VecElem;
666378Sgblack@eecs.umich.edu
675222Sksewell@umich.edu  public:
6811320Ssteve.reinhardt@amd.com    BaseSimpleCPU *cpu;
696378Sgblack@eecs.umich.edu    SimpleThread* thread;
706378Sgblack@eecs.umich.edu
716378Sgblack@eecs.umich.edu    // This is the offset from the current pc that fetch should be performed
726378Sgblack@eecs.umich.edu    Addr fetchOffset;
736378Sgblack@eecs.umich.edu    // This flag says to stay at the current pc. This is useful for
746378Sgblack@eecs.umich.edu    // instructions which go beyond MachInst boundaries.
755222Sksewell@umich.edu    bool stayAtPC;
766378Sgblack@eecs.umich.edu
7710905Sandreas.sandberg@arm.com    // Branch prediction
7810905Sandreas.sandberg@arm.com    TheISA::PCState predPC;
796378Sgblack@eecs.umich.edu
805222Sksewell@umich.edu    /** PER-THREAD STATS */
818763Sgblack@eecs.umich.edu
828763Sgblack@eecs.umich.edu    // Number of simulated instructions
838763Sgblack@eecs.umich.edu    Counter numInst;
848763Sgblack@eecs.umich.edu    Stats::Scalar numInsts;
858763Sgblack@eecs.umich.edu    Counter numOp;
8610558Salexandru.dutu@amd.com    Stats::Scalar numOps;
8710558Salexandru.dutu@amd.com
8810558Salexandru.dutu@amd.com    // Number of integer alu accesses
8910558Salexandru.dutu@amd.com    Stats::Scalar numIntAluAccesses;
9010558Salexandru.dutu@amd.com
9110558Salexandru.dutu@amd.com    // Number of float alu accesses
9210558Salexandru.dutu@amd.com    Stats::Scalar numFpAluAccesses;
9310558Salexandru.dutu@amd.com
948763Sgblack@eecs.umich.edu    // Number of vector alu accesses
958763Sgblack@eecs.umich.edu    Stats::Scalar numVecAluAccesses;
968763Sgblack@eecs.umich.edu
978763Sgblack@eecs.umich.edu    // Number of function calls/returns
988763Sgblack@eecs.umich.edu    Stats::Scalar numCallsReturns;
998763Sgblack@eecs.umich.edu
1008763Sgblack@eecs.umich.edu    // Conditional control instructions;
1018763Sgblack@eecs.umich.edu    Stats::Scalar numCondCtrlInsts;
1028763Sgblack@eecs.umich.edu
10310905Sandreas.sandberg@arm.com    // Number of int instructions
1048763Sgblack@eecs.umich.edu    Stats::Scalar numIntInsts;
1058763Sgblack@eecs.umich.edu
1068763Sgblack@eecs.umich.edu    // Number of float instructions
1078763Sgblack@eecs.umich.edu    Stats::Scalar numFpInsts;
10810905Sandreas.sandberg@arm.com
1098763Sgblack@eecs.umich.edu    // Number of vector instructions
1108763Sgblack@eecs.umich.edu    Stats::Scalar numVecInsts;
1118763Sgblack@eecs.umich.edu
1128763Sgblack@eecs.umich.edu    // Number of integer register file accesses
1138763Sgblack@eecs.umich.edu    Stats::Scalar numIntRegReads;
1148763Sgblack@eecs.umich.edu    Stats::Scalar numIntRegWrites;
1155222Sksewell@umich.edu
1165222Sksewell@umich.edu    // Number of float register file accesses
1175222Sksewell@umich.edu    Stats::Scalar numFpRegReads;
118    Stats::Scalar numFpRegWrites;
119
120    // Number of vector register file accesses
121    mutable Stats::Scalar numVecRegReads;
122    Stats::Scalar numVecRegWrites;
123
124    // Number of predicate register file accesses
125    mutable Stats::Scalar numVecPredRegReads;
126    Stats::Scalar numVecPredRegWrites;
127
128    // Number of condition code register file accesses
129    Stats::Scalar numCCRegReads;
130    Stats::Scalar numCCRegWrites;
131
132    // Number of simulated memory references
133    Stats::Scalar numMemRefs;
134    Stats::Scalar numLoadInsts;
135    Stats::Scalar numStoreInsts;
136
137    // Number of idle cycles
138    Stats::Formula numIdleCycles;
139
140    // Number of busy cycles
141    Stats::Formula numBusyCycles;
142
143    // Number of simulated loads
144    Counter numLoad;
145
146    // Number of idle cycles
147    Stats::Average notIdleFraction;
148    Stats::Formula idleFraction;
149
150    // Number of cycles stalled for I-cache responses
151    Stats::Scalar icacheStallCycles;
152    Counter lastIcacheStall;
153
154    // Number of cycles stalled for D-cache responses
155    Stats::Scalar dcacheStallCycles;
156    Counter lastDcacheStall;
157
158    /// @{
159    /// Total number of branches fetched
160    Stats::Scalar numBranches;
161    /// Number of branches predicted as taken
162    Stats::Scalar numPredictedBranches;
163    /// Number of misprediced branches
164    Stats::Scalar numBranchMispred;
165    /// @}
166
167   // Instruction mix histogram by OpClass
168   Stats::Vector statExecutedInstType;
169
170  public:
171    /** Constructor */
172    SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
173        : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
174        numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
175    { }
176
177    /** Reads an integer register. */
178    RegVal
179    readIntRegOperand(const StaticInst *si, int idx) override
180    {
181        numIntRegReads++;
182        const RegId& reg = si->srcRegIdx(idx);
183        assert(reg.isIntReg());
184        return thread->readIntReg(reg.index());
185    }
186
187    /** Sets an integer register to a value. */
188    void
189    setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
190    {
191        numIntRegWrites++;
192        const RegId& reg = si->destRegIdx(idx);
193        assert(reg.isIntReg());
194        thread->setIntReg(reg.index(), val);
195    }
196
197    /** Reads a floating point register in its binary format, instead
198     * of by value. */
199    RegVal
200    readFloatRegOperandBits(const StaticInst *si, int idx) override
201    {
202        numFpRegReads++;
203        const RegId& reg = si->srcRegIdx(idx);
204        assert(reg.isFloatReg());
205        return thread->readFloatReg(reg.index());
206    }
207
208    /** Sets the bits of a floating point register of single width
209     * to a binary value. */
210    void
211    setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
212    {
213        numFpRegWrites++;
214        const RegId& reg = si->destRegIdx(idx);
215        assert(reg.isFloatReg());
216        thread->setFloatReg(reg.index(), val);
217    }
218
219    /** Reads a vector register. */
220    const VecRegContainer &
221    readVecRegOperand(const StaticInst *si, int idx) const override
222    {
223        numVecRegReads++;
224        const RegId& reg = si->srcRegIdx(idx);
225        assert(reg.isVecReg());
226        return thread->readVecReg(reg);
227    }
228
229    /** Reads a vector register for modification. */
230    VecRegContainer &
231    getWritableVecRegOperand(const StaticInst *si, int idx) override
232    {
233        numVecRegWrites++;
234        const RegId& reg = si->destRegIdx(idx);
235        assert(reg.isVecReg());
236        return thread->getWritableVecReg(reg);
237    }
238
239    /** Sets a vector register to a value. */
240    void
241    setVecRegOperand(const StaticInst *si, int idx,
242                     const VecRegContainer& val) override
243    {
244        numVecRegWrites++;
245        const RegId& reg = si->destRegIdx(idx);
246        assert(reg.isVecReg());
247        thread->setVecReg(reg, val);
248    }
249
250    /** Vector Register Lane Interfaces. */
251    /** @{ */
252    /** Reads source vector lane. */
253    template <typename VecElem>
254    VecLaneT<VecElem, true>
255    readVecLaneOperand(const StaticInst *si, int idx) const
256    {
257        numVecRegReads++;
258        const RegId& reg = si->srcRegIdx(idx);
259        assert(reg.isVecReg());
260        return thread->readVecLane<VecElem>(reg);
261    }
262    /** Reads source vector 8bit operand. */
263    virtual ConstVecLane8
264    readVec8BitLaneOperand(const StaticInst *si, int idx) const
265                            override
266    { return readVecLaneOperand<uint8_t>(si, idx); }
267
268    /** Reads source vector 16bit operand. */
269    virtual ConstVecLane16
270    readVec16BitLaneOperand(const StaticInst *si, int idx) const
271                            override
272    { return readVecLaneOperand<uint16_t>(si, idx); }
273
274    /** Reads source vector 32bit operand. */
275    virtual ConstVecLane32
276    readVec32BitLaneOperand(const StaticInst *si, int idx) const
277                            override
278    { return readVecLaneOperand<uint32_t>(si, idx); }
279
280    /** Reads source vector 64bit operand. */
281    virtual ConstVecLane64
282    readVec64BitLaneOperand(const StaticInst *si, int idx) const
283                            override
284    { return readVecLaneOperand<uint64_t>(si, idx); }
285
286    /** Write a lane of the destination vector operand. */
287    template <typename LD>
288    void
289    setVecLaneOperandT(const StaticInst *si, int idx,
290            const LD& val)
291    {
292        numVecRegWrites++;
293        const RegId& reg = si->destRegIdx(idx);
294        assert(reg.isVecReg());
295        return thread->setVecLane(reg, val);
296    }
297    /** Write a lane of the destination vector operand. */
298    virtual void
299    setVecLaneOperand(const StaticInst *si, int idx,
300            const LaneData<LaneSize::Byte>& val) override
301    { return setVecLaneOperandT(si, idx, val); }
302    /** Write a lane of the destination vector operand. */
303    virtual void
304    setVecLaneOperand(const StaticInst *si, int idx,
305            const LaneData<LaneSize::TwoByte>& val) override
306    { return setVecLaneOperandT(si, idx, val); }
307    /** Write a lane of the destination vector operand. */
308    virtual void
309    setVecLaneOperand(const StaticInst *si, int idx,
310            const LaneData<LaneSize::FourByte>& val) override
311    { return setVecLaneOperandT(si, idx, val); }
312    /** Write a lane of the destination vector operand. */
313    virtual void
314    setVecLaneOperand(const StaticInst *si, int idx,
315            const LaneData<LaneSize::EightByte>& val) override
316    { return setVecLaneOperandT(si, idx, val); }
317    /** @} */
318
319    /** Reads an element of a vector register. */
320    VecElem
321    readVecElemOperand(const StaticInst *si, int idx) const override
322    {
323        numVecRegReads++;
324        const RegId& reg = si->srcRegIdx(idx);
325        assert(reg.isVecElem());
326        return thread->readVecElem(reg);
327    }
328
329    /** Sets an element of a vector register to a value. */
330    void
331    setVecElemOperand(const StaticInst *si, int idx,
332                      const VecElem val) override
333    {
334        numVecRegWrites++;
335        const RegId& reg = si->destRegIdx(idx);
336        assert(reg.isVecElem());
337        thread->setVecElem(reg, val);
338    }
339
340    const VecPredRegContainer&
341    readVecPredRegOperand(const StaticInst *si, int idx) const override
342    {
343        numVecPredRegReads++;
344        const RegId& reg = si->srcRegIdx(idx);
345        assert(reg.isVecPredReg());
346        return thread->readVecPredReg(reg);
347    }
348
349    VecPredRegContainer&
350    getWritableVecPredRegOperand(const StaticInst *si, int idx) override
351    {
352        numVecPredRegWrites++;
353        const RegId& reg = si->destRegIdx(idx);
354        assert(reg.isVecPredReg());
355        return thread->getWritableVecPredReg(reg);
356    }
357
358    void
359    setVecPredRegOperand(const StaticInst *si, int idx,
360                         const VecPredRegContainer& val) override
361    {
362        numVecPredRegWrites++;
363        const RegId& reg = si->destRegIdx(idx);
364        assert(reg.isVecPredReg());
365        thread->setVecPredReg(reg, val);
366    }
367
368    CCReg
369    readCCRegOperand(const StaticInst *si, int idx) override
370    {
371        numCCRegReads++;
372        const RegId& reg = si->srcRegIdx(idx);
373        assert(reg.isCCReg());
374        return thread->readCCReg(reg.index());
375    }
376
377    void
378    setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
379    {
380        numCCRegWrites++;
381        const RegId& reg = si->destRegIdx(idx);
382        assert(reg.isCCReg());
383        thread->setCCReg(reg.index(), val);
384    }
385
386    RegVal
387    readMiscRegOperand(const StaticInst *si, int idx) override
388    {
389        numIntRegReads++;
390        const RegId& reg = si->srcRegIdx(idx);
391        assert(reg.isMiscReg());
392        return thread->readMiscReg(reg.index());
393    }
394
395    void
396    setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
397    {
398        numIntRegWrites++;
399        const RegId& reg = si->destRegIdx(idx);
400        assert(reg.isMiscReg());
401        thread->setMiscReg(reg.index(), val);
402    }
403
404    /**
405     * Reads a miscellaneous register, handling any architectural
406     * side effects due to reading that register.
407     */
408    RegVal
409    readMiscReg(int misc_reg) override
410    {
411        numIntRegReads++;
412        return thread->readMiscReg(misc_reg);
413    }
414
415    /**
416     * Sets a miscellaneous register, handling any architectural
417     * side effects due to writing that register.
418     */
419    void
420    setMiscReg(int misc_reg, RegVal val) override
421    {
422        numIntRegWrites++;
423        thread->setMiscReg(misc_reg, val);
424    }
425
426    PCState
427    pcState() const override
428    {
429        return thread->pcState();
430    }
431
432    void
433    pcState(const PCState &val) override
434    {
435        thread->pcState(val);
436    }
437
438
439    Fault
440    readMem(Addr addr, uint8_t *data, unsigned int size,
441            Request::Flags flags) override
442    {
443        return cpu->readMem(addr, data, size, flags);
444    }
445
446    Fault
447    initiateMemRead(Addr addr, unsigned int size,
448                    Request::Flags flags) override
449    {
450        return cpu->initiateMemRead(addr, size, flags);
451    }
452
453    Fault
454    writeMem(uint8_t *data, unsigned int size, Addr addr,
455             Request::Flags flags, uint64_t *res) override
456    {
457        return cpu->writeMem(data, size, addr, flags, res);
458    }
459
460    /**
461     * Sets the number of consecutive store conditional failures.
462     */
463    void
464    setStCondFailures(unsigned int sc_failures) override
465    {
466        thread->setStCondFailures(sc_failures);
467    }
468
469    /**
470     * Returns the number of consecutive store conditional failures.
471     */
472    unsigned int
473    readStCondFailures() const override
474    {
475        return thread->readStCondFailures();
476    }
477
478    /**
479     * Executes a syscall specified by the callnum.
480     */
481    void
482    syscall(int64_t callnum, Fault *fault) override
483    {
484        if (FullSystem)
485            panic("Syscall emulation isn't available in FS mode.");
486
487        thread->syscall(callnum, fault);
488    }
489
490    /** Returns a pointer to the ThreadContext. */
491    ThreadContext *tcBase() override { return thread->getTC(); }
492
493    /**
494     * Somewhat Alpha-specific function that handles returning from an
495     * error or interrupt.
496     */
497    Fault hwrei() override { return thread->hwrei(); }
498
499    /**
500     * Check for special simulator handling of specific PAL calls.  If
501     * return value is false, actual PAL call will be suppressed.
502     */
503    bool
504    simPalCheck(int palFunc) override
505    {
506        return thread->simPalCheck(palFunc);
507    }
508
509    bool
510    readPredicate() const override
511    {
512        return thread->readPredicate();
513    }
514
515    void
516    setPredicate(bool val) override
517    {
518        thread->setPredicate(val);
519
520        if (cpu->traceData) {
521            cpu->traceData->setPredicate(val);
522        }
523    }
524
525    /**
526     * Invalidate a page in the DTLB <i>and</i> ITLB.
527     */
528    void
529    demapPage(Addr vaddr, uint64_t asn) override
530    {
531        thread->demapPage(vaddr, asn);
532    }
533
534    void
535    armMonitor(Addr address) override
536    {
537        cpu->armMonitor(thread->threadId(), address);
538    }
539
540    bool
541    mwait(PacketPtr pkt) override
542    {
543        return cpu->mwait(thread->threadId(), pkt);
544    }
545
546    void
547    mwaitAtomic(ThreadContext *tc) override
548    {
549        cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
550    }
551
552    AddressMonitor *
553    getAddrMonitor() override
554    {
555        return cpu->getCpuAddrMonitor(thread->threadId());
556    }
557
558#if THE_ISA == MIPS_ISA
559    RegVal
560    readRegOtherThread(const RegId& reg, ThreadID tid=InvalidThreadID)
561        override
562    {
563        panic("Simple CPU models do not support multithreaded "
564              "register access.");
565    }
566
567    void
568    setRegOtherThread(const RegId& reg, RegVal val,
569                      ThreadID tid=InvalidThreadID) override
570    {
571        panic("Simple CPU models do not support multithreaded "
572              "register access.");
573    }
574#endif
575
576};
577
578#endif // __CPU_EXEC_CONTEXT_HH__
579