/*
 * Copyright (c) 2010, 2012-2013, 2017-2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2007-2008 The Florida State University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Stephen Hines
 */

#ifndef __ARCH_ARM_TYPES_HH__
#define __ARCH_ARM_TYPES_HH__

#include "arch/generic/types.hh"
#include "base/bitunion.hh"
#include "base/logging.hh"
#include "base/types.hh"
#include "debug/Decoder.hh"

namespace ArmISA
{
    typedef uint32_t MachInst;

    BitUnion8(ITSTATE)
        /* Note that the split (cond, mask) below is not as in ARM ARM.
         * But it is more convenient for simulation. The condition
         * is always the concatenation of the top 3 bits and the next bit,
         * which applies when one of the bottom 4 bits is set.
         * Refer to predecoder.cc for the use case.
         */
        Bitfield<7, 4> cond;
        Bitfield<3, 0> mask;
        // Bitfields for moving to/from CPSR
        Bitfield<7, 2> top6;
        Bitfield<1, 0> bottom2;
    EndBitUnion(ITSTATE)

    BitUnion64(ExtMachInst)
        // Decoder state
        Bitfield<63, 62> decoderFault; // See DecoderFault
        Bitfield<61> illegalExecution;

        // SVE vector length, encoded in the same format as the ZCR_EL<x>.LEN
        // bitfields
        Bitfield<59, 56> sveLen;

        // ITSTATE bits
        Bitfield<55, 48> itstate;
        Bitfield<55, 52> itstateCond;
        Bitfield<51, 48> itstateMask;

        // FPSCR fields
        Bitfield<41, 40> fpscrStride;
        Bitfield<39, 37> fpscrLen;

        // Bitfields to select mode.
        Bitfield<36>     thumb;
        Bitfield<35>     bigThumb;
        Bitfield<34>     aarch64;

        // Made up bitfields that make life easier.
        Bitfield<33>     sevenAndFour;
        Bitfield<32>     isMisc;

        uint32_t         instBits;

        // All the different types of opcode fields.
        Bitfield<27, 25> encoding;
        Bitfield<25>     useImm;
        Bitfield<24, 21> opcode;
        Bitfield<24, 20> mediaOpcode;
        Bitfield<24>     opcode24;
        Bitfield<24, 23> opcode24_23;
        Bitfield<23, 20> opcode23_20;
        Bitfield<23, 21> opcode23_21;
        Bitfield<20>     opcode20;
        Bitfield<22>     opcode22;
        Bitfield<19, 16> opcode19_16;
        Bitfield<19>     opcode19;
        Bitfield<18>     opcode18;
        Bitfield<15, 12> opcode15_12;
        Bitfield<15>     opcode15;
        Bitfield<7,  4>  miscOpcode;
        Bitfield<7,5>    opc2;
        Bitfield<7>      opcode7;
        Bitfield<6>      opcode6;
        Bitfield<4>      opcode4;

        Bitfield<31, 28> condCode;
        Bitfield<20>     sField;
        Bitfield<19, 16> rn;
        Bitfield<15, 12> rd;
        Bitfield<15, 12> rt;
        Bitfield<11, 7>  shiftSize;
        Bitfield<6,  5>  shift;
        Bitfield<3,  0>  rm;

        Bitfield<11, 8>  rs;

        SubBitUnion(puswl, 24, 20)
            Bitfield<24> prepost;
            Bitfield<23> up;
            Bitfield<22> psruser;
            Bitfield<21> writeback;
            Bitfield<20> loadOp;
        EndSubBitUnion(puswl)

        Bitfield<24, 20> pubwl;

        Bitfield<7, 0> imm;

        Bitfield<11, 8>  rotate;

        Bitfield<11, 0>  immed11_0;
        Bitfield<7,  0>  immed7_0;

        Bitfield<11, 8>  immedHi11_8;
        Bitfield<3,  0>  immedLo3_0;

        Bitfield<15, 0>  regList;

        Bitfield<23, 0>  offset;

        Bitfield<23, 0>  immed23_0;

        Bitfield<11, 8>  cpNum;
        Bitfield<18, 16> fn;
        Bitfield<14, 12> fd;
        Bitfield<3>      fpRegImm;
        Bitfield<3,  0>  fm;
        Bitfield<2,  0>  fpImm;
        Bitfield<24, 20> punwl;

