simple_thread.hh revision 13622:ba31c2a23eca
15625Sgblack@eecs.umich.edu/*
25625Sgblack@eecs.umich.edu * Copyright (c) 2011-2012, 2016-2018 ARM Limited
35625Sgblack@eecs.umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc.
45625Sgblack@eecs.umich.edu * All rights reserved
55625Sgblack@eecs.umich.edu *
65625Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
75625Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
85625Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
95625Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
105625Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
115625Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
125625Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
135625Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
145625Sgblack@eecs.umich.edu *
155625Sgblack@eecs.umich.edu * Copyright (c) 2001-2006 The Regents of The University of Michigan
165625Sgblack@eecs.umich.edu * All rights reserved.
175625Sgblack@eecs.umich.edu *
185625Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
195625Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
205625Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
215625Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
225625Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
235625Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
245625Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
255625Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
265625Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
275625Sgblack@eecs.umich.edu * this software without specific prior written permission.
285625Sgblack@eecs.umich.edu *
295625Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
305625Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
315625Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
325625Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
335625Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
345625Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
355625Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
365625Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
375625Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
385625Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
395625Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
405625Sgblack@eecs.umich.edu *
415625Sgblack@eecs.umich.edu * Authors: Steve Reinhardt
425625Sgblack@eecs.umich.edu *          Nathan Binkert
435625Sgblack@eecs.umich.edu */
445625Sgblack@eecs.umich.edu
455625Sgblack@eecs.umich.edu#ifndef __CPU_SIMPLE_THREAD_HH__
465625Sgblack@eecs.umich.edu#define __CPU_SIMPLE_THREAD_HH__
475625Sgblack@eecs.umich.edu
485625Sgblack@eecs.umich.edu#include "arch/decoder.hh"
495625Sgblack@eecs.umich.edu#include "arch/generic/tlb.hh"
505625Sgblack@eecs.umich.edu#include "arch/isa.hh"
515625Sgblack@eecs.umich.edu#include "arch/isa_traits.hh"
525625Sgblack@eecs.umich.edu#include "arch/registers.hh"
535625Sgblack@eecs.umich.edu#include "arch/types.hh"
545625Sgblack@eecs.umich.edu#include "base/types.hh"
555625Sgblack@eecs.umich.edu#include "config/the_isa.hh"
565625Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
575625Sgblack@eecs.umich.edu#include "cpu/thread_state.hh"
585625Sgblack@eecs.umich.edu#include "debug/CCRegs.hh"
595625Sgblack@eecs.umich.edu#include "debug/FloatRegs.hh"
605625Sgblack@eecs.umich.edu#include "debug/IntRegs.hh"
615625Sgblack@eecs.umich.edu#include "debug/VecPredRegs.hh"
625625Sgblack@eecs.umich.edu#include "debug/VecRegs.hh"
635625Sgblack@eecs.umich.edu#include "mem/page_table.hh"
645625Sgblack@eecs.umich.edu#include "mem/request.hh"
655625Sgblack@eecs.umich.edu#include "sim/byteswap.hh"
665625Sgblack@eecs.umich.edu#include "sim/eventq.hh"
675625Sgblack@eecs.umich.edu#include "sim/process.hh"
685625Sgblack@eecs.umich.edu#include "sim/serialize.hh"
695625Sgblack@eecs.umich.edu#include "sim/system.hh"
705625Sgblack@eecs.umich.edu
715625Sgblack@eecs.umich.educlass BaseCPU;
725625Sgblack@eecs.umich.educlass CheckerCPU;
735625Sgblack@eecs.umich.edu
745625Sgblack@eecs.umich.educlass FunctionProfile;
755625Sgblack@eecs.umich.educlass ProfileNode;
765625Sgblack@eecs.umich.edu
775625Sgblack@eecs.umich.edunamespace TheISA {
785625Sgblack@eecs.umich.edu    namespace Kernel {
795625Sgblack@eecs.umich.edu        class Statistics;
805625Sgblack@eecs.umich.edu    }
815625Sgblack@eecs.umich.edu}
825625Sgblack@eecs.umich.edu
835625Sgblack@eecs.umich.edu/**
845625Sgblack@eecs.umich.edu * The SimpleThread object provides a combination of the ThreadState
855625Sgblack@eecs.umich.edu * object and the ThreadContext interface. It implements the
865625Sgblack@eecs.umich.edu * ThreadContext interface so that a ProxyThreadContext class can be
875625Sgblack@eecs.umich.edu * made using SimpleThread as the template parameter (see
885625Sgblack@eecs.umich.edu * thread_context.hh). It adds to the ThreadState object by adding all
895625Sgblack@eecs.umich.edu * the objects needed for simple functional execution, including a
905625Sgblack@eecs.umich.edu * simple architectural register file, and pointers to the ITB and DTB
915625Sgblack@eecs.umich.edu * in full system mode. For CPU models that do not need more advanced
925625Sgblack@eecs.umich.edu * ways to hold state (i.e. a separate physical register file, or
935625Sgblack@eecs.umich.edu * separate fetch and commit PC's), this SimpleThread class provides
945625Sgblack@eecs.umich.edu * all the necessary state for full architecture-level functional
955625Sgblack@eecs.umich.edu * simulation.  See the AtomicSimpleCPU or TimingSimpleCPU for
965625Sgblack@eecs.umich.edu * examples.
975625Sgblack@eecs.umich.edu */
985625Sgblack@eecs.umich.edu
995625Sgblack@eecs.umich.educlass SimpleThread : public ThreadState
1005625Sgblack@eecs.umich.edu{
1015625Sgblack@eecs.umich.edu  protected:
1025625Sgblack@eecs.umich.edu    typedef TheISA::MachInst MachInst;
1035625Sgblack@eecs.umich.edu    using VecRegContainer = TheISA::VecRegContainer;
1045625Sgblack@eecs.umich.edu    using VecElem = TheISA::VecElem;
1055625Sgblack@eecs.umich.edu    using VecPredRegContainer = TheISA::VecPredRegContainer;
1065625Sgblack@eecs.umich.edu  public:
1075625Sgblack@eecs.umich.edu    typedef ThreadContext::Status Status;
1085625Sgblack@eecs.umich.edu
1095625Sgblack@eecs.umich.edu  protected:
1105625Sgblack@eecs.umich.edu    RegVal floatRegs[TheISA::NumFloatRegs];
1115625Sgblack@eecs.umich.edu    RegVal intRegs[TheISA::NumIntRegs];
1125625Sgblack@eecs.umich.edu    VecRegContainer vecRegs[TheISA::NumVecRegs];
1135625Sgblack@eecs.umich.edu    VecPredRegContainer vecPredRegs[TheISA::NumVecPredRegs];
1145625Sgblack@eecs.umich.edu#ifdef ISA_HAS_CC_REGS
1155625Sgblack@eecs.umich.edu    RegVal ccRegs[TheISA::NumCCRegs];
1165625Sgblack@eecs.umich.edu#endif
1175625Sgblack@eecs.umich.edu    TheISA::ISA *const isa;    // one "instance" of the current ISA.
1185625Sgblack@eecs.umich.edu
1195625Sgblack@eecs.umich.edu    TheISA::PCState _pcState;
1205625Sgblack@eecs.umich.edu
1215625Sgblack@eecs.umich.edu    /** Did this instruction execute or is it predicated false */
1225625Sgblack@eecs.umich.edu    bool predicate;
1235625Sgblack@eecs.umich.edu
1245625Sgblack@eecs.umich.edu  public:
1255625Sgblack@eecs.umich.edu    std::string name() const
1265625Sgblack@eecs.umich.edu    {
1275625Sgblack@eecs.umich.edu        return csprintf("%s.[tid:%i]", baseCpu->name(), tc->threadId());
1285625Sgblack@eecs.umich.edu    }
1295625Sgblack@eecs.umich.edu
1305625Sgblack@eecs.umich.edu    ProxyThreadContext<SimpleThread> *tc;
1315625Sgblack@eecs.umich.edu
1325625Sgblack@eecs.umich.edu    System *system;
1335625Sgblack@eecs.umich.edu
1345625Sgblack@eecs.umich.edu    BaseTLB *itb;
1355625Sgblack@eecs.umich.edu    BaseTLB *dtb;
1365625Sgblack@eecs.umich.edu
1375625Sgblack@eecs.umich.edu    TheISA::Decoder decoder;
1385625Sgblack@eecs.umich.edu
1395625Sgblack@eecs.umich.edu    // constructor: initialize SimpleThread from given process structure
1405625Sgblack@eecs.umich.edu    // FS
1415625Sgblack@eecs.umich.edu    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
1425625Sgblack@eecs.umich.edu                 BaseTLB *_itb, BaseTLB *_dtb, TheISA::ISA *_isa,
1435625Sgblack@eecs.umich.edu                 bool use_kernel_stats = true);
1445625Sgblack@eecs.umich.edu    // SE
1455625Sgblack@eecs.umich.edu    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
1465625Sgblack@eecs.umich.edu                 Process *_process, BaseTLB *_itb, BaseTLB *_dtb,
1475625Sgblack@eecs.umich.edu                 TheISA::ISA *_isa);
1485625Sgblack@eecs.umich.edu
1495625Sgblack@eecs.umich.edu    virtual ~SimpleThread();
1505625Sgblack@eecs.umich.edu
1515625Sgblack@eecs.umich.edu    virtual void takeOverFrom(ThreadContext *oldContext);
1525625Sgblack@eecs.umich.edu
1535625Sgblack@eecs.umich.edu    void regStats(const std::string &name);
1545625Sgblack@eecs.umich.edu
1555625Sgblack@eecs.umich.edu    void copyState(ThreadContext *oldContext);
1565625Sgblack@eecs.umich.edu
1575625Sgblack@eecs.umich.edu    void serialize(CheckpointOut &cp) const override;
1585625Sgblack@eecs.umich.edu    void unserialize(CheckpointIn &cp) override;
1595625Sgblack@eecs.umich.edu    void startup();
1605625Sgblack@eecs.umich.edu
1615625Sgblack@eecs.umich.edu    /***************************************************************
1625625Sgblack@eecs.umich.edu     *  SimpleThread functions to provide CPU with access to various
1635625Sgblack@eecs.umich.edu     *  state.
1645625Sgblack@eecs.umich.edu     **************************************************************/
1655625Sgblack@eecs.umich.edu
1665625Sgblack@eecs.umich.edu    /** Returns the pointer to this SimpleThread's ThreadContext. Used
1675625Sgblack@eecs.umich.edu     *  when a ThreadContext must be passed to objects outside of the
1685625Sgblack@eecs.umich.edu     *  CPU.
1695625Sgblack@eecs.umich.edu     */
1705625Sgblack@eecs.umich.edu    ThreadContext *getTC() { return tc; }
1715625Sgblack@eecs.umich.edu
1725625Sgblack@eecs.umich.edu    void demapPage(Addr vaddr, uint64_t asn)
1735625Sgblack@eecs.umich.edu    {
1745625Sgblack@eecs.umich.edu        itb->demapPage(vaddr, asn);
1755625Sgblack@eecs.umich.edu        dtb->demapPage(vaddr, asn);
1765625Sgblack@eecs.umich.edu    }
1775625Sgblack@eecs.umich.edu
1785625Sgblack@eecs.umich.edu    void demapInstPage(Addr vaddr, uint64_t asn)
1795625Sgblack@eecs.umich.edu    {
1805625Sgblack@eecs.umich.edu        itb->demapPage(vaddr, asn);
1815625Sgblack@eecs.umich.edu    }
1825625Sgblack@eecs.umich.edu
1835625Sgblack@eecs.umich.edu    void demapDataPage(Addr vaddr, uint64_t asn)
1845625Sgblack@eecs.umich.edu    {
1855625Sgblack@eecs.umich.edu        dtb->demapPage(vaddr, asn);
1865625Sgblack@eecs.umich.edu    }
1875625Sgblack@eecs.umich.edu
1885625Sgblack@eecs.umich.edu    void dumpFuncProfile();
1895625Sgblack@eecs.umich.edu
1905625Sgblack@eecs.umich.edu    Fault hwrei();
1915625Sgblack@eecs.umich.edu
1925625Sgblack@eecs.umich.edu    bool simPalCheck(int palFunc);
1935625Sgblack@eecs.umich.edu
1945625Sgblack@eecs.umich.edu    /*******************************************
1955625Sgblack@eecs.umich.edu     * ThreadContext interface functions.
1965625Sgblack@eecs.umich.edu     ******************************************/
1975625Sgblack@eecs.umich.edu
1985625Sgblack@eecs.umich.edu    BaseCPU *getCpuPtr() { return baseCpu; }
1995625Sgblack@eecs.umich.edu
2005625Sgblack@eecs.umich.edu    BaseTLB *getITBPtr() { return itb; }
2015625Sgblack@eecs.umich.edu
2025625Sgblack@eecs.umich.edu    BaseTLB *getDTBPtr() { return dtb; }
2035625Sgblack@eecs.umich.edu
2045625Sgblack@eecs.umich.edu    CheckerCPU *getCheckerCpuPtr() { return NULL; }
2055625Sgblack@eecs.umich.edu
2065625Sgblack@eecs.umich.edu    TheISA::Decoder *getDecoderPtr() { return &decoder; }
2075625Sgblack@eecs.umich.edu
2085625Sgblack@eecs.umich.edu    System *getSystemPtr() { return system; }
2095625Sgblack@eecs.umich.edu
2105625Sgblack@eecs.umich.edu    Status status() const { return _status; }
2115625Sgblack@eecs.umich.edu
2125625Sgblack@eecs.umich.edu    void setStatus(Status newStatus) { _status = newStatus; }
2135625Sgblack@eecs.umich.edu
2145625Sgblack@eecs.umich.edu    /// Set the status to Active.
2155625Sgblack@eecs.umich.edu    void activate();
2165625Sgblack@eecs.umich.edu
2175625Sgblack@eecs.umich.edu    /// Set the status to Suspended.
2185625Sgblack@eecs.umich.edu    void suspend();
2195625Sgblack@eecs.umich.edu
2205625Sgblack@eecs.umich.edu    /// Set the status to Halted.
2215625Sgblack@eecs.umich.edu    void halt();
2225625Sgblack@eecs.umich.edu
2235625Sgblack@eecs.umich.edu    void copyArchRegs(ThreadContext *tc);
2245625Sgblack@eecs.umich.edu
2255625Sgblack@eecs.umich.edu    void clearArchRegs()
2265625Sgblack@eecs.umich.edu    {
2275625Sgblack@eecs.umich.edu        _pcState = 0;
2285625Sgblack@eecs.umich.edu        memset(intRegs, 0, sizeof(intRegs));
2295625Sgblack@eecs.umich.edu        memset(floatRegs, 0, sizeof(floatRegs));
2305625Sgblack@eecs.umich.edu        for (int i = 0; i < TheISA::NumVecRegs; i++) {
2315625Sgblack@eecs.umich.edu            vecRegs[i].zero();
2325625Sgblack@eecs.umich.edu        }
2335625Sgblack@eecs.umich.edu        for (int i = 0; i < TheISA::NumVecPredRegs; i++) {
2345625Sgblack@eecs.umich.edu            vecPredRegs[i].reset();
2355625Sgblack@eecs.umich.edu        }
2365625Sgblack@eecs.umich.edu#ifdef ISA_HAS_CC_REGS
2375625Sgblack@eecs.umich.edu        memset(ccRegs, 0, sizeof(ccRegs));
2385625Sgblack@eecs.umich.edu#endif
2395625Sgblack@eecs.umich.edu        isa->clear();
2405625Sgblack@eecs.umich.edu    }
2415625Sgblack@eecs.umich.edu
2425625Sgblack@eecs.umich.edu    //
2435625Sgblack@eecs.umich.edu    // New accessors for new decoder.
2445625Sgblack@eecs.umich.edu    //
2455625Sgblack@eecs.umich.edu    RegVal
2465625Sgblack@eecs.umich.edu    readIntReg(int reg_idx)
2475625Sgblack@eecs.umich.edu    {
2485625Sgblack@eecs.umich.edu        int flatIndex = isa->flattenIntIndex(reg_idx);
2495625Sgblack@eecs.umich.edu        assert(flatIndex < TheISA::NumIntRegs);
2505625Sgblack@eecs.umich.edu        uint64_t regVal(readIntRegFlat(flatIndex));
2515625Sgblack@eecs.umich.edu        DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
2525625Sgblack@eecs.umich.edu                reg_idx, flatIndex, regVal);
2535625Sgblack@eecs.umich.edu        return regVal;
2545625Sgblack@eecs.umich.edu    }
2555625Sgblack@eecs.umich.edu
2565625Sgblack@eecs.umich.edu    RegVal
2575625Sgblack@eecs.umich.edu    readFloatReg(int reg_idx)
2585625Sgblack@eecs.umich.edu    {
2595625Sgblack@eecs.umich.edu        int flatIndex = isa->flattenFloatIndex(reg_idx);
2605625Sgblack@eecs.umich.edu        assert(flatIndex < TheISA::NumFloatRegs);
2615625Sgblack@eecs.umich.edu        RegVal regVal(readFloatRegFlat(flatIndex));
2625625Sgblack@eecs.umich.edu        DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n",
2635625Sgblack@eecs.umich.edu                reg_idx, flatIndex, regVal);
2645625Sgblack@eecs.umich.edu        return regVal;
2655625Sgblack@eecs.umich.edu    }
2665625Sgblack@eecs.umich.edu
2675625Sgblack@eecs.umich.edu    const VecRegContainer&
2685625Sgblack@eecs.umich.edu    readVecReg(const RegId& reg) const
2695625Sgblack@eecs.umich.edu    {
2705625Sgblack@eecs.umich.edu        int flatIndex = isa->flattenVecIndex(reg.index());
2715625Sgblack@eecs.umich.edu        assert(flatIndex < TheISA::NumVecRegs);
2725625Sgblack@eecs.umich.edu        const VecRegContainer& regVal = readVecRegFlat(flatIndex);
2735625Sgblack@eecs.umich.edu        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
2745625Sgblack@eecs.umich.edu                reg.index(), flatIndex, regVal.print());
2755625Sgblack@eecs.umich.edu        return regVal;
2765625Sgblack@eecs.umich.edu    }
2775625Sgblack@eecs.umich.edu
2785625Sgblack@eecs.umich.edu    VecRegContainer&
2795625Sgblack@eecs.umich.edu    getWritableVecReg(const RegId& reg)
2805625Sgblack@eecs.umich.edu    {
2815625Sgblack@eecs.umich.edu        int flatIndex = isa->flattenVecIndex(reg.index());
2825625Sgblack@eecs.umich.edu        assert(flatIndex < TheISA::NumVecRegs);
2835625Sgblack@eecs.umich.edu        VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
2845625Sgblack@eecs.umich.edu        DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
2855625Sgblack@eecs.umich.edu                reg.index(), flatIndex, regVal.print());
2865625Sgblack@eecs.umich.edu        return regVal;
2875625Sgblack@eecs.umich.edu    }
2885625Sgblack@eecs.umich.edu
2895625Sgblack@eecs.umich.edu    /** Vector Register Lane Interfaces. */
2905625Sgblack@eecs.umich.edu    /** @{ */
2915625Sgblack@eecs.umich.edu    /** Reads source vector <T> operand. */
2925625Sgblack@eecs.umich.edu    template <typename T>
2935625Sgblack@eecs.umich.edu    VecLaneT<T, true>
2945625Sgblack@eecs.umich.edu    readVecLane(const RegId& reg) const
2955625Sgblack@eecs.umich.edu    {
2965625Sgblack@eecs.umich.edu        int flatIndex = isa->flattenVecIndex(reg.index());
2975625Sgblack@eecs.umich.edu        assert(flatIndex < TheISA::NumVecRegs);
2985625Sgblack@eecs.umich.edu        auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex());
2995625Sgblack@eecs.umich.edu        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n",
3005625Sgblack@eecs.umich.edu                reg.index(), flatIndex, reg.elemIndex(), regVal);
3015625Sgblack@eecs.umich.edu        return regVal;
3025625Sgblack@eecs.umich.edu    }
3035625Sgblack@eecs.umich.edu
3045625Sgblack@eecs.umich.edu    /** Reads source vector 8bit operand. */
3055625Sgblack@eecs.umich.edu    virtual ConstVecLane8
3065625Sgblack@eecs.umich.edu    readVec8BitLaneReg(const RegId& reg) const
3075625Sgblack@eecs.umich.edu    { return readVecLane<uint8_t>(reg); }
3085625Sgblack@eecs.umich.edu
3095625Sgblack@eecs.umich.edu    /** Reads source vector 16bit operand. */
3105625Sgblack@eecs.umich.edu    virtual ConstVecLane16
3115625Sgblack@eecs.umich.edu    readVec16BitLaneReg(const RegId& reg) const
3125625Sgblack@eecs.umich.edu    { return readVecLane<uint16_t>(reg); }
3135625Sgblack@eecs.umich.edu
3145625Sgblack@eecs.umich.edu    /** Reads source vector 32bit operand. */
3155625Sgblack@eecs.umich.edu    virtual ConstVecLane32
3165625Sgblack@eecs.umich.edu    readVec32BitLaneReg(const RegId& reg) const
3175625Sgblack@eecs.umich.edu    { return readVecLane<uint32_t>(reg); }
3185625Sgblack@eecs.umich.edu
3195625Sgblack@eecs.umich.edu    /** Reads source vector 64bit operand. */
3205625Sgblack@eecs.umich.edu    virtual ConstVecLane64
3215625Sgblack@eecs.umich.edu    readVec64BitLaneReg(const RegId& reg) const
3225625Sgblack@eecs.umich.edu    { return readVecLane<uint64_t>(reg); }
3235625Sgblack@eecs.umich.edu
3245625Sgblack@eecs.umich.edu    /** Write a lane of the destination vector register. */
3255625Sgblack@eecs.umich.edu    template <typename LD>
3265625Sgblack@eecs.umich.edu    void setVecLaneT(const RegId& reg, const LD& val)
3275625Sgblack@eecs.umich.edu    {
3285625Sgblack@eecs.umich.edu        int flatIndex = isa->flattenVecIndex(reg.index());
3295625Sgblack@eecs.umich.edu        assert(flatIndex < TheISA::NumVecRegs);
3305625Sgblack@eecs.umich.edu        setVecLaneFlat(flatIndex, reg.elemIndex(), val);
331        DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n",
332                reg.index(), flatIndex, reg.elemIndex(), val);
333    }
334    virtual void setVecLane(const RegId& reg,
335            const LaneData<LaneSize::Byte>& val)
336    { return setVecLaneT(reg, val); }
337    virtual void setVecLane(const RegId& reg,
338            const LaneData<LaneSize::TwoByte>& val)
339    { return setVecLaneT(reg, val); }
340    virtual void setVecLane(const RegId& reg,
341            const LaneData<LaneSize::FourByte>& val)
342    { return setVecLaneT(reg, val); }
343    virtual void setVecLane(const RegId& reg,
344            const LaneData<LaneSize::EightByte>& val)
345    { return setVecLaneT(reg, val); }
346    /** @} */
347
348    const VecElem& readVecElem(const RegId& reg) const
349    {
350        int flatIndex = isa->flattenVecElemIndex(reg.index());
351        assert(flatIndex < TheISA::NumVecRegs);
352        const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex());
353        DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as"
354                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal);
355        return regVal;
356    }
357
358    const VecPredRegContainer&
359    readVecPredReg(const RegId& reg) const
360    {
361        int flatIndex = isa->flattenVecPredIndex(reg.index());
362        assert(flatIndex < TheISA::NumVecPredRegs);
363        const VecPredRegContainer& regVal = readVecPredRegFlat(flatIndex);
364        DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n",
365                reg.index(), flatIndex, regVal.print());
366        return regVal;
367    }
368
369    VecPredRegContainer&
370    getWritableVecPredReg(const RegId& reg)
371    {
372        int flatIndex = isa->flattenVecPredIndex(reg.index());
373        assert(flatIndex < TheISA::NumVecPredRegs);
374        VecPredRegContainer& regVal = getWritableVecPredRegFlat(flatIndex);
375        DPRINTF(VecPredRegs,
376                "Reading predicate reg %d (%d) as %s for modify.\n",
377                reg.index(), flatIndex, regVal.print());
378        return regVal;
379    }
380
381    RegVal
382    readCCReg(int reg_idx)
383    {
384#ifdef ISA_HAS_CC_REGS
385        int flatIndex = isa->flattenCCIndex(reg_idx);
386        assert(0 <= flatIndex);
387        assert(flatIndex < TheISA::NumCCRegs);
388        uint64_t regVal(readCCRegFlat(flatIndex));
389        DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
390                reg_idx, flatIndex, regVal);
391        return regVal;
392#else
393        panic("Tried to read a CC register.");
394        return 0;
395#endif
396    }
397
398    void
399    setIntReg(int reg_idx, RegVal val)
400    {
401        int flatIndex = isa->flattenIntIndex(reg_idx);
402        assert(flatIndex < TheISA::NumIntRegs);
403        DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
404                reg_idx, flatIndex, val);
405        setIntRegFlat(flatIndex, val);
406    }
407
408    void
409    setFloatReg(int reg_idx, RegVal val)
410    {
411        int flatIndex = isa->flattenFloatIndex(reg_idx);
412        assert(flatIndex < TheISA::NumFloatRegs);
413        // XXX: Fix array out of bounds compiler error for gem5.fast
414        // when checkercpu enabled
415        if (flatIndex < TheISA::NumFloatRegs)
416            setFloatRegFlat(flatIndex, val);
417        DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n",
418                reg_idx, flatIndex, val);
419    }
420
421    void
422    setVecReg(const RegId& reg, const VecRegContainer& val)
423    {
424        int flatIndex = isa->flattenVecIndex(reg.index());
425        assert(flatIndex < TheISA::NumVecRegs);
426        setVecRegFlat(flatIndex, val);
427        DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
428                reg.index(), flatIndex, val.print());
429    }
430
431    void
432    setVecElem(const RegId& reg, const VecElem& val)
433    {
434        int flatIndex = isa->flattenVecElemIndex(reg.index());
435        assert(flatIndex < TheISA::NumVecRegs);
436        setVecElemFlat(flatIndex, reg.elemIndex(), val);
437        DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to"
438                " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val);
439    }
440
441    void
442    setVecPredReg(const RegId& reg, const VecPredRegContainer& val)
443    {
444        int flatIndex = isa->flattenVecPredIndex(reg.index());
445        assert(flatIndex < TheISA::NumVecPredRegs);
446        setVecPredRegFlat(flatIndex, val);
447        DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n",
448                reg.index(), flatIndex, val.print());
449    }
450
451    void
452    setCCReg(int reg_idx, RegVal val)
453    {
454#ifdef ISA_HAS_CC_REGS
455        int flatIndex = isa->flattenCCIndex(reg_idx);
456        assert(flatIndex < TheISA::NumCCRegs);
457        DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n",
458                reg_idx, flatIndex, val);
459        setCCRegFlat(flatIndex, val);
460#else
461        panic("Tried to set a CC register.");
462#endif
463    }
464
465    TheISA::PCState
466    pcState()
467    {
468        return _pcState;
469    }
470
471    void
472    pcState(const TheISA::PCState &val)
473    {
474        _pcState = val;
475    }
476
477    void
478    pcStateNoRecord(const TheISA::PCState &val)
479    {
480        _pcState = val;
481    }
482
483    Addr
484    instAddr()
485    {
486        return _pcState.instAddr();
487    }
488
489    Addr
490    nextInstAddr()
491    {
492        return _pcState.nextInstAddr();
493    }
494
495    void
496    setNPC(Addr val)
497    {
498        _pcState.setNPC(val);
499    }
500
501    MicroPC
502    microPC()
503    {
504        return _pcState.microPC();
505    }
506
507    bool readPredicate()
508    {
509        return predicate;
510    }
511
512    void setPredicate(bool val)
513    {
514        predicate = val;
515    }
516
517    RegVal
518    readMiscRegNoEffect(int misc_reg, ThreadID tid=0) const
519    {
520        return isa->readMiscRegNoEffect(misc_reg);
521    }
522
523    RegVal
524    readMiscReg(int misc_reg, ThreadID tid=0)
525    {
526        return isa->readMiscReg(misc_reg, tc);
527    }
528
529    void
530    setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid = 0)
531    {
532        return isa->setMiscRegNoEffect(misc_reg, val);
533    }
534
535    void
536    setMiscReg(int misc_reg, RegVal val, ThreadID tid = 0)
537    {
538        return isa->setMiscReg(misc_reg, val, tc);
539    }
540
541    RegId
542    flattenRegId(const RegId& regId) const
543    {
544        return isa->flattenRegId(regId);
545    }
546
547    unsigned readStCondFailures() { return storeCondFailures; }
548
549    void setStCondFailures(unsigned sc_failures)
550    { storeCondFailures = sc_failures; }
551
552    void
553    syscall(int64_t callnum, Fault *fault)
554    {
555        process->syscall(callnum, tc, fault);
556    }
557
558    RegVal readIntRegFlat(int idx) { return intRegs[idx]; }
559    void setIntRegFlat(int idx, RegVal val) { intRegs[idx] = val; }
560
561    RegVal readFloatRegFlat(int idx) { return floatRegs[idx]; }
562    void setFloatRegFlat(int idx, RegVal val) { floatRegs[idx] = val; }
563
564    const VecRegContainer &
565    readVecRegFlat(const RegIndex& reg) const
566    {
567        return vecRegs[reg];
568    }
569
570    VecRegContainer &
571    getWritableVecRegFlat(const RegIndex& reg)
572    {
573        return vecRegs[reg];
574    }
575
576    void
577    setVecRegFlat(const RegIndex& reg, const VecRegContainer& val)
578    {
579        vecRegs[reg] = val;
580    }
581
582    template <typename T>
583    VecLaneT<T, true>
584    readVecLaneFlat(const RegIndex& reg, int lId) const
585    {
586        return vecRegs[reg].laneView<T>(lId);
587    }
588
589    template <typename LD>
590    void
591    setVecLaneFlat(const RegIndex& reg, int lId, const LD& val)
592    {
593        vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val;
594    }
595
596    const VecElem &
597    readVecElemFlat(const RegIndex& reg, const ElemIndex& elemIndex) const
598    {
599        return vecRegs[reg].as<TheISA::VecElem>()[elemIndex];
600    }
601
602    void
603    setVecElemFlat(const RegIndex& reg, const ElemIndex& elemIndex,
604                   const VecElem val)
605    {
606        vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val;
607    }
608
609    const VecPredRegContainer& readVecPredRegFlat(const RegIndex& reg) const
610    {
611        return vecPredRegs[reg];
612    }
613
614    VecPredRegContainer& getWritableVecPredRegFlat(const RegIndex& reg)
615    {
616        return vecPredRegs[reg];
617    }
618
619    void setVecPredRegFlat(const RegIndex& reg, const VecPredRegContainer& val)
620    {
621        vecPredRegs[reg] = val;
622    }
623
624#ifdef ISA_HAS_CC_REGS
625    RegVal readCCRegFlat(int idx) { return ccRegs[idx]; }
626    void setCCRegFlat(int idx, RegVal val) { ccRegs[idx] = val; }
627#else
628    RegVal readCCRegFlat(int idx)
629    { panic("readCCRegFlat w/no CC regs!\n"); }
630
631    void setCCRegFlat(int idx, RegVal val)
632    { panic("setCCRegFlat w/no CC regs!\n"); }
633#endif
634};
635
636
637#endif // __CPU_CPU_EXEC_CONTEXT_HH__
638