simple_thread.hh revision 13875:656d633621fa
111569Sgabor.dozsa@arm.com/*
211569Sgabor.dozsa@arm.com * Copyright (c) 2011-2012, 2016-2018 ARM Limited
311569Sgabor.dozsa@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
411569Sgabor.dozsa@arm.com * All rights reserved
511569Sgabor.dozsa@arm.com *
611569Sgabor.dozsa@arm.com * The license below extends only to copyright in the software and shall
711569Sgabor.dozsa@arm.com * not be construed as granting a license to any other intellectual
811569Sgabor.dozsa@arm.com * property including but not limited to intellectual property relating
911569Sgabor.dozsa@arm.com * to a hardware implementation of the functionality of the software
1011569Sgabor.dozsa@arm.com * licensed hereunder.  You may use the software subject to the license
1111569Sgabor.dozsa@arm.com * terms below provided that you ensure that this notice is replicated
1211569Sgabor.dozsa@arm.com * unmodified and in its entirety in all distributions of the software,
1311569Sgabor.dozsa@arm.com * modified or unmodified, in source code or in binary form.
1411569Sgabor.dozsa@arm.com *
1511569Sgabor.dozsa@arm.com * Copyright (c) 2001-2006 The Regents of The University of Michigan
1611569Sgabor.dozsa@arm.com * All rights reserved.
1711569Sgabor.dozsa@arm.com *
1811569Sgabor.dozsa@arm.com * Redistribution and use in source and binary forms, with or without
1911569Sgabor.dozsa@arm.com * modification, are permitted provided that the following conditions are
2011569Sgabor.dozsa@arm.com * met: redistributions of source code must retain the above copyright
2111569Sgabor.dozsa@arm.com * notice, this list of conditions and the following disclaimer;
2211569Sgabor.dozsa@arm.com * redistributions in binary form must reproduce the above copyright
2311569Sgabor.dozsa@arm.com * notice, this list of conditions and the following disclaimer in the
2411569Sgabor.dozsa@arm.com * documentation and/or other materials provided with the distribution;
2511569Sgabor.dozsa@arm.com * neither the name of the copyright holders nor the names of its
2611569Sgabor.dozsa@arm.com * contributors may be used to endorse or promote products derived from
2711569Sgabor.dozsa@arm.com * this software without specific prior written permission.
2811569Sgabor.dozsa@arm.com *
2911569Sgabor.dozsa@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3011569Sgabor.dozsa@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3111569Sgabor.dozsa@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3211569Sgabor.dozsa@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3311569Sgabor.dozsa@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3411569Sgabor.dozsa@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3511569Sgabor.dozsa@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3611569Sgabor.dozsa@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3711569Sgabor.dozsa@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3811569Sgabor.dozsa@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3911569Sgabor.dozsa@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4011569Sgabor.dozsa@arm.com *
4111569Sgabor.dozsa@arm.com * Authors: Steve Reinhardt
4211569Sgabor.dozsa@arm.com *          Nathan Binkert
4311569Sgabor.dozsa@arm.com */
4411569Sgabor.dozsa@arm.com
4511569Sgabor.dozsa@arm.com#ifndef __CPU_SIMPLE_THREAD_HH__
4611569Sgabor.dozsa@arm.com#define __CPU_SIMPLE_THREAD_HH__
4711569Sgabor.dozsa@arm.com
4811569Sgabor.dozsa@arm.com#include "arch/decoder.hh"
4911569Sgabor.dozsa@arm.com#include "arch/generic/tlb.hh"
5011569Sgabor.dozsa@arm.com#include "arch/isa.hh"
5111569Sgabor.dozsa@arm.com#include "arch/isa_traits.hh"
5211569Sgabor.dozsa@arm.com#include "arch/registers.hh"
5311569Sgabor.dozsa@arm.com#include "arch/types.hh"
5411569Sgabor.dozsa@arm.com#include "base/types.hh"
5511569Sgabor.dozsa@arm.com#include "config/the_isa.hh"
5611569Sgabor.dozsa@arm.com#include "cpu/thread_context.hh"
5711569Sgabor.dozsa@arm.com#include "cpu/thread_state.hh"
5811569Sgabor.dozsa@arm.com#include "debug/CCRegs.hh"
5911569Sgabor.dozsa@arm.com#include "debug/FloatRegs.hh"
6011569Sgabor.dozsa@arm.com#include "debug/IntRegs.hh"
6111569Sgabor.dozsa@arm.com#include "debug/VecPredRegs.hh"
6211569Sgabor.dozsa@arm.com#include "debug/VecRegs.hh"
6311630Sgabor.dozsa@arm.com#include "mem/page_table.hh"
6411630Sgabor.dozsa@arm.com#include "mem/request.hh"
6511630Sgabor.dozsa@arm.com#include "sim/byteswap.hh"
6611630Sgabor.dozsa@arm.com#include "sim/eventq.hh"
6711630Sgabor.dozsa@arm.com#include "sim/process.hh"
6811630Sgabor.dozsa@arm.com#include "sim/serialize.hh"
6911630Sgabor.dozsa@arm.com#include "sim/system.hh"
7011630Sgabor.dozsa@arm.com
7111630Sgabor.dozsa@arm.comclass BaseCPU;
7211630Sgabor.dozsa@arm.comclass CheckerCPU;
7311630Sgabor.dozsa@arm.com
7411630Sgabor.dozsa@arm.comclass FunctionProfile;
7511630Sgabor.dozsa@arm.comclass ProfileNode;
7611630Sgabor.dozsa@arm.com
7711630Sgabor.dozsa@arm.comnamespace TheISA {
7811630Sgabor.dozsa@arm.com    namespace Kernel {
7911630Sgabor.dozsa@arm.com        class Statistics;
8011630Sgabor.dozsa@arm.com    }
8111630Sgabor.dozsa@arm.com}
8211569Sgabor.dozsa@arm.com
8311569Sgabor.dozsa@arm.com/**
8411569Sgabor.dozsa@arm.com * The SimpleThread object provides a combination of the ThreadState
8511569Sgabor.dozsa@arm.com * object and the ThreadContext interface. It implements the
8611569Sgabor.dozsa@arm.com * ThreadContext interface and adds to the ThreadState object by adding all
8711569Sgabor.dozsa@arm.com * the objects needed for simple functional execution, including a
8811569Sgabor.dozsa@arm.com * simple architectural register file, and pointers to the ITB and DTB
8911569Sgabor.dozsa@arm.com * in full system mode. For CPU models that do not need more advanced
9011569Sgabor.dozsa@arm.com * ways to hold state (i.e. a separate physical register file, or
9111569Sgabor.dozsa@arm.com * separate fetch and commit PC's), this SimpleThread class provides
9211569Sgabor.dozsa@arm.com * all the necessary state for full architecture-level functional
9311569Sgabor.dozsa@arm.com * simulation.  See the AtomicSimpleCPU or TimingSimpleCPU for
9411569Sgabor.dozsa@arm.com * examples.
9511569Sgabor.dozsa@arm.com */
9611569Sgabor.dozsa@arm.com
9711569Sgabor.dozsa@arm.comclass SimpleThread : public ThreadState, public ThreadContext
9811569Sgabor.dozsa@arm.com{
9911569Sgabor.dozsa@arm.com  protected:
10011569Sgabor.dozsa@arm.com    typedef TheISA::MachInst MachInst;
10111569Sgabor.dozsa@arm.com    using VecRegContainer = TheISA::VecRegContainer;
10211569Sgabor.dozsa@arm.com    using VecElem = TheISA::VecElem;
10311569Sgabor.dozsa@arm.com    using VecPredRegContainer = TheISA::VecPredRegContainer;
10411569Sgabor.dozsa@arm.com  public:
10511569Sgabor.dozsa@arm.com    typedef ThreadContext::Status Status;
10611569Sgabor.dozsa@arm.com
10711569Sgabor.dozsa@arm.com  protected:
10811569Sgabor.dozsa@arm.com    RegVal floatRegs[TheISA::NumFloatRegs];
10911569Sgabor.dozsa@arm.com    RegVal intRegs[TheISA::NumIntRegs];
11011569Sgabor.dozsa@arm.com    VecRegContainer vecRegs[TheISA::NumVecRegs];
11111569Sgabor.dozsa@arm.com    VecPredRegContainer vecPredRegs[TheISA::NumVecPredRegs];
11211569Sgabor.dozsa@arm.com#ifdef ISA_HAS_CC_REGS
11311569Sgabor.dozsa@arm.com    RegVal ccRegs[TheISA::NumCCRegs];
11411569Sgabor.dozsa@arm.com#endif
11511569Sgabor.dozsa@arm.com    TheISA::ISA *const isa;    // one "instance" of the current ISA.
11611569Sgabor.dozsa@arm.com
11711569Sgabor.dozsa@arm.com    TheISA::PCState _pcState;
11811569Sgabor.dozsa@arm.com
11911569Sgabor.dozsa@arm.com    /** Did this instruction execute or is it predicated false */
12011569Sgabor.dozsa@arm.com    bool predicate;
12111569Sgabor.dozsa@arm.com
12211569Sgabor.dozsa@arm.com  public:
12311569Sgabor.dozsa@arm.com    std::string name() const
12411569Sgabor.dozsa@arm.com    {
12511569Sgabor.dozsa@arm.com        return csprintf("%s.[tid:%i]", baseCpu->name(), threadId());
12611569Sgabor.dozsa@arm.com    }
12711569Sgabor.dozsa@arm.com
12811569Sgabor.dozsa@arm.com    System *system;
12911569Sgabor.dozsa@arm.com
13011569Sgabor.dozsa@arm.com    BaseTLB *itb;
13111569Sgabor.dozsa@arm.com    BaseTLB *dtb;
13211569Sgabor.dozsa@arm.com
13311569Sgabor.dozsa@arm.com    TheISA::Decoder decoder;
13411569Sgabor.dozsa@arm.com
13511569Sgabor.dozsa@arm.com    // constructor: initialize SimpleThread from given process structure
13611569Sgabor.dozsa@arm.com    // FS
13711569Sgabor.dozsa@arm.com    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
13811569Sgabor.dozsa@arm.com                 BaseTLB *_itb, BaseTLB *_dtb, TheISA::ISA *_isa,
13911569Sgabor.dozsa@arm.com                 bool use_kernel_stats = true);
14011569Sgabor.dozsa@arm.com    // SE
14111569Sgabor.dozsa@arm.com    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
14211569Sgabor.dozsa@arm.com                 Process *_process, BaseTLB *_itb, BaseTLB *_dtb,
14311569Sgabor.dozsa@arm.com                 TheISA::ISA *_isa);
14411569Sgabor.dozsa@arm.com
14511569Sgabor.dozsa@arm.com    virtual ~SimpleThread() {}
14611569Sgabor.dozsa@arm.com
14711569Sgabor.dozsa@arm.com    void takeOverFrom(ThreadContext *oldContext) override;
14811569Sgabor.dozsa@arm.com
14911569Sgabor.dozsa@arm.com    void regStats(const std::string &name) override;
15011569Sgabor.dozsa@arm.com
15111569Sgabor.dozsa@arm.com    void copyState(ThreadContext *oldContext);
15211569Sgabor.dozsa@arm.com
15311569Sgabor.dozsa@arm.com    void serialize(CheckpointOut &cp) const override;
15411569Sgabor.dozsa@arm.com    void unserialize(CheckpointIn &cp) override;
15511569Sgabor.dozsa@arm.com    void startup();
15611569Sgabor.dozsa@arm.com
15711569Sgabor.dozsa@arm.com    /***************************************************************
15811569Sgabor.dozsa@arm.com     *  SimpleThread functions to provide CPU with access to various
15911569Sgabor.dozsa@arm.com     *  state.
16011569Sgabor.dozsa@arm.com     **************************************************************/
16111569Sgabor.dozsa@arm.com
16211630Sgabor.dozsa@arm.com    /** Returns the pointer to this SimpleThread's ThreadContext. Used
16311569Sgabor.dozsa@arm.com     *  when a ThreadContext must be passed to objects outside of the
16411569Sgabor.dozsa@arm.com     *  CPU.
16511569Sgabor.dozsa@arm.com     */
16611569Sgabor.dozsa@arm.com    ThreadContext *getTC() { return this; }
16711630Sgabor.dozsa@arm.com
16811630Sgabor.dozsa@arm.com    void demapPage(Addr vaddr, uint64_t asn)
16911630Sgabor.dozsa@arm.com    {
17011630Sgabor.dozsa@arm.com        itb->demapPage(vaddr, asn);
17111630Sgabor.dozsa@arm.com        dtb->demapPage(vaddr, asn);
17211569Sgabor.dozsa@arm.com    }
17311569Sgabor.dozsa@arm.com
17411630Sgabor.dozsa@arm.com    void demapInstPage(Addr vaddr, uint64_t asn)
17511630Sgabor.dozsa@arm.com    {
17611630Sgabor.dozsa@arm.com        itb->demapPage(vaddr, asn);
17711630Sgabor.dozsa@arm.com    }
17811630Sgabor.dozsa@arm.com
17911630Sgabor.dozsa@arm.com    void demapDataPage(Addr vaddr, uint64_t asn)
18011630Sgabor.dozsa@arm.com    {
18111630Sgabor.dozsa@arm.com        dtb->demapPage(vaddr, asn);
18211630Sgabor.dozsa@arm.com    }
18311630Sgabor.dozsa@arm.com
18411630Sgabor.dozsa@arm.com    void dumpFuncProfile() override;
18511630Sgabor.dozsa@arm.com
18611569Sgabor.dozsa@arm.com    Fault hwrei();
18711630Sgabor.dozsa@arm.com
18811630Sgabor.dozsa@arm.com    bool simPalCheck(int palFunc);
18911630Sgabor.dozsa@arm.com
19011630Sgabor.dozsa@arm.com    /*******************************************
19111569Sgabor.dozsa@arm.com     * ThreadContext interface functions.
19211630Sgabor.dozsa@arm.com     ******************************************/
19311630Sgabor.dozsa@arm.com
19411630Sgabor.dozsa@arm.com    BaseCPU *getCpuPtr() override { return baseCpu; }
19511630Sgabor.dozsa@arm.com
19611569Sgabor.dozsa@arm.com    int cpuId() const override { return ThreadState::cpuId(); }
19711630Sgabor.dozsa@arm.com    uint32_t socketId() const override { return ThreadState::socketId(); }
19811630Sgabor.dozsa@arm.com    int threadId() const override { return ThreadState::threadId(); }
19911630Sgabor.dozsa@arm.com    void setThreadId(int id) override { ThreadState::setThreadId(id); }
20011630Sgabor.dozsa@arm.com    ContextID contextId() const override { return ThreadState::contextId(); }
20111630Sgabor.dozsa@arm.com    void setContextId(ContextID id) override { ThreadState::setContextId(id); }
20211630Sgabor.dozsa@arm.com
20311630Sgabor.dozsa@arm.com    BaseTLB *getITBPtr() override { return itb; }
20411569Sgabor.dozsa@arm.com
20511569Sgabor.dozsa@arm.com    BaseTLB *getDTBPtr() override { return dtb; }
20611569Sgabor.dozsa@arm.com
20711569Sgabor.dozsa@arm.com    CheckerCPU *getCheckerCpuPtr() override { return NULL; }
20811569Sgabor.dozsa@arm.com
20911569Sgabor.dozsa@arm.com    TheISA::ISA *getIsaPtr() override { return isa; }
21011569Sgabor.dozsa@arm.com
21111569Sgabor.dozsa@arm.com    TheISA::Decoder *getDecoderPtr() override { return &decoder; }
21211569Sgabor.dozsa@arm.com
21311569Sgabor.dozsa@arm.com    System *getSystemPtr() override { return system; }
21411569Sgabor.dozsa@arm.com
21511569Sgabor.dozsa@arm.com    TheISA::Kernel::Statistics *
21611569Sgabor.dozsa@arm.com    getKernelStats() override
21711569Sgabor.dozsa@arm.com    {
21811569Sgabor.dozsa@arm.com        return ThreadState::getKernelStats();
21911569Sgabor.dozsa@arm.com    }
22011569Sgabor.dozsa@arm.com
22111569Sgabor.dozsa@arm.com    PortProxy &getPhysProxy() override { return ThreadState::getPhysProxy(); }
22211569Sgabor.dozsa@arm.com    FSTranslatingPortProxy &
22311569Sgabor.dozsa@arm.com    getVirtProxy() override
22411569Sgabor.dozsa@arm.com    {
22511569Sgabor.dozsa@arm.com        return ThreadState::getVirtProxy();
22611569Sgabor.dozsa@arm.com    }
22711569Sgabor.dozsa@arm.com
22811569Sgabor.dozsa@arm.com    void initMemProxies(ThreadContext *tc) override
22911569Sgabor.dozsa@arm.com    {
23011569Sgabor.dozsa@arm.com        ThreadState::initMemProxies(tc);
23111569Sgabor.dozsa@arm.com    }
232
233    SETranslatingPortProxy &
234    getMemProxy() override
235    {
236        return ThreadState::getMemProxy();
237    }
238
239    Process *getProcessPtr() override { return ThreadState::getProcessPtr(); }
240    void setProcessPtr(Process *p) override { ThreadState::setProcessPtr(p); }
241
242    Status status() const override { return _status; }
243
244    void setStatus(Status newStatus) override { _status = newStatus; }
245
246    /// Set the status to Active.
247    void activate() override;
248
249    /// Set the status to Suspended.
250    void suspend() override;
251
252    /// Set the status to Halted.
253    void halt() override;
254
255    EndQuiesceEvent *
256    getQuiesceEvent() override
257    {
258        return ThreadState::getQuiesceEvent();
259    }
260
261    Tick
262    readLastActivate() override
263    {
264        return ThreadState::readLastActivate();
265    }
266    Tick
267    readLastSuspend() override
268    {
269        return ThreadState::readLastSuspend();
270    }
271
272    void profileClear() override { ThreadState::profileClear(); }
273    void profileSample() override { ThreadState::profileSample(); }
274
275    void copyArchRegs(ThreadContext *tc) override;
276
277    void clearArchRegs() override
278    {
279        _pcState = 0;
280        memset(intRegs, 0, sizeof(intRegs));
281        memset(floatRegs, 0, sizeof(floatRegs));
282        for (int i = 0; i < TheISA::NumVecRegs; i++) {
283            vecRegs[i].zero();
284        }
285        for (int i = 0; i < TheISA::NumVecPredRegs; i++) {
286            vecPredRegs[i].reset();
287        }
288#ifdef ISA_HAS_CC_REGS
289        memset(ccRegs, 0, sizeof(ccRegs));
290#endif
291        isa->clear();
292    }
293
294    //
295    // New accessors for new decoder.
296    //
297    RegVal
298    readIntReg(RegIndex reg_idx) const override
299    {
300        int flatIndex = isa->flattenIntIndex(reg_idx);
301        assert(flatIndex < TheISA::NumIntRegs);
302        uint64_t regVal(readIntRegFlat(flatIndex));
303        DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
304                reg_idx, flatIndex, regVal);
305        return regVal;
306    }
307
308    RegVal
309    readFloatReg(RegIndex reg_idx) const override
310    {
311        int flatIndex = isa->flattenFloatIndex(reg_idx);
312        assert(flatIndex < TheISA::NumFloatRegs);
313        RegVal regVal(readFloatRegFlat(flatIndex));
314        DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n",
315                reg_idx, flatIndex, regVal);
316        return regVal;
317    }
318
319    const VecRegContainer&
320    readVecReg(const RegId& reg) const override
321    {
322        int flatIndex = isa->flattenVecIndex(reg.index());
323        assert(flatIndex < TheISA::NumVecRegs);
324        const VecRegContainer& regVal = readVecRegFlat(flatIndex);
325        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
326                reg.index(), flatIndex, regVal.print());
327        return regVal;
328    }
329
330    VecRegContainer&
331    getWritableVecReg(const RegId& reg) override
332    {
333        int flatIndex = isa->flattenVecIndex(reg.index());
334        assert(flatIndex < TheISA::NumVecRegs);
335        VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
336        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
337                reg.index(), flatIndex, regVal.print());
338        return regVal;
339    }
340
341    /** Vector Register Lane Interfaces. */
342    /** @{ */
343    /** Reads source vector <T> operand. */
344    template <typename T>
345    VecLaneT<T, true>
346    readVecLane(const RegId& reg) const
347    {
348        int flatIndex = isa->flattenVecIndex(reg.index());
349        assert(flatIndex < TheISA::NumVecRegs);
350        auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex());
351        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n",
352                reg.index(), flatIndex, reg.elemIndex(), regVal);
353        return regVal;
354    }
355
356    /** Reads source vector 8bit operand. */
357    virtual ConstVecLane8
358    readVec8BitLaneReg(const RegId &reg) const override
359    {
360        return readVecLane<uint8_t>(reg);
361    }
362
363    /** Reads source vector 16bit operand. */
364    virtual ConstVecLane16
365    readVec16BitLaneReg(const RegId &reg) const override
366    {
367        return readVecLane<uint16_t>(reg);
368    }
369
370    /** Reads source vector 32bit operand. */
371    virtual ConstVecLane32
372    readVec32BitLaneReg(const RegId &reg) const override
373    {
374        return readVecLane<uint32_t>(reg);
375    }
376
377    /** Reads source vector 64bit operand. */
378    virtual ConstVecLane64
379    readVec64BitLaneReg(const RegId &reg) const override
380    {
381        return readVecLane<uint64_t>(reg);
382    }
383
384    /** Write a lane of the destination vector register. */
385    template <typename LD>
386    void
387    setVecLaneT(const RegId &reg, const LD &val)
388    {
389        int flatIndex = isa->flattenVecIndex(reg.index());
390        assert(flatIndex < TheISA::NumVecRegs);
391        setVecLaneFlat(flatIndex, reg.elemIndex(), val);
392        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n",
393                reg.index(), flatIndex, reg.elemIndex(), val);
394    }
395    virtual void
396    setVecLane(const RegId &reg, const LaneData<LaneSize::Byte> &val) override
397    {
398        return setVecLaneT(reg, val);
399    }
400    virtual void
401    setVecLane(const RegId &reg,
402               const LaneData<LaneSize::TwoByte> &val) override
403    {
404        return setVecLaneT(reg, val);
405    }
406    virtual void
407    setVecLane(const RegId &reg,
408               const LaneData<LaneSize::FourByte> &val) override
409    {
410        return setVecLaneT(reg, val);
411    }
412    virtual void
413    setVecLane(const RegId &reg,
414               const LaneData<LaneSize::EightByte> &val) override
415    {
416        return setVecLaneT(reg, val);
417    }
418    /** @} */
419
420    const VecElem &
421    readVecElem(const RegId &reg) const override
422    {
423        int flatIndex = isa->flattenVecElemIndex(reg.index());
424        assert(flatIndex < TheISA::NumVecRegs);
425        const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex());
426        DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as"
427                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal);
428        return regVal;
429    }
430
431    const VecPredRegContainer &
432    readVecPredReg(const RegId &reg) const override
433    {
434        int flatIndex = isa->flattenVecPredIndex(reg.index());
435        assert(flatIndex < TheISA::NumVecPredRegs);
436        const VecPredRegContainer& regVal = readVecPredRegFlat(flatIndex);
437        DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n",
438                reg.index(), flatIndex, regVal.print());
439        return regVal;
440    }
441
442    VecPredRegContainer &
443    getWritableVecPredReg(const RegId &reg) override
444    {
445        int flatIndex = isa->flattenVecPredIndex(reg.index());
446        assert(flatIndex < TheISA::NumVecPredRegs);
447        VecPredRegContainer& regVal = getWritableVecPredRegFlat(flatIndex);
448        DPRINTF(VecPredRegs,
449                "Reading predicate reg %d (%d) as %s for modify.\n",
450                reg.index(), flatIndex, regVal.print());
451        return regVal;
452    }
453
454    RegVal
455    readCCReg(RegIndex reg_idx) const override
456    {
457#ifdef ISA_HAS_CC_REGS
458        int flatIndex = isa->flattenCCIndex(reg_idx);
459        assert(0 <= flatIndex);
460        assert(flatIndex < TheISA::NumCCRegs);
461        uint64_t regVal(readCCRegFlat(flatIndex));
462        DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
463                reg_idx, flatIndex, regVal);
464        return regVal;
465#else
466        panic("Tried to read a CC register.");
467        return 0;
468#endif
469    }
470
471    void
472    setIntReg(RegIndex reg_idx, RegVal val) override
473    {
474        int flatIndex = isa->flattenIntIndex(reg_idx);
475        assert(flatIndex < TheISA::NumIntRegs);
476        DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
477                reg_idx, flatIndex, val);
478        setIntRegFlat(flatIndex, val);
479    }
480
481    void
482    setFloatReg(RegIndex reg_idx, RegVal val) override
483    {
484        int flatIndex = isa->flattenFloatIndex(reg_idx);
485        assert(flatIndex < TheISA::NumFloatRegs);
486        // XXX: Fix array out of bounds compiler error for gem5.fast
487        // when checkercpu enabled
488        if (flatIndex < TheISA::NumFloatRegs)
489            setFloatRegFlat(flatIndex, val);
490        DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n",
491                reg_idx, flatIndex, val);
492    }
493
494    void
495    setVecReg(const RegId &reg, const VecRegContainer &val) override
496    {
497        int flatIndex = isa->flattenVecIndex(reg.index());
498        assert(flatIndex < TheISA::NumVecRegs);
499        setVecRegFlat(flatIndex, val);
500        DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
501                reg.index(), flatIndex, val.print());
502    }
503
504    void
505    setVecElem(const RegId &reg, const VecElem &val) override
506    {
507        int flatIndex = isa->flattenVecElemIndex(reg.index());
508        assert(flatIndex < TheISA::NumVecRegs);
509        setVecElemFlat(flatIndex, reg.elemIndex(), val);
510        DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to"
511                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val);
512    }
513
514    void
515    setVecPredReg(const RegId &reg, const VecPredRegContainer &val) override
516    {
517        int flatIndex = isa->flattenVecPredIndex(reg.index());
518        assert(flatIndex < TheISA::NumVecPredRegs);
519        setVecPredRegFlat(flatIndex, val);
520        DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n",
521                reg.index(), flatIndex, val.print());
522    }
523
524    void
525    setCCReg(RegIndex reg_idx, RegVal val) override
526    {
527#ifdef ISA_HAS_CC_REGS
528        int flatIndex = isa->flattenCCIndex(reg_idx);
529        assert(flatIndex < TheISA::NumCCRegs);
530        DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n",
531                reg_idx, flatIndex, val);
532        setCCRegFlat(flatIndex, val);
533#else
534        panic("Tried to set a CC register.");
535#endif
536    }
537
538    TheISA::PCState pcState() const override { return _pcState; }
539    void pcState(const TheISA::PCState &val) override { _pcState = val; }
540
541    void
542    pcStateNoRecord(const TheISA::PCState &val) override
543    {
544        _pcState = val;
545    }
546
547    Addr instAddr() const override  { return _pcState.instAddr(); }
548    Addr nextInstAddr() const override { return _pcState.nextInstAddr(); }
549    MicroPC microPC() const override { return _pcState.microPC(); }
550    bool readPredicate() const { return predicate; }
551    void setPredicate(bool val) { predicate = val; }
552
553    RegVal
554    readMiscRegNoEffect(RegIndex misc_reg) const override
555    {
556        return isa->readMiscRegNoEffect(misc_reg);
557    }
558
559    RegVal
560    readMiscReg(RegIndex misc_reg) override
561    {
562        return isa->readMiscReg(misc_reg, this);
563    }
564
565    void
566    setMiscRegNoEffect(RegIndex misc_reg, RegVal val) override
567    {
568        return isa->setMiscRegNoEffect(misc_reg, val);
569    }
570
571    void
572    setMiscReg(RegIndex misc_reg, RegVal val) override
573    {
574        return isa->setMiscReg(misc_reg, val, this);
575    }
576
577    RegId
578    flattenRegId(const RegId& regId) const override
579    {
580        return isa->flattenRegId(regId);
581    }
582
583    unsigned readStCondFailures() const override { return storeCondFailures; }
584
585    void
586    setStCondFailures(unsigned sc_failures) override
587    {
588        storeCondFailures = sc_failures;
589    }
590
591    Counter
592    readFuncExeInst() const override
593    {
594        return ThreadState::readFuncExeInst();
595    }
596
597    void
598    syscall(int64_t callnum, Fault *fault) override
599    {
600        process->syscall(callnum, this, fault);
601    }
602
603    RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; }
604    void
605    setIntRegFlat(RegIndex idx, RegVal val) override
606    {
607        intRegs[idx] = val;
608    }
609
610    RegVal
611    readFloatRegFlat(RegIndex idx) const override
612    {
613        return floatRegs[idx];
614    }
615    void
616    setFloatRegFlat(RegIndex idx, RegVal val) override
617    {
618        floatRegs[idx] = val;
619    }
620
621    const VecRegContainer &
622    readVecRegFlat(RegIndex reg) const override
623    {
624        return vecRegs[reg];
625    }
626
627    VecRegContainer &
628    getWritableVecRegFlat(RegIndex reg) override
629    {
630        return vecRegs[reg];
631    }
632
633    void
634    setVecRegFlat(RegIndex reg, const VecRegContainer &val) override
635    {
636        vecRegs[reg] = val;
637    }
638
639    template <typename T>
640    VecLaneT<T, true>
641    readVecLaneFlat(RegIndex reg, int lId) const
642    {
643        return vecRegs[reg].laneView<T>(lId);
644    }
645
646    template <typename LD>
647    void
648    setVecLaneFlat(RegIndex reg, int lId, const LD &val)
649    {
650        vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val;
651    }
652
653    const VecElem &
654    readVecElemFlat(RegIndex reg, const ElemIndex &elemIndex) const override
655    {
656        return vecRegs[reg].as<TheISA::VecElem>()[elemIndex];
657    }
658
659    void
660    setVecElemFlat(RegIndex reg, const ElemIndex &elemIndex,
661                   const VecElem &val) override
662    {
663        vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val;
664    }
665
666    const VecPredRegContainer &
667    readVecPredRegFlat(RegIndex reg) const override
668    {
669        return vecPredRegs[reg];
670    }
671
672    VecPredRegContainer &
673    getWritableVecPredRegFlat(RegIndex reg) override
674    {
675        return vecPredRegs[reg];
676    }
677
678    void
679    setVecPredRegFlat(RegIndex reg, const VecPredRegContainer &val) override
680    {
681        vecPredRegs[reg] = val;
682    }
683
684#ifdef ISA_HAS_CC_REGS
685    RegVal readCCRegFlat(RegIndex idx) const override { return ccRegs[idx]; }
686    void setCCRegFlat(RegIndex idx, RegVal val) override { ccRegs[idx] = val; }
687#else
688    RegVal
689    readCCRegFlat(RegIndex idx) const override
690    {
691        panic("readCCRegFlat w/no CC regs!\n");
692    }
693
694    void
695    setCCRegFlat(RegIndex idx, RegVal val) override
696    {
697        panic("setCCRegFlat w/no CC regs!\n");
698    }
699#endif
700};
701
702
703#endif // __CPU_CPU_EXEC_CONTEXT_HH__
704