        Bitfield<15,  8>  m5Func;

        // 16 bit thumb bitfields
        Bitfield<15, 13> topcode15_13;
        Bitfield<13, 11> topcode13_11;
        Bitfield<12, 11> topcode12_11;
        Bitfield<12, 10> topcode12_10;
        Bitfield<11, 9>  topcode11_9;
        Bitfield<11, 8>  topcode11_8;
        Bitfield<10, 9>  topcode10_9;
        Bitfield<10, 8>  topcode10_8;
        Bitfield<9,  6>  topcode9_6;
        Bitfield<7>      topcode7;
        Bitfield<7, 6>   topcode7_6;
        Bitfield<7, 5>   topcode7_5;
        Bitfield<7, 4>   topcode7_4;
        Bitfield<3, 0>   topcode3_0;

        // 32 bit thumb bitfields
        Bitfield<28, 27> htopcode12_11;
        Bitfield<26, 25> htopcode10_9;
        Bitfield<25>     htopcode9;
        Bitfield<25, 24> htopcode9_8;
        Bitfield<25, 21> htopcode9_5;
        Bitfield<25, 20> htopcode9_4;
        Bitfield<24>     htopcode8;
        Bitfield<24, 23> htopcode8_7;
        Bitfield<24, 22> htopcode8_6;
        Bitfield<24, 21> htopcode8_5;
        Bitfield<23>     htopcode7;
        Bitfield<23, 21> htopcode7_5;
        Bitfield<22>     htopcode6;
        Bitfield<22, 21> htopcode6_5;
        Bitfield<21, 20> htopcode5_4;
        Bitfield<20>     htopcode4;

        Bitfield<19, 16> htrn;
        Bitfield<20>     hts;

        Bitfield<15>     ltopcode15;
        Bitfield<11, 8>  ltopcode11_8;
        Bitfield<7,  6>  ltopcode7_6;
        Bitfield<7,  4>  ltopcode7_4;
        Bitfield<4>      ltopcode4;

        Bitfield<11, 8>  ltrd;
        Bitfield<11, 8>  ltcoproc;
    EndBitUnion(ExtMachInst)

    class PCState : public GenericISA::UPCState<MachInst>
    {
      protected:

        typedef GenericISA::UPCState<MachInst> Base;

        enum FlagBits {
            ThumbBit = (1 << 0),
            JazelleBit = (1 << 1),
            AArch64Bit = (1 << 2)
        };

        uint8_t flags;
        uint8_t nextFlags;
        uint8_t _itstate;
        uint8_t _nextItstate;
        uint8_t _size;
        bool _illegalExec;
      public:
        PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0),
                    _size(0), _illegalExec(false)
        {}

        void
        set(Addr val)
        {
            Base::set(val);
            npc(val + (thumb() ? 2 : 4));
        }

        PCState(Addr val) : flags(0), nextFlags(0), _itstate(0),
                            _nextItstate(0), _size(0), _illegalExec(false)
        { set(val); }

        bool
        illegalExec() const
        {
            return _illegalExec;
        }

        void
        illegalExec(bool val)
        {
            _illegalExec = val;
        }

        bool
        thumb() const
        {
            return flags & ThumbBit;
        }

        void
        thumb(bool val)
        {
            if (val)
                flags |= ThumbBit;
            else
                flags &= ~ThumbBit;
        }

        bool
        nextThumb() const
        {
            return nextFlags & ThumbBit;
        }

        void
        nextThumb(bool val)
        {
            if (val)
                nextFlags |= ThumbBit;
            else
                nextFlags &= ~ThumbBit;
        }

        void size(uint8_t s) { _size = s; }
        uint8_t size() const { return _size; }

        bool
        branching() const
        {
            return ((this->pc() + this->size()) != this->npc());
        }


        bool
        jazelle() const
        {
            return flags & JazelleBit;
        }

        void
        jazelle(bool val)
        {
            if (val)
                flags |= JazelleBit;
            else
                flags &= ~JazelleBit;
        }

        bool
        nextJazelle() const
        {
            return nextFlags & JazelleBit;
        }

        void
        nextJazelle(bool val)
        {
            if (val)
                nextFlags |= JazelleBit;
            else
                nextFlags &= ~JazelleBit;
        }

        bool
        aarch64() const
        {
            return flags & AArch64Bit;
        }

