mem.isa revision 12236
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 4712236Sgabeblack@google.com Fault execute(ExecContext *, Trace::InstRecord *) const; 4812236Sgabeblack@google.com Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 4912236Sgabeblack@google.com Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const; 506691Stjones1@inf.ed.ac.uk }; 516691Stjones1@inf.ed.ac.uk}}; 526691Stjones1@inf.ed.ac.uk 536691Stjones1@inf.ed.ac.uk 546691Stjones1@inf.ed.ac.ukdef template LoadStoreConstructor {{ 5510184SCurtis.Dunham@arm.com %(class_name)s::%(class_name)s(ExtMachInst machInst) 566691Stjones1@inf.ed.ac.uk : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 576691Stjones1@inf.ed.ac.uk { 586691Stjones1@inf.ed.ac.uk %(constructor)s; 596691Stjones1@inf.ed.ac.uk } 606691Stjones1@inf.ed.ac.uk}}; 616691Stjones1@inf.ed.ac.uk 626691Stjones1@inf.ed.ac.uk 636691Stjones1@inf.ed.ac.ukdef template LoadExecute {{ 6412234Sgabeblack@google.com Fault %(class_name)s::execute(ExecContext *xc, 656691Stjones1@inf.ed.ac.uk Trace::InstRecord *traceData) const 666691Stjones1@inf.ed.ac.uk { 676691Stjones1@inf.ed.ac.uk Addr EA; 686691Stjones1@inf.ed.ac.uk Fault fault = NoFault; 696691Stjones1@inf.ed.ac.uk 706691Stjones1@inf.ed.ac.uk %(op_decl)s; 716691Stjones1@inf.ed.ac.uk %(op_rd)s; 726691Stjones1@inf.ed.ac.uk %(ea_code)s; 736691Stjones1@inf.ed.ac.uk 746691Stjones1@inf.ed.ac.uk if (fault == NoFault) { 758442Sgblack@eecs.umich.edu fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 766691Stjones1@inf.ed.ac.uk %(memacc_code)s; 776691Stjones1@inf.ed.ac.uk } 786691Stjones1@inf.ed.ac.uk 796691Stjones1@inf.ed.ac.uk if (fault == NoFault) { 806691Stjones1@inf.ed.ac.uk %(op_wb)s; 816691Stjones1@inf.ed.ac.uk } 826691Stjones1@inf.ed.ac.uk 836691Stjones1@inf.ed.ac.uk return fault; 846691Stjones1@inf.ed.ac.uk } 856691Stjones1@inf.ed.ac.uk}}; 866691Stjones1@inf.ed.ac.uk 876691Stjones1@inf.ed.ac.uk 886691Stjones1@inf.ed.ac.ukdef template LoadInitiateAcc {{ 8912234Sgabeblack@google.com Fault %(class_name)s::initiateAcc(ExecContext *xc, 906691Stjones1@inf.ed.ac.uk Trace::InstRecord *traceData) const 916691Stjones1@inf.ed.ac.uk { 926691Stjones1@inf.ed.ac.uk Addr EA; 936691Stjones1@inf.ed.ac.uk Fault fault = NoFault; 946691Stjones1@inf.ed.ac.uk 956691Stjones1@inf.ed.ac.uk %(op_src_decl)s; 966691Stjones1@inf.ed.ac.uk %(op_rd)s; 976691Stjones1@inf.ed.ac.uk %(ea_code)s; 986691Stjones1@inf.ed.ac.uk 996691Stjones1@inf.ed.ac.uk if (fault == NoFault) { 10011303Ssteve.reinhardt@amd.com fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 1016691Stjones1@inf.ed.ac.uk xc->setEA(EA); 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 1206691Stjones1@inf.ed.ac.uk EA = xc->getEA(); 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