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

// Copyright (c) 2010, 2012, 2014, 2016 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.


def template PanicExecute {{
    Fault
    %(class_name)s::execute(ExecContext *xc,
                            Trace::InstRecord *traceData) const
    {
        panic("Execute function executed when it shouldn't be!\n");
        return NoFault;
    }
}};

def template PanicInitiateAcc {{
    Fault
    %(class_name)s::initiateAcc(ExecContext *xc,
                                Trace::InstRecord *traceData) const
    {
        panic("InitiateAcc function executed when it shouldn't be!\n");
        return NoFault;
    }
}};

def template PanicCompleteAcc {{
    Fault
    %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                Trace::InstRecord *traceData) const
    {
        panic("CompleteAcc function executed when it shouldn't be!\n");
        return NoFault;
    }
}};


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

        %(op_decl)s;
        uint64_t memData = 0;
        %(op_rd)s;
        %(ea_code)s;

        if (%(predicate_test)s) {
            %(preacc_code)s;

            if (fault == NoFault) {
                fault = writeMemAtomicLE(xc, traceData, Mem, EA,
                        memAccessFlags, &memData);
            }

            if (fault == NoFault) {
                %(postacc_code)s;
            }

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

        return fault;
    }
}};

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

        %(op_decl)s;
        uint64_t memData = 0;
        %(op_rd)s;
        %(ea_code)s;

        if (%(predicate_test)s) {
            %(preacc_code)s;

            if (fault == NoFault) {
                fault = writeMemTimingLE(xc, traceData, Mem, EA,
                        memAccessFlags, &memData);
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

def template SwapCompleteAcc {{
    Fault
    %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

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

        if (%(predicate_test)s) {
            // ARM instructions will not have a pkt if the predicate is false
            getMemLE(pkt, Mem, traceData);
            uint64_t memData = Mem;

            %(postacc_code)s;

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

        return fault;
    }
}};

def template LoadExecute {{
    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) {
                fault = readMemAtomicLE(
                        xc, traceData, EA, Mem, memAccessFlags);
                %(memacc_code)s;
            }

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

        return fault;
    }
}};

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

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

        MemUnion memUnion;
        uint8_t *dataPtr = memUnion.bytes;

        if (%(predicate_test)s) {
            if (fault == NoFault) {
                const auto size = %(size)d;
                fault = readMemAtomic(xc, EA, dataPtr,
                                      size, memAccessFlags,
                                      std::vector<bool>(size, true));
                %(memacc_code)s;
            }

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

        return fault;
    }
}};

def template StoreExecute {{
    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) {
                fault = writeMemAtomicLE(xc, traceData, Mem, EA,
                        memAccessFlags, NULL);
            }

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

        return fault;
    }
}};

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

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

        MemUnion memUnion;
        uint8_t *dataPtr = memUnion.bytes;

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

            if (fault == NoFault) {
                const auto size = %(size)d;
                fault = writeMemAtomic(xc, dataPtr, EA, size,
                                       memAccessFlags, NULL,
                                       std::vector<bool>(size, true));
            }

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

        return fault;
    }
}};

def template StoreExExecute {{
    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;
            }

            uint64_t writeResult;

            if (fault == NoFault) {
                fault = writeMemAtomicLE(xc, traceData, Mem, EA,
                        memAccessFlags, &writeResult);
            }

            if (fault == NoFault) {
                %(postacc_code)s;
            }

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

        return fault;
    }
}};

def template StoreExInitiateAcc {{
    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) {
                fault = writeMemTimingLE(xc, traceData, Mem, EA,
                        memAccessFlags, NULL);
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

def template StoreInitiateAcc {{
    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) {
                fault = writeMemTimingLE(xc, traceData, Mem, EA,
                        memAccessFlags, NULL);
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

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

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

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

            if (fault == NoFault) {
                const auto size = %(size)d;
                fault = writeMemTiming(xc, memUnion.bytes, EA,
                                       size, memAccessFlags, nullptr,
                                       std::vector<bool>(size, true));
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

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

        %(op_src_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        if (%(predicate_test)s) {
            if (fault == NoFault) {
                fault = initiateMemRead(xc, traceData, EA, Mem,
                                        memAccessFlags);
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

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

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

        if (%(predicate_test)s) {
            if (fault == NoFault) {
                const auto size = %(size)d;
                fault = initiateMemRead(xc, EA, size, memAccessFlags,
                                        std::vector<bool>(size, true));
            }
        } else {
            xc->setPredicate(false);
        }

        return fault;
    }
}};

def template LoadCompleteAcc {{
    Fault
    %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

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

        if (%(predicate_test)s) {
            // ARM instructions will not have a pkt if the predicate is false
            getMemLE(pkt, Mem, traceData);

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

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

        return fault;
    }
}};

def template NeonLoadCompleteAcc {{
    template <class Element>
    Fault
    %(class_name)s<Element>::completeAcc(
            PacketPtr pkt, ExecContext *xc, Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

        %(mem_decl)s;
        %(op_decl)s;
        %(op_rd)s;

        if (%(predicate_test)s) {
            // ARM instructions will not have a pkt if the predicate is false
            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();

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

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

        return fault;
    }
}};

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

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

def template StoreExCompleteAcc {{
    Fault
    %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

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

        if (%(predicate_test)s) {
            uint64_t writeResult = pkt->req->getExtraData();
            %(postacc_code)s;

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

        return fault;
    }
}};

def template RfeDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _base, int _mode, bool _wb);

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

def template SrsDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _regMode, int _mode, bool _wb);

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

def template SwapDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _dest, uint32_t _op1, uint32_t _base);

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

def template LoadStoreDImmDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _dest, uint32_t _dest2,
                uint32_t _base, bool _add, int32_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 StoreExDImmDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _result, uint32_t _dest, uint32_t _dest2,
                uint32_t _base, bool _add, int32_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 LoadStoreImmDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);

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

        void
        annotateFault(ArmISA::ArmFault *fault) override
        {
            %(fa_code)s
        }
    };
}};

