// -*- 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.
//
// Authors: Mbou Eyole
//          Giacomo Gabrielli

let {{
    simd64EnabledCheckCode = vfp64EnabledCheckCode
}};

def template NeonX2RegOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dest, _op1, _op2)
    {
        %(constructor)s;
    }

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

def template NeonX2RegImmOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
                   uint64_t _imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dest, _op1, _op2, _imm)
    {
        %(constructor)s;
    }

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

def template NeonX1RegOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   IntRegIndex _dest, IntRegIndex _op1)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dest, _op1)
    {
        %(constructor)s;
    }

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

def template NeonX1RegImmOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dest, _op1, _imm)
    {
        %(constructor)s;
    }

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

def template NeonX1Reg2ImmOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm1,
                   uint64_t _imm2)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dest, _op1, _imm1, _imm2)
    {
        %(constructor)s;
    }

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

def template NeonX1RegImmOnlyOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   IntRegIndex _dest, uint64_t _imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dest, _imm)
    {
        %(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
    {
      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)
        {
            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 = xc->readMem(EA, dataPtr, accSize, memAccessFlags);
            %(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 = xc->initiateMemRead(EA, accSize, memAccessFlags);
        }

        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 = xc->writeMem(dataPtr, accSize, EA, memAccessFlags,
                                 NULL);
        }

        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 = xc->writeMem(memUnion.bytes, accSize, EA, memAccessFlags,
                                 NULL);
        }

        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
    {
      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
    {
      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)
    {
        %(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)
    {
        %(constructor)s;
    }
}};

def template MicroNeonMixDeclare64 {{
    class %(class_name)s : public %(base_class)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)
        {
            %(constructor)s;
        }

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

def template MicroNeonMixLaneDeclare64 {{
    class %(class_name)s : public %(base_class)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)
        {
            %(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;
    }
}};
