mem.isa revision 5222:bb733a878f85
1// -*- mode:c++ -*-
2
3// Copyright .AN) 2007 MIPS Technologies, Inc.  All Rights Reserved
4
5//  This software is part of the M5 simulator.
6
7//  THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING
8//  DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
9//  TO THESE TERMS AND CONDITIONS.
10
11//  Permission is granted to use, copy, create derivative works and
12//  distribute this software and such derivative works for any purpose,
13//  so long as (1) the copyright notice above, this grant of permission,
14//  and the disclaimer below appear in all copies and derivative works
15//  made, (2) the copyright notice above is augmented as appropriate to
16//  reflect the addition of any new copyrightable work in a derivative
17//  work (e.g., Copyright .AN) <Publication Year> Copyright Owner), and (3)
18//  the name of MIPS Technologies, Inc. ($B!H(BMIPS$B!I(B) is not used in any
19//  advertising or publicity pertaining to the use or distribution of
20//  this software without specific, written prior authorization.
21
22//  THIS SOFTWARE IS PROVIDED $B!H(BAS IS.$B!I(B  MIPS MAKES NO WARRANTIES AND
23//  DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
24//  OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
26//  NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
27//  IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
28//  INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
29//  ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
30//  THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
31//  IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
32//  STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
33//  POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
34
35//Authors: Steve Reinhardt
36//         Korey L. Sewell
37
38////////////////////////////////////////////////////////////////////
39//
40// Memory-format instructions
41//
42
43output header {{
44    /**
45     * Base class for general Mips memory-format instructions.
46     */
47    class Memory : public MipsStaticInst
48    {
49      protected:
50
51        /// Memory request flags.  See mem_req_base.hh.
52        unsigned memAccessFlags;
53        /// Pointer to EAComp object.
54        const StaticInstPtr eaCompPtr;
55        /// Pointer to MemAcc object.
56        const StaticInstPtr memAccPtr;
57
58        /// Displacement for EA calculation (signed).
59        int32_t disp;
60
61        /// Constructor
62        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
63               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
64               StaticInstPtr _memAccPtr = nullStaticInstPtr)
65            : MipsStaticInst(mnem, _machInst, __opClass),
66              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
67              disp(sext<16>(OFFSET))
68        {
69        }
70
71        std::string
72        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
73
74      public:
75
76        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
77        const StaticInstPtr &memAccInst() const { return memAccPtr; }
78
79        unsigned memAccFlags() { return memAccessFlags; }
80    };
81
82     /**
83     * Base class for a few miscellaneous memory-format insts
84     * that don't interpret the disp field
85     */
86    class MemoryNoDisp : public Memory
87    {
88      protected:
89        /// Constructor
90        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
91                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
92                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
93            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
94        {
95        }
96
97        std::string
98        generateDisassembly(Addr pc, const SymbolTable *symtab) const;
99    };
100}};
101
102
103output decoder {{
104    std::string
105    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
106    {
107        return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
108                        flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
109    }
110
111    std::string
112    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
113    {
114        return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
115                        flags[IsFloating] ? 'f' : 'r',
116                        flags[IsFloating] ? FD : RD,
117                        RS, RT);
118    }
119
120}};
121
122output exec {{
123    /** return data in cases where there the size of data is only
124        known in the packet
125    */
126    uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) {
127        switch (packet->getSize())
128        {
129          case 1:
130            return packet->get<uint8_t>();
131
132          case 2:
133            return packet->get<uint16_t>();
134
135          case 4:
136            return packet->get<uint32_t>();
137
138          case 8:
139            return packet->get<uint64_t>();
140
141          default:
142            std::cerr << "bad store data size = " << packet->getSize() << std::endl;
143
144            assert(0);
145            return 0;
146        }
147    }
148
149
150}};
151
152def template LoadStoreDeclare {{
153    /**
154     * Static instruction class for "%(mnemonic)s".
155     */
156    class %(class_name)s : public %(base_class)s
157    {
158      protected:
159
160        /**
161         * "Fake" effective address computation class for "%(mnemonic)s".
162         */
163        class EAComp : public %(base_class)s
164        {
165          public:
166            /// Constructor
167            EAComp(ExtMachInst machInst);
168
169            %(BasicExecDeclare)s
170        };
171
172        /**
173         * "Fake" memory access instruction class for "%(mnemonic)s".
174         */
175        class MemAcc : public %(base_class)s
176        {
177          public:
178            /// Constructor
179            MemAcc(ExtMachInst machInst);
180
181            %(BasicExecDeclare)s
182        };
183
184      public:
185
186        /// Constructor.
187        %(class_name)s(ExtMachInst machInst);
188
189        %(BasicExecDeclare)s
190
191        %(InitiateAccDeclare)s
192
193        %(CompleteAccDeclare)s
194
195        %(MemAccSizeDeclare)s
196    };
197}};
198
199
200def template InitiateAccDeclare {{
201    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
202}};
203
204
205def template CompleteAccDeclare {{
206    Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
207}};
208
209def template MemAccSizeDeclare {{
210    int memAccSize(%(CPU_exec_context)s *xc);
211}};
212
213
214def template MiscMemAccSize {{
215    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
216    {
217        panic("Misc instruction does not support split access method!");
218        return 0;
219    }
220}};
221
222def template EACompConstructor {{
223    /** TODO: change op_class to AddrGenOp or something (requires
224     * creating new member of OpClass enum in op_class.hh, updating
225     * config files, etc.). */
226    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
227        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
228    {
229        %(constructor)s;
230    }
231}};
232
233
234def template MemAccConstructor {{
235    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
236        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
237    {
238        %(constructor)s;
239    }
240}};
241
242
243def template LoadStoreConstructor {{
244    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
245         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
246                          new EAComp(machInst), new MemAcc(machInst))
247    {
248        %(constructor)s;
249    }
250}};
251
252
253def template EACompExecute {{
254    Fault
255    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
256                                   Trace::InstRecord *traceData) const
257    {
258        Addr EA;
259        Fault fault = NoFault;
260
261        if (this->isFloating()) {
262            %(fp_enable_check)s;
263
264            if(fault != NoFault)
265                return fault;
266        }
267
268        %(op_decl)s;
269        %(op_rd)s;
270        %(ea_code)s;
271
272        // NOTE: Trace Data is written using execute or completeAcc templates
273        if (fault == NoFault) {
274            xc->setEA(EA);
275        }
276
277        return fault;
278    }
279}};
280
281def template LoadStoreFPEACompExecute {{
282    Fault
283    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
284                                   Trace::InstRecord *traceData) const
285    {
286        Addr EA;
287        Fault fault = NoFault;
288
289        %(fp_enable_check)s;
290        if(fault != NoFault)
291          return fault;
292        %(op_decl)s;
293        %(op_rd)s;
294        %(ea_code)s;
295
296        // NOTE: Trace Data is written using execute or completeAcc templates
297        if (fault == NoFault) {
298            xc->setEA(EA);
299        }
300
301        return fault;
302    }
303}};
304
305
306def template LoadMemAccExecute {{
307    Fault
308    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
309                                   Trace::InstRecord *traceData) const
310    {
311        Addr EA;
312
313        Fault fault = NoFault;
314
315        if (this->isFloating()) {
316            %(fp_enable_check)s;
317
318            if(fault != NoFault)
319                return fault;
320        }
321
322        %(op_decl)s;
323        %(op_rd)s;
324
325        EA = xc->getEA();
326
327        fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
328
329        %(memacc_code)s;
330
331        // NOTE: Write back data using execute or completeAcc templates
332
333        return fault;
334    }
335}};
336
337
338def template LoadExecute {{
339    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
340                                  Trace::InstRecord *traceData) const
341    {
342        Addr EA;
343        Fault fault = NoFault;
344
345        if (this->isFloating()) {
346            %(fp_enable_check)s;
347
348            if(fault != NoFault)
349                return fault;
350        }
351
352        %(op_decl)s;
353        %(op_rd)s;
354        %(ea_code)s;
355
356        if (fault == NoFault) {
357            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
358            %(memacc_code)s;
359        }
360
361        if (fault == NoFault) {
362            %(op_wb)s;
363        }
364
365        return fault;
366    }
367}};
368
369
370def template LoadInitiateAcc {{
371    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
372                                      Trace::InstRecord *traceData) const
373    {
374        Addr EA;
375        Fault fault = NoFault;
376
377        if (this->isFloating()) {
378            %(fp_enable_check)s;
379
380            if(fault != NoFault)
381                return fault;
382        }
383
384        %(op_src_decl)s;
385        %(op_rd)s;
386        %(ea_code)s;
387
388        if (fault == NoFault) {
389            fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
390        }
391
392        return fault;
393    }
394}};
395
396def template LoadCompleteAcc {{
397    Fault %(class_name)s::completeAcc(Packet *pkt,
398                                      %(CPU_exec_context)s *xc,
399                                      Trace::InstRecord *traceData) const
400    {
401        Fault fault = NoFault;
402
403        if (this->isFloating()) {
404            %(fp_enable_check)s;
405
406            if(fault != NoFault)
407                return fault;
408        }
409
410        %(op_decl)s;
411        %(op_rd)s;
412
413        Mem = pkt->get<typeof(Mem)>();
414
415        if (fault == NoFault) {
416            %(memacc_code)s;
417        }
418
419        if (fault == NoFault) {
420            %(op_wb)s;
421        }
422
423        return fault;
424    }
425}};
426
427
428def template LoadStoreMemAccSize {{
429    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
430    {
431        // Return the memory access size in bytes
432        return (%(mem_acc_size)d / 8);
433    }
434}};
435
436def template StoreMemAccExecute {{
437    Fault
438    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
439                                   Trace::InstRecord *traceData) const
440    {
441        Addr EA;
442        Fault fault = NoFault;
443
444        %(fp_enable_check)s;
445        %(op_decl)s;
446        %(op_rd)s;
447
448        EA = xc->getEA();
449
450        if (fault == NoFault) {
451            %(memacc_code)s;
452        }
453
454        if (fault == NoFault) {
455            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
456                              memAccessFlags, NULL);
457            // @NOTE: Need to Call Complete Access to Set Trace Data
458            //if (traceData) { traceData->setData(Mem); }
459        }
460
461        return fault;
462    }
463}};
464
465def template StoreCondMemAccExecute {{
466    Fault
467    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
468                                   Trace::InstRecord *traceData) const
469    {
470        Addr EA;
471        Fault fault = NoFault;
472        uint64_t write_result = 0;
473
474        %(fp_enable_check)s;
475        %(op_decl)s;
476        %(op_rd)s;
477        EA = xc->getEA();
478
479        if (fault == NoFault) {
480            %(memacc_code)s;
481        }
482
483        if (fault == NoFault) {
484            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
485                              memAccessFlags, &write_result);
486            if (traceData) { traceData->setData(Mem); }
487        }
488
489        if (fault == NoFault) {
490            %(postacc_code)s;
491        }
492
493        if (fault == NoFault) {
494            %(op_wb)s;
495        }
496
497        return fault;
498    }
499}};
500
501def template StoreExecute {{
502    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
503                                  Trace::InstRecord *traceData) const
504    {
505        Addr EA;
506        Fault fault = NoFault;
507
508        %(fp_enable_check)s;
509        %(op_decl)s;
510        %(op_rd)s;
511        %(ea_code)s;
512
513        if (fault == NoFault) {
514            %(memacc_code)s;
515        }
516
517        if (fault == NoFault) {
518            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
519                              memAccessFlags, NULL);
520            if (traceData) { traceData->setData(Mem); }
521        }
522
523        if (fault == NoFault) {
524            %(postacc_code)s;
525        }
526
527        if (fault == NoFault) {
528            %(op_wb)s;
529        }
530
531        return fault;
532    }
533}};
534
535
536def template StoreFPExecute {{
537    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
538                                  Trace::InstRecord *traceData) const
539    {
540        Addr EA;
541        Fault fault = NoFault;
542
543        %(fp_enable_check)s;
544        if(fault != NoFault)
545          return fault;
546        %(op_decl)s;
547        %(op_rd)s;
548        %(ea_code)s;
549
550        if (fault == NoFault) {
551            %(memacc_code)s;
552        }
553
554        if (fault == NoFault) {
555            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
556                              memAccessFlags, NULL);
557            if (traceData) { traceData->setData(Mem); }
558        }
559
560        if (fault == NoFault) {
561            %(postacc_code)s;
562        }
563
564        if (fault == NoFault) {
565            %(op_wb)s;
566        }
567
568        return fault;
569    }
570}};
571
572def template StoreCondExecute {{
573    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
574                                  Trace::InstRecord *traceData) const
575    {
576        Addr EA;
577        Fault fault = NoFault;
578        uint64_t write_result = 0;
579
580        %(fp_enable_check)s;
581        %(op_decl)s;
582        %(op_rd)s;
583        %(ea_code)s;
584
585        if (fault == NoFault) {
586            %(memacc_code)s;
587        }
588
589        if (fault == NoFault) {
590            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
591                              memAccessFlags, &write_result);
592            if (traceData) { traceData->setData(Mem); }
593        }
594
595        if (fault == NoFault) {
596            %(postacc_code)s;
597        }
598
599        if (fault == NoFault) {
600            %(op_wb)s;
601        }
602
603        return fault;
604    }
605}};
606
607def template StoreInitiateAcc {{
608    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
609                                      Trace::InstRecord *traceData) const
610    {
611        Addr EA;
612        Fault fault = NoFault;
613
614        %(fp_enable_check)s;
615        %(op_decl)s;
616        %(op_rd)s;
617        %(ea_code)s;
618
619        if (fault == NoFault) {
620            %(memacc_code)s;
621        }
622
623        if (fault == NoFault) {
624            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
625                              memAccessFlags, NULL);
626            if (traceData) { traceData->setData(Mem); }
627        }
628
629        return fault;
630    }
631}};
632
633
634def template StoreCompleteAcc {{
635    Fault %(class_name)s::completeAcc(Packet *pkt,
636                                      %(CPU_exec_context)s *xc,
637                                      Trace::InstRecord *traceData) const
638    {
639        Fault fault = NoFault;
640
641        %(fp_enable_check)s;
642        %(op_dest_decl)s;
643
644        if (fault == NoFault) {
645            %(postacc_code)s;
646        }
647
648        if (fault == NoFault) {
649            %(op_wb)s;
650
651            if (traceData) { traceData->setData(getMemData(xc, pkt)); }
652        }
653
654        return fault;
655    }
656}};
657
658
659def template StoreCompleteAcc {{
660    Fault %(class_name)s::completeAcc(Packet *pkt,
661                                      %(CPU_exec_context)s *xc,
662                                      Trace::InstRecord *traceData) const
663    {
664        Fault fault = NoFault;
665
666        %(op_dest_decl)s;
667
668        if (fault == NoFault) {
669            %(postacc_code)s;
670        }
671
672        if (fault == NoFault) {
673            %(op_wb)s;
674
675            if (traceData) { traceData->setData(getMemData(xc, pkt)); }
676        }
677
678        return fault;
679    }
680}};
681
682def template StoreCondCompleteAcc {{
683    Fault %(class_name)s::completeAcc(Packet *pkt,
684                                      %(CPU_exec_context)s *xc,
685                                      Trace::InstRecord *traceData) const
686    {
687        Fault fault = NoFault;
688
689        %(fp_enable_check)s;
690        %(op_dest_decl)s;
691
692        uint64_t write_result = pkt->req->getExtraData();
693
694        if (fault == NoFault) {
695            %(postacc_code)s;
696        }
697
698        if (fault == NoFault) {
699            %(op_wb)s;
700        }
701
702        return fault;
703    }
704}};
705
706
707def template MiscMemAccExecute {{
708    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
709                                          Trace::InstRecord *traceData) const
710    {
711        Addr EA;
712        Fault fault = NoFault;
713
714        %(fp_enable_check)s;
715        %(op_decl)s;
716        %(op_rd)s;
717        EA = xc->getEA();
718
719        if (fault == NoFault) {
720            %(memacc_code)s;
721        }
722
723        return NoFault;
724    }
725}};
726
727def template MiscExecute {{
728    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
729                                  Trace::InstRecord *traceData) const
730    {
731        Addr EA;
732        Fault fault = NoFault;
733
734        %(fp_enable_check)s;
735        %(op_decl)s;
736        %(op_rd)s;
737        %(ea_code)s;
738
739        if (fault == NoFault) {
740            %(memacc_code)s;
741        }
742
743        return NoFault;
744    }
745}};
746
747def template MiscInitiateAcc {{
748    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
749                                      Trace::InstRecord *traceData) const
750    {
751        panic("Misc instruction does not support split access method!");
752        return NoFault;
753    }
754}};
755
756
757def template MiscCompleteAcc {{
758    Fault %(class_name)s::completeAcc(Packet *pkt,
759                                      %(CPU_exec_context)s *xc,
760                                      Trace::InstRecord *traceData) const
761    {
762        panic("Misc instruction does not support split access method!");
763
764        return NoFault;
765    }
766}};
767
768
769def template MiscMemAccSize {{
770    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
771    {
772        panic("Misc instruction does not support split access method!");
773        return 0;
774    }
775}};
776
777def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
778                     mem_flags = [], inst_flags = []) {{
779    (header_output, decoder_output, decode_block, exec_output) = \
780        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
781                      decode_template = ImmNopCheckDecode,
782                      exec_template_base = 'Load')
783}};
784
785
786def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + 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
793def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
794                     mem_flags = [], inst_flags = []) {{
795    inst_flags += ['IsIndexed']
796    (header_output, decoder_output, decode_block, exec_output) = \
797        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
798                      decode_template = ImmNopCheckDecode,
799                      exec_template_base = 'Load')
800}};
801
802def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
803                     mem_flags = [], inst_flags = []) {{
804    inst_flags += ['IsIndexed']
805    (header_output, decoder_output, decode_block, exec_output) = \
806        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
807                      exec_template_base = 'Store')
808}};
809
810def format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
811                     mem_flags = [], inst_flags = []) {{
812    inst_flags += ['IsIndexed', 'IsFloating']
813    (header_output, decoder_output, decode_block, exec_output) = \
814        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
815                      decode_template = ImmNopCheckDecode,
816                      exec_template_base = 'Load')
817}};
818
819def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
820                     mem_flags = [], inst_flags = []) {{
821    inst_flags += ['IsIndexed', 'IsFloating']
822    (header_output, decoder_output, decode_block, exec_output) = \
823        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
824                      exec_template_base = 'Store')
825}};
826
827
828def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
829                     mem_flags = [], inst_flags = []) {{
830    decl_code = 'uint32_t mem_word = Mem.uw;\n'
831    decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
832    decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
833    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
834    decl_code += '\tbyte_offset ^= 3;\n'
835    decl_code += '#endif\n'
836
837    memacc_code = decl_code + memacc_code
838
839    (header_output, decoder_output, decode_block, exec_output) = \
840        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
841                      decode_template = ImmNopCheckDecode,
842                      exec_template_base = 'Load')
843}};
844
845def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
846                     mem_flags = [], inst_flags = []) {{
847    decl_code = 'uint32_t mem_word = 0;\n'
848    decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
849    decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
850    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
851    decl_code += '\tbyte_offset ^= 3;\n'
852    decl_code += '#endif\n'
853    decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
854    #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
855    memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
856
857    (header_output, decoder_output, decode_block, exec_output) = \
858        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
859                      exec_template_base = 'Store')
860}};
861
862def format Prefetch(ea_code = {{ EA = Rs + disp; }},
863                          mem_flags = [], pf_flags = [], inst_flags = []) {{
864    pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
865    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
866                                  'IsDataPrefetch', 'MemReadOp']
867
868    (header_output, decoder_output, decode_block, exec_output) = \
869        LoadStoreBase(name, Name, ea_code,
870                      'xc->prefetch(EA, memAccessFlags);',
871                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
872
873}};
874
875def format StoreCond(memacc_code, postacc_code,
876                     ea_code = {{ EA = Rs + disp; }},
877                     mem_flags = [], inst_flags = []) {{
878    (header_output, decoder_output, decode_block, exec_output) = \
879        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
880                      postacc_code, exec_template_base = 'StoreCond')
881}};
882