cpu.hh revision 13610:5d5404ac6288
14188Sgblack@eecs.umich.edu/*
24188Sgblack@eecs.umich.edu * Copyright (c) 2011, 2016-2017 ARM Limited
34188Sgblack@eecs.umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc.
44188Sgblack@eecs.umich.edu * All rights reserved
54188Sgblack@eecs.umich.edu *
64188Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
74188Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
84188Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
94188Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
104188Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
114188Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
124188Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
134188Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
144188Sgblack@eecs.umich.edu *
154188Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
164188Sgblack@eecs.umich.edu * All rights reserved.
174188Sgblack@eecs.umich.edu *
184188Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
194188Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
204188Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
214188Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
224188Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
234188Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
244188Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
254188Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
264188Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
274188Sgblack@eecs.umich.edu * this software without specific prior written permission.
284188Sgblack@eecs.umich.edu *
294188Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
304188Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
314188Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3211794Sbrandon.potter@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
334188Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
344188Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3511851Sbrandon.potter@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
364188Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
374188Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
384188Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
394188Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
404188Sgblack@eecs.umich.edu *
414188Sgblack@eecs.umich.edu * Authors: Kevin Lim
4213995Sbrandon.potter@amd.com */
434188Sgblack@eecs.umich.edu
446701Sgblack@eecs.umich.edu#ifndef __CPU_CHECKER_CPU_HH__
4513995Sbrandon.potter@amd.com#define __CPU_CHECKER_CPU_HH__
466701Sgblack@eecs.umich.edu
474188Sgblack@eecs.umich.edu#include <list>
484188Sgblack@eecs.umich.edu#include <map>
499149SAli.Saidi@ARM.com#include <queue>
5014014Sciro.santilli@arm.com
514188Sgblack@eecs.umich.edu#include "arch/types.hh"
524188Sgblack@eecs.umich.edu#include "base/statistics.hh"
534188Sgblack@eecs.umich.edu#include "cpu/base.hh"
5414024Sgabeblack@google.com#include "cpu/base_dyn_inst.hh"
554188Sgblack@eecs.umich.edu#include "cpu/exec_context.hh"
564188Sgblack@eecs.umich.edu#include "cpu/inst_res.hh"
574188Sgblack@eecs.umich.edu#include "cpu/pc_event.hh"
584188Sgblack@eecs.umich.edu#include "cpu/simple_thread.hh"
594188Sgblack@eecs.umich.edu#include "cpu/static_inst.hh"
607741Sgblack@eecs.umich.edu#include "debug/Checker.hh"
6113995Sbrandon.potter@amd.com#include "mem/request.hh"
624188Sgblack@eecs.umich.edu#include "params/CheckerCPU.hh"
6313583Sgabeblack@google.com#include "sim/eventq.hh"
646701Sgblack@eecs.umich.edu
6513995Sbrandon.potter@amd.comclass BaseTLB;
666701Sgblack@eecs.umich.edutemplate <class>
676701Sgblack@eecs.umich.educlass BaseDynInst;
686701Sgblack@eecs.umich.educlass ThreadContext;
697741Sgblack@eecs.umich.educlass Request;
707741Sgblack@eecs.umich.edu
717741Sgblack@eecs.umich.edu/**
7213583Sgabeblack@google.com * CheckerCPU class.  Dynamically verifies instructions as they are
7313583Sgabeblack@google.com * completed by making sure that the instruction and its results match
7414024Sgabeblack@google.com * the independent execution of the benchmark inside the checker.  The
754188Sgblack@eecs.umich.edu * checker verifies instructions in order, regardless of the order in
767741Sgblack@eecs.umich.edu * which instructions complete.  There are certain results that can
777741Sgblack@eecs.umich.edu * not be verified, specifically the result of a store conditional or
7813583Sgabeblack@google.com * the values of uncached accesses.  In these cases, and with
7913583Sgabeblack@google.com * instructions marked as "IsUnverifiable", the checker assumes that
8014024Sgabeblack@google.com * the value from the main CPU's execution is correct and simply
814188Sgblack@eecs.umich.edu * copies that value.  It provides a CheckerThreadContext (see
827741Sgblack@eecs.umich.edu * checker/thread_context.hh) that provides hooks for updating the
837741Sgblack@eecs.umich.edu * Checker's state through any ThreadContext accesses.  This allows the
8413583Sgabeblack@google.com * checker to be able to correctly verify instructions, even with
8513583Sgabeblack@google.com * external accesses to the ThreadContext that change state.
8614024Sgabeblack@google.com */
874188Sgblack@eecs.umich.educlass CheckerCPU : public BaseCPU, public ExecContext
884188Sgblack@eecs.umich.edu{
894188Sgblack@eecs.umich.edu  protected:
904188Sgblack@eecs.umich.edu    typedef TheISA::MachInst MachInst;
914188Sgblack@eecs.umich.edu    using VecRegContainer = TheISA::VecRegContainer;
924188Sgblack@eecs.umich.edu
937741Sgblack@eecs.umich.edu    /** id attached to all issued requests */
944188Sgblack@eecs.umich.edu    MasterID masterId;
9513570Sbrandon.potter@amd.com  public:
9613570Sbrandon.potter@amd.com    void init() override;
977741Sgblack@eecs.umich.edu
984188Sgblack@eecs.umich.edu    typedef CheckerCPUParams Params;
997741Sgblack@eecs.umich.edu    CheckerCPU(Params *p);
1007741Sgblack@eecs.umich.edu    virtual ~CheckerCPU();
1014188Sgblack@eecs.umich.edu
1024188Sgblack@eecs.umich.edu    void setSystem(System *system);
1034188Sgblack@eecs.umich.edu
1044188Sgblack@eecs.umich.edu    void setIcachePort(MasterPort *icache_port);
1057741Sgblack@eecs.umich.edu
1064188Sgblack@eecs.umich.edu    void setDcachePort(MasterPort *dcache_port);
1074188Sgblack@eecs.umich.edu
1087741Sgblack@eecs.umich.edu    MasterPort &getDataPort() override
1095748SSteve.Reinhardt@amd.com    {
1107741Sgblack@eecs.umich.edu        // the checker does not have ports on its own so return the
1117741Sgblack@eecs.umich.edu        // data port of the actual CPU core
1124188Sgblack@eecs.umich.edu        assert(dcachePort);
1134188Sgblack@eecs.umich.edu        return *dcachePort;
1144188Sgblack@eecs.umich.edu    }
1157741Sgblack@eecs.umich.edu
1167741Sgblack@eecs.umich.edu    MasterPort &getInstPort() override
1174188Sgblack@eecs.umich.edu    {
1184188Sgblack@eecs.umich.edu        // the checker does not have ports on its own so return the
1194188Sgblack@eecs.umich.edu        // data port of the actual CPU core
1207741Sgblack@eecs.umich.edu        assert(icachePort);
1217741Sgblack@eecs.umich.edu        return *icachePort;
1224188Sgblack@eecs.umich.edu    }
1234188Sgblack@eecs.umich.edu
1244188Sgblack@eecs.umich.edu  protected:
1257741Sgblack@eecs.umich.edu
1267741Sgblack@eecs.umich.edu    std::vector<Process*> workload;
1274188Sgblack@eecs.umich.edu
1284188Sgblack@eecs.umich.edu    System *systemPtr;
1297741Sgblack@eecs.umich.edu
1304188Sgblack@eecs.umich.edu    MasterPort *icachePort;
1317741Sgblack@eecs.umich.edu    MasterPort *dcachePort;
1324188Sgblack@eecs.umich.edu
1334188Sgblack@eecs.umich.edu    ThreadContext *tc;
1344188Sgblack@eecs.umich.edu
1354264Sgblack@eecs.umich.edu    BaseTLB *itb;
1364188Sgblack@eecs.umich.edu    BaseTLB *dtb;
1377741Sgblack@eecs.umich.edu
1387741Sgblack@eecs.umich.edu    Addr dbg_vtophys(Addr addr);
1397741Sgblack@eecs.umich.edu
1407741Sgblack@eecs.umich.edu    // ISAs like ARM can have multiple destination registers to check,
1417741Sgblack@eecs.umich.edu    // keep them all in a std::queue
1427741Sgblack@eecs.umich.edu    std::queue<InstResult> result;
1434188Sgblack@eecs.umich.edu
1444188Sgblack@eecs.umich.edu    StaticInstPtr curStaticInst;
1454188Sgblack@eecs.umich.edu    StaticInstPtr curMacroStaticInst;
1464188Sgblack@eecs.umich.edu
1477741Sgblack@eecs.umich.edu    // number of simulated instructions
1487741Sgblack@eecs.umich.edu    Counter numInst;
1494188Sgblack@eecs.umich.edu    Counter startNumInst;
1507741Sgblack@eecs.umich.edu
1517741Sgblack@eecs.umich.edu    std::queue<int> miscRegIdxs;
1527741Sgblack@eecs.umich.edu
1534188Sgblack@eecs.umich.edu  public:
1544188Sgblack@eecs.umich.edu
1554188Sgblack@eecs.umich.edu    // Primary thread being run.
1564188Sgblack@eecs.umich.edu    SimpleThread *thread;
1577741Sgblack@eecs.umich.edu
1584188Sgblack@eecs.umich.edu    BaseTLB* getITBPtr() { return itb; }
1597741Sgblack@eecs.umich.edu    BaseTLB* getDTBPtr() { return dtb; }
1607741Sgblack@eecs.umich.edu
1614188Sgblack@eecs.umich.edu    virtual Counter totalInsts() const override
1624188Sgblack@eecs.umich.edu    {
1634188Sgblack@eecs.umich.edu        return 0;
1644188Sgblack@eecs.umich.edu    }
1654188Sgblack@eecs.umich.edu
1666109Ssanchezd@stanford.edu    virtual Counter totalOps() const override
1674188Sgblack@eecs.umich.edu    {
1684188Sgblack@eecs.umich.edu        return 0;
1697741Sgblack@eecs.umich.edu    }
1704188Sgblack@eecs.umich.edu
1717741Sgblack@eecs.umich.edu    // number of simulated loads
1727741Sgblack@eecs.umich.edu    Counter numLoad;
1734188Sgblack@eecs.umich.edu    Counter startNumLoad;
1747741Sgblack@eecs.umich.edu
1757741Sgblack@eecs.umich.edu    void serialize(CheckpointOut &cp) const override;
1767741Sgblack@eecs.umich.edu    void unserialize(CheckpointIn &cp) override;
1777741Sgblack@eecs.umich.edu
1787741Sgblack@eecs.umich.edu    // The register accessor methods provide the index of the
1794188Sgblack@eecs.umich.edu    // instruction's operand (e.g., 0 or 1), not the architectural
1807741Sgblack@eecs.umich.edu    // register index, to simplify the implementation of register
1814188Sgblack@eecs.umich.edu    // renaming.  We find the architectural register index by indexing
1824188Sgblack@eecs.umich.edu    // into the instruction's own operand index table.  Note that a
1834188Sgblack@eecs.umich.edu    // raw pointer to the StaticInst is provided instead of a
1844188Sgblack@eecs.umich.edu    // ref-counted StaticInstPtr to redice overhead.  This is fine as
1857741Sgblack@eecs.umich.edu    // long as these methods don't copy the pointer into any long-term
1864188Sgblack@eecs.umich.edu    // storage (which is pretty hard to imagine they would have reason
1874188Sgblack@eecs.umich.edu    // to do).
1887741Sgblack@eecs.umich.edu
1894188Sgblack@eecs.umich.edu    RegVal
1904188Sgblack@eecs.umich.edu    readIntRegOperand(const StaticInst *si, int idx) override
1914188Sgblack@eecs.umich.edu    {
1927741Sgblack@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
1937741Sgblack@eecs.umich.edu        assert(reg.isIntReg());
1947741Sgblack@eecs.umich.edu        return thread->readIntReg(reg.index());
1957741Sgblack@eecs.umich.edu    }
1967741Sgblack@eecs.umich.edu
1974188Sgblack@eecs.umich.edu    RegVal
1987741Sgblack@eecs.umich.edu    readFloatRegOperandBits(const StaticInst *si, int idx) override
1994188Sgblack@eecs.umich.edu    {
2004188Sgblack@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
2014188Sgblack@eecs.umich.edu        assert(reg.isFloatReg());
2026109Ssanchezd@stanford.edu        return thread->readFloatRegBits(reg.index());
2034188Sgblack@eecs.umich.edu    }
2044188Sgblack@eecs.umich.edu
2054188Sgblack@eecs.umich.edu    /**
2064188Sgblack@eecs.umich.edu     * Read source vector register operand.
2077741Sgblack@eecs.umich.edu     */
2087741Sgblack@eecs.umich.edu    const VecRegContainer &
2097741Sgblack@eecs.umich.edu    readVecRegOperand(const StaticInst *si, int idx) const override
2104188Sgblack@eecs.umich.edu    {
2115513SMichael.Adler@intel.com        const RegId& reg = si->srcRegIdx(idx);
2124188Sgblack@eecs.umich.edu        assert(reg.isVecReg());
2134188Sgblack@eecs.umich.edu        return thread->readVecReg(reg);
2147741Sgblack@eecs.umich.edu    }
2157741Sgblack@eecs.umich.edu
2164188Sgblack@eecs.umich.edu    /**
2174188Sgblack@eecs.umich.edu     * Read destination vector register operand for modification.
2187741Sgblack@eecs.umich.edu     */
2197741Sgblack@eecs.umich.edu    VecRegContainer &
2204236Sgblack@eecs.umich.edu    getWritableVecRegOperand(const StaticInst *si, int idx) override
2214188Sgblack@eecs.umich.edu    {
2224188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
2234188Sgblack@eecs.umich.edu        assert(reg.isVecReg());
2244188Sgblack@eecs.umich.edu        return thread->getWritableVecReg(reg);
2254188Sgblack@eecs.umich.edu    }
2264188Sgblack@eecs.umich.edu
2274188Sgblack@eecs.umich.edu    /** Vector Register Lane Interfaces. */
2287741Sgblack@eecs.umich.edu    /** @{ */
2294188Sgblack@eecs.umich.edu    /** Reads source vector 8bit operand. */
2307741Sgblack@eecs.umich.edu    virtual ConstVecLane8
2314188Sgblack@eecs.umich.edu    readVec8BitLaneOperand(const StaticInst *si, int idx) const override
2327741Sgblack@eecs.umich.edu    {
2334188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
2347741Sgblack@eecs.umich.edu        assert(reg.isVecReg());
2354188Sgblack@eecs.umich.edu        return thread->readVec8BitLaneReg(reg);
2364188Sgblack@eecs.umich.edu    }
2374188Sgblack@eecs.umich.edu
2384188Sgblack@eecs.umich.edu    /** Reads source vector 16bit operand. */
2397741Sgblack@eecs.umich.edu    virtual ConstVecLane16
2404188Sgblack@eecs.umich.edu    readVec16BitLaneOperand(const StaticInst *si, int idx) const override
2414188Sgblack@eecs.umich.edu    {
2424188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
2434188Sgblack@eecs.umich.edu        assert(reg.isVecReg());
2444188Sgblack@eecs.umich.edu        return thread->readVec16BitLaneReg(reg);
2454188Sgblack@eecs.umich.edu    }
24610495Snilay@cs.wisc.edu
2474188Sgblack@eecs.umich.edu    /** Reads source vector 32bit operand. */
2484188Sgblack@eecs.umich.edu    virtual ConstVecLane32
2494188Sgblack@eecs.umich.edu    readVec32BitLaneOperand(const StaticInst *si, int idx) const override
2504188Sgblack@eecs.umich.edu    {
2514188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
2524188Sgblack@eecs.umich.edu        assert(reg.isVecReg());
2534188Sgblack@eecs.umich.edu        return thread->readVec32BitLaneReg(reg);
2547741Sgblack@eecs.umich.edu    }
2557741Sgblack@eecs.umich.edu
2564188Sgblack@eecs.umich.edu    /** Reads source vector 64bit operand. */
2574188Sgblack@eecs.umich.edu    virtual ConstVecLane64
2584188Sgblack@eecs.umich.edu    readVec64BitLaneOperand(const StaticInst *si, int idx) const override
2594188Sgblack@eecs.umich.edu    {
2604188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
2617741Sgblack@eecs.umich.edu        assert(reg.isVecReg());
2627741Sgblack@eecs.umich.edu        return thread->readVec64BitLaneReg(reg);
2637741Sgblack@eecs.umich.edu    }
2644188Sgblack@eecs.umich.edu
2654188Sgblack@eecs.umich.edu    /** Write a lane of the destination vector operand. */
26610495Snilay@cs.wisc.edu    template <typename LD>
2674188Sgblack@eecs.umich.edu    void
2684188Sgblack@eecs.umich.edu    setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
2697741Sgblack@eecs.umich.edu    {
2704188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
2714188Sgblack@eecs.umich.edu        assert(reg.isVecReg());
2727741Sgblack@eecs.umich.edu        return thread->setVecLane(reg, val);
2734188Sgblack@eecs.umich.edu    }
2744188Sgblack@eecs.umich.edu    virtual void
2754188Sgblack@eecs.umich.edu    setVecLaneOperand(const StaticInst *si, int idx,
2764188Sgblack@eecs.umich.edu            const LaneData<LaneSize::Byte>& val) override
2777741Sgblack@eecs.umich.edu    {
2787741Sgblack@eecs.umich.edu        setVecLaneOperandT(si, idx, val);
2797741Sgblack@eecs.umich.edu    }
2807741Sgblack@eecs.umich.edu    virtual void
2814188Sgblack@eecs.umich.edu    setVecLaneOperand(const StaticInst *si, int idx,
2827741Sgblack@eecs.umich.edu            const LaneData<LaneSize::TwoByte>& val) override
2834188Sgblack@eecs.umich.edu    {
2844188Sgblack@eecs.umich.edu        setVecLaneOperandT(si, idx, val);
2857741Sgblack@eecs.umich.edu    }
2867741Sgblack@eecs.umich.edu    virtual void
2877741Sgblack@eecs.umich.edu    setVecLaneOperand(const StaticInst *si, int idx,
2887741Sgblack@eecs.umich.edu            const LaneData<LaneSize::FourByte>& val) override
2894188Sgblack@eecs.umich.edu    {
2907741Sgblack@eecs.umich.edu        setVecLaneOperandT(si, idx, val);
2914188Sgblack@eecs.umich.edu    }
2924188Sgblack@eecs.umich.edu    virtual void
2934188Sgblack@eecs.umich.edu    setVecLaneOperand(const StaticInst *si, int idx,
2944188Sgblack@eecs.umich.edu            const LaneData<LaneSize::EightByte>& val) override
2954188Sgblack@eecs.umich.edu    {
2964188Sgblack@eecs.umich.edu        setVecLaneOperandT(si, idx, val);
2977741Sgblack@eecs.umich.edu    }
2987741Sgblack@eecs.umich.edu    /** @} */
2997741Sgblack@eecs.umich.edu
3007741Sgblack@eecs.umich.edu    VecElem
3017741Sgblack@eecs.umich.edu    readVecElemOperand(const StaticInst *si, int idx) const override
3027741Sgblack@eecs.umich.edu    {
3037741Sgblack@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
3047741Sgblack@eecs.umich.edu        return thread->readVecElem(reg);
3054188Sgblack@eecs.umich.edu    }
3067741Sgblack@eecs.umich.edu
3077741Sgblack@eecs.umich.edu    const VecPredRegContainer&
3087741Sgblack@eecs.umich.edu    readVecPredRegOperand(const StaticInst *si, int idx) const override
30911886Sbrandon.potter@amd.com    {
3107741Sgblack@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
3117741Sgblack@eecs.umich.edu        assert(reg.isVecPredReg());
3127741Sgblack@eecs.umich.edu        return thread->readVecPredReg(reg);
3134188Sgblack@eecs.umich.edu    }
3147741Sgblack@eecs.umich.edu
3154188Sgblack@eecs.umich.edu    VecPredRegContainer&
3167741Sgblack@eecs.umich.edu    getWritableVecPredRegOperand(const StaticInst *si, int idx) override
3177741Sgblack@eecs.umich.edu    {
3187741Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
3194188Sgblack@eecs.umich.edu        assert(reg.isVecPredReg());
3207741Sgblack@eecs.umich.edu        return thread->getWritableVecPredReg(reg);
3217741Sgblack@eecs.umich.edu    }
3227741Sgblack@eecs.umich.edu
3234264Sgblack@eecs.umich.edu    CCReg
3244188Sgblack@eecs.umich.edu    readCCRegOperand(const StaticInst *si, int idx) override
3254188Sgblack@eecs.umich.edu    {
3264188Sgblack@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
3274188Sgblack@eecs.umich.edu        assert(reg.isCCReg());
3284188Sgblack@eecs.umich.edu        return thread->readCCReg(reg.index());
3294188Sgblack@eecs.umich.edu    }
3304188Sgblack@eecs.umich.edu
3317741Sgblack@eecs.umich.edu    template<typename T>
3324188Sgblack@eecs.umich.edu    void
3337741Sgblack@eecs.umich.edu    setScalarResult(T&& t)
3347741Sgblack@eecs.umich.edu    {
3357741Sgblack@eecs.umich.edu        result.push(InstResult(std::forward<T>(t),
3367741Sgblack@eecs.umich.edu                               InstResult::ResultType::Scalar));
3374188Sgblack@eecs.umich.edu    }
3387741Sgblack@eecs.umich.edu
3397741Sgblack@eecs.umich.edu    template<typename T>
3407741Sgblack@eecs.umich.edu    void
3414188Sgblack@eecs.umich.edu    setVecResult(T&& t)
3427741Sgblack@eecs.umich.edu    {
3437741Sgblack@eecs.umich.edu        result.push(InstResult(std::forward<T>(t),
3447741Sgblack@eecs.umich.edu                               InstResult::ResultType::VecReg));
3454188Sgblack@eecs.umich.edu    }
3467741Sgblack@eecs.umich.edu
3474188Sgblack@eecs.umich.edu    template<typename T>
3484188Sgblack@eecs.umich.edu    void
3494188Sgblack@eecs.umich.edu    setVecElemResult(T&& t)
3504188Sgblack@eecs.umich.edu    {
3517741Sgblack@eecs.umich.edu        result.push(InstResult(std::forward<T>(t),
3524188Sgblack@eecs.umich.edu                               InstResult::ResultType::VecElem));
3534188Sgblack@eecs.umich.edu    }
3547741Sgblack@eecs.umich.edu
3554188Sgblack@eecs.umich.edu    template<typename T>
3564188Sgblack@eecs.umich.edu    void
3574188Sgblack@eecs.umich.edu    setVecPredResult(T&& t)
3584188Sgblack@eecs.umich.edu    {
3594188Sgblack@eecs.umich.edu        result.push(InstResult(std::forward<T>(t),
3604188Sgblack@eecs.umich.edu                               InstResult::ResultType::VecPredReg));
3614188Sgblack@eecs.umich.edu    }
3627741Sgblack@eecs.umich.edu
3634188Sgblack@eecs.umich.edu    void
3644188Sgblack@eecs.umich.edu    setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
3657741Sgblack@eecs.umich.edu    {
3664188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
3674188Sgblack@eecs.umich.edu        assert(reg.isIntReg());
3684188Sgblack@eecs.umich.edu        thread->setIntReg(reg.index(), val);
3694188Sgblack@eecs.umich.edu        setScalarResult(val);
3704188Sgblack@eecs.umich.edu    }
3714188Sgblack@eecs.umich.edu
3724188Sgblack@eecs.umich.edu    void
3734188Sgblack@eecs.umich.edu    setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
3744188Sgblack@eecs.umich.edu    {
3754188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
3764188Sgblack@eecs.umich.edu        assert(reg.isFloatReg());
3774188Sgblack@eecs.umich.edu        thread->setFloatRegBits(reg.index(), val);
3784188Sgblack@eecs.umich.edu        setScalarResult(val);
3794188Sgblack@eecs.umich.edu    }
3804188Sgblack@eecs.umich.edu
3814188Sgblack@eecs.umich.edu    void
3824188Sgblack@eecs.umich.edu    setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
3834188Sgblack@eecs.umich.edu    {
3844188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
3854188Sgblack@eecs.umich.edu        assert(reg.isCCReg());
3864188Sgblack@eecs.umich.edu        thread->setCCReg(reg.index(), val);
3874188Sgblack@eecs.umich.edu        setScalarResult((uint64_t)val);
3884188Sgblack@eecs.umich.edu    }
3894188Sgblack@eecs.umich.edu
3904188Sgblack@eecs.umich.edu    void
3914188Sgblack@eecs.umich.edu    setVecRegOperand(const StaticInst *si, int idx,
3924188Sgblack@eecs.umich.edu                     const VecRegContainer& val) override
3934188Sgblack@eecs.umich.edu    {
3946075Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
3956075Sgblack@eecs.umich.edu        assert(reg.isVecReg());
3966075Sgblack@eecs.umich.edu        thread->setVecReg(reg, val);
3974188Sgblack@eecs.umich.edu        setVecResult(val);
3984188Sgblack@eecs.umich.edu    }
3994188Sgblack@eecs.umich.edu
4004188Sgblack@eecs.umich.edu    void
40113570Sbrandon.potter@amd.com    setVecElemOperand(const StaticInst *si, int idx,
40213570Sbrandon.potter@amd.com                      const VecElem val) override
4034188Sgblack@eecs.umich.edu    {
4044188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
4054188Sgblack@eecs.umich.edu        assert(reg.isVecElem());
4064188Sgblack@eecs.umich.edu        thread->setVecElem(reg, val);
4074188Sgblack@eecs.umich.edu        setVecElemResult(val);
4084188Sgblack@eecs.umich.edu    }
4094188Sgblack@eecs.umich.edu
4104188Sgblack@eecs.umich.edu    void setVecPredRegOperand(const StaticInst *si, int idx,
4114188Sgblack@eecs.umich.edu                              const VecPredRegContainer& val) override
4124188Sgblack@eecs.umich.edu    {
4134188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
4144188Sgblack@eecs.umich.edu        assert(reg.isVecPredReg());
4155748SSteve.Reinhardt@amd.com        thread->setVecPredReg(reg, val);
4164188Sgblack@eecs.umich.edu        setVecPredResult(val);
4174188Sgblack@eecs.umich.edu    }
4184188Sgblack@eecs.umich.edu
4194188Sgblack@eecs.umich.edu    bool readPredicate() const override { return thread->readPredicate(); }
4204188Sgblack@eecs.umich.edu
4214188Sgblack@eecs.umich.edu    void
4224188Sgblack@eecs.umich.edu    setPredicate(bool val) override
4234188Sgblack@eecs.umich.edu    {
4244188Sgblack@eecs.umich.edu        thread->setPredicate(val);
4254188Sgblack@eecs.umich.edu    }
4264188Sgblack@eecs.umich.edu
4274188Sgblack@eecs.umich.edu    TheISA::PCState pcState() const override { return thread->pcState(); }
4284188Sgblack@eecs.umich.edu    void
4294188Sgblack@eecs.umich.edu    pcState(const TheISA::PCState &val) override
4304188Sgblack@eecs.umich.edu    {
4314188Sgblack@eecs.umich.edu        DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
4324188Sgblack@eecs.umich.edu                         val, thread->pcState());
4334188Sgblack@eecs.umich.edu        thread->pcState(val);
4344188Sgblack@eecs.umich.edu    }
4354188Sgblack@eecs.umich.edu    Addr instAddr() { return thread->instAddr(); }
4364188Sgblack@eecs.umich.edu    Addr nextInstAddr() { return thread->nextInstAddr(); }
4374188Sgblack@eecs.umich.edu    MicroPC microPC() { return thread->microPC(); }
4384188Sgblack@eecs.umich.edu    //////////////////////////////////////////
4394188Sgblack@eecs.umich.edu
4404188Sgblack@eecs.umich.edu    RegVal
4414264Sgblack@eecs.umich.edu    readMiscRegNoEffect(int misc_reg) const
4424188Sgblack@eecs.umich.edu    {
4434188Sgblack@eecs.umich.edu        return thread->readMiscRegNoEffect(misc_reg);
4444188Sgblack@eecs.umich.edu    }
4454188Sgblack@eecs.umich.edu
4464188Sgblack@eecs.umich.edu    RegVal
4474188Sgblack@eecs.umich.edu    readMiscReg(int misc_reg) override
4484188Sgblack@eecs.umich.edu    {
4494188Sgblack@eecs.umich.edu        return thread->readMiscReg(misc_reg);
4504188Sgblack@eecs.umich.edu    }
4514188Sgblack@eecs.umich.edu
4524188Sgblack@eecs.umich.edu    void
4534188Sgblack@eecs.umich.edu    setMiscRegNoEffect(int misc_reg, RegVal val)
4544188Sgblack@eecs.umich.edu    {
4554188Sgblack@eecs.umich.edu        DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n",
4565513SMichael.Adler@intel.com                misc_reg);
4574188Sgblack@eecs.umich.edu        miscRegIdxs.push(misc_reg);
4584188Sgblack@eecs.umich.edu        return thread->setMiscRegNoEffect(misc_reg, val);
4594188Sgblack@eecs.umich.edu    }
4604188Sgblack@eecs.umich.edu
4614188Sgblack@eecs.umich.edu    void
4624188Sgblack@eecs.umich.edu    setMiscReg(int misc_reg, RegVal val) override
4634188Sgblack@eecs.umich.edu    {
4644188Sgblack@eecs.umich.edu        DPRINTF(Checker, "Setting misc reg %d with effect to check later\n",
4654188Sgblack@eecs.umich.edu                misc_reg);
4664188Sgblack@eecs.umich.edu        miscRegIdxs.push(misc_reg);
4674188Sgblack@eecs.umich.edu        return thread->setMiscReg(misc_reg, val);
4684188Sgblack@eecs.umich.edu    }
4694188Sgblack@eecs.umich.edu
4704188Sgblack@eecs.umich.edu    RegVal
4714188Sgblack@eecs.umich.edu    readMiscRegOperand(const StaticInst *si, int idx) override
4726109Ssanchezd@stanford.edu    {
4734188Sgblack@eecs.umich.edu        const RegId& reg = si->srcRegIdx(idx);
4744188Sgblack@eecs.umich.edu        assert(reg.isMiscReg());
4754188Sgblack@eecs.umich.edu        return thread->readMiscReg(reg.index());
4764188Sgblack@eecs.umich.edu    }
4774188Sgblack@eecs.umich.edu
4784188Sgblack@eecs.umich.edu    void
4794188Sgblack@eecs.umich.edu    setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
4804188Sgblack@eecs.umich.edu    {
4814188Sgblack@eecs.umich.edu        const RegId& reg = si->destRegIdx(idx);
4824188Sgblack@eecs.umich.edu        assert(reg.isMiscReg());
4834188Sgblack@eecs.umich.edu        return this->setMiscReg(reg.index(), val);
4844188Sgblack@eecs.umich.edu    }
4854188Sgblack@eecs.umich.edu
4864188Sgblack@eecs.umich.edu#if THE_ISA == MIPS_ISA
4874188Sgblack@eecs.umich.edu    RegVal
4884188Sgblack@eecs.umich.edu    readRegOtherThread(const RegId &misc_reg, ThreadID tid) override
4894188Sgblack@eecs.umich.edu    {
4904188Sgblack@eecs.umich.edu        panic("MIPS MT not defined for CheckerCPU.\n");
4914188Sgblack@eecs.umich.edu        return 0;
4924188Sgblack@eecs.umich.edu    }
4934188Sgblack@eecs.umich.edu
4944188Sgblack@eecs.umich.edu    void
4954188Sgblack@eecs.umich.edu    setRegOtherThread(const RegId& misc_reg, RegVal val, ThreadID tid) override
4964188Sgblack@eecs.umich.edu    {
4974188Sgblack@eecs.umich.edu        panic("MIPS MT not defined for CheckerCPU.\n");
4984188Sgblack@eecs.umich.edu    }
4994188Sgblack@eecs.umich.edu#endif
5004188Sgblack@eecs.umich.edu
5016109Ssanchezd@stanford.edu    /////////////////////////////////////////
5024188Sgblack@eecs.umich.edu
5034188Sgblack@eecs.umich.edu    void
5044188Sgblack@eecs.umich.edu    recordPCChange(const TheISA::PCState &val)
5054188Sgblack@eecs.umich.edu    {
5064188Sgblack@eecs.umich.edu       changedPC = true;
5074188Sgblack@eecs.umich.edu       newPCState = val;
5086109Ssanchezd@stanford.edu    }
5094188Sgblack@eecs.umich.edu
5104188Sgblack@eecs.umich.edu    void
5114188Sgblack@eecs.umich.edu    demapPage(Addr vaddr, uint64_t asn) override
5124188Sgblack@eecs.umich.edu    {
5134188Sgblack@eecs.umich.edu        this->itb->demapPage(vaddr, asn);
5146109Ssanchezd@stanford.edu        this->dtb->demapPage(vaddr, asn);
5154188Sgblack@eecs.umich.edu    }
5164188Sgblack@eecs.umich.edu
5174188Sgblack@eecs.umich.edu    // monitor/mwait funtions
5184188Sgblack@eecs.umich.edu    void armMonitor(Addr address) override { BaseCPU::armMonitor(0, address); }
5194188Sgblack@eecs.umich.edu    bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); }
5204188Sgblack@eecs.umich.edu    void mwaitAtomic(ThreadContext *tc) override
5214188Sgblack@eecs.umich.edu    { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
5224188Sgblack@eecs.umich.edu    AddressMonitor *getAddrMonitor() override
5234188Sgblack@eecs.umich.edu    { return BaseCPU::getCpuAddrMonitor(0); }
5244188Sgblack@eecs.umich.edu
5254188Sgblack@eecs.umich.edu    void
5264236Sgblack@eecs.umich.edu    demapInstPage(Addr vaddr, uint64_t asn)
5274188Sgblack@eecs.umich.edu    {
5284188Sgblack@eecs.umich.edu        this->itb->demapPage(vaddr, asn);
5294188Sgblack@eecs.umich.edu    }
5304188Sgblack@eecs.umich.edu
5314188Sgblack@eecs.umich.edu    void
5324188Sgblack@eecs.umich.edu    demapDataPage(Addr vaddr, uint64_t asn)
5334188Sgblack@eecs.umich.edu    {
5345513SMichael.Adler@intel.com        this->dtb->demapPage(vaddr, asn);
5354188Sgblack@eecs.umich.edu    }
5364188Sgblack@eecs.umich.edu
5374188Sgblack@eecs.umich.edu    Fault readMem(Addr addr, uint8_t *data, unsigned size,
5384188Sgblack@eecs.umich.edu                  Request::Flags flags) override;
5394188Sgblack@eecs.umich.edu    Fault writeMem(uint8_t *data, unsigned size, Addr addr,
5404188Sgblack@eecs.umich.edu                   Request::Flags flags, uint64_t *res) override;
5414188Sgblack@eecs.umich.edu
5424188Sgblack@eecs.umich.edu    unsigned int
5434188Sgblack@eecs.umich.edu    readStCondFailures() const override {
5444188Sgblack@eecs.umich.edu        return thread->readStCondFailures();
5454188Sgblack@eecs.umich.edu    }
5464188Sgblack@eecs.umich.edu
5474188Sgblack@eecs.umich.edu    void setStCondFailures(unsigned int sc_failures) override {}
5484188Sgblack@eecs.umich.edu    /////////////////////////////////////////////////////
5494188Sgblack@eecs.umich.edu
5504188Sgblack@eecs.umich.edu    Fault hwrei() override { return thread->hwrei(); }
5514188Sgblack@eecs.umich.edu    bool simPalCheck(int palFunc) override
55210495Snilay@cs.wisc.edu    { return thread->simPalCheck(palFunc); }
5534188Sgblack@eecs.umich.edu    void wakeup(ThreadID tid) override { }
5544188Sgblack@eecs.umich.edu    // Assume that the normal CPU's call to syscall was successful.
5554188Sgblack@eecs.umich.edu    // The checker's state would have already been updated by the syscall.
5564188Sgblack@eecs.umich.edu    void syscall(int64_t callnum, Fault *fault) override { }
5574188Sgblack@eecs.umich.edu
5584188Sgblack@eecs.umich.edu    void
5594188Sgblack@eecs.umich.edu    handleError()
5604188Sgblack@eecs.umich.edu    {
5614188Sgblack@eecs.umich.edu        if (exitOnError)
5624188Sgblack@eecs.umich.edu            dumpAndExit();
5634188Sgblack@eecs.umich.edu    }
5644188Sgblack@eecs.umich.edu
5654188Sgblack@eecs.umich.edu    bool checkFlags(const RequestPtr &unverified_req, Addr vAddr,
5664188Sgblack@eecs.umich.edu                    Addr pAddr, int flags);
5674188Sgblack@eecs.umich.edu
5684188Sgblack@eecs.umich.edu    void dumpAndExit();
5694188Sgblack@eecs.umich.edu
5704188Sgblack@eecs.umich.edu    ThreadContext *tcBase() override { return tc; }
5714188Sgblack@eecs.umich.edu    SimpleThread *threadBase() { return thread; }
57210495Snilay@cs.wisc.edu
5734188Sgblack@eecs.umich.edu    InstResult unverifiedResult;
5744188Sgblack@eecs.umich.edu    RequestPtr unverifiedReq;
5754188Sgblack@eecs.umich.edu    uint8_t *unverifiedMemData;
5764188Sgblack@eecs.umich.edu
5774188Sgblack@eecs.umich.edu    bool changedPC;
5784188Sgblack@eecs.umich.edu    bool willChangePC;
5794188Sgblack@eecs.umich.edu    TheISA::PCState newPCState;
5804188Sgblack@eecs.umich.edu    bool exitOnError;
5814188Sgblack@eecs.umich.edu    bool updateOnError;
5824188Sgblack@eecs.umich.edu    bool warnOnlyOnLoadError;
5834188Sgblack@eecs.umich.edu
5844188Sgblack@eecs.umich.edu    InstSeqNum youngestSN;
5854188Sgblack@eecs.umich.edu};
5866109Ssanchezd@stanford.edu
5874188Sgblack@eecs.umich.edu/**
5884188Sgblack@eecs.umich.edu * Templated Checker class.  This Checker class is templated on the
5894188Sgblack@eecs.umich.edu * DynInstPtr of the instruction type that will be verified.  Proper
5904188Sgblack@eecs.umich.edu * template instantiations of the Checker must be placed at the bottom
5914188Sgblack@eecs.umich.edu * of checker/cpu.cc.
5924188Sgblack@eecs.umich.edu */
5934188Sgblack@eecs.umich.edutemplate <class Impl>
5944188Sgblack@eecs.umich.educlass Checker : public CheckerCPU
5954188Sgblack@eecs.umich.edu{
5964188Sgblack@eecs.umich.edu  private:
5974188Sgblack@eecs.umich.edu    typedef typename Impl::DynInstPtr DynInstPtr;
5984188Sgblack@eecs.umich.edu
5994188Sgblack@eecs.umich.edu  public:
6004188Sgblack@eecs.umich.edu    Checker(Params *p)
6014188Sgblack@eecs.umich.edu        : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
6024188Sgblack@eecs.umich.edu    { }
6034188Sgblack@eecs.umich.edu
6044188Sgblack@eecs.umich.edu    void switchOut();
6054188Sgblack@eecs.umich.edu    void takeOverFrom(BaseCPU *oldCPU);
6064188Sgblack@eecs.umich.edu
6074188Sgblack@eecs.umich.edu    void advancePC(const Fault &fault);
6084188Sgblack@eecs.umich.edu
6094188Sgblack@eecs.umich.edu    void verify(const DynInstPtr &inst);
6104188Sgblack@eecs.umich.edu
6114188Sgblack@eecs.umich.edu    void validateInst(const DynInstPtr &inst);
6126640Svince@csl.cornell.edu    void validateExecution(const DynInstPtr &inst);
6134188Sgblack@eecs.umich.edu    void validateState();
6144188Sgblack@eecs.umich.edu
61511886Sbrandon.potter@amd.com    void copyResult(const DynInstPtr &inst, const InstResult& mismatch_val,
6164188Sgblack@eecs.umich.edu                    int start_idx);
6174188Sgblack@eecs.umich.edu    void handlePendingInt();
6184188Sgblack@eecs.umich.edu
6194188Sgblack@eecs.umich.edu  private:
6204188Sgblack@eecs.umich.edu    void handleError(const DynInstPtr &inst)
6214188Sgblack@eecs.umich.edu    {
6224188Sgblack@eecs.umich.edu        if (exitOnError) {
6234188Sgblack@eecs.umich.edu            dumpAndExit(inst);
6244188Sgblack@eecs.umich.edu        } else if (updateOnError) {
6254188Sgblack@eecs.umich.edu            updateThisCycle = true;
6264188Sgblack@eecs.umich.edu        }
6274188Sgblack@eecs.umich.edu    }
6284188Sgblack@eecs.umich.edu
6294264Sgblack@eecs.umich.edu    void dumpAndExit(const DynInstPtr &inst);
6304188Sgblack@eecs.umich.edu
6314188Sgblack@eecs.umich.edu    bool updateThisCycle;
6324188Sgblack@eecs.umich.edu
6334188Sgblack@eecs.umich.edu    DynInstPtr unverifiedInst;
6344188Sgblack@eecs.umich.edu
6354188Sgblack@eecs.umich.edu    std::list<DynInstPtr> instList;
6364188Sgblack@eecs.umich.edu    typedef typename std::list<DynInstPtr>::iterator InstListIt;
6374188Sgblack@eecs.umich.edu    void dumpInsts();
6384188Sgblack@eecs.umich.edu};
6394188Sgblack@eecs.umich.edu
6404188Sgblack@eecs.umich.edu#endif // __CPU_CHECKER_CPU_HH__
6414188Sgblack@eecs.umich.edu