mem.isa revision 2069
12914Ssaidi@eecs.umich.edu// -*- mode:c++ -*-
22914Ssaidi@eecs.umich.edu
32914Ssaidi@eecs.umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan
42914Ssaidi@eecs.umich.edu// All rights reserved.
52914Ssaidi@eecs.umich.edu//
62914Ssaidi@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
72914Ssaidi@eecs.umich.edu// modification, are permitted provided that the following conditions are
82914Ssaidi@eecs.umich.edu// met: redistributions of source code must retain the above copyright
92914Ssaidi@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
102914Ssaidi@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
112914Ssaidi@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
122914Ssaidi@eecs.umich.edu// documentation and/or other materials provided with the distribution;
132914Ssaidi@eecs.umich.edu// neither the name of the copyright holders nor the names of its
142914Ssaidi@eecs.umich.edu// contributors may be used to endorse or promote products derived from
152914Ssaidi@eecs.umich.edu// this software without specific prior written permission.
162914Ssaidi@eecs.umich.edu//
172914Ssaidi@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182914Ssaidi@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192914Ssaidi@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202914Ssaidi@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212914Ssaidi@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222914Ssaidi@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232914Ssaidi@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242914Ssaidi@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252914Ssaidi@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262914Ssaidi@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272914Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282914Ssaidi@eecs.umich.edu
292914Ssaidi@eecs.umich.eduoutput header {{
302914Ssaidi@eecs.umich.edu    /**
312914Ssaidi@eecs.umich.edu     * Base class for general Alpha memory-format instructions.
322914Ssaidi@eecs.umich.edu     */
332914Ssaidi@eecs.umich.edu    class Memory : public AlphaStaticInst
344490Sstever@eecs.umich.edu    {
353091Sstever@eecs.umich.edu      protected:
364490Sstever@eecs.umich.edu
374490Sstever@eecs.umich.edu        /// Memory request flags.  See mem_req_base.hh.
383296Ssaidi@eecs.umich.edu        unsigned memAccessFlags;
394492Sstever@eecs.umich.edu        /// Pointer to EAComp object.
404490Sstever@eecs.umich.edu        const StaticInstPtr<AlphaISA> eaCompPtr;
413284Srdreslin@umich.edu        /// Pointer to MemAcc object.
423284Srdreslin@umich.edu        const StaticInstPtr<AlphaISA> memAccPtr;
434490Sstever@eecs.umich.edu
444490Sstever@eecs.umich.edu        /// Constructor
454490Sstever@eecs.umich.edu        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
464490Sstever@eecs.umich.edu               StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
474490Sstever@eecs.umich.edu               StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
484490Sstever@eecs.umich.edu            : AlphaStaticInst(mnem, _machInst, __opClass),
493284Srdreslin@umich.edu              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
504490Sstever@eecs.umich.edu        {
513342Srdreslin@umich.edu        }
524490Sstever@eecs.umich.edu
534490Sstever@eecs.umich.edu        std::string
544490Sstever@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
554490Sstever@eecs.umich.edu
564490Sstever@eecs.umich.edu      public:
574490Sstever@eecs.umich.edu
583342Srdreslin@umich.edu        const StaticInstPtr<AlphaISA> &eaCompInst() const { return eaCompPtr; }
593296Ssaidi@eecs.umich.edu        const StaticInstPtr<AlphaISA> &memAccInst() const { return memAccPtr; }
603091Sstever@eecs.umich.edu    };
613091Sstever@eecs.umich.edu
623091Sstever@eecs.umich.edu    /**
633349Sbinkertn@umich.edu     * Base class for memory-format instructions using a 32-bit
643091Sstever@eecs.umich.edu     * displacement (i.e. most of them).
653091Sstever@eecs.umich.edu     */
663091Sstever@eecs.umich.edu    class MemoryDisp32 : public Memory
673091Sstever@eecs.umich.edu    {
683091Sstever@eecs.umich.edu      protected:
693091Sstever@eecs.umich.edu        /// Displacement for EA calculation (signed).
704626Sstever@eecs.umich.edu        int32_t disp;
714626Sstever@eecs.umich.edu
724670Sstever@eecs.umich.edu        /// Constructor.
734670Sstever@eecs.umich.edu        MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass,
744670Sstever@eecs.umich.edu                     StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
754670Sstever@eecs.umich.edu                     StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
764670Sstever@eecs.umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
774670Sstever@eecs.umich.edu              disp(MEMDISP)
784670Sstever@eecs.umich.edu        {
794670Sstever@eecs.umich.edu        }
804670Sstever@eecs.umich.edu    };
814626Sstever@eecs.umich.edu
823091Sstever@eecs.umich.edu
833175Srdreslin@umich.edu    /**
844626Sstever@eecs.umich.edu     * Base class for a few miscellaneous memory-format insts
854670Sstever@eecs.umich.edu     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
864670Sstever@eecs.umich.edu     * None of these instructions has a destination register either.
874626Sstever@eecs.umich.edu     */
884626Sstever@eecs.umich.edu    class MemoryNoDisp : public Memory
894493Sstever@eecs.umich.edu    {
904626Sstever@eecs.umich.edu      protected:
914490Sstever@eecs.umich.edu        /// Constructor
924490Sstever@eecs.umich.edu        MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass,
933309Srdreslin@umich.edu                     StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
944670Sstever@eecs.umich.edu                     StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
953091Sstever@eecs.umich.edu            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
963091Sstever@eecs.umich.edu        {
973091Sstever@eecs.umich.edu        }
982914Ssaidi@eecs.umich.edu
992914Ssaidi@eecs.umich.edu        std::string
1004492Sstever@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1013403Ssaidi@eecs.umich.edu    };
1024492Sstever@eecs.umich.edu}};
1034492Sstever@eecs.umich.edu
1043450Ssaidi@eecs.umich.edu
1054666Sstever@eecs.umich.eduoutput decoder {{
1064666Sstever@eecs.umich.edu    std::string
1074666Sstever@eecs.umich.edu    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1084666Sstever@eecs.umich.edu    {
1094666Sstever@eecs.umich.edu        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
1104666Sstever@eecs.umich.edu                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
1114666Sstever@eecs.umich.edu    }
1124666Sstever@eecs.umich.edu
1134666Sstever@eecs.umich.edu    std::string
1144666Sstever@eecs.umich.edu    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1154666Sstever@eecs.umich.edu    {
1164666Sstever@eecs.umich.edu        return csprintf("%-10s (r%d)", mnemonic, RB);
1174666Sstever@eecs.umich.edu    }
1184492Sstever@eecs.umich.edu}};
1193450Ssaidi@eecs.umich.edu
1203403Ssaidi@eecs.umich.edudef format LoadAddress(code) {{
1213450Ssaidi@eecs.umich.edu    iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
1224666Sstever@eecs.umich.edu    header_output = BasicDeclare.subst(iop)
1234490Sstever@eecs.umich.edu    decoder_output = BasicConstructor.subst(iop)
1244666Sstever@eecs.umich.edu    decode_block = BasicDecode.subst(iop)
1254490Sstever@eecs.umich.edu    exec_output = BasicExecute.subst(iop)
1263450Ssaidi@eecs.umich.edu}};
1274492Sstever@eecs.umich.edu
1284492Sstever@eecs.umich.edu
1294492Sstever@eecs.umich.edudef template LoadStoreDeclare {{
1304492Sstever@eecs.umich.edu    /**
1313610Srdreslin@umich.edu     * Static instruction class for "%(mnemonic)s".
1323450Ssaidi@eecs.umich.edu     */
1334492Sstever@eecs.umich.edu    class %(class_name)s : public %(base_class)s
1343403Ssaidi@eecs.umich.edu    {
1353403Ssaidi@eecs.umich.edu      protected:
1364492Sstever@eecs.umich.edu
1373403Ssaidi@eecs.umich.edu        /**
1384492Sstever@eecs.umich.edu         * "Fake" effective address computation class for "%(mnemonic)s".
1392914Ssaidi@eecs.umich.edu         */
1404492Sstever@eecs.umich.edu        class EAComp : public %(base_class)s
1414492Sstever@eecs.umich.edu        {
1424492Sstever@eecs.umich.edu          public:
1434492Sstever@eecs.umich.edu            /// Constructor
1443403Ssaidi@eecs.umich.edu            EAComp(MachInst machInst);
1454490Sstever@eecs.umich.edu
1464490Sstever@eecs.umich.edu            %(BasicExecDeclare)s
1474490Sstever@eecs.umich.edu        };
1484490Sstever@eecs.umich.edu
1493263Srdreslin@umich.edu        /**
1504492Sstever@eecs.umich.edu         * "Fake" memory access instruction class for "%(mnemonic)s".
1514490Sstever@eecs.umich.edu         */
1524490Sstever@eecs.umich.edu        class MemAcc : public %(base_class)s
1534490Sstever@eecs.umich.edu        {
1543091Sstever@eecs.umich.edu          public:
1553091Sstever@eecs.umich.edu            /// Constructor
1564492Sstever@eecs.umich.edu            MemAcc(MachInst machInst);
1574492Sstever@eecs.umich.edu
1584492Sstever@eecs.umich.edu            %(BasicExecDeclare)s
1594492Sstever@eecs.umich.edu        };
1604492Sstever@eecs.umich.edu
1614492Sstever@eecs.umich.edu      public:
1624492Sstever@eecs.umich.edu
1634492Sstever@eecs.umich.edu        /// Constructor.
1644492Sstever@eecs.umich.edu        %(class_name)s(MachInst machInst);
1654492Sstever@eecs.umich.edu
1664492Sstever@eecs.umich.edu        %(BasicExecDeclare)s
1674492Sstever@eecs.umich.edu    };
1684492Sstever@eecs.umich.edu}};
1694492Sstever@eecs.umich.edu
1704492Sstever@eecs.umich.edudef template LoadStoreConstructor {{
1714492Sstever@eecs.umich.edu    /** TODO: change op_class to AddrGenOp or something (requires
1724492Sstever@eecs.umich.edu     * creating new member of OpClass enum in op_class.hh, updating
1734492Sstever@eecs.umich.edu     * config files, etc.). */
1744492Sstever@eecs.umich.edu    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
1754492Sstever@eecs.umich.edu        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
1764492Sstever@eecs.umich.edu    {
1774492Sstever@eecs.umich.edu        %(ea_constructor)s;
1784492Sstever@eecs.umich.edu    }
1792914Ssaidi@eecs.umich.edu
1802914Ssaidi@eecs.umich.edu    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
1812914Ssaidi@eecs.umich.edu        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
1822914Ssaidi@eecs.umich.edu    {
1832914Ssaidi@eecs.umich.edu        %(memacc_constructor)s;
1842914Ssaidi@eecs.umich.edu    }
1853403Ssaidi@eecs.umich.edu
1862914Ssaidi@eecs.umich.edu    inline %(class_name)s::%(class_name)s(MachInst machInst)
1872914Ssaidi@eecs.umich.edu         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1882914Ssaidi@eecs.umich.edu                          new EAComp(machInst), new MemAcc(machInst))
1892914Ssaidi@eecs.umich.edu    {
190        %(constructor)s;
191    }
192}};
193
194
195def template EACompExecute {{
196    Fault
197    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
198                                   Trace::InstRecord *traceData) const
199    {
200        Addr EA;
201        Fault fault = No_Fault;
202
203        %(fp_enable_check)s;
204        %(op_decl)s;
205        %(op_rd)s;
206        %(code)s;
207
208        if (fault == No_Fault) {
209            %(op_wb)s;
210            xc->setEA(EA);
211        }
212
213        return fault;
214    }
215}};
216
217def template LoadMemAccExecute {{
218    Fault
219    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
220                                   Trace::InstRecord *traceData) const
221    {
222        Addr EA;
223        Fault fault = No_Fault;
224
225        %(fp_enable_check)s;
226        %(op_decl)s;
227        %(op_rd)s;
228        EA = xc->getEA();
229
230        if (fault == No_Fault) {
231            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
232            %(code)s;
233        }
234
235        if (fault == No_Fault) {
236            %(op_wb)s;
237        }
238
239        return fault;
240    }
241}};
242
243
244def template LoadExecute {{
245    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
246                                  Trace::InstRecord *traceData) const
247    {
248        Addr EA;
249        Fault fault = No_Fault;
250
251        %(fp_enable_check)s;
252        %(op_decl)s;
253        %(op_rd)s;
254        %(ea_code)s;
255
256        if (fault == No_Fault) {
257            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
258            %(memacc_code)s;
259        }
260
261        if (fault == No_Fault) {
262            %(op_wb)s;
263        }
264
265        return fault;
266    }
267}};
268
269
270def template StoreMemAccExecute {{
271    Fault
272    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
273                                   Trace::InstRecord *traceData) const
274    {
275        Addr EA;
276        Fault fault = No_Fault;
277        uint64_t write_result = 0;
278
279        %(fp_enable_check)s;
280        %(op_decl)s;
281        %(op_rd)s;
282        EA = xc->getEA();
283
284        if (fault == No_Fault) {
285            %(code)s;
286        }
287
288        if (fault == No_Fault) {
289            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
290                              memAccessFlags, &write_result);
291            if (traceData) { traceData->setData(Mem); }
292        }
293
294        if (fault == No_Fault) {
295            %(postacc_code)s;
296        }
297
298        if (fault == No_Fault) {
299            %(op_wb)s;
300        }
301
302        return fault;
303    }
304}};
305
306
307def template StoreExecute {{
308    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
309                                  Trace::InstRecord *traceData) const
310    {
311        Addr EA;
312        Fault fault = No_Fault;
313        uint64_t write_result = 0;
314
315        %(fp_enable_check)s;
316        %(op_decl)s;
317        %(op_rd)s;
318        %(ea_code)s;
319
320        if (fault == No_Fault) {
321            %(memacc_code)s;
322        }
323
324        if (fault == No_Fault) {
325            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
326                              memAccessFlags, &write_result);
327            if (traceData) { traceData->setData(Mem); }
328        }
329
330        if (fault == No_Fault) {
331            %(postacc_code)s;
332        }
333
334        if (fault == No_Fault) {
335            %(op_wb)s;
336        }
337
338        return fault;
339    }
340}};
341
342
343def template MiscMemAccExecute {{
344    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
345                                          Trace::InstRecord *traceData) const
346    {
347        Addr EA;
348        Fault fault = No_Fault;
349
350        %(fp_enable_check)s;
351        %(op_decl)s;
352        %(op_rd)s;
353        EA = xc->getEA();
354
355        if (fault == No_Fault) {
356            %(code)s;
357        }
358
359        return No_Fault;
360    }
361}};
362
363def template MiscExecute {{
364    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
365                                  Trace::InstRecord *traceData) const
366    {
367        Addr EA;
368        Fault fault = No_Fault;
369
370        %(fp_enable_check)s;
371        %(op_decl)s;
372        %(op_rd)s;
373        %(ea_code)s;
374
375        if (fault == No_Fault) {
376            %(memacc_code)s;
377        }
378
379        return No_Fault;
380    }
381}};
382
383// load instructions use Ra as dest, so check for
384// Ra == 31 to detect nops
385def template LoadNopCheckDecode {{
386 {
387     AlphaStaticInst *i = new %(class_name)s(machInst);
388     if (RA == 31) {
389         i = makeNop(i);
390     }
391     return i;
392 }
393}};
394
395
396// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
397def template LoadPrefetchCheckDecode {{
398 {
399     if (RA != 31) {
400         return new %(class_name)s(machInst);
401     }
402     else {
403         return new %(class_name)sPrefetch(machInst);
404     }
405 }
406}};
407
408
409let {{
410def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '',
411                  base_class = 'MemoryDisp32', flags = [],
412                  decode_template = BasicDecode, exec_template_base = ''):
413    # Segregate flags into instruction flags (handled by InstObjParams)
414    # and memory access flags (handled here).
415
416    # Would be nice to autogenerate this list, but oh well.
417    valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE']
418    mem_flags =  [f for f in flags if f in valid_mem_flags]
419    inst_flags = [f for f in flags if f not in valid_mem_flags]
420
421    # add hook to get effective addresses into execution trace output.
422    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
423
424    # generate code block objects
425    ea_cblk = CodeBlock(ea_code)
426    memacc_cblk = CodeBlock(memacc_code)
427    postacc_cblk = CodeBlock(postacc_code)
428
429    # Some CPU models execute the memory operation as an atomic unit,
430    # while others want to separate them into an effective address
431    # computation and a memory access operation.  As a result, we need
432    # to generate three StaticInst objects.  Note that the latter two
433    # are nested inside the larger "atomic" one.
434
435    # generate InstObjParams for EAComp object
436    ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
437
438    # generate InstObjParams for MemAcc object
439    memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
440    # in the split execution model, the MemAcc portion is responsible
441    # for the post-access code.
442    memacc_iop.postacc_code = postacc_cblk.code
443
444    # generate InstObjParams for unified execution
445    cblk = CodeBlock(ea_code + memacc_code + postacc_code)
446    iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
447
448    iop.ea_constructor = ea_cblk.constructor
449    iop.ea_code = ea_cblk.code
450    iop.memacc_constructor = memacc_cblk.constructor
451    iop.memacc_code = memacc_cblk.code
452    iop.postacc_code = postacc_cblk.code
453
454    if mem_flags:
455        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
456        iop.constructor += s
457        memacc_iop.constructor += s
458
459    # select templates
460    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
461    fullExecTemplate = eval(exec_template_base + 'Execute')
462
463    # (header_output, decoder_output, decode_block, exec_output)
464    return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
465            decode_template.subst(iop),
466            EACompExecute.subst(ea_iop)
467            + memAccExecTemplate.subst(memacc_iop)
468            + fullExecTemplate.subst(iop))
469}};
470
471
472def format LoadOrNop(ea_code, memacc_code, *flags) {{
473    (header_output, decoder_output, decode_block, exec_output) = \
474        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,
475                      decode_template = LoadNopCheckDecode,
476                      exec_template_base = 'Load')
477}};
478
479
480// Note that the flags passed in apply only to the prefetch version
481def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{
482    # declare the load instruction object and generate the decode block
483    (header_output, decoder_output, decode_block, exec_output) = \
484        LoadStoreBase(name, Name, ea_code, memacc_code,
485                      decode_template = LoadPrefetchCheckDecode,
486                      exec_template_base = 'Load')
487
488    # Declare the prefetch instruction object.
489
490    # convert flags from tuple to list to make them mutable
491    pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT']
492
493    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
494        LoadStoreBase(name, Name + 'Prefetch', ea_code,
495                      'xc->prefetch(EA, memAccessFlags);',
496                      flags = pf_flags, exec_template_base = 'Misc')
497
498    header_output += pf_header_output
499    decoder_output += pf_decoder_output
500    exec_output += pf_exec_output
501}};
502
503
504def format Store(ea_code, memacc_code, *flags) {{
505    (header_output, decoder_output, decode_block, exec_output) = \
506        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,
507                      exec_template_base = 'Store')
508}};
509
510
511def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{
512    (header_output, decoder_output, decode_block, exec_output) = \
513        LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code,
514                      flags = flags, exec_template_base = 'Store')
515}};
516
517
518// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
519def format MiscPrefetch(ea_code, memacc_code, *flags) {{
520    (header_output, decoder_output, decode_block, exec_output) = \
521        LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags,
522                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
523}};
524
525
526