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

// Copyright (c) 2011-2014, 2017, 2019 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
// not be construed as granting a license to any other intellectual
// property including but not limited to intellectual property relating
// to a hardware implementation of the functionality of the software
// licensed hereunder.  You may use the software subject to the license
// terms below provided that you ensure that this notice is replicated
// unmodified and in its entirety in all distributions of the software,
// modified or unmodified, in source code or in binary form.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Gabe Black

let {{
    SPAlignmentCheckCode = '''
        if (baseIsSP && bits(XBase, 3, 0) &&
            SPAlignmentCheckEnabled(xc->tcBase())) {
            return std::make_shared<SPAlignmentFault>();
        }
   '''
}};

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

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

        return fault;
    }
}};

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

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

        return fault;
    }
}};

def template Store64Execute {{
    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 (fault == NoFault) {
            %(memacc_code)s;
        }

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

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

        return fault;
    }
}};

def template Store64InitiateAcc {{
    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 (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = writeMemTimingLE(xc, traceData, Mem, EA, memAccessFlags,
                                     NULL);
        }

        return fault;
    }
}};

def template StoreEx64Execute {{
    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 (fault == NoFault) {
            %(memacc_code)s;
        }

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

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

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

        return fault;
    }
}};

def template StoreEx64InitiateAcc {{
    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 (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = writeMemTimingLE(xc, traceData, Mem, EA, memAccessFlags,
                                     NULL);
        }

        return fault;
    }
}};

def template Load64InitiateAcc {{
    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 (fault == NoFault) {
            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
        }

        return fault;
    }
}};

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

        %(op_decl)s;
        %(op_rd)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 Store64CompleteAcc {{
    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        return NoFault;
    }
}};

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

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

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

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

        return fault;
    }
}};

def template DCStore64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst, IntRegIndex _base,
                       MiscRegIndex _dest, uint64_t _imm);

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

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

def template DCStore64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex _base,
                                   MiscRegIndex _dest, uint64_t _imm)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                          _base, _dest, _imm)
    {
        %(constructor)s;
        assert(!%(use_uops)d);
    }
}};

def template DCStore64Execute {{
    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 (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = xc->writeMem(NULL, op_size, EA, memAccessFlags, NULL);
        }

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

        return fault;
    }
}};

def template DCStore64InitiateAcc {{
    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 (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = xc->writeMem(NULL, op_size, EA, memAccessFlags, NULL);
        }

        return fault;
    }
}};


def template LoadStoreImm64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                IntRegIndex _dest, IntRegIndex _base, int64_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 LoadStoreImmU64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                IntRegIndex _dest, IntRegIndex _base, int64_t _imm,
                bool noAlloc = false, bool exclusive = false,
                bool acrel = false);

        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 LoadStoreImmDU64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                IntRegIndex _dest, IntRegIndex _dest2, IntRegIndex _base,
                int64_t _imm = 0, bool noAlloc = false, bool exclusive = false,
                bool acrel = false);

        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 StoreImmDEx64Declare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                IntRegIndex _result, IntRegIndex _dest, IntRegIndex _dest2,
                IntRegIndex _base, int64_t _imm = 0);

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


def template LoadStoreReg64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset,
                ArmExtendType _type, uint32_t _shiftAmt);

        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 LoadStoreRegU64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst,
                IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset,
                ArmExtendType _type, uint32_t _shiftAmt,
                bool noAlloc = false, bool exclusive = false,
                bool acrel = false);

        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 LoadStoreRaw64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
                       IntRegIndex _base);

        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 LoadStoreEx64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
                       IntRegIndex _base, IntRegIndex _result);

        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 LoadStoreLit64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, int64_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 LoadStoreLitU64Declare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, int64_t _imm,
                bool noAlloc = false, bool exclusive = false,
                bool acrel = false);

        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 LoadStoreImm64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base, int64_t _imm)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (IntRegIndex)_dest, (IntRegIndex)_base, _imm)
    {
        %(constructor)s;
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _dest, _base, _imm);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template LoadStoreImmU64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base, int64_t _imm,
            bool noAlloc, bool exclusive, bool acrel)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 _dest, _base, _imm)
    {
        %(constructor)s;
        assert(!%(use_uops)d);
        setExcAcRel(exclusive, acrel);
    }
}};

def template LoadStoreImmDU64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _dest2, IntRegIndex _base,
            int64_t _imm, bool noAlloc, bool exclusive, bool acrel)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 _dest, _dest2, _base, _imm)
    {
        %(constructor)s;
        assert(!%(use_uops)d);
        setExcAcRel(exclusive, acrel);
    }
}};

