mem.isa revision 6691:cd68b6ecd68d
19793Sakash.bagdia@arm.com// -*- mode:c++ -*-
28706Sandreas.hansson@arm.com
38706Sandreas.hansson@arm.com// Copyright (c) 2009 The University of Edinburgh
48706Sandreas.hansson@arm.com// All rights reserved.
58706Sandreas.hansson@arm.com//
68706Sandreas.hansson@arm.com// Redistribution and use in source and binary forms, with or without
78706Sandreas.hansson@arm.com// modification, are permitted provided that the following conditions are
88706Sandreas.hansson@arm.com// met: redistributions of source code must retain the above copyright
98706Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer;
108706Sandreas.hansson@arm.com// redistributions in binary form must reproduce the above copyright
118706Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer in the
128706Sandreas.hansson@arm.com// documentation and/or other materials provided with the distribution;
135369Ssaidi@eecs.umich.edu// neither the name of the copyright holders nor the names of its
143005Sstever@eecs.umich.edu// contributors may be used to endorse or promote products derived from
153005Sstever@eecs.umich.edu// this software without specific prior written permission.
163005Sstever@eecs.umich.edu//
173005Sstever@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
183005Sstever@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
193005Sstever@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
203005Sstever@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
213005Sstever@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
223005Sstever@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
233005Sstever@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
243005Sstever@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
253005Sstever@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
263005Sstever@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
273005Sstever@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
283005Sstever@eecs.umich.edu//
293005Sstever@eecs.umich.edu// Authors: Timothy M. Jones
303005Sstever@eecs.umich.edu
313005Sstever@eecs.umich.edu////////////////////////////////////////////////////////////////////
323005Sstever@eecs.umich.edu//
333005Sstever@eecs.umich.edu// Memory-format instructions
343005Sstever@eecs.umich.edu//
353005Sstever@eecs.umich.edu
363005Sstever@eecs.umich.edudef template LoadStoreDeclare {{
373005Sstever@eecs.umich.edu    /**
383005Sstever@eecs.umich.edu     * Static instruction class for "%(mnemonic)s".
393005Sstever@eecs.umich.edu     */
403005Sstever@eecs.umich.edu    class %(class_name)s : public %(base_class)s
412710SN/A    {
422710SN/A      public:
433005Sstever@eecs.umich.edu
442889SN/A        /// Constructor.
456654Snate@binkert.org        %(class_name)s(ExtMachInst machInst);
466654Snate@binkert.org
479907Snilay@cs.wisc.edu        %(BasicExecDeclare)s
486654Snate@binkert.org
492667SN/A        %(InitiateAccDeclare)s
506654Snate@binkert.org
516654Snate@binkert.org        %(CompleteAccDeclare)s
526654Snate@binkert.org    };
535457Ssaidi@eecs.umich.edu}};
546654Snate@binkert.org
558169SLisa.Hsu@amd.com
568169SLisa.Hsu@amd.comdef template InitiateAccDeclare {{
578920Snilay@cs.wisc.edu    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
588169SLisa.Hsu@amd.com}};
593395Shsul@eecs.umich.edu
606981SLisa.Hsu@amd.com
619836Sandreas.hansson@arm.comdef template CompleteAccDeclare {{
623448Shsul@eecs.umich.edu    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
635369Ssaidi@eecs.umich.edu}};
643394Shsul@eecs.umich.edu
659197Snilay@cs.wisc.edu
669197Snilay@cs.wisc.edudef template LoadStoreConstructor {{
679197Snilay@cs.wisc.edu    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
689197Snilay@cs.wisc.edu         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
699197Snilay@cs.wisc.edu    {
709197Snilay@cs.wisc.edu        %(constructor)s;
719197Snilay@cs.wisc.edu    }
729197Snilay@cs.wisc.edu}};
739197Snilay@cs.wisc.edu
749197Snilay@cs.wisc.edu
759197Snilay@cs.wisc.edudef template LoadExecute {{
769197Snilay@cs.wisc.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
779197Snilay@cs.wisc.edu                                  Trace::InstRecord *traceData) const
789197Snilay@cs.wisc.edu    {
799197Snilay@cs.wisc.edu        Addr EA;
809197Snilay@cs.wisc.edu        Fault fault = NoFault;
819197Snilay@cs.wisc.edu
829197Snilay@cs.wisc.edu        %(op_decl)s;
839197Snilay@cs.wisc.edu        %(op_rd)s;
849197Snilay@cs.wisc.edu        %(ea_code)s;
859197Snilay@cs.wisc.edu
869197Snilay@cs.wisc.edu        if (fault == NoFault) {
879197Snilay@cs.wisc.edu            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
889907Snilay@cs.wisc.edu            %(memacc_code)s;
899197Snilay@cs.wisc.edu        }
909197Snilay@cs.wisc.edu
919217Snilay@cs.wisc.edu        if (fault == NoFault) {
929197Snilay@cs.wisc.edu            %(op_wb)s;
939197Snilay@cs.wisc.edu        }
949197Snilay@cs.wisc.edu
959197Snilay@cs.wisc.edu        return fault;
969197Snilay@cs.wisc.edu    }
979197Snilay@cs.wisc.edu}};
989197Snilay@cs.wisc.edu
999197Snilay@cs.wisc.edu
1009197Snilay@cs.wisc.edudef template LoadInitiateAcc {{
1019197Snilay@cs.wisc.edu    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
1029197Snilay@cs.wisc.edu                                      Trace::InstRecord *traceData) const
1039197Snilay@cs.wisc.edu    {
1049197Snilay@cs.wisc.edu        Addr EA;
1059197Snilay@cs.wisc.edu        Fault fault = NoFault;
1069197Snilay@cs.wisc.edu
1079197Snilay@cs.wisc.edu        %(op_src_decl)s;
1089197Snilay@cs.wisc.edu        %(op_rd)s;
1099197Snilay@cs.wisc.edu        %(ea_code)s;
1109197Snilay@cs.wisc.edu
1119197Snilay@cs.wisc.edu        if (fault == NoFault) {
1122957SN/A            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
1138920Snilay@cs.wisc.edu            xc->setEA(EA);
1148920Snilay@cs.wisc.edu        }
1152957SN/A
1168862Snilay@cs.wisc.edu        return fault;
1178862Snilay@cs.wisc.edu    }
1188467Snilay@cs.wisc.edu}};
1192957SN/A
1202957SN/A
1212957SN/Adef template LoadCompleteAcc {{
1222957SN/A    Fault %(class_name)s::completeAcc(PacketPtr pkt,
1232957SN/A                                      %(CPU_exec_context)s *xc,
1242957SN/A                                      Trace::InstRecord *traceData) const
1258167SLisa.Hsu@amd.com    {
1269197Snilay@cs.wisc.edu        Addr EA;
1278167SLisa.Hsu@amd.com        Fault fault = NoFault;
1285369Ssaidi@eecs.umich.edu        uint%(mem_acc_size)d_t val;
1298167SLisa.Hsu@amd.com
1308167SLisa.Hsu@amd.com        %(op_decl)s;
1318167SLisa.Hsu@amd.com        %(op_rd)s;
1328167SLisa.Hsu@amd.com
1338167SLisa.Hsu@amd.com        EA = xc->getEA();
1348167SLisa.Hsu@amd.com
1358167SLisa.Hsu@amd.com        val = pkt->get<uint%(mem_acc_size)d_t>();
1368168SLisa.Hsu@amd.com        *((uint%(mem_acc_size)d_t*)&Mem) = val;
13710037SARM gem5 Developers
13810037SARM gem5 Developers        if (fault == NoFault) {
13910037SARM gem5 Developers            %(memacc_code)s;
14010037SARM gem5 Developers        }
14110037SARM gem5 Developers
1428168SLisa.Hsu@amd.com        if (fault == NoFault) {
14310037SARM gem5 Developers          %(op_wb)s;
14410037SARM gem5 Developers        }
1458167SLisa.Hsu@amd.com
1468167SLisa.Hsu@amd.com        return fault;
14710118Snilay@cs.wisc.edu    }
14810118Snilay@cs.wisc.edu}};
1495369Ssaidi@eecs.umich.edu
1508920Snilay@cs.wisc.edu
1519197Snilay@cs.wisc.edudef template StoreExecute {{
1528920Snilay@cs.wisc.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
1538920Snilay@cs.wisc.edu                                  Trace::InstRecord *traceData) const
1548920Snilay@cs.wisc.edu    {
1555369Ssaidi@eecs.umich.edu        Addr EA;
1565369Ssaidi@eecs.umich.edu        Fault fault = NoFault;
1578718Snilay@cs.wisc.edu
1589197Snilay@cs.wisc.edu        %(op_decl)s;
1599197Snilay@cs.wisc.edu        %(op_rd)s;
1609197Snilay@cs.wisc.edu        %(ea_code)s;
1619197Snilay@cs.wisc.edu
1629197Snilay@cs.wisc.edu        if (fault == NoFault) {
1633005Sstever@eecs.umich.edu            %(memacc_code)s;
1643395Shsul@eecs.umich.edu        }
1653395Shsul@eecs.umich.edu
1669793Sakash.bagdia@arm.com        if (fault == NoFault) {
1679836Sandreas.hansson@arm.com            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
1689815SAndreas Hansson <andreas.hansson>                              memAccessFlags, NULL);
1699793Sakash.bagdia@arm.com            if (traceData) { traceData->setData(Mem); }
1709827Sakash.bagdia@arm.com        }
1719827Sakash.bagdia@arm.com
1729827Sakash.bagdia@arm.com        if (fault == NoFault) {
1739827Sakash.bagdia@arm.com            %(op_wb)s;
1749827Sakash.bagdia@arm.com        }
1759827Sakash.bagdia@arm.com
1769827Sakash.bagdia@arm.com        return fault;
1779827Sakash.bagdia@arm.com    }
1789827Sakash.bagdia@arm.com}};
1799827Sakash.bagdia@arm.com
1809793Sakash.bagdia@arm.com
1819827Sakash.bagdia@arm.comdef template StoreInitiateAcc {{
1829827Sakash.bagdia@arm.com    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
1839827Sakash.bagdia@arm.com                                      Trace::InstRecord *traceData) const
1849793Sakash.bagdia@arm.com    {
1859793Sakash.bagdia@arm.com        Addr EA;
1869793Sakash.bagdia@arm.com        Fault fault = NoFault;
1879793Sakash.bagdia@arm.com
1889793Sakash.bagdia@arm.com        %(op_decl)s;
1893395Shsul@eecs.umich.edu        %(op_rd)s;
1908926Sandreas.hansson@arm.com        %(ea_code)s;
1919317Sandreas.hansson@arm.com
1929317Sandreas.hansson@arm.com        if (fault == NoFault) {
1939317Sandreas.hansson@arm.com            %(memacc_code)s;
1949317Sandreas.hansson@arm.com        }
1959317Sandreas.hansson@arm.com
1968926Sandreas.hansson@arm.com        if (fault == NoFault) {
1979647Sdam.sunwoo@arm.com            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
1989647Sdam.sunwoo@arm.com                              memAccessFlags, NULL);
1999647Sdam.sunwoo@arm.com            if (traceData) { traceData->setData(Mem); }
2009647Sdam.sunwoo@arm.com        }
2019647Sdam.sunwoo@arm.com
2029647Sdam.sunwoo@arm.com        // Need to write back any potential address register update
2039647Sdam.sunwoo@arm.com        if (fault == NoFault) {
2043395Shsul@eecs.umich.edu            %(op_wb)s;
2059197Snilay@cs.wisc.edu        }
2069197Snilay@cs.wisc.edu
2079197Snilay@cs.wisc.edu        return fault;
2088957Sjayneel@cs.wisc.edu    }
2098957Sjayneel@cs.wisc.edu}};
2108957Sjayneel@cs.wisc.edu
2113005Sstever@eecs.umich.edu
2124968Sacolyte@umich.edudef template StoreCompleteAcc {{
2139006Sandreas.hansson@arm.com    Fault %(class_name)s::completeAcc(PacketPtr pkt,
2144968Sacolyte@umich.edu                                      %(CPU_exec_context)s *xc,
2159647Sdam.sunwoo@arm.com                                      Trace::InstRecord *traceData) const
21610381Sdam.sunwoo@arm.com    {
2179647Sdam.sunwoo@arm.com        Fault fault = NoFault;
2188887Sgeoffrey.blake@arm.com
2198887Sgeoffrey.blake@arm.com        %(op_dest_decl)s;
2208887Sgeoffrey.blake@arm.com
2219384SAndreas.Sandberg@arm.com        if (fault == NoFault) {
2229384SAndreas.Sandberg@arm.com          %(op_wb)s;
2238887Sgeoffrey.blake@arm.com        }
2248896Snilay@cs.wisc.edu
2258896Snilay@cs.wisc.edu        return fault;
2268896Snilay@cs.wisc.edu    }
2278896Snilay@cs.wisc.edu}};
22810150Snilay@cs.wisc.edu
22910150Snilay@cs.wisc.edu
23010150Snilay@cs.wisc.edu// The generic memory operation generator. This is called when two versions
23110150Snilay@cs.wisc.edu// of an instruction are needed - when Ra == 0 and otherwise. This is so
2329836Sandreas.hansson@arm.com// that instructions can use the value 0 when Ra == 0 but avoid having a
23310092Snilay@cs.wisc.edu// dependence on Ra.
23410117Snilay@cs.wisc.edulet {{
23510120Snilay@cs.wisc.edu
2368896Snilay@cs.wisc.edudef GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
23710300Scastilloe@unican.es             load_or_store, mem_flags = [], inst_flags = []):
23810300Scastilloe@unican.es
2398896Snilay@cs.wisc.edu    # First the version where Ra is non-zero
24010120Snilay@cs.wisc.edu    (header_output, decoder_output, decode_block, exec_output) = \
2418896Snilay@cs.wisc.edu        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
2428896Snilay@cs.wisc.edu                      base_class = base,
2439268Smalek.musleh@gmail.com                      decode_template = CheckRaDecode,
2449268Smalek.musleh@gmail.com                      exec_template_base = load_or_store)
2458896Snilay@cs.wisc.edu
2468896Snilay@cs.wisc.edu    # Now another version where Ra == 0
2478896Snilay@cs.wisc.edu    (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
2488896Snilay@cs.wisc.edu        LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
2498896Snilay@cs.wisc.edu                      mem_flags, inst_flags,
2509222Shestness@cs.wisc.edu                      base_class = base,
2519268Smalek.musleh@gmail.com                      exec_template_base = load_or_store)
2529268Smalek.musleh@gmail.com
2539268Smalek.musleh@gmail.com    # Finally, add to the other outputs
2549222Shestness@cs.wisc.edu    header_output += header_output_ra0
2559222Shestness@cs.wisc.edu    decoder_output += decoder_output_ra0
2568887Sgeoffrey.blake@arm.com    exec_output += exec_output_ra0
25710150Snilay@cs.wisc.edu    return (header_output, decoder_output, decode_block, exec_output)
2589756Snilay@cs.wisc.edu
2598887Sgeoffrey.blake@arm.com}};
2608887Sgeoffrey.blake@arm.com
2619836Sandreas.hansson@arm.com
2628887Sgeoffrey.blake@arm.comdef format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2638801Sgblack@eecs.umich.edu                       ea_code_ra0 = {{ EA = Rb; }},
2643481Shsul@eecs.umich.edu                       mem_flags = [], inst_flags = []) {{
265    (header_output, decoder_output, decode_block, exec_output) = \
266        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
267                 'MemOp', 'Load', mem_flags, inst_flags)
268}};
269
270
271def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
272                        ea_code_ra0 = {{ EA = Rb; }},
273                        mem_flags = [], inst_flags = []) {{
274    (header_output, decoder_output, decode_block, exec_output) = \
275        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
276                 'MemOp', 'Store', mem_flags, inst_flags)
277}};
278
279
280def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
281                             mem_flags = [], inst_flags = []) {{
282
283    # Add in the update code
284    memacc_code += 'Ra = EA;'
285
286    # Generate the class
287    (header_output, decoder_output, decode_block, exec_output) = \
288        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
289                      base_class = 'MemOp',
290                      exec_template_base = 'Load')
291}};
292
293
294def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
295                              mem_flags = [], inst_flags = []) {{
296
297    # Add in the update code
298    memacc_code += 'Ra = EA;'
299
300    # Generate the class
301    (header_output, decoder_output, decode_block, exec_output) = \
302        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
303                      base_class = 'MemOp',
304                      exec_template_base = 'Store')
305}};
306
307
308def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
309                      ea_code_ra0 = {{ EA = disp; }},
310                      mem_flags = [], inst_flags = []) {{
311    (header_output, decoder_output, decode_block, exec_output) = \
312        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
313                 'MemDispOp', 'Load', mem_flags, inst_flags)
314}};
315
316
317def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
318                       ea_code_ra0 = {{ EA = disp; }},
319                       mem_flags = [], inst_flags = []) {{
320    (header_output, decoder_output, decode_block, exec_output) = \
321        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
322                 'MemDispOp', 'Store', mem_flags, inst_flags)
323}};
324
325
326def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
327                            mem_flags = [], inst_flags = []) {{
328
329    # Add in the update code
330    memacc_code += 'Ra = EA;'
331
332    # Generate the class
333    (header_output, decoder_output, decode_block, exec_output) = \
334        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
335                      base_class = 'MemDispOp',
336                      exec_template_base = 'Load')
337}};
338
339
340def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
341                             mem_flags = [], inst_flags = []) {{
342
343    # Add in the update code
344    memacc_code += 'Ra = EA;'
345
346    # Generate the class
347    (header_output, decoder_output, decode_block, exec_output) = \
348        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
349                      base_class = 'MemDispOp',
350                      exec_template_base = 'Store')
351}};
352