        void
        aarch64(bool val)
        {
            if (val)
                flags |= AArch64Bit;
            else
                flags &= ~AArch64Bit;
        }

        bool
        nextAArch64() const
        {
            return nextFlags & AArch64Bit;
        }

        void
        nextAArch64(bool val)
        {
            if (val)
                nextFlags |= AArch64Bit;
            else
                nextFlags &= ~AArch64Bit;
        }


        uint8_t
        itstate() const
        {
            return _itstate;
        }

        void
        itstate(uint8_t value)
        {
            _itstate = value;
        }

        uint8_t
        nextItstate() const
        {
            return _nextItstate;
        }

        void
        nextItstate(uint8_t value)
        {
            _nextItstate = value;
        }

        void
        advance()
        {
            Base::advance();
            flags = nextFlags;
            npc(pc() + (thumb() ? 2 : 4));

            if (_nextItstate) {
                _itstate = _nextItstate;
                _nextItstate = 0;
            } else if (_itstate) {
                ITSTATE it = _itstate;
                uint8_t cond_mask = it.mask;
                uint8_t thumb_cond = it.cond;
                DPRINTF(Decoder, "Advancing ITSTATE from %#x,%#x.\n",
                        thumb_cond, cond_mask);
                cond_mask <<= 1;
                uint8_t new_bit = bits(cond_mask, 4);
                cond_mask &= mask(4);
                if (cond_mask == 0)
                    thumb_cond = 0;
                else
                    replaceBits(thumb_cond, 0, new_bit);
                DPRINTF(Decoder, "Advancing ITSTATE to %#x,%#x.\n",
                        thumb_cond, cond_mask);
                it.mask = cond_mask;
                it.cond = thumb_cond;
                _itstate = it;
            }
        }

        void
        uEnd()
        {
            advance();
            upc(0);
            nupc(1);
        }

        Addr
        instPC() const
        {
            return pc() + (thumb() ? 4 : 8);
        }

        void
        instNPC(Addr val)
        {
            // @todo: review this when AArch32/64 interprocessing is
            // supported
            if (aarch64())
                npc(val);  // AArch64 doesn't force PC alignment, a PC
                           // Alignment Fault can be raised instead
            else
                npc(val &~ mask(nextThumb() ? 1 : 2));
        }

        Addr
        instNPC() const
        {
            return npc();
        }

        // Perform an interworking branch.
        void
        instIWNPC(Addr val)
        {
            bool thumbEE = (thumb() && jazelle());

            Addr newPC = val;
            if (thumbEE) {
                if (bits(newPC, 0)) {
                    newPC = newPC & ~mask(1);
                }  // else we have a bad interworking address; do not call
                   // panic() since the instruction could be executed
                   // speculatively
            } else {
                if (bits(newPC, 0)) {
                    nextThumb(true);
                    newPC = newPC & ~mask(1);
                } else if (!bits(newPC, 1)) {
                    nextThumb(false);
                } else {
                    // This state is UNPREDICTABLE in the ARM architecture
                    // The easy thing to do is just mask off the bit and
                    // stay in the current mode, so we'll do that.
                    newPC &= ~mask(2);
                }
            }
            npc(newPC);
        }

        // Perform an interworking branch in ARM mode, a regular branch
        // otherwise.
        void
        instAIWNPC(Addr val)
        {
            if (!thumb() && !jazelle())
                instIWNPC(val);
            else
                instNPC(val);
        }

        bool
        operator == (const PCState &opc) const
        {
            return Base::operator == (opc) &&
                flags == opc.flags && nextFlags == opc.nextFlags &&
                _itstate == opc._itstate &&
                _nextItstate == opc._nextItstate &&
                _illegalExec == opc._illegalExec;
        }

        bool
        operator != (const PCState &opc) const
        {
            return !(*this == opc);
        }

        void
        serialize(CheckpointOut &cp) const override
        {
            Base::serialize(cp);
            SERIALIZE_SCALAR(flags);
            SERIALIZE_SCALAR(_size);
            SERIALIZE_SCALAR(nextFlags);
            SERIALIZE_SCALAR(_itstate);
            SERIALIZE_SCALAR(_nextItstate);
            SERIALIZE_SCALAR(_illegalExec);
        }

