mem.isa revision 12420:f5c80f4ed41f
1// -*- mode:c++ -*-
2
3// Copyright (c) 2009 The University of Edinburgh
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Timothy M. Jones
30
31////////////////////////////////////////////////////////////////////
32//
33// Memory-format instructions
34//
35
36def template LoadStoreDeclare {{
37    /**
38     * Static instruction class for "%(mnemonic)s".
39     */
40    class %(class_name)s : public %(base_class)s
41    {
42      public:
43
44        /// Constructor.
45        %(class_name)s(ExtMachInst machInst);
46
47        Fault execute(ExecContext *, Trace::InstRecord *) const;
48        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
49        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
50    };
51}};
52
53
54def template LoadStoreConstructor {{
55    %(class_name)s::%(class_name)s(ExtMachInst machInst)
56         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
57    {
58        %(constructor)s;
59    }
60}};
61
62
63def template LoadExecute {{
64    Fault %(class_name)s::execute(ExecContext *xc,
65                                  Trace::InstRecord *traceData) const
66    {
67        Addr EA;
68        Fault fault = NoFault;
69
70        %(op_decl)s;
71        %(op_rd)s;
72        %(ea_code)s;
73
74        if (fault == NoFault) {
75            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
76            %(memacc_code)s;
77        }
78
79        if (fault == NoFault) {
80            %(op_wb)s;
81        }
82
83        return fault;
84    }
85}};
86
87
88def template LoadInitiateAcc {{
89    Fault %(class_name)s::initiateAcc(ExecContext *xc,
90                                      Trace::InstRecord *traceData) const
91    {
92        Addr EA;
93        Fault fault = NoFault;
94
95        %(op_src_decl)s;
96        %(op_rd)s;
97        %(ea_code)s;
98
99        if (fault == NoFault) {
100            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
101        }
102
103        return fault;
104    }
105}};
106
107
108def template LoadCompleteAcc {{
109    Fault %(class_name)s::completeAcc(PacketPtr pkt,
110                                      ExecContext *xc,
111                                      Trace::InstRecord *traceData) const
112    {
113        Addr M5_VAR_USED EA;
114        Fault fault = NoFault;
115
116        %(op_decl)s;
117        %(op_rd)s;
118
119        EA = pkt->req->getVaddr();
120
121        getMem(pkt, Mem, traceData);
122
123        if (fault == NoFault) {
124            %(memacc_code)s;
125        }
126
127        if (fault == NoFault) {
128          %(op_wb)s;
129        }
130
131        return fault;
132    }
133}};
134
135
136def template StoreExecute {{
137    Fault %(class_name)s::execute(ExecContext *xc,
138                                  Trace::InstRecord *traceData) const
139    {
140        Addr EA;
141        Fault fault = NoFault;
142
143        %(op_decl)s;
144        %(op_rd)s;
145        %(ea_code)s;
146
147        if (fault == NoFault) {
148            %(memacc_code)s;
149        }
150
151        if (fault == NoFault) {
152            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
153                    NULL);
154        }
155
156        if (fault == NoFault) {
157            %(op_wb)s;
158        }
159
160        return fault;
161    }
162}};
163
164
165def template StoreInitiateAcc {{
166    Fault %(class_name)s::initiateAcc(ExecContext *xc,
167                                      Trace::InstRecord *traceData) const
168    {
169        Addr EA;
170        Fault fault = NoFault;
171
172        %(op_decl)s;
173        %(op_rd)s;
174        %(ea_code)s;
175
176        if (fault == NoFault) {
177            %(memacc_code)s;
178        }
179
180        if (fault == NoFault) {
181            fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
182                    NULL);
183        }
184
185        // Need to write back any potential address register update
186        if (fault == NoFault) {
187            %(op_wb)s;
188        }
189
190        return fault;
191    }
192}};
193
194
195def template StoreCompleteAcc {{
196    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
197                                      Trace::InstRecord *traceData) const
198    {
199        return NoFault;
200    }
201}};
202
203
204// The generic memory operation generator. This is called when two versions
205// of an instruction are needed - when Ra == 0 and otherwise. This is so
206// that instructions can use the value 0 when Ra == 0 but avoid having a
207// dependence on Ra.
208let {{
209
210def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
211             load_or_store, mem_flags = [], inst_flags = []):
212
213    # First the version where Ra is non-zero
214    (header_output, decoder_output, decode_block, exec_output) = \
215        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
216                      base_class = base,
217                      decode_template = CheckRaDecode,
218                      exec_template_base = load_or_store)
219
220    # Now another version where Ra == 0
221    (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
222        LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
223                      mem_flags, inst_flags,
224                      base_class = base,
225                      exec_template_base = load_or_store)
226
227    # Finally, add to the other outputs
228    header_output += header_output_ra0
229    decoder_output += decoder_output_ra0
230    exec_output += exec_output_ra0
231    return (header_output, decoder_output, decode_block, exec_output)
232
233}};
234
235
236def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
237                       ea_code_ra0 = {{ EA = Rb; }},
238                       mem_flags = [], inst_flags = []) {{
239    (header_output, decoder_output, decode_block, exec_output) = \
240        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
241                 'MemOp', 'Load', mem_flags, inst_flags)
242}};
243
244
245def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
246                        ea_code_ra0 = {{ EA = Rb; }},
247                        mem_flags = [], inst_flags = []) {{
248    (header_output, decoder_output, decode_block, exec_output) = \
249        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
250                 'MemOp', 'Store', mem_flags, inst_flags)
251}};
252
253
254def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
255                             mem_flags = [], inst_flags = []) {{
256
257    # Add in the update code
258    memacc_code += 'Ra = EA;'
259
260    # Generate the class
261    (header_output, decoder_output, decode_block, exec_output) = \
262        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
263                      base_class = 'MemOp',
264                      exec_template_base = 'Load')
265}};
266
267
268def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
269                              mem_flags = [], inst_flags = []) {{
270
271    # Add in the update code
272    memacc_code += 'Ra = EA;'
273
274    # Generate the class
275    (header_output, decoder_output, decode_block, exec_output) = \
276        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
277                      base_class = 'MemOp',
278                      exec_template_base = 'Store')
279}};
280
281
282def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
283                      ea_code_ra0 = {{ EA = disp; }},
284                      mem_flags = [], inst_flags = []) {{
285    (header_output, decoder_output, decode_block, exec_output) = \
286        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
287                 'MemDispOp', 'Load', mem_flags, inst_flags)
288}};
289
290
291def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
292                       ea_code_ra0 = {{ EA = disp; }},
293                       mem_flags = [], inst_flags = []) {{
294    (header_output, decoder_output, decode_block, exec_output) = \
295        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
296                 'MemDispOp', 'Store', mem_flags, inst_flags)
297}};
298
299
300def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
301                            mem_flags = [], inst_flags = []) {{
302
303    # Add in the update code
304    memacc_code += 'Ra = EA;'
305
306    # Generate the class
307    (header_output, decoder_output, decode_block, exec_output) = \
308        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
309                      base_class = 'MemDispOp',
310                      exec_template_base = 'Load')
311}};
312
313
314def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
315                             mem_flags = [], inst_flags = []) {{
316
317    # Add in the update code
318    memacc_code += 'Ra = EA;'
319
320    # Generate the class
321    (header_output, decoder_output, decode_block, exec_output) = \
322        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
323                      base_class = 'MemDispOp',
324                      exec_template_base = 'Store')
325}};
326