// 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;
                Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
                Fault completeAcc(PacketPtr, ExecContext *,
                                  Trace::InstRecord *) const;
            };

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

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

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

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

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

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

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

// 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)
}};