        void
        unserialize(CheckpointIn &cp) override
        {
            Base::unserialize(cp);
            UNSERIALIZE_SCALAR(flags);
            UNSERIALIZE_SCALAR(_size);
            UNSERIALIZE_SCALAR(nextFlags);
            UNSERIALIZE_SCALAR(_itstate);
            UNSERIALIZE_SCALAR(_nextItstate);
            UNSERIALIZE_SCALAR(_illegalExec);
        }
    };

    // Shift types for ARM instructions
    enum ArmShiftType {
        LSL = 0,
        LSR,
        ASR,
        ROR
    };

    // Extension types for ARM instructions
    enum ArmExtendType {
        UXTB = 0,
        UXTH = 1,
        UXTW = 2,
        UXTX = 3,
        SXTB = 4,
        SXTH = 5,
        SXTW = 6,
        SXTX = 7
    };

    typedef int RegContextParam;
    typedef int RegContextVal;

    //used in FP convert & round function
    enum ConvertType{
        SINGLE_TO_DOUBLE,
        SINGLE_TO_WORD,
        SINGLE_TO_LONG,

        DOUBLE_TO_SINGLE,
        DOUBLE_TO_WORD,
        DOUBLE_TO_LONG,

        LONG_TO_SINGLE,
        LONG_TO_DOUBLE,
        LONG_TO_WORD,
        LONG_TO_PS,

        WORD_TO_SINGLE,
        WORD_TO_DOUBLE,
        WORD_TO_LONG,
        WORD_TO_PS,

        PL_TO_SINGLE,
        PU_TO_SINGLE
    };

    //used in FP convert & round function
    enum RoundMode{
        RND_ZERO,
        RND_DOWN,
        RND_UP,
        RND_NEAREST
    };

    enum ExceptionLevel {
        EL0 = 0,
        EL1,
        EL2,
        EL3
    };

    enum OperatingMode {
        MODE_EL0T = 0x0,
        MODE_EL1T = 0x4,
        MODE_EL1H = 0x5,
        MODE_EL2T = 0x8,
        MODE_EL2H = 0x9,
        MODE_EL3T = 0xC,
        MODE_EL3H = 0xD,
        MODE_USER = 16,
        MODE_FIQ = 17,
        MODE_IRQ = 18,
        MODE_SVC = 19,
        MODE_MON = 22,
        MODE_ABORT = 23,
        MODE_HYP = 26,
        MODE_UNDEFINED = 27,
        MODE_SYSTEM = 31,
        MODE_MAXMODE = MODE_SYSTEM
    };

    enum ExceptionClass {
        EC_INVALID                 = -1,
        EC_UNKNOWN                 = 0x0,
        EC_TRAPPED_WFI_WFE         = 0x1,
        EC_TRAPPED_CP15_MCR_MRC    = 0x3,
        EC_TRAPPED_CP15_MCRR_MRRC  = 0x4,
        EC_TRAPPED_CP14_MCR_MRC    = 0x5,
        EC_TRAPPED_CP14_LDC_STC    = 0x6,
        EC_TRAPPED_HCPTR           = 0x7,
        EC_TRAPPED_SIMD_FP         = 0x7,   // AArch64 alias
        EC_TRAPPED_CP10_MRC_VMRS   = 0x8,
        EC_TRAPPED_BXJ             = 0xA,
        EC_TRAPPED_CP14_MCRR_MRRC  = 0xC,
        EC_ILLEGAL_INST            = 0xE,
        EC_SVC_TO_HYP              = 0x11,
        EC_SVC                     = 0x11,  // AArch64 alias
        EC_HVC                     = 0x12,
        EC_SMC_TO_HYP              = 0x13,
        EC_SMC                     = 0x13,  // AArch64 alias
        EC_SVC_64                  = 0x15,
        EC_HVC_64                  = 0x16,
        EC_SMC_64                  = 0x17,
        EC_TRAPPED_MSR_MRS_64      = 0x18,
        EC_TRAPPED_SVE             = 0x19,
        EC_PREFETCH_ABORT_TO_HYP   = 0x20,
        EC_PREFETCH_ABORT_LOWER_EL = 0x20,  // AArch64 alias
        EC_PREFETCH_ABORT_FROM_HYP = 0x21,
        EC_PREFETCH_ABORT_CURR_EL  = 0x21,  // AArch64 alias
        EC_PC_ALIGNMENT            = 0x22,
        EC_DATA_ABORT_TO_HYP       = 0x24,
        EC_DATA_ABORT_LOWER_EL     = 0x24,  // AArch64 alias
        EC_DATA_ABORT_FROM_HYP     = 0x25,
        EC_DATA_ABORT_CURR_EL      = 0x25,  // AArch64 alias
        EC_STACK_PTR_ALIGNMENT     = 0x26,
        EC_FP_EXCEPTION            = 0x28,
        EC_FP_EXCEPTION_64         = 0x2C,
        EC_SERROR                  = 0x2F,
        EC_SOFTWARE_BREAKPOINT     = 0x38,
        EC_SOFTWARE_BREAKPOINT_64  = 0x3C,
    };

    /**
     * Instruction decoder fault codes in ExtMachInst.
     */
    enum DecoderFault : std::uint8_t {
        OK = 0x0, ///< No fault
        UNALIGNED = 0x1, ///< Unaligned instruction fault

        PANIC = 0x3, ///< Internal gem5 error
    };

    BitUnion8(OperatingMode64)
        Bitfield<0> spX;
        Bitfield<3, 2> el;
        Bitfield<4> width;
    EndBitUnion(OperatingMode64)

    static bool inline
    opModeIs64(OperatingMode mode)
    {
        return ((OperatingMode64)(uint8_t)mode).width == 0;
    }

    static bool inline
    opModeIsH(OperatingMode mode)
    {
        return (mode == MODE_EL1H || mode == MODE_EL2H || mode == MODE_EL3H);
    }

    static bool inline
    opModeIsT(OperatingMode mode)
    {
        return (mode == MODE_EL0T || mode == MODE_EL1T || mode == MODE_EL2T ||
                mode == MODE_EL3T);
    }

    static ExceptionLevel inline
    opModeToEL(OperatingMode mode)
    {
        bool aarch32 = ((mode >> 4) & 1) ? true : false;
        if (aarch32) {
            switch (mode) {
              case MODE_USER:
                return EL0;
              case MODE_FIQ:
              case MODE_IRQ:
              case MODE_SVC:
              case MODE_ABORT:
              case MODE_UNDEFINED:
              case MODE_SYSTEM:
                return EL1;
              case MODE_HYP:
                return EL2;
              case MODE_MON:
                return EL3;
              default:
                panic("Invalid operating mode: %d", mode);
                break;
            }
        } else {
            // aarch64
            return (ExceptionLevel) ((mode >> 2) & 3);
        }
    }

    static inline bool
    unknownMode(OperatingMode mode)
    {
        switch (mode) {
          case MODE_EL0T:
          case MODE_EL1T:
          case MODE_EL1H:
          case MODE_EL2T:
          case MODE_EL2H:
          case MODE_EL3T:
          case MODE_EL3H:
          case MODE_USER:
          case MODE_FIQ:
          case MODE_IRQ:
          case MODE_SVC:
          case MODE_MON:
          case MODE_ABORT:
          case MODE_HYP:
          case MODE_UNDEFINED:
          case MODE_SYSTEM:
            return false;
          default:
            return true;
        }
    }

    static inline bool
    unknownMode32(OperatingMode mode)
    {
        switch (mode) {
          case MODE_USER:
          case MODE_FIQ:
          case MODE_IRQ:
          case MODE_SVC:
          case MODE_MON:
          case MODE_ABORT:
          case MODE_HYP:
          case MODE_UNDEFINED:
          case MODE_SYSTEM:
            return false;
          default:
            return true;
        }
    }

    constexpr unsigned MaxSveVecLenInBits = 2048;
    static_assert(MaxSveVecLenInBits >= 128 &&
                  MaxSveVecLenInBits <= 2048 &&
                  MaxSveVecLenInBits % 128 == 0,
                  "Unsupported max. SVE vector length");
    constexpr unsigned MaxSveVecLenInBytes  = MaxSveVecLenInBits >> 3;
    constexpr unsigned MaxSveVecLenInWords  = MaxSveVecLenInBits >> 5;
    constexpr unsigned MaxSveVecLenInDWords = MaxSveVecLenInBits >> 6;

    constexpr unsigned VecRegSizeBytes = MaxSveVecLenInBytes;
    constexpr unsigned VecPredRegSizeBits = MaxSveVecLenInBytes;
    constexpr unsigned VecPredRegHasPackedRepr = false;
} // namespace ArmISA

#endif
