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

// Copyright (c) 2010-2014 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.
//
// Copyright (c) 2007-2008 The Florida State University
// All rights reserved.
//
// 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.

////////////////////////////////////////////////////////////////////
//
// Load/store microops
//

def template MicroMemDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst,
                       RegIndex _ura, RegIndex _urb, bool _up,
                       uint8_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 MicroMemConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   RegIndex _ura,
                                   RegIndex _urb,
                                   bool _up,
                                   uint8_t _imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _ura, _urb, _up, _imm)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
    }
}};


def template MicroMemPairDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst,
                       RegIndex _dreg1, RegIndex _dreg2, RegIndex _base,
                       bool _up, uint8_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 MicroMemPairConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   RegIndex _dreg1,
                                   RegIndex _dreg2,
                                   RegIndex _base,
                                   bool _up,
                                   uint8_t _imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _dreg1, _dreg2, _base, _up, _imm)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
    }
}};

////////////////////////////////////////////////////////////////////
//
// Neon load/store microops
//

def template MicroNeonMemDeclare {{
    template <class Element>
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst, RegIndex _dest,
                       RegIndex _ura, uint32_t _imm, unsigned extraMemFlags)
            : %(base_class)s("%(mnemonic)s", machInst,
                              %(op_class)s, _dest, _ura, _imm)
        {
            memAccessFlags |= extraMemFlags;
            %(constructor)s;
            if (!(condCode == COND_AL || condCode == COND_UC)) {
                for (int x = 0; x < _numDestRegs; x++) {
                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
                }
            }
        }

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

////////////////////////////////////////////////////////////////////
//
// PC   = Integer(ura)
// CPSR = Integer(urb)
//

def template MicroSetPCCPSRDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst,
                       IntRegIndex _ura,
                       IntRegIndex _urb,
                       IntRegIndex _urc);
        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};

def template MicroSetPCCPSRConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   IntRegIndex _ura,
                                   IntRegIndex _urb,
                                   IntRegIndex _urc)
          : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                           _ura, _urb, _urc)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            flags[IsCondControl] = true;
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        } else {
            flags[IsUncondControl] = true;
        }
    }
}};

////////////////////////////////////////////////////////////////////
//
// Integer = Integer op Integer microops
//

def template MicroIntDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst,
                       RegIndex _ura, RegIndex _urb, RegIndex _urc);
        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};

def template MicroIntConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   RegIndex _ura,
                                   RegIndex _urb,
                                   RegIndex _urc)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _ura, _urb, _urc)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
    }
}};

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

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

////////////////////////////////////////////////////////////////////
//
// Neon (de)interlacing microops
//

def template MicroNeonMixDeclare {{
    template <class Element>
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
                       uint8_t _step) :
            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                           _dest, _op1, _step)
        {
            %(constructor)s;
            if (!(condCode == COND_AL || condCode == COND_UC)) {
                for (int x = 0; x < _numDestRegs; x++) {
                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
                }
            }
        }

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

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

        if (%(predicate_test)s)
        {
            %(code)s;
            if (fault == NoFault)
            {
                %(op_wb)s;
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

////////////////////////////////////////////////////////////////////
//
// Neon (un)packing microops using a particular lane
//

def template MicroNeonMixLaneDeclare {{
    template <class Element>
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1,
                       uint8_t _step, unsigned _lane) :
            %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                           _dest, _op1, _step, _lane)
        {
            %(constructor)s;
            if (!(condCode == COND_AL || condCode == COND_UC)) {
                for (int x = 0; x < _numDestRegs; x++) {
                    _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
                }
            }
        }

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

////////////////////////////////////////////////////////////////////
//
// Integer = Integer
//

def template MicroIntMovDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst,
                       RegIndex _ura, RegIndex _urb);
        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};
def template MicroIntMovConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   RegIndex _ura,
                                   RegIndex _urb)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _ura, _urb)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
    }
}};

////////////////////////////////////////////////////////////////////
//
// Integer = Integer op Immediate microops
//

def template MicroIntImmDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst,
                       RegIndex _ura, RegIndex _urb,
                       int32_t _imm);
        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};

def template MicroIntImmConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   RegIndex _ura,
                                   RegIndex _urb,
                                   int32_t _imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _ura, _urb, _imm)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
    }
}};

def template MicroIntImmXConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   RegIndex _ura,
                                   RegIndex _urb,
                                   int32_t _imm)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _ura, _urb, _imm)
    {
        %(constructor)s;
    }
}};

def template MicroIntRegDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst,
                       RegIndex _ura, RegIndex _urb, RegIndex _urc,
                       int32_t _shiftAmt, ArmShiftType _shiftType);
        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};

def template MicroIntXERegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   RegIndex _ura, RegIndex _urb, RegIndex _urc,
                                   ArmExtendType _type, uint32_t _shiftAmt)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _ura, _urb, _urc, _type, _shiftAmt)
    {
        %(constructor)s;
    }
}};

def template MicroIntXERegDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        %(class_name)s(ExtMachInst machInst,
                       RegIndex _ura, RegIndex _urb, RegIndex _urc,
                       ArmExtendType _type, uint32_t _shiftAmt);
        Fault execute(ExecContext *, Trace::InstRecord *) const override;
    };
}};

def template MicroIntRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
                                   RegIndex _ura, RegIndex _urb, RegIndex _urc,
                                   int32_t _shiftAmt, ArmShiftType _shiftType)
        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                         _ura, _urb, _urc, _shiftAmt, _shiftType)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
    }
}};

