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
4712616Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
4812616Sgabeblack@google.com        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
4912616Sgabeblack@google.com        Fault completeAcc(PacketPtr, ExecContext *,
5012616Sgabeblack@google.com                          Trace::InstRecord *) const override;
516691Stjones1@inf.ed.ac.uk    };
526691Stjones1@inf.ed.ac.uk}};
536691Stjones1@inf.ed.ac.uk
546691Stjones1@inf.ed.ac.uk
556691Stjones1@inf.ed.ac.ukdef template LoadStoreConstructor {{
5610184SCurtis.Dunham@arm.com    %(class_name)s::%(class_name)s(ExtMachInst machInst)
576691Stjones1@inf.ed.ac.uk         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
586691Stjones1@inf.ed.ac.uk    {
596691Stjones1@inf.ed.ac.uk        %(constructor)s;
606691Stjones1@inf.ed.ac.uk    }
616691Stjones1@inf.ed.ac.uk}};
626691Stjones1@inf.ed.ac.uk
636691Stjones1@inf.ed.ac.uk
646691Stjones1@inf.ed.ac.ukdef template LoadExecute {{
6512234Sgabeblack@google.com    Fault %(class_name)s::execute(ExecContext *xc,
666691Stjones1@inf.ed.ac.uk                                  Trace::InstRecord *traceData) const
676691Stjones1@inf.ed.ac.uk    {
686691Stjones1@inf.ed.ac.uk        Addr EA;
696691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
706691Stjones1@inf.ed.ac.uk
716691Stjones1@inf.ed.ac.uk        %(op_decl)s;
726691Stjones1@inf.ed.ac.uk        %(op_rd)s;
736691Stjones1@inf.ed.ac.uk        %(ea_code)s;
746691Stjones1@inf.ed.ac.uk
756691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
768442Sgblack@eecs.umich.edu            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
776691Stjones1@inf.ed.ac.uk            %(memacc_code)s;
786691Stjones1@inf.ed.ac.uk        }
796691Stjones1@inf.ed.ac.uk
806691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
816691Stjones1@inf.ed.ac.uk            %(op_wb)s;
826691Stjones1@inf.ed.ac.uk        }
836691Stjones1@inf.ed.ac.uk
846691Stjones1@inf.ed.ac.uk        return fault;
856691Stjones1@inf.ed.ac.uk    }
866691Stjones1@inf.ed.ac.uk}};
876691Stjones1@inf.ed.ac.uk
886691Stjones1@inf.ed.ac.uk
896691Stjones1@inf.ed.ac.ukdef template LoadInitiateAcc {{
9012234Sgabeblack@google.com    Fault %(class_name)s::initiateAcc(ExecContext *xc,
916691Stjones1@inf.ed.ac.uk                                      Trace::InstRecord *traceData) const
926691Stjones1@inf.ed.ac.uk    {
936691Stjones1@inf.ed.ac.uk        Addr EA;
946691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
956691Stjones1@inf.ed.ac.uk
966691Stjones1@inf.ed.ac.uk        %(op_src_decl)s;
976691Stjones1@inf.ed.ac.uk        %(op_rd)s;
986691Stjones1@inf.ed.ac.uk        %(ea_code)s;
996691Stjones1@inf.ed.ac.uk
1006691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
10111303Ssteve.reinhardt@amd.com            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
1026691Stjones1@inf.ed.ac.uk        }
1036691Stjones1@inf.ed.ac.uk
1046691Stjones1@inf.ed.ac.uk        return fault;
1056691Stjones1@inf.ed.ac.uk    }
1066691Stjones1@inf.ed.ac.uk}};
1076691Stjones1@inf.ed.ac.uk
1086691Stjones1@inf.ed.ac.uk
1096691Stjones1@inf.ed.ac.ukdef template LoadCompleteAcc {{
1106691Stjones1@inf.ed.ac.uk    Fault %(class_name)s::completeAcc(PacketPtr pkt,
11112234Sgabeblack@google.com                                      ExecContext *xc,
1126691Stjones1@inf.ed.ac.uk                                      Trace::InstRecord *traceData) const
1136691Stjones1@inf.ed.ac.uk    {
1148607Sgblack@eecs.umich.edu        Addr M5_VAR_USED EA;
1156691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1166691Stjones1@inf.ed.ac.uk
1176691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1186691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1196691Stjones1@inf.ed.ac.uk
12012420Sgabeblack@google.com        EA = pkt->req->getVaddr();
1216691Stjones1@inf.ed.ac.uk
1228450Sgblack@eecs.umich.edu        getMem(pkt, Mem, traceData);
1236691Stjones1@inf.ed.ac.uk
1246691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1256691Stjones1@inf.ed.ac.uk            %(memacc_code)s;
1266691Stjones1@inf.ed.ac.uk        }
1276691Stjones1@inf.ed.ac.uk
1286691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1296691Stjones1@inf.ed.ac.uk          %(op_wb)s;
1306691Stjones1@inf.ed.ac.uk        }
1316691Stjones1@inf.ed.ac.uk
1326691Stjones1@inf.ed.ac.uk        return fault;
1336691Stjones1@inf.ed.ac.uk    }
1346691Stjones1@inf.ed.ac.uk}};
1356691Stjones1@inf.ed.ac.uk
1366691Stjones1@inf.ed.ac.uk
1376691Stjones1@inf.ed.ac.ukdef template StoreExecute {{
13812234Sgabeblack@google.com    Fault %(class_name)s::execute(ExecContext *xc,
1396691Stjones1@inf.ed.ac.uk                                  Trace::InstRecord *traceData) const
1406691Stjones1@inf.ed.ac.uk    {
1416691Stjones1@inf.ed.ac.uk        Addr EA;
1426691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1436691Stjones1@inf.ed.ac.uk
1446691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1456691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1466691Stjones1@inf.ed.ac.uk        %(ea_code)s;
1476691Stjones1@inf.ed.ac.uk
1486691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1496691Stjones1@inf.ed.ac.uk            %(memacc_code)s;
1506691Stjones1@inf.ed.ac.uk        }
1516691Stjones1@inf.ed.ac.uk
1526691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1538442Sgblack@eecs.umich.edu            fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
1548442Sgblack@eecs.umich.edu                    NULL);
1556691Stjones1@inf.ed.ac.uk        }
1566691Stjones1@inf.ed.ac.uk
1576691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1586691Stjones1@inf.ed.ac.uk            %(op_wb)s;
1596691Stjones1@inf.ed.ac.uk        }
1606691Stjones1@inf.ed.ac.uk
1616691Stjones1@inf.ed.ac.uk        return fault;
1626691Stjones1@inf.ed.ac.uk    }
1636691Stjones1@inf.ed.ac.uk}};
1646691Stjones1@inf.ed.ac.uk
1656691Stjones1@inf.ed.ac.uk
1666691Stjones1@inf.ed.ac.ukdef template StoreInitiateAcc {{
16712234Sgabeblack@google.com    Fault %(class_name)s::initiateAcc(ExecContext *xc,
1686691Stjones1@inf.ed.ac.uk                                      Trace::InstRecord *traceData) const
1696691Stjones1@inf.ed.ac.uk    {
1706691Stjones1@inf.ed.ac.uk        Addr EA;
1716691Stjones1@inf.ed.ac.uk        Fault fault = NoFault;
1726691Stjones1@inf.ed.ac.uk
1736691Stjones1@inf.ed.ac.uk        %(op_decl)s;
1746691Stjones1@inf.ed.ac.uk        %(op_rd)s;
1756691Stjones1@inf.ed.ac.uk        %(ea_code)s;
1766691Stjones1@inf.ed.ac.uk
1776691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1786691Stjones1@inf.ed.ac.uk            %(memacc_code)s;
1796691Stjones1@inf.ed.ac.uk        }
1806691Stjones1@inf.ed.ac.uk
1816691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1828442Sgblack@eecs.umich.edu            fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
1838442Sgblack@eecs.umich.edu                    NULL);
1846691Stjones1@inf.ed.ac.uk        }
1856691Stjones1@inf.ed.ac.uk
1866691Stjones1@inf.ed.ac.uk        // Need to write back any potential address register update
1876691Stjones1@inf.ed.ac.uk        if (fault == NoFault) {
1886691Stjones1@inf.ed.ac.uk            %(op_wb)s;
1896691Stjones1@inf.ed.ac.uk        }
1906691Stjones1@inf.ed.ac.uk
1916691Stjones1@inf.ed.ac.uk        return fault;
1926691Stjones1@inf.ed.ac.uk    }
1936691Stjones1@inf.ed.ac.uk}};
1946691Stjones1@inf.ed.ac.uk
1956691Stjones1@inf.ed.ac.uk
1966691Stjones1@inf.ed.ac.ukdef template StoreCompleteAcc {{
19712234Sgabeblack@google.com    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
1986691Stjones1@inf.ed.ac.uk                                      Trace::InstRecord *traceData) const
1996691Stjones1@inf.ed.ac.uk    {
2007712Sgblack@eecs.umich.edu        return NoFault;
2016691Stjones1@inf.ed.ac.uk    }
2026691Stjones1@inf.ed.ac.uk}};
2036691Stjones1@inf.ed.ac.uk
2046691Stjones1@inf.ed.ac.uk
2056691Stjones1@inf.ed.ac.uk// The generic memory operation generator. This is called when two versions
2066691Stjones1@inf.ed.ac.uk// of an instruction are needed - when Ra == 0 and otherwise. This is so
2076691Stjones1@inf.ed.ac.uk// that instructions can use the value 0 when Ra == 0 but avoid having a
2086691Stjones1@inf.ed.ac.uk// dependence on Ra.
2096691Stjones1@inf.ed.ac.uklet {{
2106691Stjones1@inf.ed.ac.uk
2116691Stjones1@inf.ed.ac.ukdef GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base,
2126691Stjones1@inf.ed.ac.uk             load_or_store, mem_flags = [], inst_flags = []):
2136691Stjones1@inf.ed.ac.uk
2146691Stjones1@inf.ed.ac.uk    # First the version where Ra is non-zero
2156691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2166691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
2176691Stjones1@inf.ed.ac.uk                      base_class = base,
2186691Stjones1@inf.ed.ac.uk                      decode_template = CheckRaDecode,
2196691Stjones1@inf.ed.ac.uk                      exec_template_base = load_or_store)
2206691Stjones1@inf.ed.ac.uk
2216691Stjones1@inf.ed.ac.uk    # Now another version where Ra == 0
2226691Stjones1@inf.ed.ac.uk    (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
2236691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code,
2246691Stjones1@inf.ed.ac.uk                      mem_flags, inst_flags,
2256691Stjones1@inf.ed.ac.uk                      base_class = base,
2266691Stjones1@inf.ed.ac.uk                      exec_template_base = load_or_store)
2276691Stjones1@inf.ed.ac.uk
2286691Stjones1@inf.ed.ac.uk    # Finally, add to the other outputs
2296691Stjones1@inf.ed.ac.uk    header_output += header_output_ra0
2306691Stjones1@inf.ed.ac.uk    decoder_output += decoder_output_ra0
2316691Stjones1@inf.ed.ac.uk    exec_output += exec_output_ra0
2326691Stjones1@inf.ed.ac.uk    return (header_output, decoder_output, decode_block, exec_output)
2336691Stjones1@inf.ed.ac.uk
2346691Stjones1@inf.ed.ac.uk}};
2356691Stjones1@inf.ed.ac.uk
2366691Stjones1@inf.ed.ac.uk
2376691Stjones1@inf.ed.ac.ukdef format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2386691Stjones1@inf.ed.ac.uk                       ea_code_ra0 = {{ EA = Rb; }},
2396691Stjones1@inf.ed.ac.uk                       mem_flags = [], inst_flags = []) {{
2406691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2416691Stjones1@inf.ed.ac.uk        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
2426691Stjones1@inf.ed.ac.uk                 'MemOp', 'Load', mem_flags, inst_flags)
2436691Stjones1@inf.ed.ac.uk}};
2446691Stjones1@inf.ed.ac.uk
2456691Stjones1@inf.ed.ac.uk
2466691Stjones1@inf.ed.ac.ukdef format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2476691Stjones1@inf.ed.ac.uk                        ea_code_ra0 = {{ EA = Rb; }},
2486691Stjones1@inf.ed.ac.uk                        mem_flags = [], inst_flags = []) {{
2496691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2506691Stjones1@inf.ed.ac.uk        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
2516691Stjones1@inf.ed.ac.uk                 'MemOp', 'Store', mem_flags, inst_flags)
2526691Stjones1@inf.ed.ac.uk}};
2536691Stjones1@inf.ed.ac.uk
2546691Stjones1@inf.ed.ac.uk
2556691Stjones1@inf.ed.ac.ukdef format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2566691Stjones1@inf.ed.ac.uk                             mem_flags = [], inst_flags = []) {{
2576691Stjones1@inf.ed.ac.uk
2586691Stjones1@inf.ed.ac.uk    # Add in the update code
2596691Stjones1@inf.ed.ac.uk    memacc_code += 'Ra = EA;'
2606691Stjones1@inf.ed.ac.uk
2616691Stjones1@inf.ed.ac.uk    # Generate the class
2626691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2636691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
2646691Stjones1@inf.ed.ac.uk                      base_class = 'MemOp',
2656691Stjones1@inf.ed.ac.uk                      exec_template_base = 'Load')
2666691Stjones1@inf.ed.ac.uk}};
2676691Stjones1@inf.ed.ac.uk
2686691Stjones1@inf.ed.ac.uk
2696691Stjones1@inf.ed.ac.ukdef format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
2706691Stjones1@inf.ed.ac.uk                              mem_flags = [], inst_flags = []) {{
2716691Stjones1@inf.ed.ac.uk
2726691Stjones1@inf.ed.ac.uk    # Add in the update code
2736691Stjones1@inf.ed.ac.uk    memacc_code += 'Ra = EA;'
2746691Stjones1@inf.ed.ac.uk
2756691Stjones1@inf.ed.ac.uk    # Generate the class
2766691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2776691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
2786691Stjones1@inf.ed.ac.uk                      base_class = 'MemOp',
2796691Stjones1@inf.ed.ac.uk                      exec_template_base = 'Store')
2806691Stjones1@inf.ed.ac.uk}};
2816691Stjones1@inf.ed.ac.uk
2826691Stjones1@inf.ed.ac.uk
2836691Stjones1@inf.ed.ac.ukdef format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
2846691Stjones1@inf.ed.ac.uk                      ea_code_ra0 = {{ EA = disp; }},
2856691Stjones1@inf.ed.ac.uk                      mem_flags = [], inst_flags = []) {{
2866691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2876691Stjones1@inf.ed.ac.uk        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
2886691Stjones1@inf.ed.ac.uk                 'MemDispOp', 'Load', mem_flags, inst_flags)
2896691Stjones1@inf.ed.ac.uk}};
2906691Stjones1@inf.ed.ac.uk
2916691Stjones1@inf.ed.ac.uk
2926691Stjones1@inf.ed.ac.ukdef format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
2936691Stjones1@inf.ed.ac.uk                       ea_code_ra0 = {{ EA = disp; }},
2946691Stjones1@inf.ed.ac.uk                       mem_flags = [], inst_flags = []) {{
2956691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
2966691Stjones1@inf.ed.ac.uk        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
2976691Stjones1@inf.ed.ac.uk                 'MemDispOp', 'Store', mem_flags, inst_flags)
2986691Stjones1@inf.ed.ac.uk}};
2996691Stjones1@inf.ed.ac.uk
3006691Stjones1@inf.ed.ac.uk
3016691Stjones1@inf.ed.ac.ukdef format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
3026691Stjones1@inf.ed.ac.uk                            mem_flags = [], inst_flags = []) {{
3036691Stjones1@inf.ed.ac.uk
3046691Stjones1@inf.ed.ac.uk    # Add in the update code
3056691Stjones1@inf.ed.ac.uk    memacc_code += 'Ra = EA;'
3066691Stjones1@inf.ed.ac.uk
3076691Stjones1@inf.ed.ac.uk    # Generate the class
3086691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
3096691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
3106691Stjones1@inf.ed.ac.uk                      base_class = 'MemDispOp',
3116691Stjones1@inf.ed.ac.uk                      exec_template_base = 'Load')
3126691Stjones1@inf.ed.ac.uk}};
3136691Stjones1@inf.ed.ac.uk
3146691Stjones1@inf.ed.ac.uk
3156691Stjones1@inf.ed.ac.ukdef format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
3166691Stjones1@inf.ed.ac.uk                             mem_flags = [], inst_flags = []) {{
3176691Stjones1@inf.ed.ac.uk
3186691Stjones1@inf.ed.ac.uk    # Add in the update code
3196691Stjones1@inf.ed.ac.uk    memacc_code += 'Ra = EA;'
3206691Stjones1@inf.ed.ac.uk
3216691Stjones1@inf.ed.ac.uk    # Generate the class
3226691Stjones1@inf.ed.ac.uk    (header_output, decoder_output, decode_block, exec_output) = \
3236691Stjones1@inf.ed.ac.uk        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
3246691Stjones1@inf.ed.ac.uk                      base_class = 'MemDispOp',
3256691Stjones1@inf.ed.ac.uk                      exec_template_base = 'Store')
3266691Stjones1@inf.ed.ac.uk}};
327