// -*- mode: c++ -*-

// Copyright (c) 2012-2013 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.
//
// 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.

let {{
    simd64EnabledCheckCode = vfp64EnabledCheckCode
}};

def template NeonX2RegOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   RegIndex _dest, RegIndex _op1, RegIndex _op2) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _op1, _op2)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template NeonX2RegImmOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   RegIndex _dest, RegIndex _op1, RegIndex _op2,
                   uint64_t _imm) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _op1, _op2, _imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template NeonX1RegOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _op1)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template NeonX1RegImmOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   RegIndex _dest, RegIndex _op1, uint64_t _imm) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _op1, _imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template NeonX1Reg2ImmOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   RegIndex _dest, RegIndex _op1, uint64_t _imm1,
                   uint64_t _imm2) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _op1, _imm1, _imm2)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template NeonX1RegImmOnlyOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, uint64_t _imm) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template NeonXExecDeclare {{
    template
    Fault %(class_name)s<%(targs)s>::execute(
            ExecContext *, Trace::InstRecord *) const;
}};

def template NeonXEqualRegOpExecute {{
    template <class Element>
    Fault
    %(class_name)s<Element>::execute(ExecContext *xc,
            Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;
        %(op_decl)s;
        %(op_rd)s;

        const unsigned rCount = %(r_count)d;
        const unsigned eCount = rCount * sizeof(uint32_t) / sizeof(Element);
        const unsigned eCountFull = 4 * sizeof(uint32_t) / sizeof(Element);

        union RegVect
        {
            uint32_t regs[rCount];
            Element elements[eCount];
        };

        union FullRegVect
        {
            uint32_t regs[4];
            Element elements[eCountFull];
        };

        %(code)s;
        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

def template NeonXUnequalRegOpExecute {{
    template <class Element>
    Fault
    %(class_name)s<Element>::execute(ExecContext *xc,
            Trace::InstRecord *traceData) const
    {
        typedef typename bigger_type_t<Element>::type BigElement;
        Fault fault = NoFault;
        %(op_decl)s;
        %(op_rd)s;

        const unsigned rCount = %(r_count)d;
        const unsigned eCount = rCount * sizeof(uint32_t) / sizeof(Element);
        const unsigned eCountFull = 4 * sizeof(uint32_t) / sizeof(Element);

        union RegVect
        {
            uint32_t regs[rCount];
            Element elements[eCount];
            BigElement bigElements[eCount / 2];
        };

        union BigRegVect
        {
            uint32_t regs[2 * rCount];
            BigElement elements[eCount];
        };

        union FullRegVect
        {
            uint32_t regs[4];
            Element elements[eCountFull];
        };

        %(code)s;
        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

def template MicroNeonMemDeclare64 {{
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      protected:
        // True if the base register is SP (used for SP alignment checking)
        bool baseIsSP;
        // Access size in bytes
        uint8_t accSize;
        // Vector element size (0 -> 8-bit, 1 -> 16-bit, 2 -> 32-bit,
        // 3 -> 64-bit)
        uint8_t eSize;

      public:
        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _ura,
                       uint32_t _imm, unsigned extraMemFlags, bool _baseIsSP,
                       uint8_t _accSize, uint8_t _eSize) :
            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest,
                             _ura, _imm),
            baseIsSP(_baseIsSP), accSize(_accSize), eSize(_eSize)
        {
            %(set_reg_idx_arr)s;
            memAccessFlags |= extraMemFlags;
            %(constructor)s;
        }

        Fault execute(ExecContext *, Trace::InstRecord *) const override;
        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
        Fault completeAcc(PacketPtr, ExecContext *,
                          Trace::InstRecord *) const override;
    };
}};

def template NeonLoadExecute64 {{
    Fault
    %(class_name)s::execute(
            ExecContext *xc, Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(op_decl)s;
        %(mem_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        MemUnion memUnion;
        uint8_t *dataPtr = memUnion.bytes;

        if (fault == NoFault) {
            fault = readMemAtomic(xc, EA, dataPtr,
                                  accSize, memAccessFlags,
                                  std::vector<bool>(accSize, true));
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

def template NeonLoadInitiateAcc64 {{
    Fault
    %(class_name)s::initiateAcc(
        ExecContext *xc, Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(op_decl)s;
        %(mem_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        if (fault == NoFault) {
            fault = initiateMemRead(xc, EA, accSize, memAccessFlags,
                                    std::vector<bool>(accSize, true));
        }

        return fault;
    }
}};

def template NeonLoadCompleteAcc64 {{
    Fault
    %(class_name)s::completeAcc(
        PacketPtr pkt, ExecContext *xc, Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

        %(mem_decl)s;
        %(op_decl)s;
        %(op_rd)s;

        MemUnion memUnion { { } };
        memcpy(&memUnion, pkt->getPtr<uint8_t>(), pkt->getSize());

        if (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

def template NeonStoreExecute64 {{
    Fault
    %(class_name)s::execute(
        ExecContext *xc, Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(op_decl)s;
        %(mem_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        MemUnion memUnion;
        uint8_t *dataPtr = memUnion.bytes;

        if (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = writeMemAtomic(xc, dataPtr, EA, accSize,
                                   memAccessFlags, nullptr,
                                   std::vector<bool>(accSize, true));
        }

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

def template NeonStoreInitiateAcc64 {{
    Fault
    %(class_name)s::initiateAcc(
        ExecContext *xc, Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(op_decl)s;
        %(mem_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        MemUnion memUnion;
        if (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = writeMemTiming(xc, memUnion.bytes, EA,
                                   accSize, memAccessFlags, NULL,
                                   std::vector<bool>(accSize, true));
        }

        return fault;
    }
}};

def template NeonStoreCompleteAcc64 {{
    Fault
    %(class_name)s::completeAcc(
        PacketPtr pkt, ExecContext *xc, Trace::InstRecord *traceData) const
    {
        return NoFault;
    }
}};

def template VMemMultDeclare64 {{
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        // Constructor
        %(class_name)s(ExtMachInst machInst, RegIndex rn, RegIndex vd,
                       RegIndex rm, uint8_t eSize, uint8_t dataSize,
                       uint8_t numStructElems, uint8_t numRegs, bool wb);
    };
}};

def template VMemSingleDeclare64 {{
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        // Constructor
        %(class_name)s(ExtMachInst machInst, RegIndex rn, RegIndex vd,
                       RegIndex rm, uint8_t eSize, uint8_t dataSize,
                       uint8_t numStructElems, uint8_t index, bool wb,
                       bool replicate=false);
    };
}};

def template VMemMultConstructor64 {{
    %(class_name)s::%(class_name)s(
        ExtMachInst machInst, RegIndex rn, RegIndex vd, RegIndex rm,
        uint8_t _eSize, uint8_t _dataSize, uint8_t _numStructElems,
        uint8_t _numRegs, bool _wb) :
            %(base_class)s(
                "%(mnemonic)s", machInst, %(op_class)s, rn, vd, rm,
                _eSize, _dataSize, _numStructElems, _numRegs, _wb)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }
}};

def template VMemSingleConstructor64 {{
    %(class_name)s::%(class_name)s(
        ExtMachInst machInst, RegIndex rn, RegIndex vd, RegIndex rm,
        uint8_t _eSize, uint8_t _dataSize, uint8_t _numStructElems,
        uint8_t _index, bool _wb, bool _replicate) :
            %(base_class)s(
                "%(mnemonic)s", machInst, %(op_class)s, rn, vd, rm,
                _eSize, _dataSize, _numStructElems, _index, _wb,
                _replicate)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }
}};

def template MicroNeonMixDeclare64 {{
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
                       uint8_t _eSize, uint8_t _dataSize,
                       uint8_t _numStructElems, uint8_t _numRegs,
                       uint8_t _step) :
            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                           _dest, _op1, _eSize, _dataSize, _numStructElems,
                           _numRegs, _step)
        {
            %(set_reg_idx_arr)s;
            %(constructor)s;
        }

        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};

def template MicroNeonMixLaneDeclare64 {{
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
                       uint8_t _eSize, uint8_t _dataSize,
                       uint8_t _numStructElems, uint8_t _lane, uint8_t _step,
                       bool _replicate = false) :
            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                           _dest, _op1, _eSize, _dataSize, _numStructElems,
                           _lane, _step, _replicate)
        {
            %(set_reg_idx_arr)s;
            %(constructor)s;
        }

        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};

def template MicroNeonMixExecute64 {{
    Fault
    %(class_name)s::execute(
            ExecContext *xc, Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;
        uint64_t resTemp = 0;
        resTemp = resTemp;
        %(op_decl)s;
        %(op_rd)s;

        %(code)s;
        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};
