17720Sgblack@eecs.umich.edu/*
27720Sgblack@eecs.umich.edu * Copyright (c) 2010 Gabe Black
37720Sgblack@eecs.umich.edu * All rights reserved.
47720Sgblack@eecs.umich.edu *
57720Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67720Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77720Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87720Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97720Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107720Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117720Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127720Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137720Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147720Sgblack@eecs.umich.edu * this software without specific prior written permission.
157720Sgblack@eecs.umich.edu *
167720Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177720Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187720Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197720Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207720Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217720Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227720Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237720Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247720Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257720Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267720Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277720Sgblack@eecs.umich.edu *
287720Sgblack@eecs.umich.edu * Authors: Gabe Black
297720Sgblack@eecs.umich.edu */
307720Sgblack@eecs.umich.edu
317720Sgblack@eecs.umich.edu#ifndef __ARCH_GENERIC_TYPES_HH__
327720Sgblack@eecs.umich.edu#define __ARCH_GENERIC_TYPES_HH__
337720Sgblack@eecs.umich.edu
347720Sgblack@eecs.umich.edu#include <iostream>
3514176Sciro.santilli@arm.com#include <limits>
367720Sgblack@eecs.umich.edu
378229Snate@binkert.org#include "base/trace.hh"
387720Sgblack@eecs.umich.edu#include "base/types.hh"
397720Sgblack@eecs.umich.edu#include "sim/serialize.hh"
407720Sgblack@eecs.umich.edu
4112104Snathanael.premillieu@arm.com// Logical register index type.
4212104Snathanael.premillieu@arm.comtypedef uint16_t RegIndex;
4312104Snathanael.premillieu@arm.com
4412109SRekai.GonzalezAlberquilla@arm.com/** Logical vector register elem index type. */
4512109SRekai.GonzalezAlberquilla@arm.comusing ElemIndex = uint16_t;
4612109SRekai.GonzalezAlberquilla@arm.com
4714176Sciro.santilli@arm.com/** ElemIndex value that indicates that the register is not a vector. */
4814176Sciro.santilli@arm.com#define ILLEGAL_ELEM_INDEX std::numeric_limits<ElemIndex>::max()
4914176Sciro.santilli@arm.com
507720Sgblack@eecs.umich.edunamespace GenericISA
517720Sgblack@eecs.umich.edu{
527720Sgblack@eecs.umich.edu
537720Sgblack@eecs.umich.edu// The guaranteed interface.
5410905Sandreas.sandberg@arm.comclass PCStateBase : public Serializable
557720Sgblack@eecs.umich.edu{
567720Sgblack@eecs.umich.edu  protected:
577720Sgblack@eecs.umich.edu    Addr _pc;
587720Sgblack@eecs.umich.edu    Addr _npc;
597720Sgblack@eecs.umich.edu
6010537Sandreas.hansson@arm.com    PCStateBase() : _pc(0), _npc(0) {}
6110537Sandreas.hansson@arm.com    PCStateBase(Addr val) : _pc(0), _npc(0) { set(val); }
627720Sgblack@eecs.umich.edu
637720Sgblack@eecs.umich.edu  public:
647720Sgblack@eecs.umich.edu    /**
657720Sgblack@eecs.umich.edu     * Returns the memory address the bytes of this instruction came from.
667720Sgblack@eecs.umich.edu     *
677720Sgblack@eecs.umich.edu     * @return Memory address of the current instruction's encoding.
687720Sgblack@eecs.umich.edu     */
697720Sgblack@eecs.umich.edu    Addr
707720Sgblack@eecs.umich.edu    instAddr() const
717720Sgblack@eecs.umich.edu    {
727720Sgblack@eecs.umich.edu        return _pc;
737720Sgblack@eecs.umich.edu    }
747720Sgblack@eecs.umich.edu
757720Sgblack@eecs.umich.edu    /**
767720Sgblack@eecs.umich.edu     * Returns the memory address the bytes of the next instruction came from.
777720Sgblack@eecs.umich.edu     *
787720Sgblack@eecs.umich.edu     * @return Memory address of the next instruction's encoding.
797720Sgblack@eecs.umich.edu     */
807720Sgblack@eecs.umich.edu    Addr
817720Sgblack@eecs.umich.edu    nextInstAddr() const
827720Sgblack@eecs.umich.edu    {
837720Sgblack@eecs.umich.edu        return _npc;
847720Sgblack@eecs.umich.edu    }
857720Sgblack@eecs.umich.edu
867720Sgblack@eecs.umich.edu    /**
877720Sgblack@eecs.umich.edu     * Returns the current micropc.
887720Sgblack@eecs.umich.edu     *
897720Sgblack@eecs.umich.edu     * @return The current micropc.
907720Sgblack@eecs.umich.edu     */
917720Sgblack@eecs.umich.edu    MicroPC
927720Sgblack@eecs.umich.edu    microPC() const
937720Sgblack@eecs.umich.edu    {
947720Sgblack@eecs.umich.edu        return 0;
957720Sgblack@eecs.umich.edu    }
967720Sgblack@eecs.umich.edu
977720Sgblack@eecs.umich.edu    /**
987720Sgblack@eecs.umich.edu     * Force this PC to reflect a particular value, resetting all its other
997720Sgblack@eecs.umich.edu     * fields around it. This is useful for in place (re)initialization.
1007720Sgblack@eecs.umich.edu     *
1017720Sgblack@eecs.umich.edu     * @param val The value to set the PC to.
1027720Sgblack@eecs.umich.edu     */
1037720Sgblack@eecs.umich.edu    void set(Addr val);
1047720Sgblack@eecs.umich.edu
1057720Sgblack@eecs.umich.edu    bool
1067720Sgblack@eecs.umich.edu    operator == (const PCStateBase &opc) const
1077720Sgblack@eecs.umich.edu    {
1087720Sgblack@eecs.umich.edu        return _pc == opc._pc && _npc == opc._npc;
1097720Sgblack@eecs.umich.edu    }
1107720Sgblack@eecs.umich.edu
1118361Sksewell@umich.edu    bool
1128361Sksewell@umich.edu    operator != (const PCStateBase &opc) const
1138361Sksewell@umich.edu    {
1148361Sksewell@umich.edu        return !(*this == opc);
1158361Sksewell@umich.edu    }
1168361Sksewell@umich.edu
1177720Sgblack@eecs.umich.edu    void
11811168Sandreas.hansson@arm.com    serialize(CheckpointOut &cp) const override
1197720Sgblack@eecs.umich.edu    {
1207720Sgblack@eecs.umich.edu        SERIALIZE_SCALAR(_pc);
1217720Sgblack@eecs.umich.edu        SERIALIZE_SCALAR(_npc);
1227720Sgblack@eecs.umich.edu    }
1237720Sgblack@eecs.umich.edu
1247720Sgblack@eecs.umich.edu    void
12511168Sandreas.hansson@arm.com    unserialize(CheckpointIn &cp) override
1267720Sgblack@eecs.umich.edu    {
1277720Sgblack@eecs.umich.edu        UNSERIALIZE_SCALAR(_pc);
1287720Sgblack@eecs.umich.edu        UNSERIALIZE_SCALAR(_npc);
1297720Sgblack@eecs.umich.edu    }
1307720Sgblack@eecs.umich.edu};
1317720Sgblack@eecs.umich.edu
1327720Sgblack@eecs.umich.edu
1337720Sgblack@eecs.umich.edu/*
1347720Sgblack@eecs.umich.edu * Different flavors of PC state. Only ISA specific code should rely on
1357720Sgblack@eecs.umich.edu * any particular type of PC state being available. All other code should
1367720Sgblack@eecs.umich.edu * use the interface above.
1377720Sgblack@eecs.umich.edu */
1387720Sgblack@eecs.umich.edu
1397720Sgblack@eecs.umich.edu// The most basic type of PC.
1407720Sgblack@eecs.umich.edutemplate <class MachInst>
1417720Sgblack@eecs.umich.educlass SimplePCState : public PCStateBase
1427720Sgblack@eecs.umich.edu{
1437720Sgblack@eecs.umich.edu  protected:
1447720Sgblack@eecs.umich.edu    typedef PCStateBase Base;
1457720Sgblack@eecs.umich.edu
1467720Sgblack@eecs.umich.edu  public:
1477720Sgblack@eecs.umich.edu
1487720Sgblack@eecs.umich.edu    Addr pc() const { return _pc; }
1497720Sgblack@eecs.umich.edu    void pc(Addr val) { _pc = val; }
1507720Sgblack@eecs.umich.edu
1517720Sgblack@eecs.umich.edu    Addr npc() const { return _npc; }
1527720Sgblack@eecs.umich.edu    void npc(Addr val) { _npc = val; }
1537720Sgblack@eecs.umich.edu
1547720Sgblack@eecs.umich.edu    void
1557720Sgblack@eecs.umich.edu    set(Addr val)
1567720Sgblack@eecs.umich.edu    {
1577720Sgblack@eecs.umich.edu        pc(val);
1587720Sgblack@eecs.umich.edu        npc(val + sizeof(MachInst));
1597720Sgblack@eecs.umich.edu    };
1607720Sgblack@eecs.umich.edu
16111886Sbrandon.potter@amd.com    void
16211886Sbrandon.potter@amd.com    setNPC(Addr val)
16311886Sbrandon.potter@amd.com    {
16411886Sbrandon.potter@amd.com        npc(val);
16511886Sbrandon.potter@amd.com    }
16611886Sbrandon.potter@amd.com
1677720Sgblack@eecs.umich.edu    SimplePCState() {}
1687720Sgblack@eecs.umich.edu    SimplePCState(Addr val) { set(val); }
1697720Sgblack@eecs.umich.edu
1707720Sgblack@eecs.umich.edu    bool
1717720Sgblack@eecs.umich.edu    branching() const
1727720Sgblack@eecs.umich.edu    {
1737720Sgblack@eecs.umich.edu        return this->npc() != this->pc() + sizeof(MachInst);
1747720Sgblack@eecs.umich.edu    }
1757720Sgblack@eecs.umich.edu
1767720Sgblack@eecs.umich.edu    // Advance the PC.
1777720Sgblack@eecs.umich.edu    void
1787720Sgblack@eecs.umich.edu    advance()
1797720Sgblack@eecs.umich.edu    {
1807720Sgblack@eecs.umich.edu        _pc = _npc;
1817720Sgblack@eecs.umich.edu        _npc += sizeof(MachInst);
1827720Sgblack@eecs.umich.edu    }
1837720Sgblack@eecs.umich.edu};
1847720Sgblack@eecs.umich.edu
1857720Sgblack@eecs.umich.edutemplate <class MachInst>
1867720Sgblack@eecs.umich.edustd::ostream &
1877720Sgblack@eecs.umich.eduoperator<<(std::ostream & os, const SimplePCState<MachInst> &pc)
1887720Sgblack@eecs.umich.edu{
1897720Sgblack@eecs.umich.edu    ccprintf(os, "(%#x=>%#x)", pc.pc(), pc.npc());
1907720Sgblack@eecs.umich.edu    return os;
1917720Sgblack@eecs.umich.edu}
1927720Sgblack@eecs.umich.edu
1937720Sgblack@eecs.umich.edu// A PC and microcode PC.
1947720Sgblack@eecs.umich.edutemplate <class MachInst>
1957720Sgblack@eecs.umich.educlass UPCState : public SimplePCState<MachInst>
1967720Sgblack@eecs.umich.edu{
1977720Sgblack@eecs.umich.edu  protected:
1987720Sgblack@eecs.umich.edu    typedef SimplePCState<MachInst> Base;
1997720Sgblack@eecs.umich.edu
2007720Sgblack@eecs.umich.edu    MicroPC _upc;
2017720Sgblack@eecs.umich.edu    MicroPC _nupc;
2027720Sgblack@eecs.umich.edu
2037720Sgblack@eecs.umich.edu  public:
2047720Sgblack@eecs.umich.edu
2057720Sgblack@eecs.umich.edu    MicroPC upc() const { return _upc; }
2067720Sgblack@eecs.umich.edu    void upc(MicroPC val) { _upc = val; }
2077720Sgblack@eecs.umich.edu
2087720Sgblack@eecs.umich.edu    MicroPC nupc() const { return _nupc; }
2097720Sgblack@eecs.umich.edu    void nupc(MicroPC val) { _nupc = val; }
2107720Sgblack@eecs.umich.edu
2117720Sgblack@eecs.umich.edu    MicroPC
2127720Sgblack@eecs.umich.edu    microPC() const
2137720Sgblack@eecs.umich.edu    {
2147720Sgblack@eecs.umich.edu        return _upc;
2157720Sgblack@eecs.umich.edu    }
2167720Sgblack@eecs.umich.edu
2177720Sgblack@eecs.umich.edu    void
2187720Sgblack@eecs.umich.edu    set(Addr val)
2197720Sgblack@eecs.umich.edu    {
2207720Sgblack@eecs.umich.edu        Base::set(val);
2217720Sgblack@eecs.umich.edu        upc(0);
2227720Sgblack@eecs.umich.edu        nupc(1);
2237720Sgblack@eecs.umich.edu    }
2247720Sgblack@eecs.umich.edu
22510537Sandreas.hansson@arm.com    UPCState() : _upc(0), _nupc(0) {}
22610537Sandreas.hansson@arm.com    UPCState(Addr val) : _upc(0), _nupc(0) { set(val); }
2277720Sgblack@eecs.umich.edu
2287720Sgblack@eecs.umich.edu    bool
2297720Sgblack@eecs.umich.edu    branching() const
2307720Sgblack@eecs.umich.edu    {
2317720Sgblack@eecs.umich.edu        return this->npc() != this->pc() + sizeof(MachInst) ||
2327720Sgblack@eecs.umich.edu               this->nupc() != this->upc() + 1;
2337720Sgblack@eecs.umich.edu    }
2347720Sgblack@eecs.umich.edu
2357720Sgblack@eecs.umich.edu    // Advance the upc within the instruction.
2367720Sgblack@eecs.umich.edu    void
2377720Sgblack@eecs.umich.edu    uAdvance()
2387720Sgblack@eecs.umich.edu    {
2397720Sgblack@eecs.umich.edu        _upc = _nupc;
2407720Sgblack@eecs.umich.edu        _nupc++;
2417720Sgblack@eecs.umich.edu    }
2427720Sgblack@eecs.umich.edu
2437720Sgblack@eecs.umich.edu    // End the macroop by resetting the upc and advancing the regular pc.
2447720Sgblack@eecs.umich.edu    void
2457720Sgblack@eecs.umich.edu    uEnd()
2467720Sgblack@eecs.umich.edu    {
2477720Sgblack@eecs.umich.edu        this->advance();
2487720Sgblack@eecs.umich.edu        _upc = 0;
2497720Sgblack@eecs.umich.edu        _nupc = 1;
2507720Sgblack@eecs.umich.edu    }
2517720Sgblack@eecs.umich.edu
2527720Sgblack@eecs.umich.edu    bool
2537720Sgblack@eecs.umich.edu    operator == (const UPCState<MachInst> &opc) const
2547720Sgblack@eecs.umich.edu    {
2557720Sgblack@eecs.umich.edu        return Base::_pc == opc._pc &&
2567720Sgblack@eecs.umich.edu               Base::_npc == opc._npc &&
2577720Sgblack@eecs.umich.edu               _upc == opc._upc && _nupc == opc._nupc;
2587720Sgblack@eecs.umich.edu    }
2597720Sgblack@eecs.umich.edu
2608361Sksewell@umich.edu    bool
2618361Sksewell@umich.edu    operator != (const UPCState<MachInst> &opc) const
2628361Sksewell@umich.edu    {
2638361Sksewell@umich.edu        return !(*this == opc);
2648361Sksewell@umich.edu    }
2658361Sksewell@umich.edu
2667720Sgblack@eecs.umich.edu    void
26711168Sandreas.hansson@arm.com    serialize(CheckpointOut &cp) const override
2687720Sgblack@eecs.umich.edu    {
26910905Sandreas.sandberg@arm.com        Base::serialize(cp);
2707720Sgblack@eecs.umich.edu        SERIALIZE_SCALAR(_upc);
2717720Sgblack@eecs.umich.edu        SERIALIZE_SCALAR(_nupc);
2727720Sgblack@eecs.umich.edu    }
2737720Sgblack@eecs.umich.edu
2747720Sgblack@eecs.umich.edu    void
27511168Sandreas.hansson@arm.com    unserialize(CheckpointIn &cp) override
2767720Sgblack@eecs.umich.edu    {
27710905Sandreas.sandberg@arm.com        Base::unserialize(cp);
2787720Sgblack@eecs.umich.edu        UNSERIALIZE_SCALAR(_upc);
2797720Sgblack@eecs.umich.edu        UNSERIALIZE_SCALAR(_nupc);
2807720Sgblack@eecs.umich.edu    }
2817720Sgblack@eecs.umich.edu};
2827720Sgblack@eecs.umich.edu
2837720Sgblack@eecs.umich.edutemplate <class MachInst>
2847720Sgblack@eecs.umich.edustd::ostream &
2857720Sgblack@eecs.umich.eduoperator<<(std::ostream & os, const UPCState<MachInst> &pc)
2867720Sgblack@eecs.umich.edu{
2877720Sgblack@eecs.umich.edu    ccprintf(os, "(%#x=>%#x).(%d=>%d)",
2888435Snilay@cs.wisc.edu            pc.pc(), pc.npc(), pc.upc(), pc.nupc());
2897720Sgblack@eecs.umich.edu    return os;
2907720Sgblack@eecs.umich.edu}
2917720Sgblack@eecs.umich.edu
2927720Sgblack@eecs.umich.edu// A PC with a delay slot.
2937720Sgblack@eecs.umich.edutemplate <class MachInst>
2947720Sgblack@eecs.umich.educlass DelaySlotPCState : public SimplePCState<MachInst>
2957720Sgblack@eecs.umich.edu{
2967720Sgblack@eecs.umich.edu  protected:
2977720Sgblack@eecs.umich.edu    typedef SimplePCState<MachInst> Base;
2987720Sgblack@eecs.umich.edu
2997720Sgblack@eecs.umich.edu    Addr _nnpc;
3007720Sgblack@eecs.umich.edu
3017720Sgblack@eecs.umich.edu  public:
3027720Sgblack@eecs.umich.edu
3037720Sgblack@eecs.umich.edu    Addr nnpc() const { return _nnpc; }
3047720Sgblack@eecs.umich.edu    void nnpc(Addr val) { _nnpc = val; }
3057720Sgblack@eecs.umich.edu
3067720Sgblack@eecs.umich.edu    void
3077720Sgblack@eecs.umich.edu    set(Addr val)
3087720Sgblack@eecs.umich.edu    {
3097720Sgblack@eecs.umich.edu        Base::set(val);
3107720Sgblack@eecs.umich.edu        nnpc(val + 2 * sizeof(MachInst));
3117720Sgblack@eecs.umich.edu    }
3127720Sgblack@eecs.umich.edu
3137720Sgblack@eecs.umich.edu    DelaySlotPCState() {}
3147720Sgblack@eecs.umich.edu    DelaySlotPCState(Addr val) { set(val); }
3157720Sgblack@eecs.umich.edu
3167720Sgblack@eecs.umich.edu    bool
3177720Sgblack@eecs.umich.edu    branching() const
3187720Sgblack@eecs.umich.edu    {
3197720Sgblack@eecs.umich.edu        return !(this->nnpc() == this->npc() + sizeof(MachInst) &&
3207720Sgblack@eecs.umich.edu                 (this->npc() == this->pc() + sizeof(MachInst) ||
3217720Sgblack@eecs.umich.edu                  this->npc() == this->pc() + 2 * sizeof(MachInst)));
3227720Sgblack@eecs.umich.edu    }
3237720Sgblack@eecs.umich.edu
3247720Sgblack@eecs.umich.edu    // Advance the PC.
3257720Sgblack@eecs.umich.edu    void
3267720Sgblack@eecs.umich.edu    advance()
3277720Sgblack@eecs.umich.edu    {
3287720Sgblack@eecs.umich.edu        Base::_pc = Base::_npc;
3297720Sgblack@eecs.umich.edu        Base::_npc = _nnpc;
3307720Sgblack@eecs.umich.edu        _nnpc += sizeof(MachInst);
3317720Sgblack@eecs.umich.edu    }
3327720Sgblack@eecs.umich.edu
3337720Sgblack@eecs.umich.edu    bool
3347720Sgblack@eecs.umich.edu    operator == (const DelaySlotPCState<MachInst> &opc) const
3357720Sgblack@eecs.umich.edu    {
3367720Sgblack@eecs.umich.edu        return Base::_pc == opc._pc &&
3377720Sgblack@eecs.umich.edu               Base::_npc == opc._npc &&
3387720Sgblack@eecs.umich.edu               _nnpc == opc._nnpc;
3397720Sgblack@eecs.umich.edu    }
3407720Sgblack@eecs.umich.edu
3418361Sksewell@umich.edu    bool
3428361Sksewell@umich.edu    operator != (const DelaySlotPCState<MachInst> &opc) const
3438361Sksewell@umich.edu    {
3448361Sksewell@umich.edu        return !(*this == opc);
3458361Sksewell@umich.edu    }
3468361Sksewell@umich.edu
3477720Sgblack@eecs.umich.edu    void
34811168Sandreas.hansson@arm.com    serialize(CheckpointOut &cp) const override
3497720Sgblack@eecs.umich.edu    {
35010905Sandreas.sandberg@arm.com        Base::serialize(cp);
3517720Sgblack@eecs.umich.edu        SERIALIZE_SCALAR(_nnpc);
3527720Sgblack@eecs.umich.edu    }
3537720Sgblack@eecs.umich.edu
3547720Sgblack@eecs.umich.edu    void
35511168Sandreas.hansson@arm.com    unserialize(CheckpointIn &cp) override
3567720Sgblack@eecs.umich.edu    {
35710905Sandreas.sandberg@arm.com        Base::unserialize(cp);
3587720Sgblack@eecs.umich.edu        UNSERIALIZE_SCALAR(_nnpc);
3597720Sgblack@eecs.umich.edu    }
3607720Sgblack@eecs.umich.edu};
3617720Sgblack@eecs.umich.edu
3627720Sgblack@eecs.umich.edutemplate <class MachInst>
3637720Sgblack@eecs.umich.edustd::ostream &
3647720Sgblack@eecs.umich.eduoperator<<(std::ostream & os, const DelaySlotPCState<MachInst> &pc)
3657720Sgblack@eecs.umich.edu{
3667720Sgblack@eecs.umich.edu    ccprintf(os, "(%#x=>%#x=>%#x)",
3677720Sgblack@eecs.umich.edu            pc.pc(), pc.npc(), pc.nnpc());
3687720Sgblack@eecs.umich.edu    return os;
3697720Sgblack@eecs.umich.edu}
3707720Sgblack@eecs.umich.edu
3717720Sgblack@eecs.umich.edu// A PC with a delay slot and a microcode PC.
3727720Sgblack@eecs.umich.edutemplate <class MachInst>
3737720Sgblack@eecs.umich.educlass DelaySlotUPCState : public DelaySlotPCState<MachInst>
3747720Sgblack@eecs.umich.edu{
3757720Sgblack@eecs.umich.edu  protected:
3767720Sgblack@eecs.umich.edu    typedef DelaySlotPCState<MachInst> Base;
3777720Sgblack@eecs.umich.edu
3787720Sgblack@eecs.umich.edu    MicroPC _upc;
3797720Sgblack@eecs.umich.edu    MicroPC _nupc;
3807720Sgblack@eecs.umich.edu
3817720Sgblack@eecs.umich.edu  public:
3827720Sgblack@eecs.umich.edu
3837720Sgblack@eecs.umich.edu    MicroPC upc() const { return _upc; }
3847720Sgblack@eecs.umich.edu    void upc(MicroPC val) { _upc = val; }
3857720Sgblack@eecs.umich.edu
3867720Sgblack@eecs.umich.edu    MicroPC nupc() const { return _nupc; }
3877720Sgblack@eecs.umich.edu    void nupc(MicroPC val) { _nupc = val; }
3887720Sgblack@eecs.umich.edu
3897720Sgblack@eecs.umich.edu    MicroPC
3907720Sgblack@eecs.umich.edu    microPC() const
3917720Sgblack@eecs.umich.edu    {
3927720Sgblack@eecs.umich.edu        return _upc;
3937720Sgblack@eecs.umich.edu    }
3947720Sgblack@eecs.umich.edu
3957720Sgblack@eecs.umich.edu    void
3967720Sgblack@eecs.umich.edu    set(Addr val)
3977720Sgblack@eecs.umich.edu    {
3987720Sgblack@eecs.umich.edu        Base::set(val);
3997720Sgblack@eecs.umich.edu        upc(0);
4007720Sgblack@eecs.umich.edu        nupc(1);
4017720Sgblack@eecs.umich.edu    }
4027720Sgblack@eecs.umich.edu
4037720Sgblack@eecs.umich.edu    DelaySlotUPCState() {}
4047720Sgblack@eecs.umich.edu    DelaySlotUPCState(Addr val) { set(val); }
4057720Sgblack@eecs.umich.edu
4067720Sgblack@eecs.umich.edu    bool
4077720Sgblack@eecs.umich.edu    branching() const
4087720Sgblack@eecs.umich.edu    {
4097720Sgblack@eecs.umich.edu        return Base::branching() || this->nupc() != this->upc() + 1;
4107720Sgblack@eecs.umich.edu    }
4117720Sgblack@eecs.umich.edu
4127720Sgblack@eecs.umich.edu    // Advance the upc within the instruction.
4137720Sgblack@eecs.umich.edu    void
4147720Sgblack@eecs.umich.edu    uAdvance()
4157720Sgblack@eecs.umich.edu    {
4167720Sgblack@eecs.umich.edu        _upc = _nupc;
4177720Sgblack@eecs.umich.edu        _nupc++;
4187720Sgblack@eecs.umich.edu    }
4197720Sgblack@eecs.umich.edu
4207720Sgblack@eecs.umich.edu    // End the macroop by resetting the upc and advancing the regular pc.
4217720Sgblack@eecs.umich.edu    void
4227720Sgblack@eecs.umich.edu    uEnd()
4237720Sgblack@eecs.umich.edu    {
4247720Sgblack@eecs.umich.edu        this->advance();
4257720Sgblack@eecs.umich.edu        _upc = 0;
4267720Sgblack@eecs.umich.edu        _nupc = 1;
4277720Sgblack@eecs.umich.edu    }
4287720Sgblack@eecs.umich.edu
4297720Sgblack@eecs.umich.edu    bool
4307720Sgblack@eecs.umich.edu    operator == (const DelaySlotUPCState<MachInst> &opc) const
4317720Sgblack@eecs.umich.edu    {
4327720Sgblack@eecs.umich.edu        return Base::_pc == opc._pc &&
4337720Sgblack@eecs.umich.edu               Base::_npc == opc._npc &&
4347720Sgblack@eecs.umich.edu               Base::_nnpc == opc._nnpc &&
4357720Sgblack@eecs.umich.edu               _upc == opc._upc && _nupc == opc._nupc;
4367720Sgblack@eecs.umich.edu    }
4377720Sgblack@eecs.umich.edu
4388361Sksewell@umich.edu    bool
4398361Sksewell@umich.edu    operator != (const DelaySlotUPCState<MachInst> &opc) const
4408361Sksewell@umich.edu    {
4418361Sksewell@umich.edu        return !(*this == opc);
4428361Sksewell@umich.edu    }
4438361Sksewell@umich.edu
4447720Sgblack@eecs.umich.edu    void
44511168Sandreas.hansson@arm.com    serialize(CheckpointOut &cp) const override
4467720Sgblack@eecs.umich.edu    {
44710905Sandreas.sandberg@arm.com        Base::serialize(cp);
4487720Sgblack@eecs.umich.edu        SERIALIZE_SCALAR(_upc);
4497720Sgblack@eecs.umich.edu        SERIALIZE_SCALAR(_nupc);
4507720Sgblack@eecs.umich.edu    }
4517720Sgblack@eecs.umich.edu
4527720Sgblack@eecs.umich.edu    void
45311168Sandreas.hansson@arm.com    unserialize(CheckpointIn &cp) override
4547720Sgblack@eecs.umich.edu    {
45510905Sandreas.sandberg@arm.com        Base::unserialize(cp);
4567720Sgblack@eecs.umich.edu        UNSERIALIZE_SCALAR(_upc);
4577720Sgblack@eecs.umich.edu        UNSERIALIZE_SCALAR(_nupc);
4587720Sgblack@eecs.umich.edu    }
4597720Sgblack@eecs.umich.edu};
4607720Sgblack@eecs.umich.edu
4617720Sgblack@eecs.umich.edutemplate <class MachInst>
4627720Sgblack@eecs.umich.edustd::ostream &
4637720Sgblack@eecs.umich.eduoperator<<(std::ostream & os, const DelaySlotUPCState<MachInst> &pc)
4647720Sgblack@eecs.umich.edu{
4657720Sgblack@eecs.umich.edu    ccprintf(os, "(%#x=>%#x=>%#x).(%d=>%d)",
4667720Sgblack@eecs.umich.edu            pc.pc(), pc.npc(), pc.nnpc(), pc.upc(), pc.nupc());
4677720Sgblack@eecs.umich.edu    return os;
4687720Sgblack@eecs.umich.edu}
4697720Sgblack@eecs.umich.edu
4707720Sgblack@eecs.umich.edu}
4717720Sgblack@eecs.umich.edu
4727720Sgblack@eecs.umich.edu#endif
473