mem.isa revision 7712
16691Stjones1@inf.ed.ac.uk// -*- mode:c++ -*-
26691Stjones1@inf.ed.ac.uk
36691Stjones1@inf.ed.ac.uk// Copyright (c) 2009 The University of Edinburgh
46691Stjones1@inf.ed.ac.uk// All rights reserved.
56691Stjones1@inf.ed.ac.uk//
66691Stjones1@inf.ed.ac.uk// Redistribution and use in source and binary forms, with or without
76691Stjones1@inf.ed.ac.uk// modification, are permitted provided that the following conditions are
86691Stjones1@inf.ed.ac.uk// met: redistributions of source code must retain the above copyright
96691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer;
106691Stjones1@inf.ed.ac.uk// redistributions in binary form must reproduce the above copyright
116691Stjones1@inf.ed.ac.uk// notice, this list of conditions and the following disclaimer in the
126691Stjones1@inf.ed.ac.uk// documentation and/or other materials provided with the distribution;
136691Stjones1@inf.ed.ac.uk// neither the name of the copyright holders nor the names of its
146691Stjones1@inf.ed.ac.uk// contributors may be used to endorse or promote products derived from
156691Stjones1@inf.ed.ac.uk// this software without specific prior written permission.
166691Stjones1@inf.ed.ac.uk//
176691Stjones1@inf.ed.ac.uk// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186691Stjones1@inf.ed.ac.uk// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196691Stjones1@inf.ed.ac.uk// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206691Stjones1@inf.ed.ac.uk// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216691Stjones1@inf.ed.ac.uk// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226691Stjones1@inf.ed.ac.uk// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236691Stjones1@inf.ed.ac.uk// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246691Stjones1@inf.ed.ac.uk// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256691Stjones1@inf.ed.ac.uk// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266691Stjones1@inf.ed.ac.uk// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276691Stjones1@inf.ed.ac.uk// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286691Stjones1@inf.ed.ac.uk//
296691Stjones1@inf.ed.ac.uk// Authors: Timothy M. Jones
306691Stjones1@inf.ed.ac.uk
316691Stjones1@inf.ed.ac.uk////////////////////////////////////////////////////////////////////
326691Stjones1@inf.ed.ac.uk//
336691Stjones1@inf.ed.ac.uk// Memory-format instructions
346691Stjones1@inf.ed.ac.uk//
356691Stjones1@inf.ed.ac.uk
366691Stjones1@inf.ed.ac.ukdef template LoadStoreDeclare {{
376691Stjones1@inf.ed.ac.uk    /**
386691Stjones1@inf.ed.ac.uk     * Static instruction class for "%(mnemonic)s".
396691Stjones1@inf.ed.ac.uk     */
406691Stjones1@inf.ed.ac.uk    class %(class_name)s : public %(base_class)s
416691Stjones1@inf.ed.ac.uk    {
426691Stjones1@inf.ed.ac.uk      public:
436691Stjones1@inf.ed.ac.uk
446691Stjones1@inf.ed.ac.uk        /// Constructor.
456691Stjones1@inf.ed.ac.uk        %(class_name)s(ExtMachInst machInst);
466691Stjones1@inf.ed.ac.uk
476691Stjones1@inf.ed.ac.uk        %(BasicExecDeclare)s
486691Stjones1@inf.ed.ac.uk
496691Stjones1@inf.ed.ac.uk        %(InitiateAccDeclare)s
506691Stjones1@inf.ed.ac.uk
516691Stjones1@inf.ed.ac.uk        %(CompleteAccDeclare)s
526691Stjones1@inf.ed.ac.uk    };
536691Stjones1@inf.ed.ac.uk}};
546691Stjones1@inf.ed.ac.uk
556691Stjones1@inf.ed.ac.uk
566691Stjones1@inf.ed.ac.ukdef template InitiateAccDeclare {{
576691Stjones1@inf.ed.ac.uk    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
586691Stjones1@inf.ed.ac.uk}};
596691Stjones1@inf.ed.ac.uk
606691Stjones1@inf.ed.ac.uk
616691Stjones1@inf.ed.ac.ukdef template CompleteAccDeclare {{
626691Stjones1@inf.ed.ac.uk    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
636691Stjones1@inf.ed.ac.uk}};
646691Stjones1@inf.ed.ac.uk
656691Stjones1@inf.ed.ac.uk
666691Stjones1@inf.ed.ac.ukdef template LoadStoreConstructor {{
676691Stjones1@inf.ed.ac.uk    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
686691Stjones1@inf.ed.ac.uk         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
696691Stjones1@inf.ed.ac.uk    {
706691Stjones1@inf.ed.ac.uk        %(constructor)s;
716691Stjones1@inf.ed.ac.uk    }
726691Stjones1@inf.ed.ac.uk}};
736691Stjones1@inf.ed.ac.uk
746691Stjones1@inf.ed.ac.uk
756691Stjones1@inf.ed.ac.ukdef template LoadExecute {{
766691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
776691Stjones1@inf.ed.ac.uk                                  Trace::InstRecord *traceData) const
786691Stjones1@inf.ed.ac.uk    {
796691Stjones1@inf.ed.ac.uk        Addr EA;
806691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
816691Stjones1@inf.ed.ac.uk
826691Stjones1@inf.ed.ac.uk        %(op_decl)s;
836691Stjones1@inf.ed.ac.uk        %(op_rd)s;
846691Stjones1@inf.ed.ac.uk        %(ea_code)s;
856691Stjones1@inf.ed.ac.uk
866691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
876691Stjones1@inf.ed.ac.uk            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
886691Stjones1@inf.ed.ac.uk            %(memacc_code)s;
896691Stjones1@inf.ed.ac.uk        }
906691Stjones1@inf.ed.ac.uk
916691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
926691Stjones1@inf.ed.ac.uk            %(op_wb)s;
936691Stjones1@inf.ed.ac.uk        }
946691Stjones1@inf.ed.ac.uk
956691Stjones1@inf.ed.ac.uk        return fault;
966691Stjones1@inf.ed.ac.uk    }
976691Stjones1@inf.ed.ac.uk}};
986691Stjones1@inf.ed.ac.uk
996691Stjones1@inf.ed.ac.uk
1006691Stjones1@inf.ed.ac.ukdef template LoadInitiateAcc {{
1016691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
1026691Stjones1@inf.ed.ac.uk                                      Trace::InstRecord *traceData) const
1036691Stjones1@inf.ed.ac.uk    {
1046691Stjones1@inf.ed.ac.uk        Addr EA;
1056691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1066691Stjones1@inf.ed.ac.uk
1076691Stjones1@inf.ed.ac.uk        %(op_src_decl)s;
1086691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1096691Stjones1@inf.ed.ac.uk        %(ea_code)s;
1106691Stjones1@inf.ed.ac.uk
1116691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1126691Stjones1@inf.ed.ac.uk            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
1136691Stjones1@inf.ed.ac.uk            xc->setEA(EA);
1146691Stjones1@inf.ed.ac.uk        }
1156691Stjones1@inf.ed.ac.uk
1166691Stjones1@inf.ed.ac.uk        return fault;
1176691Stjones1@inf.ed.ac.uk    }
1186691Stjones1@inf.ed.ac.uk}};
1196691Stjones1@inf.ed.ac.uk
1206691Stjones1@inf.ed.ac.uk
1216691Stjones1@inf.ed.ac.ukdef template LoadCompleteAcc {{
1226691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::completeAcc(PacketPtr pkt,
1236691Stjones1@inf.ed.ac.uk                                      %(CPU_exec_context)s *xc,
1246691Stjones1@inf.ed.ac.uk                                      Trace::InstRecord *traceData) const
1256691Stjones1@inf.ed.ac.uk    {
1266691Stjones1@inf.ed.ac.uk        Addr EA;
1276691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1286691Stjones1@inf.ed.ac.uk        uint%(mem_acc_size)d_t val;
1296691Stjones1@inf.ed.ac.uk
1306691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1316691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1326691Stjones1@inf.ed.ac.uk
1336691Stjones1@inf.ed.ac.uk        EA = xc->getEA();
1346691Stjones1@inf.ed.ac.uk
1356691Stjones1@inf.ed.ac.uk        val = pkt->get<uint%(mem_acc_size)d_t>();
1366691Stjones1@inf.ed.ac.uk        *((uint%(mem_acc_size)d_t*)&Mem) = val;
1376691Stjones1@inf.ed.ac.uk
1386691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1396691Stjones1@inf.ed.ac.uk            %(memacc_code)s;
1406691Stjones1@inf.ed.ac.uk        }
1416691Stjones1@inf.ed.ac.uk
1426691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1436691Stjones1@inf.ed.ac.uk          %(op_wb)s;
1446691Stjones1@inf.ed.ac.uk        }
1456691Stjones1@inf.ed.ac.uk
1466691Stjones1@inf.ed.ac.uk        return fault;
1476691Stjones1@inf.ed.ac.uk    }
1486691Stjones1@inf.ed.ac.uk}};
1496691Stjones1@inf.ed.ac.uk
1506691Stjones1@inf.ed.ac.uk
1516691Stjones1@inf.ed.ac.ukdef template StoreExecute {{
1526691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
1536691Stjones1@inf.ed.ac.uk                                  Trace::InstRecord *traceData) const
1546691Stjones1@inf.ed.ac.uk    {
1556691Stjones1@inf.ed.ac.uk        Addr EA;
1566691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1576691Stjones1@inf.ed.ac.uk
1586691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1596691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1606691Stjones1@inf.ed.ac.uk        %(ea_code)s;
1616691Stjones1@inf.ed.ac.uk
1626691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1636691Stjones1@inf.ed.ac.uk            %(memacc_code)s;
1646691Stjones1@inf.ed.ac.uk        }
1656691Stjones1@inf.ed.ac.uk
1666691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1676691Stjones1@inf.ed.ac.uk            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
1686691Stjones1@inf.ed.ac.uk                              memAccessFlags, NULL);
1696691Stjones1@inf.ed.ac.uk        }
1706691Stjones1@inf.ed.ac.uk
1716691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1726691Stjones1@inf.ed.ac.uk            %(op_wb)s;
1736691Stjones1@inf.ed.ac.uk        }
1746691Stjones1@inf.ed.ac.uk
1756691Stjones1@inf.ed.ac.uk        return fault;
1766691Stjones1@inf.ed.ac.uk    }
1776691Stjones1@inf.ed.ac.uk}};
1786691Stjones1@inf.ed.ac.uk
1796691Stjones1@inf.ed.ac.uk
1806691Stjones1@inf.ed.ac.ukdef template StoreInitiateAcc {{
1816691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
1826691Stjones1@inf.ed.ac.uk                                      Trace::InstRecord *traceData) const
1836691Stjones1@inf.ed.ac.uk    {
1846691Stjones1@inf.ed.ac.uk        Addr EA;
1856691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1866691Stjones1@inf.ed.ac.uk
1876691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1886691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1896691Stjones1@inf.ed.ac.uk        %(ea_code)s;
1906691Stjones1@inf.ed.ac.uk
1916691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1926691Stjones1@inf.ed.ac.uk            %(memacc_code)s;
1936691Stjones1@inf.ed.ac.uk        }
1946691Stjones1@inf.ed.ac.uk
1956691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1966691Stjones1@inf.ed.ac.uk            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
1976691Stjones1@inf.ed.ac.uk                              memAccessFlags, NULL);
1986691Stjones1@inf.ed.ac.uk        }
1996691Stjones1@inf.ed.ac.uk
2006691Stjones1@inf.ed.ac.uk        // Need to write back any potential address register update
2016691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
2026691Stjones1@inf.ed.ac.uk            %(op_wb)s;
2036691Stjones1@inf.ed.ac.uk        }
2046691Stjones1@inf.ed.ac.uk
2056691Stjones1@inf.ed.ac.uk        return fault;
2066691Stjones1@inf.ed.ac.uk    }
2076691Stjones1@inf.ed.ac.uk}};
2086691Stjones1@inf.ed.ac.uk
2096691Stjones1@inf.ed.ac.uk
2106691Stjones1@inf.ed.ac.ukdef template StoreCompleteAcc {{
2116691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::completeAcc(PacketPtr pkt,
2126691Stjones1@inf.ed.ac.uk                                      %(CPU_exec_context)s *xc,
2136691Stjones1@inf.ed.ac.uk                                      Trace::InstRecord *traceData) const
2146691Stjones1@inf.ed.ac.uk    {
2157712Sgblack@eecs.umich.edu        return NoFault;
2166691Stjones1@inf.ed.ac.uk    }
2176691Stjones1@inf.ed.ac.uk}};
2186691Stjones1@inf.ed.ac.uk
2196691Stjones1@inf.ed.ac.uk
2206691Stjones1@inf.ed.ac.uk// The generic memory operation generator. This is called when two versions
2216691Stjones1@inf.ed.ac.uk// of an instruction are needed - when Ra == 0 and otherwise. This is so
2226691Stjones1@inf.ed.ac.uk// that instructions can use the value 0 when Ra == 0 but avoid having a
2236691Stjones1@inf.ed.ac.uk// dependence on Ra.
2246691Stjones1@inf.ed.ac.uklet {{
2256691Stjones1@inf.ed.ac.uk
2266691Stjones1@inf.ed.ac.ukdef GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
2276691Stjones1@inf.ed.ac.uk             load_or_store, mem_flags = [], inst_flags = []):
2286691Stjones1@inf.ed.ac.uk
2296691Stjones1@inf.ed.ac.uk    # First the version where Ra is non-zero
2306691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2316691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
2326691Stjones1@inf.ed.ac.uk                      base_class = base,
2336691Stjones1@inf.ed.ac.uk                      decode_template = CheckRaDecode,
2346691Stjones1@inf.ed.ac.uk                      exec_template_base = load_or_store)
2356691Stjones1@inf.ed.ac.uk
2366691Stjones1@inf.ed.ac.uk    # Now another version where Ra == 0
2376691Stjones1@inf.ed.ac.uk    (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
2386691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
2396691Stjones1@inf.ed.ac.uk                      mem_flags, inst_flags,
2406691Stjones1@inf.ed.ac.uk                      base_class = base,
2416691Stjones1@inf.ed.ac.uk                      exec_template_base = load_or_store)
2426691Stjones1@inf.ed.ac.uk
2436691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
2446691Stjones1@inf.ed.ac.uk    header_output += header_output_ra0
2456691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_ra0
2466691Stjones1@inf.ed.ac.uk    exec_output += exec_output_ra0
2476691Stjones1@inf.ed.ac.uk    return (header_output, decoder_output, decode_block, exec_output)
2486691Stjones1@inf.ed.ac.uk
2496691Stjones1@inf.ed.ac.uk}};
2506691Stjones1@inf.ed.ac.uk
2516691Stjones1@inf.ed.ac.uk
2526691Stjones1@inf.ed.ac.ukdef format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2536691Stjones1@inf.ed.ac.uk                       ea_code_ra0 = {{ EA = Rb; }},
2546691Stjones1@inf.ed.ac.uk                       mem_flags = [], inst_flags = []) {{
2556691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2566691Stjones1@inf.ed.ac.uk        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
2576691Stjones1@inf.ed.ac.uk                 'MemOp', 'Load', mem_flags, inst_flags)
2586691Stjones1@inf.ed.ac.uk}};
2596691Stjones1@inf.ed.ac.uk
2606691Stjones1@inf.ed.ac.uk
2616691Stjones1@inf.ed.ac.ukdef format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2626691Stjones1@inf.ed.ac.uk                        ea_code_ra0 = {{ EA = Rb; }},
2636691Stjones1@inf.ed.ac.uk                        mem_flags = [], inst_flags = []) {{
2646691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2656691Stjones1@inf.ed.ac.uk        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
2666691Stjones1@inf.ed.ac.uk                 'MemOp', 'Store', mem_flags, inst_flags)
2676691Stjones1@inf.ed.ac.uk}};
2686691Stjones1@inf.ed.ac.uk
2696691Stjones1@inf.ed.ac.uk
2706691Stjones1@inf.ed.ac.ukdef format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2716691Stjones1@inf.ed.ac.uk                             mem_flags = [], inst_flags = []) {{
2726691Stjones1@inf.ed.ac.uk
2736691Stjones1@inf.ed.ac.uk    # Add in the update code
2746691Stjones1@inf.ed.ac.uk    memacc_code += 'Ra = EA;'
2756691Stjones1@inf.ed.ac.uk
2766691Stjones1@inf.ed.ac.uk    # Generate the class
2776691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2786691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
2796691Stjones1@inf.ed.ac.uk                      base_class = 'MemOp',
2806691Stjones1@inf.ed.ac.uk                      exec_template_base = 'Load')
2816691Stjones1@inf.ed.ac.uk}};
2826691Stjones1@inf.ed.ac.uk
2836691Stjones1@inf.ed.ac.uk
2846691Stjones1@inf.ed.ac.ukdef format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2856691Stjones1@inf.ed.ac.uk                              mem_flags = [], inst_flags = []) {{
2866691Stjones1@inf.ed.ac.uk
2876691Stjones1@inf.ed.ac.uk    # Add in the update code
2886691Stjones1@inf.ed.ac.uk    memacc_code += 'Ra = EA;'
2896691Stjones1@inf.ed.ac.uk
2906691Stjones1@inf.ed.ac.uk    # Generate the class
2916691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2926691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
2936691Stjones1@inf.ed.ac.uk                      base_class = 'MemOp',
2946691Stjones1@inf.ed.ac.uk                      exec_template_base = 'Store')
2956691Stjones1@inf.ed.ac.uk}};
2966691Stjones1@inf.ed.ac.uk
2976691Stjones1@inf.ed.ac.uk
2986691Stjones1@inf.ed.ac.ukdef format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
2996691Stjones1@inf.ed.ac.uk                      ea_code_ra0 = {{ EA = disp; }},
3006691Stjones1@inf.ed.ac.uk                      mem_flags = [], inst_flags = []) {{
3016691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
3026691Stjones1@inf.ed.ac.uk        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
3036691Stjones1@inf.ed.ac.uk                 'MemDispOp', 'Load', mem_flags, inst_flags)
3046691Stjones1@inf.ed.ac.uk}};
3056691Stjones1@inf.ed.ac.uk
3066691Stjones1@inf.ed.ac.uk
3076691Stjones1@inf.ed.ac.ukdef format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
3086691Stjones1@inf.ed.ac.uk                       ea_code_ra0 = {{ EA = disp; }},
3096691Stjones1@inf.ed.ac.uk                       mem_flags = [], inst_flags = []) {{
3106691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
3116691Stjones1@inf.ed.ac.uk        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
3126691Stjones1@inf.ed.ac.uk                 'MemDispOp', 'Store', mem_flags, inst_flags)
3136691Stjones1@inf.ed.ac.uk}};
3146691Stjones1@inf.ed.ac.uk
3156691Stjones1@inf.ed.ac.uk
3166691Stjones1@inf.ed.ac.ukdef format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
3176691Stjones1@inf.ed.ac.uk                            mem_flags = [], inst_flags = []) {{
3186691Stjones1@inf.ed.ac.uk
3196691Stjones1@inf.ed.ac.uk    # Add in the update code
3206691Stjones1@inf.ed.ac.uk    memacc_code += 'Ra = EA;'
3216691Stjones1@inf.ed.ac.uk
3226691Stjones1@inf.ed.ac.uk    # Generate the class
3236691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
3246691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
3256691Stjones1@inf.ed.ac.uk                      base_class = 'MemDispOp',
3266691Stjones1@inf.ed.ac.uk                      exec_template_base = 'Load')
3276691Stjones1@inf.ed.ac.uk}};
3286691Stjones1@inf.ed.ac.uk
3296691Stjones1@inf.ed.ac.uk
3306691Stjones1@inf.ed.ac.ukdef format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
3316691Stjones1@inf.ed.ac.uk                             mem_flags = [], inst_flags = []) {{
3326691Stjones1@inf.ed.ac.uk
3336691Stjones1@inf.ed.ac.uk    # Add in the update code
3346691Stjones1@inf.ed.ac.uk    memacc_code += 'Ra = EA;'
3356691Stjones1@inf.ed.ac.uk
3366691Stjones1@inf.ed.ac.uk    # Generate the class
3376691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
3386691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
3396691Stjones1@inf.ed.ac.uk                      base_class = 'MemDispOp',
3406691Stjones1@inf.ed.ac.uk                      exec_template_base = 'Store')
3416691Stjones1@inf.ed.ac.uk}};
342