// 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.

let {{
    sveEnabledCheckCode = '''
        if (FullSystem) {
            // Check an SVE inst against the appropriate traps/enables based
            // on the Streaming Mode.
            fault = this->checkSveSmeEnabled(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
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _SElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  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 SveShiftAndInsertOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  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 SveWideImmPredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  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 SveBinImmPredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  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 SveBinIdxUnpredOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  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 SveReducOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

def template SveWideningReducOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _SElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;

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

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

def template SveIndexIIOpDeclare {{
template <class _Element>
class SveIndexII : public SveIndexIIOp
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    // Constructor
    SveIndexII(ExtMachInst machInst, RegIndex _dest,
               int8_t _imm1, int8_t _imm2) :
        SveIndexIIOp("%(mnemonic)s", machInst, %(op_class)s,
                     _dest, _imm1, _imm2)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

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

def template SveIndexIROpDeclare {{
template <class _Element>
class SveIndexIR : public SveIndexIROp
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    // Constructor
    SveIndexIR(ExtMachInst machInst, RegIndex _dest,
               int8_t _imm, RegIndex _op) :
        SveIndexIROp("%(mnemonic)s", machInst, %(op_class)s,
                     _dest, _imm, _op)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

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

def template SveIndexRIOpDeclare {{
template <class _Element>
class SveIndexRI : public SveIndexRIOp
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    // Constructor
    SveIndexRI(ExtMachInst machInst, RegIndex _dest,
               RegIndex _op, int8_t _imm) :
        SveIndexRIOp("%(mnemonic)s", machInst, %(op_class)s,
                     _dest, _op, _imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

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

def template SveIndexRROpDeclare {{
template <class _Element>
class SveIndexRR : public SveIndexRROp
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    // Constructor
    SveIndexRR(ExtMachInst machInst, RegIndex _dest,
               RegIndex _op1, RegIndex _op2) :
        SveIndexRROp("%(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 SvePredCountOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

}};

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, uint8_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 SveAdrOpDeclare {{
template <class _Element>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst,
        RegIndex _dest, RegIndex _base, RegIndex _offset,
        uint8_t _mult, SveAdrOffsetFormat _offsetFormat) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _base, _offset, _mult, _offsetFormat)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    %(class_name)s(ExtMachInst machInst,
                   RegIndex dest, RegIndex op1,
                   RegIndex gp, RegIndex op2,
                   uint64_t imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                          dest, op1, gp, op2, imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    %(class_name)s(ExtMachInst machInst, RegIndex _dest,
            uint8_t _pattern, uint8_t _imm) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest,
                _pattern, _imm, %(dstIsVec)s, %(dstIs32b)s)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        esize = sizeof(Element);
    }

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

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

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

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

def template SvePartBrkPropOpDeclare {{
// XXX: Might be done with SveTerPredOpDeclare and
// instantiating with uint8_t
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  public:
    %(class_name)s(ExtMachInst machInst, RegIndex _dest,
            RegIndex _op1, RegIndex _gp) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest,
                _op1, _gp, %(isCond)s, %(isScalar)s, %(isSimdFp)s)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        scalar_width = (sizeof(Element) == 8) ? 64 : 32;
    }

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

def template SveUnpackOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _SElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;

  public:
    %(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 SvePredicateTestOpDeclare {{
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

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

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

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

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

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

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

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

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

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

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

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

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

  public:
    %(class_name)s(ExtMachInst machInst) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
    }

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

def template SveWideningTerImmOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _DElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;

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

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

def template SveWideningTerOpDeclare {{
template <class _SElement, class _DElement>
class %(class_name)s : public %(base_class)s
{
  private:
    %(reg_idx_arr_decl)s;

  protected:
    typedef _DElement Element;
    typedef _SElement SElement;
    typedef _DElement DElement;
    typedef _SElement TPSElem;
    typedef _DElement TPDElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

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

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

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

  protected:
    typedef _Element Element;
    typedef _Element TPElem;

  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 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;
}};
