// Copyright (c) 2018-2019 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: Giacomo Gabrielli

let {{
    sveEnabledCheckCode = '''
        if (FullSystem) {
            fault = checkSveEnabled(xc->tcBase(), Cpsr, Cpacr64);
            if (fault != NoFault) {
                return fault;
            }
        }
    '''
}};

def template SveWideningUnaryPredOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _SElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _gp)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dest, _op1, _gp)
    {
        %(constructor)s;
    }

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

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

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

def template SveUnaryUnpredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  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;
};
}};

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

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

def template SveWideImmUnpredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  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;
};
}};

def template SveWideImmPredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
                   IntRegIndex _dest, uint64_t _imm, IntRegIndex _gp,
                   bool _isMerging = true)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dest, _imm, _gp, _isMerging)
    {
        %(constructor)s;
    }

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

def template SveBinImmUnpredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  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;
};
}};

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

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

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

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

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

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

def template SveBinUnpredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  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;
};
}};

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

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

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

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

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

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

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

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

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

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

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

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

def template SveTerImmUnpredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  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;
};
}};

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

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

def template SveWideningReducOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _SElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;

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

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

def template SveIndexIIOpDeclare {{
template <class _Element>
class SveIndexII : public SveIndexIIOp
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  public:
    // Constructor
    SveIndexII(ExtMachInst machInst,
            IntRegIndex _dest, int8_t _imm1, int8_t _imm2)
        : SveIndexIIOp("%(mnemonic)s", machInst, %(op_class)s,
                _dest, _imm1, _imm2)
    {
        %(constructor)s;
    }

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

def template SveIndexIROpDeclare {{
template <class _Element>
class SveIndexIR : public SveIndexIROp
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  public:
    // Constructor
    SveIndexIR(ExtMachInst machInst,
            IntRegIndex _dest, int8_t _imm, IntRegIndex _op)
        : SveIndexIROp("%(mnemonic)s", machInst, %(op_class)s,
                _dest, _imm, _op)
    {
        %(constructor)s;
    }

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

def template SveIndexRIOpDeclare {{
template <class _Element>
class SveIndexRI : public SveIndexRIOp
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  public:
    // Constructor
    SveIndexRI(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _op, int8_t _imm)
        : SveIndexRIOp("%(mnemonic)s", machInst, %(op_class)s,
                _dest, _op, _imm)
    {
        %(constructor)s;
    }

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

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

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

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

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

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

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

}};

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

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

def template SveAdrOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
        IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset,
        uint8_t _mult, SveAdrOffsetFormat _offsetFormat)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
            _dest, _base, _offset, _mult, _offsetFormat)
    {
        %(constructor)s;
    }

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

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

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

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

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

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

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

def template SveElemCountOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  public:
    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
            uint8_t _pattern, uint8_t _imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest,
                _pattern, _imm, %(dstIsVec)s, %(dstIs32b)s)
    {
        %(constructor)s;
        esize = sizeof(Element);
    }

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

def template SvePartBrkOpDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, IntRegIndex _gp,
            IntRegIndex _op1)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest,
                _gp, _op1, %(isMerging)s)
    {
        %(constructor)s;
    }

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

def template SvePartBrkPropOpDeclare {{
// XXX: Might be done with SveTerPredOpDeclare and
// instantiating with uint8_t
class %(class_name)s : public %(base_class)s
{
  public:
    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
            IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _gp)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest,
                _op1, _op2, _gp)
    {
        %(constructor)s;
    }

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

def template SveSelectOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _Element Element;
    typedef _Element TPElem;
  public:
    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
            IntRegIndex _op1, IntRegIndex _gp)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest,
                _op1, _gp, %(isCond)s, %(isScalar)s, %(isSimdFp)s)
    {
        %(constructor)s;
        scalar_width = (sizeof(Element) == 8) ? 64 : 32;
    }

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

def template SveUnpackOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _SElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;
  public:
    %(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;
};
}};

def template SvePredicateTestOpDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    %(class_name)s(ExtMachInst machInst, IntRegIndex _op1, IntRegIndex _gp)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, _gp)
    {
        %(constructor)s;
    }

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

def template SvePredUnaryOpWImplicitSrcDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest)
    {
        %(constructor)s;
    }

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

def template SvePredUnaryPredOpWImplicitSrcDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, IntRegIndex _gp)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _gp)
    {
        %(constructor)s;
    }

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

def template SvePredUnaryOpWImplicitDstDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    %(class_name)s(ExtMachInst machInst, IntRegIndex _op1)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1)
    {
        %(constructor)s;
    }

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

def template SveOpWImplicitSrcDstDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    %(class_name)s(ExtMachInst machInst)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
    {
        %(constructor)s;
    }

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

def template SveWideningTerImmOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _DElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;

  public:
    %(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;
        esize = sizeof(Element);
    }

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

def template SveWideningTerOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  protected:
    typedef _DElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;

  public:
    %(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;
        esize = sizeof(Element);
    }

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

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

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

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

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

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

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

        return fault;
    }
}};

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

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

        return fault;
    }
}};

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

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

        return fault;
    }
}};

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