14040Ssaidi@eecs.umich.edu// Copyright (c) 2007 The Regents of The University of Michigan
24040Ssaidi@eecs.umich.edu// All rights reserved.
34040Ssaidi@eecs.umich.edu//
44040Ssaidi@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
54040Ssaidi@eecs.umich.edu// modification, are permitted provided that the following conditions are
64040Ssaidi@eecs.umich.edu// met: redistributions of source code must retain the above copyright
74040Ssaidi@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
84040Ssaidi@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
94040Ssaidi@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
104040Ssaidi@eecs.umich.edu// documentation and/or other materials provided with the distribution;
114040Ssaidi@eecs.umich.edu// neither the name of the copyright holders nor the names of its
124040Ssaidi@eecs.umich.edu// contributors may be used to endorse or promote products derived from
134040Ssaidi@eecs.umich.edu// this software without specific prior written permission.
144040Ssaidi@eecs.umich.edu//
154040Ssaidi@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
164040Ssaidi@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
174040Ssaidi@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
184040Ssaidi@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
194040Ssaidi@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
204040Ssaidi@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
214040Ssaidi@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
224040Ssaidi@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
234040Ssaidi@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
244040Ssaidi@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
254040Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
264040Ssaidi@eecs.umich.edu//
274040Ssaidi@eecs.umich.edu// Authors: Gabe Black
284040Ssaidi@eecs.umich.edu//          Ali Saidi
294040Ssaidi@eecs.umich.edu
307741Sgblack@eecs.umich.edu// This template provides the execute functions for a swap
314040Ssaidi@eecs.umich.edudef template SwapExecute {{
3212234Sgabeblack@google.com        Fault %(class_name)s::execute(ExecContext *xc,
334040Ssaidi@eecs.umich.edu                Trace::InstRecord *traceData) const
344040Ssaidi@eecs.umich.edu        {
354040Ssaidi@eecs.umich.edu            Fault fault = NoFault;
367741Sgblack@eecs.umich.edu            // This is to support the conditional store in cas instructions.
377741Sgblack@eecs.umich.edu            // It should be optomized out in all the others
384040Ssaidi@eecs.umich.edu            bool storeCond = true;
394040Ssaidi@eecs.umich.edu            Addr EA;
404040Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
414040Ssaidi@eecs.umich.edu            %(op_decl)s;
424412Sbinkertn@umich.edu            uint64_t mem_data = 0;
434040Ssaidi@eecs.umich.edu
444040Ssaidi@eecs.umich.edu            %(op_rd)s;
454040Ssaidi@eecs.umich.edu            %(ea_code)s;
464040Ssaidi@eecs.umich.edu            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
474040Ssaidi@eecs.umich.edu            %(fault_check)s;
487741Sgblack@eecs.umich.edu            if (fault == NoFault) {
494040Ssaidi@eecs.umich.edu                %(code)s;
504040Ssaidi@eecs.umich.edu            }
517741Sgblack@eecs.umich.edu            if (storeCond && fault == NoFault) {
524648Sgblack@eecs.umich.edu                %(EA_trunc)s
538442Sgblack@eecs.umich.edu                fault = writeMemAtomic(xc, traceData, Mem, EA,
548442Sgblack@eecs.umich.edu                        %(asi_val)s, &mem_data);
554040Ssaidi@eecs.umich.edu            }
567741Sgblack@eecs.umich.edu            if (fault == NoFault) {
577741Sgblack@eecs.umich.edu                // Handle the swapping
587741Sgblack@eecs.umich.edu                %(postacc_code)s;
594040Ssaidi@eecs.umich.edu            }
607741Sgblack@eecs.umich.edu            if (fault == NoFault) {
617741Sgblack@eecs.umich.edu                // Write the resulting state to the execution context
627741Sgblack@eecs.umich.edu                %(op_wb)s;
634040Ssaidi@eecs.umich.edu            }
644040Ssaidi@eecs.umich.edu
654040Ssaidi@eecs.umich.edu            return fault;
664040Ssaidi@eecs.umich.edu        }
674040Ssaidi@eecs.umich.edu}};
684040Ssaidi@eecs.umich.edu
694040Ssaidi@eecs.umich.edu
704040Ssaidi@eecs.umich.edudef template SwapInitiateAcc {{
7112234Sgabeblack@google.com        Fault %(class_name)s::initiateAcc(ExecContext * xc,
724040Ssaidi@eecs.umich.edu                Trace::InstRecord * traceData) const
734040Ssaidi@eecs.umich.edu        {
744040Ssaidi@eecs.umich.edu            Fault fault = NoFault;
754040Ssaidi@eecs.umich.edu            Addr EA;
764040Ssaidi@eecs.umich.edu            %(fp_enable_check)s;
774040Ssaidi@eecs.umich.edu            uint64_t mem_data = 0;
784040Ssaidi@eecs.umich.edu            %(op_decl)s;
794040Ssaidi@eecs.umich.edu            %(op_rd)s;
804040Ssaidi@eecs.umich.edu            %(ea_code)s;
814040Ssaidi@eecs.umich.edu
824040Ssaidi@eecs.umich.edu            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
834040Ssaidi@eecs.umich.edu            %(fault_check)s;
844040Ssaidi@eecs.umich.edu
857741Sgblack@eecs.umich.edu            if (fault == NoFault) {
864040Ssaidi@eecs.umich.edu                %(code)s;
874040Ssaidi@eecs.umich.edu            }
887741Sgblack@eecs.umich.edu            if (fault == NoFault) {
894648Sgblack@eecs.umich.edu                %(EA_trunc)s
908442Sgblack@eecs.umich.edu                fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s,
918442Sgblack@eecs.umich.edu                        &mem_data);
924040Ssaidi@eecs.umich.edu            }
934040Ssaidi@eecs.umich.edu            return fault;
944040Ssaidi@eecs.umich.edu        }
954040Ssaidi@eecs.umich.edu}};
964040Ssaidi@eecs.umich.edu
974040Ssaidi@eecs.umich.edu
984040Ssaidi@eecs.umich.edu
994040Ssaidi@eecs.umich.edudef template SwapCompleteAcc {{
10012234Sgabeblack@google.com        Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext * xc,
1014040Ssaidi@eecs.umich.edu                Trace::InstRecord * traceData) const
1024040Ssaidi@eecs.umich.edu        {
1034040Ssaidi@eecs.umich.edu            Fault fault = NoFault;
1044040Ssaidi@eecs.umich.edu            %(op_decl)s;
1054040Ssaidi@eecs.umich.edu
1068442Sgblack@eecs.umich.edu            getMem(pkt, Mem, traceData);
1078442Sgblack@eecs.umich.edu            uint64_t mem_data = Mem;
1084040Ssaidi@eecs.umich.edu
1097741Sgblack@eecs.umich.edu            if (fault == NoFault) {
1107741Sgblack@eecs.umich.edu                // Handle the swapping
1117741Sgblack@eecs.umich.edu                %(postacc_code)s;
1124040Ssaidi@eecs.umich.edu            }
1137741Sgblack@eecs.umich.edu            if (fault == NoFault) {
1147741Sgblack@eecs.umich.edu                // Write the resulting state to the execution context
1157741Sgblack@eecs.umich.edu                %(op_wb)s;
1164040Ssaidi@eecs.umich.edu            }
1174040Ssaidi@eecs.umich.edu
1184040Ssaidi@eecs.umich.edu            return fault;
1194040Ssaidi@eecs.umich.edu        }
1204040Ssaidi@eecs.umich.edu}};
1214040Ssaidi@eecs.umich.edu
1224040Ssaidi@eecs.umich.edulet {{
1234040Ssaidi@eecs.umich.edu    SwapFuncs = [SwapExecute, SwapInitiateAcc, SwapCompleteAcc]
1244040Ssaidi@eecs.umich.edu}};
1254040Ssaidi@eecs.umich.edu
1264040Ssaidi@eecs.umich.edu
1274040Ssaidi@eecs.umich.edudef format Swap(code, postacc_code, mem_flags, *opt_flags) {{
1284040Ssaidi@eecs.umich.edu    mem_flags = makeList(mem_flags)
1295736Snate@binkert.org    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
1304040Ssaidi@eecs.umich.edu    flags = string.join(mem_flags, '|')
1314040Ssaidi@eecs.umich.edu
1324040Ssaidi@eecs.umich.edu    (header_output,
1334040Ssaidi@eecs.umich.edu     decoder_output,
1344040Ssaidi@eecs.umich.edu     exec_output,
1354040Ssaidi@eecs.umich.edu     decode_block) = doMemFormat(code, SwapFuncs, '', name, Name, flags,
1364350Sgblack@eecs.umich.edu         ["IsStoreConditional"], postacc_code)
1374040Ssaidi@eecs.umich.edu}};
1384040Ssaidi@eecs.umich.edu
1395096Sgblack@eecs.umich.edudef format SwapAlt(code, postacc_code, mem_flags, *opt_flags) {{
1404040Ssaidi@eecs.umich.edu    mem_flags = makeList(mem_flags)
1415736Snate@binkert.org    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
1425096Sgblack@eecs.umich.edu    mem_flags.append("EXT_ASI")
1434040Ssaidi@eecs.umich.edu    flags = string.join(mem_flags, '|')
1444040Ssaidi@eecs.umich.edu    (header_output,
1454040Ssaidi@eecs.umich.edu     decoder_output,
1464040Ssaidi@eecs.umich.edu     exec_output,
1474040Ssaidi@eecs.umich.edu     decode_block) = doMemFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
1484350Sgblack@eecs.umich.edu         name, Name, flags, ["IsStoreConditional"], postacc_code)
1494040Ssaidi@eecs.umich.edu}};
1504040Ssaidi@eecs.umich.edu
1514040Ssaidi@eecs.umich.edu
1524040Ssaidi@eecs.umich.edulet {{
1535096Sgblack@eecs.umich.edu    def doCasFormat(code, execute, faultCode, name, Name, mem_flags, opt_flags, postacc_code = ''):
1544040Ssaidi@eecs.umich.edu        addrCalcReg = 'EA = Rs1;'
1554040Ssaidi@eecs.umich.edu        iop = InstObjParams(name, Name, 'Mem',
1564040Ssaidi@eecs.umich.edu                {"code": code, "postacc_code" : postacc_code,
1574648Sgblack@eecs.umich.edu                 "fault_check": faultCode, "ea_code": addrCalcReg,
1584648Sgblack@eecs.umich.edu                 "EA_trunc" : TruncateEA}, opt_flags)
1594040Ssaidi@eecs.umich.edu        header_output = MemDeclare.subst(iop)
1604040Ssaidi@eecs.umich.edu        decoder_output = BasicConstructor.subst(iop)
1614040Ssaidi@eecs.umich.edu        decode_block = BasicDecode.subst(iop)
1624040Ssaidi@eecs.umich.edu        microParams = {"code": code, "postacc_code" : postacc_code,
1634648Sgblack@eecs.umich.edu            "ea_code" : addrCalcReg, "fault_check" : faultCode,
1644648Sgblack@eecs.umich.edu            "EA_trunc" : TruncateEA}
1655096Sgblack@eecs.umich.edu        exec_output = doSplitExecute(execute, name, Name, mem_flags,
1664350Sgblack@eecs.umich.edu                ["IsStoreConditional"], microParams);
16712385Sgabeblack@google.com        return (header_output, decoder_output, exec_output, decode_block)
1684040Ssaidi@eecs.umich.edu}};
1694040Ssaidi@eecs.umich.edu
1704040Ssaidi@eecs.umich.edu
1715096Sgblack@eecs.umich.edudef format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{
1724040Ssaidi@eecs.umich.edu    mem_flags = makeList(mem_flags)
1735736Snate@binkert.org    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
1745096Sgblack@eecs.umich.edu    mem_flags.append("EXT_ASI")
1754040Ssaidi@eecs.umich.edu    flags = string.join(mem_flags, '|')
1764040Ssaidi@eecs.umich.edu    (header_output,
1774040Ssaidi@eecs.umich.edu     decoder_output,
1784040Ssaidi@eecs.umich.edu     exec_output,
1794040Ssaidi@eecs.umich.edu     decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
1804350Sgblack@eecs.umich.edu         name, Name, flags, ["IsStoreConditional"], postacc_code)
1814040Ssaidi@eecs.umich.edu}};
1824040Ssaidi@eecs.umich.edu
1834040Ssaidi@eecs.umich.edu
184