// -*- 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) {
                fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
                %(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) {
                fault = xc->writeMem(dataPtr, %(size)d, EA,
                                     memAccessFlags, NULL);
            }

            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) {
                fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
                                     memAccessFlags, NULL);
            }
        } 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) {
                fault = xc->initiateMemRead(EA, %(size)d, memAccessFlags);
            }
        } 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
    {
      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
    {
      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
    {
      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
    {
      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
    {
      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
    {
      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(ArmFault *fault) override
        {
            %(fa_code)s
        }
    };
}};

def template StoreExImmDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)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
    {
      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
    {
      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(ArmFault *fault) override
        {
            %(fa_code)s
        }
    };
}};

def template LoadDRegDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)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
    {
      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(ArmFault *fault) override
        {
            %(fa_code)s
        }
    };
}};

def template LoadImmDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)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(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,
                         (IntRegIndex)_base, (AddrMode)_mode, _wb)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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,
                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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,
                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
                 (IntRegIndex)_base, _add, _imm)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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,
                 (IntRegIndex)_result,
                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
                 (IntRegIndex)_base, _add, _imm)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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,
                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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,
                 (IntRegIndex)_result, (IntRegIndex)_dest,
                 (IntRegIndex)_base, _add, _imm)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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,
                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
                 (IntRegIndex)_base, _add,
                 _shiftAmt, (ArmShiftType)_shiftType,
                 (IntRegIndex)_index)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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,
                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
                 _shiftAmt, (ArmShiftType)_shiftType,
                 (IntRegIndex)_index)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_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,
                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
                 (IntRegIndex)_base, _add,
                 _shiftAmt, (ArmShiftType)_shiftType,
                 (IntRegIndex)_index)
    {
        %(constructor)s;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        if ((_dest == _index) || (_dest2 == _index)) {
            IntRegIndex wbIndexReg = INTREG_UREG0;
            uops[0] = new MicroUopRegMov(machInst, INTREG_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 {
            IntRegIndex 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,
                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
                 _shiftAmt, (ArmShiftType)_shiftType,
                 (IntRegIndex)_index)
    {
        %(constructor)s;
        bool conditional M5_VAR_USED = false;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            conditional = true;
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        if (_dest == INTREG_PC && !isFloating() && !isVector()) {
            IntRegIndex wbIndexReg = index;
            uops[0] = new %(acc_name)s(machInst, INTREG_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, INTREG_PC, INTREG_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) {
            IntRegIndex wbIndexReg = INTREG_UREG0;
            uops[0] = new MicroUopRegMov(machInst, INTREG_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 {
            IntRegIndex 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 == INTREG_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,
                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
    {
        %(constructor)s;
        bool conditional M5_VAR_USED = false;
        if (!(condCode == COND_AL || condCode == COND_UC)) {
            conditional = true;
            for (int x = 0; x < _numDestRegs; x++) {
                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
            }
        }
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        if (_dest == INTREG_PC && !isFloating() && !isVector()) {
            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
                                   _imm);
            uops[0]->setDelayedCommit();
            uops[0]->setFirstMicroop();
            uops[1] = new %(wb_decl)s;
            uops[1]->setDelayedCommit();
            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_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 == INTREG_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 == INTREG_PC && !isFloating() && !isVector()) {
            flags[IsControl] = true;
            flags[IsIndirectControl] = true;
            if (conditional)
                flags[IsCondControl] = true;
            else
                flags[IsUncondControl] = true;
        }
#endif
    }
}};