def template StoreImmDEx64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _result, IntRegIndex _dest, IntRegIndex _dest2,
            IntRegIndex _base, int64_t _imm)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 _result, _dest, _dest2, _base, _imm)
    {
        %(constructor)s;
        assert(!%(use_uops)d);
    }
}};


def template LoadStoreReg64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset,
            ArmExtendType _type, uint32_t _shiftAmt)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 _dest, _base, _offset, _type, _shiftAmt)
    {
        %(constructor)s;
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _dest, _base, _offset,
                                   _type, _shiftAmt);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template LoadStoreRegU64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset,
            ArmExtendType _type, uint32_t _shiftAmt,
            bool noAlloc, bool exclusive, bool acrel)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 _dest, _base, _offset, _type, _shiftAmt)
    {
        %(constructor)s;
        assert(!%(use_uops)d);
        setExcAcRel(exclusive, acrel);
    }
}};

def template LoadStoreRaw64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _base)
    {
        %(constructor)s;
    }
}};

def template LoadStoreEx64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                          _dest, _base, _result)
    {
        %(constructor)s;
    }
}};

def template LoadStoreLit64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, int64_t _imm)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (IntRegIndex)_dest, _imm)
    {
        %(constructor)s;
#if %(use_uops)d
        assert(numMicroops >= 2);
        uops = new StaticInstPtr[numMicroops];
        uops[0] = new %(acc_name)s(machInst, _dest, _imm);
        uops[0]->setDelayedCommit();
        uops[0]->setFirstMicroop();
        uops[1] = new %(wb_decl)s;
        uops[1]->setLastMicroop();
#endif
    }
}};

def template LoadStoreLitU64Constructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, int64_t _imm,
            bool noAlloc, bool exclusive, bool acrel)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                 (IntRegIndex)_dest, _imm)
    {
        %(constructor)s;
        assert(!%(use_uops)d);
        setExcAcRel(exclusive, acrel);
    }
}};

// Atomic operations in memory

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

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

        %(usrDecl)s;

        %(memacc_code)s;

        %(amo_code)s;
        assert(amo_op);

        const Fault fault = amoMemAtomicLE(xc, traceData, Mem, EA,
                                           memAccessFlags, amo_op);

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

        return fault;
    }
}};

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

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

        %(memacc_code)s;

        %(amo_code)s;

        assert(amo_op);
        return initiateMemAMO(xc, traceData, EA, Mem, memAccessFlags,
                              amo_op);
     }
}};

def template AmoOpCompleteAcc {{
    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        %(op_decl)s;
        %(op_rd)s;

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

        %(postacc_code)s;

        %(op_wb)s;

        return NoFault;
    }

}};

def template AmoOpDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
                       IntRegIndex _base, IntRegIndex _result);

        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 AmoOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                          _dest, _base, _result)
    {
        %(constructor)s;
        flags[IsStore] = false;
        flags[IsLoad] = false;
    }
}};

def template AmoPairOpDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        uint32_t d2_src ;
        uint32_t r2_src ;
        uint32_t r2_dst ;
        /// Constructor.
        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
                       IntRegIndex _base, IntRegIndex _result);

        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 AmoPairOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                          _dest,  _base, _result)
    {
        %(constructor)s;

        uint32_t d2 = RegId(IntRegClass, dest).index() + 1 ;
        uint32_t r2 = RegId(IntRegClass, result).index() + 1 ;

        d2_src = _numSrcRegs ;
        _srcRegIdx[_numSrcRegs++] = RegId(IntRegClass, d2);
        r2_src = _numSrcRegs ;
        _srcRegIdx[_numSrcRegs++] = RegId(IntRegClass, r2);
        r2_dst = _numDestRegs ;
        _destRegIdx[_numDestRegs++] = RegId(IntRegClass, r2);
        flags[IsStore] = false;
        flags[IsLoad] = false;
    }
}};

def template AmoArithmeticOpDeclare {{
    class %(class_name)s : public %(base_class)s
    {
      public:
        bool isXZR ;
        /// Constructor.
        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
                       IntRegIndex _base, IntRegIndex _result);

        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 AmoArithmeticOpConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst,
            IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                          _dest,  _base, _result)
    {
        %(constructor)s;
        isXZR = false;
        uint32_t r2 = RegId(IntRegClass, dest).index() ;
        flags[IsStore] = false;
        flags[IsLoad] = false;
        if (r2 == 31){
            isXZR = true;
        }
    }
}};
