// Copyright (c) 2006-2007 The Regents of The University of Michigan
// 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.
//
// Authors: Ali Saidi
//          Gabe Black

////////////////////////////////////////////////////////////////////
//
// Block Memory instructions
//

def template BlockMemDeclare {{
        /**
         * Static instruction class for a block memory operation
         */
        class %(class_name)s : public %(base_class)s
        {
          public:
            // Constructor
            %(class_name)s(ExtMachInst machInst);

          protected:
            class %(class_name)s_0 : public %(base_class)sMicro
            {
              public:
                // Constructor
                %(class_name)s_0(ExtMachInst machInst);
                Fault execute(ExecContext *,
                              Trace::InstRecord *) const override;
                Fault initiateAcc(ExecContext *,
                                  Trace::InstRecord *) const override;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const override;
            };

            class %(class_name)s_1 : public %(base_class)sMicro
            {
              public:
                // Constructor
                %(class_name)s_1(ExtMachInst machInst);
                Fault execute(ExecContext *,
                              Trace::InstRecord *) const override;
                Fault initiateAcc(ExecContext *,
                                  Trace::InstRecord *) const override;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const override;
            };

            class %(class_name)s_2 : public %(base_class)sMicro
            {
              public:
                // Constructor
                %(class_name)s_2(ExtMachInst machInst);
                Fault execute(ExecContext *,
                              Trace::InstRecord *) const override;
                Fault initiateAcc(ExecContext *,
                                  Trace::InstRecord *) const override;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const override;
            };

            class %(class_name)s_3 : public %(base_class)sMicro
            {
              public:
                // Constructor
                %(class_name)s_3(ExtMachInst machInst);
                Fault execute(ExecContext *,
                              Trace::InstRecord *) const override;
                Fault initiateAcc(ExecContext *,
                                  Trace::InstRecord *) const override;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const override;
            };

            class %(class_name)s_4 : public %(base_class)sMicro
            {
              public:
                // Constructor
                %(class_name)s_4(ExtMachInst machInst);
                Fault execute(ExecContext *,
                              Trace::InstRecord *) const override;
                Fault initiateAcc(ExecContext *,
                                  Trace::InstRecord *) const override;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const override;
            };

            class %(class_name)s_5 : public %(base_class)sMicro
            {
              public:
                // Constructor
                %(class_name)s_5(ExtMachInst machInst);
                Fault execute(ExecContext *,
                              Trace::InstRecord *) const override;
                Fault initiateAcc(ExecContext *,
                                  Trace::InstRecord *) const override;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const override;
            };

            class %(class_name)s_6 : public %(base_class)sMicro
            {
              public:
                // Constructor
                %(class_name)s_6(ExtMachInst machInst);
                Fault execute(ExecContext *,
                              Trace::InstRecord *) const override;
                Fault initiateAcc(ExecContext *,
                                  Trace::InstRecord *) const override;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const override;
            };

            class %(class_name)s_7 : public %(base_class)sMicro
            {
              public:
                // Constructor
                %(class_name)s_7(ExtMachInst machInst);
                Fault execute(ExecContext *,
                              Trace::InstRecord *) const override;
                Fault initiateAcc(ExecContext *,
                                  Trace::InstRecord *) const override;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const override;
            };
        };
}};

// Basic instruction class constructor template.
def template BlockMemConstructor {{
        %(class_name)s::%(class_name)s(ExtMachInst machInst)
            : %(base_class)s("%(mnemonic)s", machInst)
        {
            %(constructor)s;
            microops[0] = new %(class_name)s_0(machInst);
            microops[1] = new %(class_name)s_1(machInst);
            microops[2] = new %(class_name)s_2(machInst);
            microops[3] = new %(class_name)s_3(machInst);
            microops[4] = new %(class_name)s_4(machInst);
            microops[5] = new %(class_name)s_5(machInst);
            microops[6] = new %(class_name)s_6(machInst);
            microops[7] = new %(class_name)s_7(machInst);
        }
}};

def template BlockMemMicroConstructor {{
        %(class_name)s::
            %(class_name)s_%(micro_pc)s::
            %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
                %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
                        machInst, %(op_class)s, %(micro_pc)s * 8)
    {
        %(constructor)s;
        %(set_flags)s;
    }
}};

let {{

    def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
        # XXX Need to take care of pstate.hpriv as well. The lower ASIs
        # are split into ones that are available in priv and hpriv, and
        # those that are only available in hpriv
        addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
        addrCalcImm = 'EA = Rs1 + imm + offset;'
        iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
        iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
        header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
        decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
        decode_block = ROrImmDecode.subst(iop)
        matcher = re.compile(r'Frd_N')
        exec_output = ''
        for microPc in range(8):
            flag_code = ''
            if (microPc == 7):
                flag_code = "flags[IsLastMicroop] = true;"
            elif (microPc == 0):
                flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;"
            else:
                flag_code = "flags[IsDelayedCommit] = true;"
            pcedCode = matcher.sub("Frd_%d" % microPc, code)
            iop = InstObjParams(name, Name, 'BlockMem',
                    {"code": pcedCode, "ea_code": addrCalcReg,
                    "fault_check": faultCode, "micro_pc": microPc,
                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
                    opt_flags)
            iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
                    {"code": pcedCode, "ea_code": addrCalcImm,
                    "fault_check": faultCode, "micro_pc": microPc,
                    "set_flags": flag_code, "EA_trunc" : TruncateEA},
                    opt_flags)
            decoder_output += BlockMemMicroConstructor.subst(iop)
            decoder_output += BlockMemMicroConstructor.subst(iop_imm)
            exec_output += doDualSplitExecute(
                    pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode,
                    makeMicroName(name, microPc),
                    makeMicroName(name + "Imm", microPc),
                    makeMicroName(Name, microPc),
                    makeMicroName(Name + "Imm", microPc),
                    "EXT_ASI", opt_flags);
            faultCode = ''
        return (header_output, decoder_output, exec_output, decode_block)
}};

def format BlockLoad(code, *opt_flags) {{
        code = filterDoubles(code)
        # We need to make sure to check the highest priority fault last.
        # That way, if other faults have been detected, they'll be overwritten
        # rather than the other way around.
        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
        (header_output,
         decoder_output,
         exec_output,
         decode_block) = doBlockMemFormat(code, faultCode,
             LoadFuncs, name, Name, opt_flags)
}};

def format BlockStore(code, *opt_flags) {{
        code = filterDoubles(code)
        # We need to make sure to check the highest priority fault last.
        # That way, if other faults have been detected, they'll be overwritten
        # rather than the other way around.
        faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
        (header_output,
         decoder_output,
         exec_output,
         decode_block) = doBlockMemFormat(code, faultCode,
             StoreFuncs, name, Name, opt_flags)
}};
