exec_context.hh revision 13611
12SN/A/*
210292SAndreas.Sandberg@ARM.com * Copyright (c) 2014-2017 ARM Limited
310292SAndreas.Sandberg@ARM.com * All rights reserved
410292SAndreas.Sandberg@ARM.com *
510292SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall
610292SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual
710292SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating
810292SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software
910292SAndreas.Sandberg@ARM.com * licensed hereunder.  You may use the software subject to the license
1010292SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated
1110292SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software,
1210292SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form.
1310292SAndreas.Sandberg@ARM.com *
144039Sbinkertn@umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
152SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272SN/A *
282SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402665Ssaidi@eecs.umich.edu * Authors: Kevin Lim
412665Ssaidi@eecs.umich.edu *          Andreas Sandberg
422SN/A *          Mitch Hayenga
432SN/A */
441354SN/A
451354SN/A#ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
462SN/A#define __CPU_SIMPLE_EXEC_CONTEXT_HH__
474046Sbinkertn@umich.edu
482SN/A#include "arch/registers.hh"
4956SN/A#include "base/types.hh"
508232Snate@binkert.org#include "config/the_isa.hh"
511031SN/A#include "cpu/base.hh"
526214Snate@binkert.org#include "cpu/exec_context.hh"
534167Sbinkertn@umich.edu#include "cpu/reg_class.hh"
542SN/A#include "cpu/simple/base.hh"
552SN/A#include "cpu/static_inst_fwd.hh"
562SN/A#include "cpu/translation.hh"
578232Snate@binkert.org#include "mem/request.hh"
588232Snate@binkert.org
598232Snate@binkert.orgclass BaseSimpleCPU;
604046Sbinkertn@umich.edu
614046Sbinkertn@umich.educlass SimpleExecContext : public ExecContext {
622SN/A  protected:
634046Sbinkertn@umich.edu    typedef TheISA::CCReg CCReg;
644046Sbinkertn@umich.edu    using VecRegContainer = TheISA::VecRegContainer;
654046Sbinkertn@umich.edu    using VecElem = TheISA::VecElem;
662SN/A
674046Sbinkertn@umich.edu  public:
684046Sbinkertn@umich.edu    BaseSimpleCPU *cpu;
692SN/A    SimpleThread* thread;
7010292SAndreas.Sandberg@ARM.com
7110292SAndreas.Sandberg@ARM.com    // This is the offset from the current pc that fetch should be performed
7210292SAndreas.Sandberg@ARM.com    Addr fetchOffset;
7310292SAndreas.Sandberg@ARM.com    // This flag says to stay at the current pc. This is useful for
7410292SAndreas.Sandberg@ARM.com    // instructions which go beyond MachInst boundaries.
7510292SAndreas.Sandberg@ARM.com    bool stayAtPC;
7610292SAndreas.Sandberg@ARM.com
7710292SAndreas.Sandberg@ARM.com    // Branch prediction
7810292SAndreas.Sandberg@ARM.com    TheISA::PCState predPC;
7910292SAndreas.Sandberg@ARM.com
8010292SAndreas.Sandberg@ARM.com    /** PER-THREAD STATS */
8110292SAndreas.Sandberg@ARM.com
8210292SAndreas.Sandberg@ARM.com    // Number of simulated instructions
8310292SAndreas.Sandberg@ARM.com    Counter numInst;
844046Sbinkertn@umich.edu    Stats::Scalar numInsts;
852SN/A    Counter numOp;
867811Ssteve.reinhardt@amd.com    Stats::Scalar numOps;
874039Sbinkertn@umich.edu
881070SN/A    // Number of integer alu accesses
891070SN/A    Stats::Scalar numIntAluAccesses;
901070SN/A
911070SN/A    // Number of float alu accesses
921070SN/A    Stats::Scalar numFpAluAccesses;
931070SN/A
941070SN/A    // Number of vector alu accesses
951070SN/A    Stats::Scalar numVecAluAccesses;
961070SN/A
972SN/A    // Number of function calls/returns
982SN/A    Stats::Scalar numCallsReturns;
9910259SAndrew.Bardsley@arm.com
10010259SAndrew.Bardsley@arm.com    // Conditional control instructions;
10110259SAndrew.Bardsley@arm.com    Stats::Scalar numCondCtrlInsts;
10210259SAndrew.Bardsley@arm.com
10310259SAndrew.Bardsley@arm.com    // Number of int instructions
10410259SAndrew.Bardsley@arm.com    Stats::Scalar numIntInsts;
10510259SAndrew.Bardsley@arm.com
10610259SAndrew.Bardsley@arm.com    // Number of float instructions
10710259SAndrew.Bardsley@arm.com    Stats::Scalar numFpInsts;
10810259SAndrew.Bardsley@arm.com
10910259SAndrew.Bardsley@arm.com    // Number of vector instructions
11010259SAndrew.Bardsley@arm.com    Stats::Scalar numVecInsts;
11110259SAndrew.Bardsley@arm.com
11210259SAndrew.Bardsley@arm.com    // Number of integer register file accesses
1132SN/A    Stats::Scalar numIntRegReads;
1142SN/A    Stats::Scalar numIntRegWrites;
1152SN/A
1162SN/A    // Number of float register file accesses
1172SN/A    Stats::Scalar numFpRegReads;
1182SN/A    Stats::Scalar numFpRegWrites;
1192SN/A
1202SN/A    // Number of vector register file accesses
1212SN/A    mutable Stats::Scalar numVecRegReads;
1222SN/A    Stats::Scalar numVecRegWrites;
1232SN/A
1242SN/A    // Number of predicate register file accesses
1258232Snate@binkert.org    mutable Stats::Scalar numVecPredRegReads;
1262SN/A    Stats::Scalar numVecPredRegWrites;
1274041Sbinkertn@umich.edu
1288232Snate@binkert.org    // Number of condition code register file accesses
1294041Sbinkertn@umich.edu    Stats::Scalar numCCRegReads;
1307823Ssteve.reinhardt@amd.com    Stats::Scalar numCCRegWrites;
1312SN/A
1322SN/A    // Number of simulated memory references
1334041Sbinkertn@umich.edu    Stats::Scalar numMemRefs;
1348232Snate@binkert.org    Stats::Scalar numLoadInsts;
1354041Sbinkertn@umich.edu    Stats::Scalar numStoreInsts;
1367823Ssteve.reinhardt@amd.com
1372SN/A    // Number of idle cycles
1382SN/A    Stats::Formula numIdleCycles;
1398232Snate@binkert.org
1408232Snate@binkert.org    // Number of busy cycles
1415806Ssaidi@eecs.umich.edu    Stats::Formula numBusyCycles;
1428232Snate@binkert.org
1435806Ssaidi@eecs.umich.edu    // Number of simulated loads
1445806Ssaidi@eecs.umich.edu    Counter numLoad;
1454041Sbinkertn@umich.edu
1468232Snate@binkert.org    // Number of idle cycles
1474041Sbinkertn@umich.edu    Stats::Average notIdleFraction;
1484041Sbinkertn@umich.edu    Stats::Formula idleFraction;
1492SN/A
1502SN/A    // Number of cycles stalled for I-cache responses
1514046Sbinkertn@umich.edu    Stats::Scalar icacheStallCycles;
1527823Ssteve.reinhardt@amd.com    Counter lastIcacheStall;
1534046Sbinkertn@umich.edu
1544046Sbinkertn@umich.edu    // Number of cycles stalled for D-cache responses
1554041Sbinkertn@umich.edu    Stats::Scalar dcacheStallCycles;
1567823Ssteve.reinhardt@amd.com    Counter lastDcacheStall;
1572SN/A
1582SN/A    /// @{
1594041Sbinkertn@umich.edu    /// Total number of branches fetched
1604041Sbinkertn@umich.edu    Stats::Scalar numBranches;
161507SN/A    /// Number of branches predicted as taken
162507SN/A    Stats::Scalar numPredictedBranches;
1632SN/A    /// Number of misprediced branches
1642SN/A    Stats::Scalar numBranchMispred;
1652SN/A    /// @}
1664046Sbinkertn@umich.edu
1674041Sbinkertn@umich.edu   // Instruction mix histogram by OpClass
1685806Ssaidi@eecs.umich.edu   Stats::Vector statExecutedInstType;
1694041Sbinkertn@umich.edu
1704046Sbinkertn@umich.edu  public:
1714041Sbinkertn@umich.edu    /** Constructor */
1724041Sbinkertn@umich.edu    SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
1732SN/A        : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
1745543Ssaidi@eecs.umich.edu        numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
1752SN/A    { }
1761354SN/A
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