def template StoreExImmDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _result, uint32_t _dest, uint32_t _base,
                bool _add, int32_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 StoreDRegDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _dest, uint32_t _dest2,
                uint32_t _base, bool _add,
                int32_t _shiftAmt, uint32_t _shiftType,
                uint32_t _index);

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

def template StoreRegDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _dest, uint32_t _base, bool _add,
                int32_t _shiftAmt, uint32_t _shiftType,
                uint32_t _index);

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

        void
        annotateFault(ArmISA::ArmFault *fault) override
        {
            %(fa_code)s
        }
    };
}};

def template LoadDRegDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _dest, uint32_t _dest2,
                uint32_t _base, bool _add,
                int32_t _shiftAmt, uint32_t _shiftType,
                uint32_t _index);

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

def template LoadRegDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _dest, uint32_t _base, bool _add,
                int32_t _shiftAmt, uint32_t _shiftType,
                uint32_t _index);

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

        void
        annotateFault(ArmISA::ArmFault *fault) override
        {
            %(fa_code)s
        }
    };
}};

def template LoadImmDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      private:
        %(reg_idx_arr_decl)s;

      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);

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

        void
        annotateFault(ArmISA::ArmFault *fault) override
        {
            %(fa_code)s
        }
    };
}};

def template RfeConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _base, int _mode, bool _wb) :
        %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                       (RegIndex)_base, (AddrMode)_mode, _wb)
    {
        %(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));
            }
        }
#if %(use_uops)d
        uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
        int uopIdx = 0;
        uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
        uops[uopIdx]->setDelayedCommit();
#if %(use_wb)d
        uops[++uopIdx] = new %(wb_decl)s;
        uops[uopIdx]->setDelayedCommit();
#endif
#if %(use_pc)d
        uops[++uopIdx] = new %(pc_decl)s;
#endif
        uops[0]->setFirstMicroop();
        uops[uopIdx]->setLastMicroop();
#endif
    }
}};

def template SrsConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _regMode, int _mode, bool _wb) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
    {
        %(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));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template SwapConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _dest, uint32_t _op1, uint32_t _base) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_dest, (RegIndex)_op1, (RegIndex)_base)
    {
        %(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 LoadStoreDImmConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _dest, uint32_t _dest2,
            uint32_t _base, bool _add, int32_t _imm) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_dest, (RegIndex)_dest2,
                 (RegIndex)_base, _add, _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));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
        uops[0]->setFirstMicroop();
        uops[0]->setDelayedCommit();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template StoreExDImmConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _result, uint32_t _dest, uint32_t _dest2,
            uint32_t _base, bool _add, int32_t _imm) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_result, (RegIndex)_dest, (RegIndex)_dest2,
                 (RegIndex)_base, _add, _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));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
                                   _base, _add, _imm);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template LoadStoreImmConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_dest, (RegIndex)_base, _add, _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));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template StoreExImmConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _result, uint32_t _dest, uint32_t _base,
            bool _add, int32_t _imm) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_result, (RegIndex)_dest,
                 (RegIndex)_base, _add, _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));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _result, _dest,
                                   _base, _add, _imm);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template StoreDRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_dest, (RegIndex)_dest2,
                 (RegIndex)_base, _add,
                 _shiftAmt, (ArmShiftType)_shiftType,
                 (RegIndex)_index)
    {
        %(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));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
                                   _shiftAmt, _shiftType, _index);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template StoreRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _dest, uint32_t _base, bool _add,
            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_dest, (RegIndex)_base, _add,
                 _shiftAmt, (ArmShiftType)_shiftType,
                 (RegIndex)_index)
    {
        %(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));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
                                   _shiftAmt, _shiftType, _index);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template LoadDRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_dest, (RegIndex)_dest2,
                 (RegIndex)_base, _add,
                 _shiftAmt, (ArmShiftType)_shiftType,
                 (RegIndex)_index)
    {
        %(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));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        if ((_dest == _index) || (_dest2 == _index)) {
            RegIndex wbIndexReg = int_reg::Ureg0;
            uops[0] = new MicroUopRegMov(machInst, int_reg::Ureg0, _index);
            uops[0]->setDelayedCommit();
            uops[0]->setFirstMicroop();
            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
                                       _shiftAmt, _shiftType, _index);
            uops[1]->setDelayedCommit();
            uops[2] = new %(wb_decl)s;
            uops[2]->setLastMicroop();
        } else {
            RegIndex wbIndexReg = index;
            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
                                       _shiftAmt, _shiftType, _index);
            uops[0]->setDelayedCommit();
            uops[0]->setFirstMicroop();
            uops[1] = new %(wb_decl)s;
            uops[1]->setLastMicroop();
        }
