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

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

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template MrsConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _dest) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  protected:
    uint8_t byteMask;
    bool r;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest,
                   uint8_t _sysM, bool _r);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template MrsBankedRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _dest,
                                   uint8_t _sysM, bool _r) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest),
        byteMask(_sysM), r(_r)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  protected:
    bool r;

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _op1,
                   uint8_t _sysM, bool _r);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template MsrBankedRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _op1,
                                   uint8_t _sysM, bool _r) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, _sysM),
        r(_r)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _op1, uint8_t mask);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template MsrRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _op1,
                                   uint8_t mask) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, mask)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, uint32_t imm, uint8_t mask);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template MsrImmConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, uint32_t imm,
                                   uint8_t mask) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, imm, mask)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, MiscRegIndex _op1,
                   RegIndex _dest, RegIndex _dest2, uint32_t imm);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template MrrcOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, MiscRegIndex op1,
                                   RegIndex dest, RegIndex dest2,
                                   uint32_t imm) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, op1, dest,
                       dest2, imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _op1, RegIndex _op2,
                   MiscRegIndex _dest, uint32_t imm);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template McrrOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex op1,
                                   RegIndex op2, MiscRegIndex dest,
                                   uint32_t imm) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, op1, op2,
                       dest, imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, uint64_t _imm);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template ImmOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, uint64_t _imm) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, uint64_t _imm);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegImmOpConstructor {{
    %(class_name)s::%(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;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegRegOpConstructor {{
    %(class_name)s::%(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;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest,
                   RegIndex _op1, RegIndex _op2, uint64_t _imm);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegRegRegImmOpConstructor {{
    %(class_name)s::%(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;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest,
                   RegIndex _op1, RegIndex _op2, RegIndex _op3);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegRegRegRegOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _dest,
                                   RegIndex _op1, RegIndex _op2,
                                   RegIndex _op3) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _op1, _op2, _op3)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest,
                   RegIndex _op1, RegIndex _op2);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegRegRegOpConstructor {{
    %(class_name)s::%(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;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
                   uint64_t _imm);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegRegImmOpConstructor {{
    %(class_name)s::%(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;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, MiscRegIndex _dest, RegIndex _op1,
                   uint64_t _imm);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template MiscRegRegImmOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, MiscRegIndex _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;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, MiscRegIndex _op1,
                   uint64_t _imm);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegMiscRegImmOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _dest,
                                   MiscRegIndex _op1, uint64_t _imm) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _op1, _imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest,
                   uint64_t _imm1, uint64_t _imm2);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegImmImmOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _dest,
                                   uint64_t _imm1, uint64_t _imm2) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _imm1, _imm2)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
                   uint64_t _imm1, uint64_t _imm2);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegRegImmImmOpConstructor {{
    %(class_name)s::%(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;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest,
                   uint64_t _imm, RegIndex _op1);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegImmRegOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _dest,
                                   uint64_t _imm, RegIndex _op1) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _imm, _op1)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

  public:
    // Constructor
    %(class_name)s(ExtMachInst machInst, RegIndex _dest, uint64_t _imm,
                   RegIndex _op1, int32_t _shiftAmt,
                   ArmShiftType _shiftType);
    Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};

def template RegImmRegShiftOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, RegIndex _dest,
                                   uint64_t _imm, RegIndex _op1,
                                   int32_t _shiftAmt,
                                   ArmShiftType _shiftType) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       _dest, _imm, _op1, _shiftAmt, _shiftType)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
    }
}};

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

      public:
        // Constructor
        %(class_name)s(ExtMachInst machInst, MiscRegIndex _dest,
                       RegIndex _op1, uint64_t _imm);
        Fault execute(ExecContext *, Trace::InstRecord *) const override;
        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
        Fault completeAcc(PacketPtr, ExecContext *,
                          Trace::InstRecord *) const override;
    };
}};

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

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

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

            if (fault == NoFault) {
                Addr op_size = xc->tcBase()->getSystemPtr()->cacheLineSize();
                EA &= ~(op_size - 1);
                fault = writeMemAtomic(xc, NULL, EA, op_size,
                    memAccessFlags, NULL, std::vector<bool>(op_size, true));
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

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

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

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

            if (fault == NoFault) {
                Addr op_size = xc->tcBase()->getSystemPtr()->cacheLineSize();
                EA &= ~(op_size - 1);
                fault = writeMemTiming(xc, NULL, EA, op_size,
                    memAccessFlags, NULL, std::vector<bool>(op_size, true));
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

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