// Copyright (c) 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: Gabe Black
//          Ali Saidi

// This template provides the execute functions for a swap
def template SwapExecute {{
        Fault %(class_name)s::execute(ExecContext *xc,
                Trace::InstRecord *traceData) const
        {
            Fault fault = NoFault;
            // This is to support the conditional store in cas instructions.
            // It should be optomized out in all the others
            bool storeCond = true;
            Addr EA;
            %(fp_enable_check)s;
            %(op_decl)s;
            uint64_t mem_data = 0;

            %(op_rd)s;
            %(ea_code)s;
            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
            %(fault_check)s;
            if (fault == NoFault) {
                %(code)s;
            }
            if (storeCond && fault == NoFault) {
                %(EA_trunc)s
                fault = writeMemAtomic(xc, traceData, Mem, EA,
                        %(asi_val)s, &mem_data);
            }
            if (fault == NoFault) {
                // Handle the swapping
                %(postacc_code)s;
            }
            if (fault == NoFault) {
                // Write the resulting state to the execution context
                %(op_wb)s;
            }

            return fault;
        }
}};


def template SwapInitiateAcc {{
        Fault %(class_name)s::initiateAcc(ExecContext * xc,
                Trace::InstRecord * traceData) const
        {
            Fault fault = NoFault;
            Addr EA;
            %(fp_enable_check)s;
            uint64_t mem_data = 0;
            %(op_decl)s;
            %(op_rd)s;
            %(ea_code)s;

            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
            %(fault_check)s;

            if (fault == NoFault) {
                %(code)s;
            }
            if (fault == NoFault) {
                %(EA_trunc)s
                fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s,
                        &mem_data);
            }
            return fault;
        }
}};



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

            getMem(pkt, Mem, traceData);
            uint64_t mem_data = Mem;

            if (fault == NoFault) {
                // Handle the swapping
                %(postacc_code)s;
            }
            if (fault == NoFault) {
                // Write the resulting state to the execution context
                %(op_wb)s;
            }

            return fault;
        }
}};

let {{
    SwapFuncs = [SwapExecute, SwapInitiateAcc, SwapCompleteAcc]
}};


def format Swap(code, postacc_code, mem_flags, *opt_flags) {{
    mem_flags = makeList(mem_flags)
    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
    flags = string.join(mem_flags, '|')

    (header_output,
     decoder_output,
     exec_output,
     decode_block) = doMemFormat(code, SwapFuncs, '', name, Name, flags,
         ["IsStoreConditional"], postacc_code)
}};

def format SwapAlt(code, postacc_code, mem_flags, *opt_flags) {{
    mem_flags = makeList(mem_flags)
    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
    mem_flags.append("EXT_ASI")
    flags = string.join(mem_flags, '|')
    (header_output,
     decoder_output,
     exec_output,
     decode_block) = doMemFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
         name, Name, flags, ["IsStoreConditional"], postacc_code)
}};


let {{
    def doCasFormat(code, execute, faultCode, name, Name, mem_flags, opt_flags, postacc_code = ''):
        addrCalcReg = 'EA = Rs1;'
        iop = InstObjParams(name, Name, 'Mem',
                {"code": code, "postacc_code" : postacc_code,
                 "fault_check": faultCode, "ea_code": addrCalcReg,
                 "EA_trunc" : TruncateEA}, opt_flags)
        header_output = MemDeclare.subst(iop)
        decoder_output = BasicConstructor.subst(iop)
        decode_block = BasicDecode.subst(iop)
        microParams = {"code": code, "postacc_code" : postacc_code,
            "ea_code" : addrCalcReg, "fault_check" : faultCode,
            "EA_trunc" : TruncateEA}
        exec_output = doSplitExecute(execute, name, Name, mem_flags,
                ["IsStoreConditional"], microParams);
        return (header_output, decoder_output, exec_output, decode_block)
}};


def format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{
    mem_flags = makeList(mem_flags)
    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
    mem_flags.append("EXT_ASI")
    flags = string.join(mem_flags, '|')
    (header_output,
     decoder_output,
     exec_output,
     decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
         name, Name, flags, ["IsStoreConditional"], postacc_code)
}};