#endif
    }
}};

def template LoadRegConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _dest, uint32_t _base, bool _add,
            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_dest, (RegIndex)_base, _add,
                 _shiftAmt, (ArmShiftType)_shiftType,
                 (RegIndex)_index)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        [[maybe_unused]] bool conditional = false;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            conditional = true;
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        if (_dest == int_reg::Pc && !isFloating() && !isVector()) {
            RegIndex wbIndexReg = index;
            uops[0] = new %(acc_name)s(machInst, int_reg::Ureg0, _base, _add,
                                       _shiftAmt, _shiftType, _index);
            uops[0]->setDelayedCommit();
            uops[0]->setFirstMicroop();
            uops[1] = new %(wb_decl)s;
            uops[1]->setDelayedCommit();
            uops[2] = new MicroUopRegMov(machInst, int_reg::Pc,
                                         int_reg::Ureg0);
            uops[2]->setFlag(StaticInst::IsControl);
            uops[2]->setFlag(StaticInst::IsIndirectControl);
            if (conditional)
                uops[2]->setFlag(StaticInst::IsCondControl);
            else
                uops[2]->setFlag(StaticInst::IsUncondControl);
            uops[2]->setLastMicroop();
        } else if(_dest == _index) {
            RegIndex wbIndexReg = int_reg::Ureg0;
            uops[0] = new MicroUopRegMov(machInst, int_reg::Ureg0, _index);
            uops[0]->setDelayedCommit();
            uops[0]->setFirstMicroop();
            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
                                      _shiftAmt, _shiftType, _index);
            uops[1]->setDelayedCommit();
            uops[2] = new %(wb_decl)s;
            uops[2]->setLastMicroop();
        } else {
            RegIndex wbIndexReg = index;
            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
                                      _shiftAmt, _shiftType, _index);
            uops[0]->setDelayedCommit();
            uops[0]->setFirstMicroop();
            uops[1] = new %(wb_decl)s;
            uops[1]->setLastMicroop();

        }
#else
        if (_dest == int_reg::Pc && !isFloating() && !isVector()) {
            flags[IsControl] = true;
            flags[IsIndirectControl] = true;
            if (conditional)
                flags[IsCondControl] = true;
            else
                flags[IsUncondControl] = true;
        }
#endif
    }
}};

def template LoadImmConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm) :
         %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (RegIndex)_dest, (RegIndex)_base, _add, _imm)
    {
        %(set_reg_idx_arr)s;
        %(constructor)s;
        [[maybe_unused]] bool conditional = false;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            conditional = true;
            for (int x = 0; x < _numDestRegs; x++) {
                setSrcRegIdx(_numSrcRegs++, destRegIdx(x));
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        if (_dest == int_reg::Pc && !isFloating() && !isVector()) {
            uops[0] = new %(acc_name)s(machInst, int_reg::Ureg0, _base, _add,
                                   _imm);
            uops[0]->setDelayedCommit();
            uops[0]->setFirstMicroop();
            uops[1] = new %(wb_decl)s;
            uops[1]->setDelayedCommit();
            uops[2] = new MicroUopRegMov(
                    machInst, int_reg::Pc, int_reg::Ureg0);
            uops[2]->setFlag(StaticInst::IsControl);
            uops[2]->setFlag(StaticInst::IsIndirectControl);
            /* Also set flags on the macroop so that pre-microop decomposition
                branch prediction can work */
            setFlag(StaticInst::IsControl);
            setFlag(StaticInst::IsIndirectControl);
            if (conditional) {
                uops[2]->setFlag(StaticInst::IsCondControl);
                setFlag(StaticInst::IsCondControl);
            } else {
                uops[2]->setFlag(StaticInst::IsUncondControl);
                setFlag(StaticInst::IsUncondControl);
            }
            if (_base == int_reg::Sp && _add && _imm == 4 && %(is_ras_pop)s) {
                uops[2]->setFlag(StaticInst::IsReturn);
                setFlag(StaticInst::IsReturn);
            }
            uops[2]->setLastMicroop();
        } else {
            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
            uops[0]->setDelayedCommit();
            uops[0]->setFirstMicroop();
            uops[1] = new %(wb_decl)s;
            uops[1]->setLastMicroop();
        }
#else
        if (_dest == int_reg::Pc && !isFloating() && !isVector()) {
            flags[IsControl] = true;
            flags[IsIndirectControl] = true;
            if (conditional)
                flags[IsCondControl] = true;
            else
                flags[IsUncondControl] = true;
        }
#endif
    }
}};

