mem.isa revision 7712:7733c562e5e3
12SN/A// -*- mode:c++ -*-
21762SN/A
32SN/A// Copyright (c) 2009 The University of Edinburgh
42SN/A// All rights reserved.
52SN/A//
62SN/A// Redistribution and use in source and binary forms, with or without
72SN/A// modification, are permitted provided that the following conditions are
82SN/A// met: redistributions of source code must retain the above copyright
92SN/A// notice, this list of conditions and the following disclaimer;
102SN/A// redistributions in binary form must reproduce the above copyright
112SN/A// notice, this list of conditions and the following disclaimer in the
122SN/A// documentation and/or other materials provided with the distribution;
132SN/A// neither the name of the copyright holders nor the names of its
142SN/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
272665Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu//
292SN/A// Authors: Timothy M. Jones
302SN/A
316216Snate@binkert.org////////////////////////////////////////////////////////////////////
326216Snate@binkert.org//
332SN/A// Memory-format instructions
346216Snate@binkert.org//
35100SN/A
366214Snate@binkert.orgdef template LoadStoreDeclare {{
37100SN/A    /**
382SN/A     * Static instruction class for "%(mnemonic)s".
392020SN/A     */
402SN/A    class %(class_name)s : public %(base_class)s
412SN/A    {
4250SN/A      public:
432SN/A
442020SN/A        /// Constructor.
452SN/A        %(class_name)s(ExtMachInst machInst);
4650SN/A
472SN/A        %(BasicExecDeclare)s
4850SN/A
4950SN/A        %(InitiateAccDeclare)s
5050SN/A
5150SN/A        %(CompleteAccDeclare)s
5250SN/A    };
5350SN/A}};
5450SN/A
5550SN/A
5650SN/Adef template InitiateAccDeclare {{
5750SN/A    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
5850SN/A}};
5950SN/A
602SN/A
612SN/Adef template CompleteAccDeclare {{
622SN/A    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
6350SN/A}};
6450SN/A
652020SN/A
662SN/Adef template LoadStoreConstructor {{
6750SN/A    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
682SN/A         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
692SN/A    {
7050SN/A        %(constructor)s;
7150SN/A    }
722020SN/A}};
7350SN/A
742020SN/A
7550SN/Adef template LoadExecute {{
7650SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
772SN/A                                  Trace::InstRecord *traceData) const
782020SN/A    {
7950SN/A        Addr EA;
80100SN/A        Fault fault = NoFault;
812SN/A
8250SN/A        %(op_decl)s;
832SN/A        %(op_rd)s;
8450SN/A        %(ea_code)s;
8550SN/A
8650SN/A        if (fault == NoFault) {
8750SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
8850SN/A            %(memacc_code)s;
8950SN/A        }
9050SN/A
9150SN/A        if (fault == NoFault) {
9250SN/A            %(op_wb)s;
93100SN/A        }
942020SN/A
951642SN/A        return fault;
961642SN/A    }
971642SN/A}};
981642SN/A
991642SN/A
1001642SN/Adef template LoadInitiateAcc {{
1011642SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
1021642SN/A                                      Trace::InstRecord *traceData) const
1031642SN/A    {
1041642SN/A        Addr EA;
1051642SN/A        Fault fault = NoFault;
1061642SN/A
1071642SN/A        %(op_src_decl)s;
1081642SN/A        %(op_rd)s;
1091642SN/A        %(ea_code)s;
1101642SN/A
1111642SN/A        if (fault == NoFault) {
1121642SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
1132020SN/A            xc->setEA(EA);
114100SN/A        }
115100SN/A
116100SN/A        return fault;
117100SN/A    }
118100SN/A}};
119100SN/A
120100SN/A
121100SN/Adef template LoadCompleteAcc {{
122100SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
123100SN/A                                      %(CPU_exec_context)s *xc,
124100SN/A                                      Trace::InstRecord *traceData) const
125100SN/A    {
126100SN/A        Addr EA;
127100SN/A        Fault fault = NoFault;
128100SN/A        uint%(mem_acc_size)d_t val;
129100SN/A
1302020SN/A        %(op_decl)s;
131100SN/A        %(op_rd)s;
132100SN/A
1332020SN/A        EA = xc->getEA();
134100SN/A
135100SN/A        val = pkt->get<uint%(mem_acc_size)d_t>();
136100SN/A        *((uint%(mem_acc_size)d_t*)&Mem) = val;
1372020SN/A
138100SN/A        if (fault == NoFault) {
139100SN/A            %(memacc_code)s;
1402020SN/A        }
1411642SN/A
1421642SN/A        if (fault == NoFault) {
1431642SN/A          %(op_wb)s;
1442020SN/A        }
1451642SN/A
1461642SN/A        return fault;
1472020SN/A    }
148100SN/A}};
149100SN/A
15050SN/A
15150SN/Adef template StoreExecute {{
1522020SN/A    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
15350SN/A                                  Trace::InstRecord *traceData) const
154100SN/A    {
155100SN/A        Addr EA;
156100SN/A        Fault fault = NoFault;
1572020SN/A
15850SN/A        %(op_decl)s;
15950SN/A        %(op_rd)s;
16050SN/A        %(ea_code)s;
16150SN/A
1622020SN/A        if (fault == NoFault) {
16350SN/A            %(memacc_code)s;
1642020SN/A        }
16550SN/A
16650SN/A        if (fault == NoFault) {
16750SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
16850SN/A                              memAccessFlags, NULL);
1692020SN/A        }
17050SN/A
1712020SN/A        if (fault == NoFault) {
17250SN/A            %(op_wb)s;
1732SN/A        }
17452SN/A
17552SN/A        return fault;
1762020SN/A    }
17752SN/A}};
17852SN/A
17952SN/A
18052SN/Adef template StoreInitiateAcc {{
18152SN/A    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
18252SN/A                                      Trace::InstRecord *traceData) const
1832021SN/A    {
18452SN/A        Addr EA;
1852021SN/A        Fault fault = NoFault;
18652SN/A
18752SN/A        %(op_decl)s;
18852SN/A        %(op_rd)s;
18952SN/A        %(ea_code)s;
19052SN/A
1912418SN/A        if (fault == NoFault) {
19252SN/A            %(memacc_code)s;
1932418SN/A        }
19452SN/A
19552SN/A        if (fault == NoFault) {
19652SN/A            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
1972SN/A                              memAccessFlags, NULL);
1982020SN/A        }
19950SN/A
2005570Snate@binkert.org        // Need to write back any potential address register update
2015570Snate@binkert.org        if (fault == NoFault) {
2025570Snate@binkert.org            %(op_wb)s;
2032SN/A        }
2042SN/A
2052SN/A        return fault;
2062020SN/A    }
20750SN/A}};
20850SN/A
20950SN/A
2102SN/Adef template StoreCompleteAcc {{
2112SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
2122020SN/A                                      %(CPU_exec_context)s *xc,
21350SN/A                                      Trace::InstRecord *traceData) const
21450SN/A    {
21550SN/A        return NoFault;
2162SN/A    }
2172SN/A}};
2182020SN/A
2192SN/A
2202SN/A// The generic memory operation generator. This is called when two versions
2212SN/A// of an instruction are needed - when Ra == 0 and otherwise. This is so
2222SN/A// that instructions can use the value 0 when Ra == 0 but avoid having a
223105SN/A// dependence on Ra.
2242SN/Alet {{
2252SN/A
2262SN/Adef GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
2272SN/A             load_or_store, mem_flags = [], inst_flags = []):
2282SN/A
2292SN/A    # First the version where Ra is non-zero
2302SN/A    (header_output, decoder_output, decode_block, exec_output) = \
2312SN/A        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
2326216Snate@binkert.org                      base_class = base,
233                      decode_template = CheckRaDecode,
234                      exec_template_base = load_or_store)
235
236    # Now another version where Ra == 0
237    (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
238        LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
239                      mem_flags, inst_flags,
240                      base_class = base,
241                      exec_template_base = load_or_store)
242
243    # Finally, add to the other outputs
244    header_output += header_output_ra0
245    decoder_output += decoder_output_ra0
246    exec_output += exec_output_ra0
247    return (header_output, decoder_output, decode_block, exec_output)
248
249}};
250
251
252def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
253                       ea_code_ra0 = {{ EA = Rb; }},
254                       mem_flags = [], inst_flags = []) {{
255    (header_output, decoder_output, decode_block, exec_output) = \
256        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
257                 'MemOp', 'Load', mem_flags, inst_flags)
258}};
259
260
261def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
262                        ea_code_ra0 = {{ EA = Rb; }},
263                        mem_flags = [], inst_flags = []) {{
264    (header_output, decoder_output, decode_block, exec_output) = \
265        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
266                 'MemOp', 'Store', mem_flags, inst_flags)
267}};
268
269
270def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
271                             mem_flags = [], inst_flags = []) {{
272
273    # Add in the update code
274    memacc_code += 'Ra = EA;'
275
276    # Generate the class
277    (header_output, decoder_output, decode_block, exec_output) = \
278        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
279                      base_class = 'MemOp',
280                      exec_template_base = 'Load')
281}};
282
283
284def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
285                              mem_flags = [], inst_flags = []) {{
286
287    # Add in the update code
288    memacc_code += 'Ra = EA;'
289
290    # Generate the class
291    (header_output, decoder_output, decode_block, exec_output) = \
292        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
293                      base_class = 'MemOp',
294                      exec_template_base = 'Store')
295}};
296
297
298def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
299                      ea_code_ra0 = {{ EA = disp; }},
300                      mem_flags = [], inst_flags = []) {{
301    (header_output, decoder_output, decode_block, exec_output) = \
302        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
303                 'MemDispOp', 'Load', mem_flags, inst_flags)
304}};
305
306
307def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
308                       ea_code_ra0 = {{ EA = disp; }},
309                       mem_flags = [], inst_flags = []) {{
310    (header_output, decoder_output, decode_block, exec_output) = \
311        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
312                 'MemDispOp', 'Store', mem_flags, inst_flags)
313}};
314
315
316def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
317                            mem_flags = [], inst_flags = []) {{
318
319    # Add in the update code
320    memacc_code += 'Ra = EA;'
321
322    # Generate the class
323    (header_output, decoder_output, decode_block, exec_output) = \
324        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
325                      base_class = 'MemDispOp',
326                      exec_template_base = 'Load')
327}};
328
329
330def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
331                             mem_flags = [], inst_flags = []) {{
332
333    # Add in the update code
334    memacc_code += 'Ra = EA;'
335
336    # Generate the class
337    (header_output, decoder_output, decode_block, exec_output) = \
338        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
339                      base_class = 'MemDispOp',
340                      exec_template_base = 'Store')
341}};
342