////////////////////////////////////////////////////////////////////
//
// Macro Memory-format instructions
//

def template MacroMemDeclare {{
/**
 * Static instructions class for a store multiple instruction
 */
class %(class_name)s : public %(base_class)s
{
    public:
        // Constructor
        %(class_name)s(ExtMachInst machInst, IntRegIndex rn,
                bool index, bool up, bool user, bool writeback, bool load,
                uint32_t reglist);
};
}};

def template MacroMemConstructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn,
        bool index, bool up, bool user, bool writeback, bool load,
        uint32_t reglist)
    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn,
                     index, up, user, writeback, load, reglist)
{
    %(constructor)s;
    if (!(condCode == COND_AL || condCode == COND_UC)) {
        for (int x = 0; x < _numDestRegs; x++) {
            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
        }
    }
}

}};

def template BigFpMemImmDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    // Constructor
    %(class_name)s(const char *mnemonic, ExtMachInst machInst,
                   bool load, IntRegIndex dest, IntRegIndex base, int64_t imm);
};
}};

def template BigFpMemImmConstructor {{
%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
        bool load, IntRegIndex dest, IntRegIndex base, int64_t imm)
    : %(base_class)s(mnemonic, machInst, %(op_class)s, load, dest, base, imm)
{
    %(constructor)s;
}
}};

def template BigFpMemRegDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    // Constructor
    %(class_name)s(const char *mnemonic, ExtMachInst machInst,
                   bool load, IntRegIndex dest, IntRegIndex base,
                   IntRegIndex offset, ArmExtendType type, int64_t imm);
};
}};

def template BigFpMemRegConstructor {{
%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
        bool load, IntRegIndex dest, IntRegIndex base,
        IntRegIndex offset, ArmExtendType type, int64_t imm)
    : %(base_class)s(mnemonic, machInst, %(op_class)s, load, dest, base,
                     offset, type, imm)
{
    %(constructor)s;
}
}};

def template BigFpMemLitDeclare {{
class %(class_name)s : public %(base_class)s
{
  public:
    // Constructor
    %(class_name)s(const char *mnemonic, ExtMachInst machInst,
                   IntRegIndex dest, int64_t imm);
};
}};

def template BigFpMemLitConstructor {{
%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
        IntRegIndex dest, int64_t imm)
    : %(base_class)s(mnemonic, machInst, %(op_class)s, dest, imm)
{
    %(constructor)s;
}
}};

def template PairMemDeclare {{
class %(class_name)s : public %(base_class)s
{
    public:
        // Constructor
        %(class_name)s(const char *mnemonic, ExtMachInst machInst,
                uint32_t size, bool fp, bool load, bool noAlloc, bool signExt,
                bool exclusive, bool acrel, uint32_t imm,
                AddrMode mode, IntRegIndex rn, IntRegIndex rt,
                IntRegIndex rt2);
};
}};

def template PairMemConstructor {{
%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst,
        uint32_t size, bool fp, bool load, bool noAlloc, bool signExt,
        bool exclusive, bool acrel, uint32_t imm, AddrMode mode,
        IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2)
    : %(base_class)s(mnemonic, machInst, %(op_class)s, size,
                     fp, load, noAlloc, signExt, exclusive, acrel,
                     imm, mode, rn, rt, rt2)
{
    %(constructor)s;
}
}};

def template VMemMultDeclare {{
class %(class_name)s : public %(base_class)s
{
    public:
        // Constructor
        %(class_name)s(ExtMachInst machInst, unsigned width,
                RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
                uint32_t size, uint32_t align, RegIndex rm);
};
}};

def template VMemMultConstructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, unsigned width,
        RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
        uint32_t size, uint32_t align, RegIndex rm)
    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, width,
                     rn, vd, regs, inc, size, align, rm)
{
    %(constructor)s;
    if (!(condCode == COND_AL || condCode == COND_UC)) {
        for (int x = 0; x < _numDestRegs; x++) {
            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
        }
    }
}
}};

def template VMemSingleDeclare {{
class %(class_name)s : public %(base_class)s
{
    public:
        // Constructor
        %(class_name)s(ExtMachInst machInst, bool all, unsigned width,
                RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
                uint32_t size, uint32_t align, RegIndex rm, unsigned lane = 0);
};
}};

def template VMemSingleConstructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, bool all, unsigned width,
        RegIndex rn, RegIndex vd, unsigned regs, unsigned inc,
        uint32_t size, uint32_t align, RegIndex rm, unsigned lane)
    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, all, width,
                     rn, vd, regs, inc, size, align, rm, lane)
{
    %(constructor)s;
    if (!(condCode == COND_AL || condCode == COND_UC)) {
        for (int x = 0; x < _numDestRegs; x++) {
            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
        }
    }
}
}};

def template MacroVFPMemDeclare {{
/**
 * Static instructions class for a store multiple instruction
 */
class %(class_name)s : public %(base_class)s
{
    public:
        // Constructor
        %(class_name)s(ExtMachInst machInst, IntRegIndex rn,
                RegIndex vd, bool single, bool up, bool writeback,
                bool load, uint32_t offset);
};
}};

def template MacroVFPMemConstructor {{
%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn,
        RegIndex vd, bool single, bool up, bool writeback, bool load,
        uint32_t offset)
    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn,
                     vd, single, up, writeback, load, offset)
{
    %(constructor)s;
    if (!(condCode == COND_AL || condCode == COND_UC)) {
        for (int x = 0; x < _numDestRegs; x++) {
            _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
        }
    }
}

}};
