mem.isa revision 6179:83693f4b79fd
1// -*- mode:c++ -*-
2
3// Copyright (c) 2003-2005 The Regents of The University of Michigan
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Steve Reinhardt
30//          Kevin Lim
31
32////////////////////////////////////////////////////////////////////
33//
34// Memory-format instructions: LoadAddress, Load, Store
35//
36
37output header {{
38    /**
39     * Base class for general Alpha memory-format instructions.
40     */
41    class Memory : public AlphaStaticInst
42    {
43      protected:
44
45        /// Memory request flags.  See mem_req_base.hh.
46        Request::Flags memAccessFlags;
47        /// Pointer to EAComp object.
48        const StaticInstPtr eaCompPtr;
49        /// Pointer to MemAcc object.
50        const StaticInstPtr memAccPtr;
51
52        /// Constructor
53        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
54               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
55               StaticInstPtr _memAccPtr = nullStaticInstPtr)
56            : AlphaStaticInst(mnem, _machInst, __opClass),
57              eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
58        {
59        }
60
61        std::string
62        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
63
64      public:
65
66        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
67        const StaticInstPtr &memAccInst() const { return memAccPtr; }
68
69        Request::Flags memAccFlags() { return memAccessFlags; }
70    };
71
72    /**
73     * Base class for memory-format instructions using a 32-bit
74     * displacement (i.e. most of them).
75     */
76    class MemoryDisp32 : public Memory
77    {
78      protected:
79        /// Displacement for EA calculation (signed).
80        int32_t disp;
81
82        /// Constructor.
83        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
84                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
85                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
86            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
87              disp(MEMDISP)
88        {
89        }
90    };
91
92
93    /**
94     * Base class for a few miscellaneous memory-format insts
95     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
96     * None of these instructions has a destination register either.
97     */
98    class MemoryNoDisp : public Memory
99    {
100      protected:
101        /// Constructor
102        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
103                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
104                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
105            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
106        {
107        }
108
109        std::string
110        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
111    };
112}};
113
114
115output decoder {{
116    std::string
117    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
118    {
119        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
120                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
121    }
122
123    std::string
124    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
125    {
126        return csprintf("%-10s (r%d)", mnemonic, RB);
127    }
128}};
129
130def format LoadAddress(code) {{
131    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
132    header_output = BasicDeclare.subst(iop)
133    decoder_output = BasicConstructor.subst(iop)
134    decode_block = BasicDecode.subst(iop)
135    exec_output = BasicExecute.subst(iop)
136}};
137
138
139def template LoadStoreDeclare {{
140    /**
141     * Static instruction class for "%(mnemonic)s".
142     */
143    class %(class_name)s : public %(base_class)s
144    {
145      protected:
146
147        /**
148         * "Fake" effective address computation class for "%(mnemonic)s".
149         */
150        class EAComp : public %(base_class)s
151        {
152          public:
153            /// Constructor
154            EAComp(ExtMachInst machInst);
155
156            %(BasicExecDeclare)s
157        };
158
159        /**
160         * "Fake" memory access instruction class for "%(mnemonic)s".
161         */
162        class MemAcc : public %(base_class)s
163        {
164          public:
165            /// Constructor
166            MemAcc(ExtMachInst machInst);
167
168            %(BasicExecDeclare)s
169        };
170
171      public:
172
173        /// Constructor.
174        %(class_name)s(ExtMachInst machInst);
175
176        %(BasicExecDeclare)s
177
178        %(InitiateAccDeclare)s
179
180        %(CompleteAccDeclare)s
181
182        %(MemAccSizeDeclare)s
183    };
184}};
185
186
187def template InitiateAccDeclare {{
188    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
189}};
190
191
192def template CompleteAccDeclare {{
193    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
194                      Trace::InstRecord *) const;
195}};
196
197def template MemAccSizeDeclare {{
198    int memAccSize(%(CPU_exec_context)s *xc);
199}};
200
201def template MiscMemAccSize {{
202    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
203    {
204        panic("Misc instruction does not support split access method!");
205        return 0;
206    }
207}};
208
209def template LoadStoreMemAccSize {{
210    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
211    {
212        // Return the memory access size in bytes
213        return (%(mem_acc_size)d / 8);
214    }
215}};
216
217def template EACompConstructor {{
218    /** TODO: change op_class to AddrGenOp or something (requires
219     * creating new member of OpClass enum in op_class.hh, updating
220     * config files, etc.). */
221    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
222        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
223    {
224        %(constructor)s;
225    }
226}};
227
228
229def template MemAccConstructor {{
230    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
231        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
232    {
233        %(constructor)s;
234    }
235}};
236
237
238def template LoadStoreConstructor {{
239    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
240         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
241                          new EAComp(machInst), new MemAcc(machInst))
242    {
243        %(constructor)s;
244    }
245}};
246
247
248def template EACompExecute {{
249    Fault
250    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
251                                   Trace::InstRecord *traceData) const
252    {
253        Addr EA;
254        Fault fault = NoFault;
255
256        %(fp_enable_check)s;
257        %(op_decl)s;
258        %(op_rd)s;
259        %(ea_code)s;
260
261        if (fault == NoFault) {
262            %(op_wb)s;
263            xc->setEA(EA);
264        }
265
266        return fault;
267    }
268}};
269
270def template LoadMemAccExecute {{
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 = NoFault;
277
278        %(fp_enable_check)s;
279        %(op_decl)s;
280        %(op_rd)s;
281        EA = xc->getEA();
282
283        if (fault == NoFault) {
284            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
285            %(memacc_code)s;
286        }
287
288        if (fault == NoFault) {
289            %(op_wb)s;
290        }
291
292        return fault;
293    }
294}};
295
296
297def template LoadExecute {{
298    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
299                                  Trace::InstRecord *traceData) const
300    {
301        Addr EA;
302        Fault fault = NoFault;
303
304        %(fp_enable_check)s;
305        %(op_decl)s;
306        %(op_rd)s;
307        %(ea_code)s;
308
309        if (fault == NoFault) {
310            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
311            %(memacc_code)s;
312        }
313
314        if (fault == NoFault) {
315            %(op_wb)s;
316        }
317
318        return fault;
319    }
320}};
321
322
323def template LoadInitiateAcc {{
324    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
325                                      Trace::InstRecord *traceData) const
326    {
327        Addr EA;
328        Fault fault = NoFault;
329
330        %(fp_enable_check)s;
331        %(op_src_decl)s;
332        %(op_rd)s;
333        %(ea_code)s;
334
335        if (fault == NoFault) {
336            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
337        }
338
339        return fault;
340    }
341}};
342
343
344def template LoadCompleteAcc {{
345    Fault %(class_name)s::completeAcc(PacketPtr pkt,
346                                      %(CPU_exec_context)s *xc,
347                                      Trace::InstRecord *traceData) const
348    {
349        Fault fault = NoFault;
350
351        %(fp_enable_check)s;
352        %(op_decl)s;
353
354        Mem = pkt->get<typeof(Mem)>();
355
356        if (fault == NoFault) {
357            %(memacc_code)s;
358        }
359
360        if (fault == NoFault) {
361            %(op_wb)s;
362        }
363
364        return fault;
365    }
366}};
367
368
369def template StoreMemAccExecute {{
370    Fault
371    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
372                                   Trace::InstRecord *traceData) const
373    {
374        Addr EA;
375        Fault fault = NoFault;
376
377        %(fp_enable_check)s;
378        %(op_decl)s;
379        %(op_rd)s;
380        EA = xc->getEA();
381
382        if (fault == NoFault) {
383            %(memacc_code)s;
384        }
385
386        if (fault == NoFault) {
387            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
388                              memAccessFlags, NULL);
389            if (traceData) { traceData->setData(Mem); }
390        }
391
392        if (fault == NoFault) {
393            %(postacc_code)s;
394        }
395
396        if (fault == NoFault) {
397            %(op_wb)s;
398        }
399
400        return fault;
401    }
402}};
403
404def template StoreCondMemAccExecute {{
405    Fault
406    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
407                                   Trace::InstRecord *traceData) const
408    {
409        Addr EA;
410        Fault fault = NoFault;
411        uint64_t write_result = 0;
412
413        %(fp_enable_check)s;
414        %(op_decl)s;
415        %(op_rd)s;
416        EA = xc->getEA();
417
418        if (fault == NoFault) {
419            %(memacc_code)s;
420        }
421
422        if (fault == NoFault) {
423            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
424                              memAccessFlags, &write_result);
425            if (traceData) { traceData->setData(Mem); }
426        }
427
428        if (fault == NoFault) {
429            %(postacc_code)s;
430        }
431
432        if (fault == NoFault) {
433            %(op_wb)s;
434        }
435
436        return fault;
437    }
438}};
439
440
441def template StoreExecute {{
442    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
443                                  Trace::InstRecord *traceData) const
444    {
445        Addr EA;
446        Fault fault = NoFault;
447
448        %(fp_enable_check)s;
449        %(op_decl)s;
450        %(op_rd)s;
451        %(ea_code)s;
452
453        if (fault == NoFault) {
454            %(memacc_code)s;
455        }
456
457        if (fault == NoFault) {
458            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
459                              memAccessFlags, NULL);
460            if (traceData) { traceData->setData(Mem); }
461        }
462
463        if (fault == NoFault) {
464            %(postacc_code)s;
465        }
466
467        if (fault == NoFault) {
468            %(op_wb)s;
469        }
470
471        return fault;
472    }
473}};
474
475def template StoreCondExecute {{
476    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
477                                  Trace::InstRecord *traceData) const
478    {
479        Addr EA;
480        Fault fault = NoFault;
481        uint64_t write_result = 0;
482
483        %(fp_enable_check)s;
484        %(op_decl)s;
485        %(op_rd)s;
486        %(ea_code)s;
487
488        if (fault == NoFault) {
489            %(memacc_code)s;
490        }
491
492        if (fault == NoFault) {
493            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
494                              memAccessFlags, &write_result);
495            if (traceData) { traceData->setData(Mem); }
496        }
497
498        if (fault == NoFault) {
499            %(postacc_code)s;
500        }
501
502        if (fault == NoFault) {
503            %(op_wb)s;
504        }
505
506        return fault;
507    }
508}};
509
510def template StoreInitiateAcc {{
511    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
512                                      Trace::InstRecord *traceData) const
513    {
514        Addr EA;
515        Fault fault = NoFault;
516
517        %(fp_enable_check)s;
518        %(op_decl)s;
519        %(op_rd)s;
520        %(ea_code)s;
521
522        if (fault == NoFault) {
523            %(memacc_code)s;
524        }
525
526        if (fault == NoFault) {
527            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
528                              memAccessFlags, NULL);
529            if (traceData) { traceData->setData(Mem); }
530        }
531
532        return fault;
533    }
534}};
535
536
537def template StoreCompleteAcc {{
538    Fault %(class_name)s::completeAcc(PacketPtr pkt,
539                                      %(CPU_exec_context)s *xc,
540                                      Trace::InstRecord *traceData) const
541    {
542        Fault fault = NoFault;
543
544        %(fp_enable_check)s;
545        %(op_dest_decl)s;
546
547        if (fault == NoFault) {
548            %(postacc_code)s;
549        }
550
551        if (fault == NoFault) {
552            %(op_wb)s;
553        }
554
555        return fault;
556    }
557}};
558
559
560def template StoreCondCompleteAcc {{
561    Fault %(class_name)s::completeAcc(PacketPtr pkt,
562                                      %(CPU_exec_context)s *xc,
563                                      Trace::InstRecord *traceData) const
564    {
565        Fault fault = NoFault;
566
567        %(fp_enable_check)s;
568        %(op_dest_decl)s;
569
570        uint64_t write_result = pkt->req->getExtraData();
571
572        if (fault == NoFault) {
573            %(postacc_code)s;
574        }
575
576        if (fault == NoFault) {
577            %(op_wb)s;
578        }
579
580        return fault;
581    }
582}};
583
584
585def template MiscMemAccExecute {{
586    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
587                                          Trace::InstRecord *traceData) const
588    {
589        Addr EA;
590        Fault fault = NoFault;
591
592        %(fp_enable_check)s;
593        %(op_decl)s;
594        %(op_rd)s;
595        EA = xc->getEA();
596
597        if (fault == NoFault) {
598            %(memacc_code)s;
599        }
600
601        return NoFault;
602    }
603}};
604
605def template MiscExecute {{
606    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
607                                  Trace::InstRecord *traceData) const
608    {
609        Addr EA;
610        Fault fault = NoFault;
611
612        %(fp_enable_check)s;
613        %(op_decl)s;
614        %(op_rd)s;
615        %(ea_code)s;
616
617        if (fault == NoFault) {
618            %(memacc_code)s;
619        }
620
621        return NoFault;
622    }
623}};
624
625def template MiscInitiateAcc {{
626    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
627                                      Trace::InstRecord *traceData) const
628    {
629        warn("Misc instruction does not support split access method!");
630        return NoFault;
631    }
632}};
633
634
635def template MiscCompleteAcc {{
636    Fault %(class_name)s::completeAcc(PacketPtr pkt,
637                                      %(CPU_exec_context)s *xc,
638                                      Trace::InstRecord *traceData) const
639    {
640        warn("Misc instruction does not support split access method!");
641
642        return NoFault;
643    }
644}};
645
646def template MiscMemAccSize {{
647    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
648    {
649        panic("Misc instruction does not support split access method!");
650        return 0;
651    }
652}};
653
654// load instructions use Ra as dest, so check for
655// Ra == 31 to detect nops
656def template LoadNopCheckDecode {{
657 {
658     AlphaStaticInst *i = new %(class_name)s(machInst);
659     if (RA == 31) {
660         i = makeNop(i);
661     }
662     return i;
663 }
664}};
665
666
667// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
668def template LoadPrefetchCheckDecode {{
669 {
670     if (RA != 31) {
671         return new %(class_name)s(machInst);
672     }
673     else {
674         return new %(class_name)sPrefetch(machInst);
675     }
676 }
677}};
678
679
680let {{
681def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
682                  postacc_code = '', base_class = 'MemoryDisp32',
683                  decode_template = BasicDecode, exec_template_base = ''):
684    # Make sure flags are in lists (convert to lists if not).
685    mem_flags = makeList(mem_flags)
686    inst_flags = makeList(inst_flags)
687
688    # add hook to get effective addresses into execution trace output.
689    ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
690
691    # Some CPU models execute the memory operation as an atomic unit,
692    # while others want to separate them into an effective address
693    # computation and a memory access operation.  As a result, we need
694    # to generate three StaticInst objects.  Note that the latter two
695    # are nested inside the larger "atomic" one.
696
697    # Generate InstObjParams for each of the three objects.  Note that
698    # they differ only in the set of code objects contained (which in
699    # turn affects the object's overall operand list).
700    iop = InstObjParams(name, Name, base_class,
701                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
702                        inst_flags)
703    ea_iop = InstObjParams(name, Name, base_class,
704                        { 'ea_code':ea_code },
705                        inst_flags)
706    memacc_iop = InstObjParams(name, Name, base_class,
707                        { 'memacc_code':memacc_code, 'postacc_code':postacc_code },
708                        inst_flags)
709
710    if mem_flags:
711        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
712        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
713        iop.constructor += s
714        memacc_iop.constructor += s
715
716    # select templates
717
718    # The InitiateAcc template is the same for StoreCond templates as the
719    # corresponding Store template..
720    StoreCondInitiateAcc = StoreInitiateAcc
721
722    memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
723    fullExecTemplate = eval(exec_template_base + 'Execute')
724    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
725    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
726
727    if (exec_template_base == 'Load' or exec_template_base == 'Store'):
728      memAccSizeTemplate = eval('LoadStoreMemAccSize')
729    else:
730      memAccSizeTemplate = eval('MiscMemAccSize')
731
732    # (header_output, decoder_output, decode_block, exec_output)
733    return (LoadStoreDeclare.subst(iop),
734            EACompConstructor.subst(ea_iop)
735            + MemAccConstructor.subst(memacc_iop)
736            + LoadStoreConstructor.subst(iop),
737            decode_template.subst(iop),
738            EACompExecute.subst(ea_iop)
739            + memAccExecTemplate.subst(memacc_iop)
740            + fullExecTemplate.subst(iop)
741            + initiateAccTemplate.subst(iop)
742            + completeAccTemplate.subst(iop)
743            + memAccSizeTemplate.subst(memacc_iop))
744}};
745
746def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
747                     mem_flags = [], inst_flags = []) {{
748    (header_output, decoder_output, decode_block, exec_output) = \
749        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
750                      decode_template = LoadNopCheckDecode,
751                      exec_template_base = 'Load')
752}};
753
754
755// Note that the flags passed in apply only to the prefetch version
756def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
757                          mem_flags = [], pf_flags = [], inst_flags = []) {{
758    # declare the load instruction object and generate the decode block
759    (header_output, decoder_output, decode_block, exec_output) = \
760        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
761                      decode_template = LoadPrefetchCheckDecode,
762                      exec_template_base = 'Load')
763
764    # Declare the prefetch instruction object.
765
766    # Make sure flag args are lists so we can mess with them.
767    mem_flags = makeList(mem_flags)
768    pf_flags = makeList(pf_flags)
769    inst_flags = makeList(inst_flags)
770
771    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
772    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
773                                  'IsDataPrefetch', 'MemReadOp']
774
775    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
776        LoadStoreBase(name, Name + 'Prefetch', ea_code,
777                      'xc->prefetch(EA, memAccessFlags);',
778                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
779
780    header_output += pf_header_output
781    decoder_output += pf_decoder_output
782    exec_output += pf_exec_output
783}};
784
785
786def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
787                 mem_flags = [], inst_flags = []) {{
788    (header_output, decoder_output, decode_block, exec_output) = \
789        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
790                      exec_template_base = 'Store')
791}};
792
793
794def format StoreCond(memacc_code, postacc_code,
795                     ea_code = {{ EA = Rb + disp; }},
796                     mem_flags = [], inst_flags = []) {{
797    (header_output, decoder_output, decode_block, exec_output) = \
798        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
799                      postacc_code, exec_template_base = 'StoreCond')
800}};
801
802
803// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
804def format MiscPrefetch(ea_code, memacc_code,
805                        mem_flags = [], inst_flags = []) {{
806    (header_output, decoder_output, decode_block, exec_output) = \
807        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
808                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
809}};
810
811
812