mem.isa revision 12234
12SN/A// -*- mode:c++ -*-
211071SN/A
311071SN/A// Copyright (c) 2009 The University of Edinburgh
411071SN/A// All rights reserved.
511071SN/A//
611071SN/A// Redistribution and use in source and binary forms, with or without
711071SN/A// modification, are permitted provided that the following conditions are
811071SN/A// met: redistributions of source code must retain the above copyright
911071SN/A// notice, this list of conditions and the following disclaimer;
1011071SN/A// redistributions in binary form must reproduce the above copyright
1111071SN/A// notice, this list of conditions and the following disclaimer in the
1211071SN/A// documentation and/or other materials provided with the distribution;
1311071SN/A// neither the name of the copyright holders nor the names of its
141762SN/A// contributors may be used to endorse or promote products derived from
152SN/A// this software without specific prior written permission.
162SN/A//
172SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282SN/A//
292SN/A// Authors: Timothy M. Jones
302SN/A
312SN/A////////////////////////////////////////////////////////////////////
322SN/A//
332SN/A// Memory-format instructions
342SN/A//
352SN/A
362SN/Adef template LoadStoreDeclare {{
372SN/A    /**
382SN/A     * Static instruction class for "%(mnemonic)s".
392665SN/A     */
402665SN/A    class %(class_name)s : public %(base_class)s
412SN/A    {
422SN/A      public:
432SN/A
442SN/A        /// Constructor.
452SN/A        %(class_name)s(ExtMachInst machInst);
462SN/A
4711263Sandreas.sandberg@arm.com        %(BasicExecDeclare)s
4811263Sandreas.sandberg@arm.com
492SN/A        %(InitiateAccDeclare)s
5011071SN/A
5111071SN/A        %(CompleteAccDeclare)s
526216SN/A    };
5311263Sandreas.sandberg@arm.com}};
5411263Sandreas.sandberg@arm.com
5511263Sandreas.sandberg@arm.com
564981SN/Adef template InitiateAccDeclare {{
571354SN/A    Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
5856SN/A}};
592SN/A
602SN/A
611435SN/Adef template CompleteAccDeclare {{
622SN/A    Fault completeAcc(PacketPtr,  ExecContext *, Trace::InstRecord *) const;
632SN/A}};
642SN/A
654981SN/A
662SN/Adef template LoadStoreConstructor {{
672SN/A    %(class_name)s::%(class_name)s(ExtMachInst machInst)
682SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
692SN/A    {
7011071SN/A        %(constructor)s;
7111071SN/A    }
7211071SN/A}};
731435SN/A
741435SN/A
752SN/Adef template LoadExecute {{
7611071SN/A    Fault %(class_name)s::execute(ExecContext *xc,
77265SN/A                                  Trace::InstRecord *traceData) const
7811071SN/A    {
7911071SN/A        Addr EA;
801435SN/A        Fault fault = NoFault;
812SN/A
822SN/A        %(op_decl)s;
832SN/A        %(op_rd)s;
8411071SN/A        %(ea_code)s;
8511071SN/A
8611071SN/A        if (fault == NoFault) {
8711071SN/A            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
882SN/A            %(memacc_code)s;
892SN/A        }
902SN/A
912SN/A        if (fault == NoFault) {
922SN/A            %(op_wb)s;
932566SN/A        }
94633SN/A
95633SN/A        return fault;
961354SN/A    }
97633SN/A}};
982SN/A
9911071SN/A
10011071SN/Adef template LoadInitiateAcc {{
10111071SN/A    Fault %(class_name)s::initiateAcc(ExecContext *xc,
10211071SN/A                                      Trace::InstRecord *traceData) const
10311071SN/A    {
10411071SN/A        Addr EA;
10511071SN/A        Fault fault = NoFault;
10611071SN/A
10711071SN/A        %(op_src_decl)s;
10811071SN/A        %(op_rd)s;
10911071SN/A        %(ea_code)s;
11011071SN/A
1112566SN/A        if (fault == NoFault) {
1122SN/A            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
1132SN/A            xc->setEA(EA);
1141435SN/A        }
1151954SN/A
1162SN/A        return fault;
1172SN/A    }
1181435SN/A}};
119265SN/A
1202SN/A
1212566SN/Adef template LoadCompleteAcc {{
1222SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
1232SN/A                                      ExecContext *xc,
1242SN/A                                      Trace::InstRecord *traceData) const
125558SN/A    {
12610905SN/A        Addr M5_VAR_USED EA;
12710905SN/A        Fault fault = NoFault;
1282SN/A
1292SN/A        %(op_decl)s;
1302SN/A        %(op_rd)s;
1312SN/A
1322SN/A        EA = xc->getEA();
1332SN/A
1342SN/A        getMem(pkt, Mem, traceData);
1352SN/A
1362SN/A        if (fault == NoFault) {
1372SN/A            %(memacc_code)s;
1382SN/A        }
1392SN/A
1402566SN/A        if (fault == NoFault) {
1411017SN/A          %(op_wb)s;
1424419SN/A        }
1432SN/A
1442SN/A        return fault;
1451435SN/A    }
1464981SN/A}};
1472SN/A
1482SN/A
1494981SN/Adef template StoreExecute {{
1504981SN/A    Fault %(class_name)s::execute(ExecContext *xc,
1512SN/A                                  Trace::InstRecord *traceData) const
152558SN/A    {
1534981SN/A        Addr EA;
1544981SN/A        Fault fault = NoFault;
1554981SN/A
1564981SN/A        %(op_decl)s;
1574981SN/A        %(op_rd)s;
1584981SN/A        %(ea_code)s;
15911169SN/A
1604981SN/A        if (fault == NoFault) {
16111168SN/A            %(memacc_code)s;
16211168SN/A        }
163558SN/A
1642SN/A        if (fault == NoFault) {
1652SN/A            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
16611263Sandreas.sandberg@arm.com                    NULL);
167        }
168
169        if (fault == NoFault) {
170            %(op_wb)s;
171        }
172
173        return fault;
174    }
175}};
176
177
178def template StoreInitiateAcc {{
179    Fault %(class_name)s::initiateAcc(ExecContext *xc,
180                                      Trace::InstRecord *traceData) const
181    {
182        Addr EA;
183        Fault fault = NoFault;
184
185        %(op_decl)s;
186        %(op_rd)s;
187        %(ea_code)s;
188
189        if (fault == NoFault) {
190            %(memacc_code)s;
191        }
192
193        if (fault == NoFault) {
194            fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
195                    NULL);
196        }
197
198        // Need to write back any potential address register update
199        if (fault == NoFault) {
200            %(op_wb)s;
201        }
202
203        return fault;
204    }
205}};
206
207
208def template StoreCompleteAcc {{
209    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
210                                      Trace::InstRecord *traceData) const
211    {
212        return NoFault;
213    }
214}};
215
216
217// The generic memory operation generator. This is called when two versions
218// of an instruction are needed - when Ra == 0 and otherwise. This is so
219// that instructions can use the value 0 when Ra == 0 but avoid having a
220// dependence on Ra.
221let {{
222
223def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
224             load_or_store, mem_flags = [], inst_flags = []):
225
226    # First the version where Ra is non-zero
227    (header_output, decoder_output, decode_block, exec_output) = \
228        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
229                      base_class = base,
230                      decode_template = CheckRaDecode,
231                      exec_template_base = load_or_store)
232
233    # Now another version where Ra == 0
234    (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
235        LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
236                      mem_flags, inst_flags,
237                      base_class = base,
238                      exec_template_base = load_or_store)
239
240    # Finally, add to the other outputs
241    header_output += header_output_ra0
242    decoder_output += decoder_output_ra0
243    exec_output += exec_output_ra0
244    return (header_output, decoder_output, decode_block, exec_output)
245
246}};
247
248
249def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
250                       ea_code_ra0 = {{ EA = Rb; }},
251                       mem_flags = [], inst_flags = []) {{
252    (header_output, decoder_output, decode_block, exec_output) = \
253        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
254                 'MemOp', 'Load', mem_flags, inst_flags)
255}};
256
257
258def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
259                        ea_code_ra0 = {{ EA = Rb; }},
260                        mem_flags = [], inst_flags = []) {{
261    (header_output, decoder_output, decode_block, exec_output) = \
262        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
263                 'MemOp', 'Store', mem_flags, inst_flags)
264}};
265
266
267def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
268                             mem_flags = [], inst_flags = []) {{
269
270    # Add in the update code
271    memacc_code += 'Ra = EA;'
272
273    # Generate the class
274    (header_output, decoder_output, decode_block, exec_output) = \
275        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
276                      base_class = 'MemOp',
277                      exec_template_base = 'Load')
278}};
279
280
281def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
282                              mem_flags = [], inst_flags = []) {{
283
284    # Add in the update code
285    memacc_code += 'Ra = EA;'
286
287    # Generate the class
288    (header_output, decoder_output, decode_block, exec_output) = \
289        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
290                      base_class = 'MemOp',
291                      exec_template_base = 'Store')
292}};
293
294
295def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
296                      ea_code_ra0 = {{ EA = disp; }},
297                      mem_flags = [], inst_flags = []) {{
298    (header_output, decoder_output, decode_block, exec_output) = \
299        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
300                 'MemDispOp', 'Load', mem_flags, inst_flags)
301}};
302
303
304def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
305                       ea_code_ra0 = {{ EA = disp; }},
306                       mem_flags = [], inst_flags = []) {{
307    (header_output, decoder_output, decode_block, exec_output) = \
308        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
309                 'MemDispOp', 'Store', mem_flags, inst_flags)
310}};
311
312
313def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
314                            mem_flags = [], inst_flags = []) {{
315
316    # Add in the update code
317    memacc_code += 'Ra = EA;'
318
319    # Generate the class
320    (header_output, decoder_output, decode_block, exec_output) = \
321        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
322                      base_class = 'MemDispOp',
323                      exec_template_base = 'Load')
324}};
325
326
327def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
328                             mem_flags = [], inst_flags = []) {{
329
330    # Add in the update code
331    memacc_code += 'Ra = EA;'
332
333    # Generate the class
334    (header_output, decoder_output, decode_block, exec_output) = \
335        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
336                      base_class = 'MemDispOp',
337                      exec_template_base = 'Store')
338}};
339