1// Copyright (c) 2007 The Regents of The University of Michigan
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met: redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer;
8// redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution;
11// neither the name of the copyright holders nor the names of its
12// contributors may be used to endorse or promote products derived from
13// this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26//
27// Authors: Gabe Black
28//          Ali Saidi
29
30// This template provides the execute functions for a swap
31def template SwapExecute {{
32        Fault %(class_name)s::execute(ExecContext *xc,
33                Trace::InstRecord *traceData) const
34        {
35            Fault fault = NoFault;
36            // This is to support the conditional store in cas instructions.
37            // It should be optomized out in all the others
38            bool storeCond = true;
39            Addr EA;
40            %(fp_enable_check)s;
41            %(op_decl)s;
42            uint64_t mem_data = 0;
43
44            %(op_rd)s;
45            %(ea_code)s;
46            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
47            %(fault_check)s;
48            if (fault == NoFault) {
49                %(code)s;
50            }
51            if (storeCond && fault == NoFault) {
52                %(EA_trunc)s
53                fault = writeMemAtomic(xc, traceData, Mem, EA,
54                        %(asi_val)s, &mem_data);
55            }
56            if (fault == NoFault) {
57                // Handle the swapping
58                %(postacc_code)s;
59            }
60            if (fault == NoFault) {
61                // Write the resulting state to the execution context
62                %(op_wb)s;
63            }
64
65            return fault;
66        }
67}};
68
69
70def template SwapInitiateAcc {{
71        Fault %(class_name)s::initiateAcc(ExecContext * xc,
72                Trace::InstRecord * traceData) const
73        {
74            Fault fault = NoFault;
75            Addr EA;
76            %(fp_enable_check)s;
77            uint64_t mem_data = 0;
78            %(op_decl)s;
79            %(op_rd)s;
80            %(ea_code)s;
81
82            DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
83            %(fault_check)s;
84
85            if (fault == NoFault) {
86                %(code)s;
87            }
88            if (fault == NoFault) {
89                %(EA_trunc)s
90                fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s,
91                        &mem_data);
92            }
93            return fault;
94        }
95}};
96
97
98
99def template SwapCompleteAcc {{
100        Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext * xc,
101                Trace::InstRecord * traceData) const
102        {
103            Fault fault = NoFault;
104            %(op_decl)s;
105
106            getMem(pkt, Mem, traceData);
107            uint64_t mem_data = Mem;
108
109            if (fault == NoFault) {
110                // Handle the swapping
111                %(postacc_code)s;
112            }
113            if (fault == NoFault) {
114                // Write the resulting state to the execution context
115                %(op_wb)s;
116            }
117
118            return fault;
119        }
120}};
121
122let {{
123    SwapFuncs = [SwapExecute, SwapInitiateAcc, SwapCompleteAcc]
124}};
125
126
127def format Swap(code, postacc_code, mem_flags, *opt_flags) {{
128    mem_flags = makeList(mem_flags)
129    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
130    flags = string.join(mem_flags, '|')
131
132    (header_output,
133     decoder_output,
134     exec_output,
135     decode_block) = doMemFormat(code, SwapFuncs, '', name, Name, flags,
136         ["IsStoreConditional"], postacc_code)
137}};
138
139def format SwapAlt(code, postacc_code, mem_flags, *opt_flags) {{
140    mem_flags = makeList(mem_flags)
141    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
142    mem_flags.append("EXT_ASI")
143    flags = string.join(mem_flags, '|')
144    (header_output,
145     decoder_output,
146     exec_output,
147     decode_block) = doMemFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
148         name, Name, flags, ["IsStoreConditional"], postacc_code)
149}};
150
151
152let {{
153    def doCasFormat(code, execute, faultCode, name, Name, mem_flags, opt_flags, postacc_code = ''):
154        addrCalcReg = 'EA = Rs1;'
155        iop = InstObjParams(name, Name, 'Mem',
156                {"code": code, "postacc_code" : postacc_code,
157                 "fault_check": faultCode, "ea_code": addrCalcReg,
158                 "EA_trunc" : TruncateEA}, opt_flags)
159        header_output = MemDeclare.subst(iop)
160        decoder_output = BasicConstructor.subst(iop)
161        decode_block = BasicDecode.subst(iop)
162        microParams = {"code": code, "postacc_code" : postacc_code,
163            "ea_code" : addrCalcReg, "fault_check" : faultCode,
164            "EA_trunc" : TruncateEA}
165        exec_output = doSplitExecute(execute, name, Name, mem_flags,
166                ["IsStoreConditional"], microParams);
167        return (header_output, decoder_output, exec_output, decode_block)
168}};
169
170
171def format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{
172    mem_flags = makeList(mem_flags)
173    mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
174    mem_flags.append("EXT_ASI")
175    flags = string.join(mem_flags, '|')
176    (header_output,
177     decoder_output,
178     exec_output,
179     decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
180         name, Name, flags, ["IsStoreConditional"], postacc_code)
181}};
182
183
184