mem.isa revision 7646:a444dbee8c07
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43
44def template PanicExecute {{
45    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
46                                  Trace::InstRecord *traceData) const
47    {
48        panic("Execute function executed when it shouldn't be!\n");
49        return NoFault;
50    }
51}};
52
53def template PanicInitiateAcc {{
54    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
55                                      Trace::InstRecord *traceData) const
56    {
57        panic("InitiateAcc function executed when it shouldn't be!\n");
58        return NoFault;
59    }
60}};
61
62def template PanicCompleteAcc {{
63    Fault %(class_name)s::completeAcc(PacketPtr pkt,
64                                      %(CPU_exec_context)s *xc,
65                                      Trace::InstRecord *traceData) const
66    {
67        panic("CompleteAcc function executed when it shouldn't be!\n");
68        return NoFault;
69    }
70}};
71
72
73def template SwapExecute {{
74    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
75                                  Trace::InstRecord *traceData) const
76    {
77        Addr EA;
78        Fault fault = NoFault;
79
80        %(op_decl)s;
81        uint64_t memData = 0;
82        %(op_rd)s;
83        %(ea_code)s;
84
85        if (%(predicate_test)s)
86        {
87            %(preacc_code)s;
88
89            if (fault == NoFault) {
90                fault = xc->write((uint%(mem_acc_size)d_t&)Mem,
91                        EA, memAccessFlags, &memData);
92            }
93
94            if (fault == NoFault) {
95                %(postacc_code)s;
96            }
97
98            if (fault == NoFault) {
99                %(op_wb)s;
100            }
101        } else {
102            xc->setPredicate(false);
103        }
104
105        if (fault == NoFault && machInst.itstateMask != 0 &&
106                (!isMicroop() || isLastMicroop())) {
107            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
108        }
109
110        return fault;
111    }
112}};
113
114def template SwapInitiateAcc {{
115    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
116                                      Trace::InstRecord *traceData) const
117    {
118        Addr EA;
119        Fault fault = NoFault;
120
121        %(op_decl)s;
122        uint64_t memData = 0;
123        %(op_rd)s;
124        %(ea_code)s;
125
126        if (%(predicate_test)s)
127        {
128            %(preacc_code)s;
129
130            if (fault == NoFault) {
131                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
132                                  memAccessFlags, &memData);
133            }
134
135            if (fault == NoFault) {
136                %(op_wb)s;
137            }
138        } else {
139            xc->setPredicate(false);
140        }
141
142        if (fault == NoFault && machInst.itstateMask != 0 &&
143                (!isMicroop() || isLastMicroop())) {
144            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
145        }
146
147        return fault;
148    }
149}};
150
151def template SwapCompleteAcc {{
152    Fault %(class_name)s::completeAcc(PacketPtr pkt,
153                                      %(CPU_exec_context)s *xc,
154                                      Trace::InstRecord *traceData) const
155    {
156        Fault fault = NoFault;
157
158        %(op_decl)s;
159        %(op_rd)s;
160
161        if (%(predicate_test)s)
162        {
163            // ARM instructions will not have a pkt if the predicate is false
164            uint64_t memData = pkt->get<typeof(Mem)>();
165
166            %(postacc_code)s;
167
168            if (fault == NoFault) {
169                %(op_wb)s;
170            }
171        }
172
173        if (fault == NoFault && machInst.itstateMask != 0) {
174            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
175        }
176
177        return fault;
178    }
179}};
180
181def template LoadExecute {{
182    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
183                                  Trace::InstRecord *traceData) const
184    {
185        Addr EA;
186        Fault fault = NoFault;
187
188        %(op_decl)s;
189        %(op_rd)s;
190        %(ea_code)s;
191
192        if (%(predicate_test)s)
193        {
194            if (fault == NoFault) {
195                fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
196                %(memacc_code)s;
197            }
198
199            if (fault == NoFault) {
200                %(op_wb)s;
201            }
202        } else {
203            xc->setPredicate(false);
204        }
205
206        if (fault == NoFault && machInst.itstateMask != 0 &&
207                (!isMicroop() || isLastMicroop())) {
208            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
209        }
210
211        return fault;
212    }
213}};
214
215def template NeonLoadExecute {{
216    template <class Element>
217    Fault %(class_name)s<Element>::execute(
218            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
219    {
220        Addr EA;
221        Fault fault = NoFault;
222
223        %(op_decl)s;
224        %(mem_decl)s;
225        %(op_rd)s;
226        %(ea_code)s;
227
228        MemUnion memUnion;
229        uint8_t *dataPtr = memUnion.bytes;
230
231        if (%(predicate_test)s)
232        {
233            if (fault == NoFault) {
234                fault = xc->readBytes(EA, dataPtr, %(size)d, memAccessFlags);
235                %(memacc_code)s;
236            }
237
238            if (fault == NoFault) {
239                %(op_wb)s;
240            }
241        }
242
243        if (fault == NoFault && machInst.itstateMask != 0 &&
244                (!isMicroop() || isLastMicroop())) {
245            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
246        }
247
248        return fault;
249    }
250}};
251
252def template StoreExecute {{
253    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
254                                  Trace::InstRecord *traceData) const
255    {
256        Addr EA;
257        Fault fault = NoFault;
258
259        %(op_decl)s;
260        %(op_rd)s;
261        %(ea_code)s;
262
263        if (%(predicate_test)s)
264        {
265            if (fault == NoFault) {
266                %(memacc_code)s;
267            }
268
269            if (fault == NoFault) {
270                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
271                                  memAccessFlags, NULL);
272            }
273
274            if (fault == NoFault) {
275                %(op_wb)s;
276            }
277        } else {
278            xc->setPredicate(false);
279        }
280
281        if (fault == NoFault && machInst.itstateMask != 0 &&
282                (!isMicroop() || isLastMicroop())) {
283            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
284        }
285
286        return fault;
287    }
288}};
289
290def template NeonStoreExecute {{
291    template <class Element>
292    Fault %(class_name)s<Element>::execute(
293            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
294    {
295        Addr EA;
296        Fault fault = NoFault;
297
298        %(op_decl)s;
299        %(mem_decl)s;
300        %(op_rd)s;
301        %(ea_code)s;
302
303        MemUnion memUnion;
304        uint8_t *dataPtr = memUnion.bytes;
305
306        if (%(predicate_test)s)
307        {
308            if (fault == NoFault) {
309                %(memacc_code)s;
310            }
311
312            if (fault == NoFault) {
313                fault = xc->writeBytes(dataPtr, %(size)d, EA,
314                                       memAccessFlags, NULL);
315            }
316
317            if (fault == NoFault) {
318                %(op_wb)s;
319            }
320        }
321
322        if (fault == NoFault && machInst.itstateMask != 0 &&
323                (!isMicroop() || isLastMicroop())) {
324            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
325        }
326
327        return fault;
328    }
329}};
330
331def template StoreExExecute {{
332    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
333                                  Trace::InstRecord *traceData) const
334    {
335        Addr EA;
336        Fault fault = NoFault;
337
338        %(op_decl)s;
339        %(op_rd)s;
340        %(ea_code)s;
341
342        if (%(predicate_test)s)
343        {
344            if (fault == NoFault) {
345                %(memacc_code)s;
346            }
347
348            uint64_t writeResult;
349
350            if (fault == NoFault) {
351                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
352                                  memAccessFlags, &writeResult);
353            }
354
355            if (fault == NoFault) {
356                %(postacc_code)s;
357            }
358
359            if (fault == NoFault) {
360                %(op_wb)s;
361            }
362        } else {
363            xc->setPredicate(false);
364        }
365
366        if (fault == NoFault && machInst.itstateMask != 0 &&
367                (!isMicroop() || isLastMicroop())) {
368            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
369        }
370
371        return fault;
372    }
373}};
374
375def template StoreExInitiateAcc {{
376    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
377                                      Trace::InstRecord *traceData) const
378    {
379        Addr EA;
380        Fault fault = NoFault;
381
382        %(op_decl)s;
383        %(op_rd)s;
384        %(ea_code)s;
385
386        if (%(predicate_test)s)
387        {
388            if (fault == NoFault) {
389                %(memacc_code)s;
390            }
391
392            if (fault == NoFault) {
393                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
394                                  memAccessFlags, NULL);
395            }
396
397            // Need to write back any potential address register update
398            if (fault == NoFault) {
399                %(op_wb)s;
400            }
401        } else {
402            xc->setPredicate(false);
403        }
404        if (fault == NoFault && machInst.itstateMask != 0 &&
405                (!isMicroop() || isLastMicroop())) {
406            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
407        }
408
409        return fault;
410    }
411}};
412
413def template StoreInitiateAcc {{
414    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
415                                      Trace::InstRecord *traceData) const
416    {
417        Addr EA;
418        Fault fault = NoFault;
419
420        %(op_decl)s;
421        %(op_rd)s;
422        %(ea_code)s;
423
424        if (%(predicate_test)s)
425        {
426            if (fault == NoFault) {
427                %(memacc_code)s;
428            }
429
430            if (fault == NoFault) {
431                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
432                                  memAccessFlags, NULL);
433            }
434
435            // Need to write back any potential address register update
436            if (fault == NoFault) {
437                %(op_wb)s;
438            }
439        } else {
440            xc->setPredicate(false);
441        }
442
443        if (fault == NoFault && machInst.itstateMask != 0 &&
444                (!isMicroop() || isLastMicroop())) {
445            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
446        }
447
448        return fault;
449    }
450}};
451
452def template NeonStoreInitiateAcc {{
453    template <class Element>
454    Fault %(class_name)s<Element>::initiateAcc(
455            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
456    {
457        Addr EA;
458        Fault fault = NoFault;
459
460        %(op_decl)s;
461        %(mem_decl)s;
462        %(op_rd)s;
463        %(ea_code)s;
464
465        if (%(predicate_test)s)
466        {
467            MemUnion memUnion;
468            if (fault == NoFault) {
469                %(memacc_code)s;
470            }
471
472            if (fault == NoFault) {
473                fault = xc->writeBytes(memUnion.bytes, %(size)d, EA,
474                                       memAccessFlags, NULL);
475            }
476
477            // Need to write back any potential address register update
478            if (fault == NoFault) {
479                %(op_wb)s;
480            }
481        }
482
483        if (fault == NoFault && machInst.itstateMask != 0 &&
484                (!isMicroop() || isLastMicroop())) {
485            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
486        }
487
488        return fault;
489    }
490}};
491
492def template LoadInitiateAcc {{
493    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
494                                      Trace::InstRecord *traceData) const
495    {
496        Addr EA;
497        Fault fault = NoFault;
498
499        %(op_src_decl)s;
500        %(op_rd)s;
501        %(ea_code)s;
502
503        if (%(predicate_test)s)
504        {
505            if (fault == NoFault) {
506                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
507            }
508        } else {
509            xc->setPredicate(false);
510            if (fault == NoFault && machInst.itstateMask != 0 &&
511                    (!isMicroop() || isLastMicroop())) {
512                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
513            }
514        }
515
516        return fault;
517    }
518}};
519
520def template NeonLoadInitiateAcc {{
521    template <class Element>
522    Fault %(class_name)s<Element>::initiateAcc(
523            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
524    {
525        Addr EA;
526        Fault fault = NoFault;
527
528        %(op_src_decl)s;
529        %(op_rd)s;
530        %(ea_code)s;
531
532        if (%(predicate_test)s)
533        {
534            if (fault == NoFault) {
535                fault = xc->readBytes(EA, NULL, %(size)d, memAccessFlags);
536            }
537        } else if (fault == NoFault && machInst.itstateMask != 0 &&
538                (!isMicroop() || isLastMicroop())) {
539            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
540        }
541
542        return fault;
543    }
544}};
545
546def template LoadCompleteAcc {{
547    Fault %(class_name)s::completeAcc(PacketPtr pkt,
548                                      %(CPU_exec_context)s *xc,
549                                      Trace::InstRecord *traceData) const
550    {
551        Fault fault = NoFault;
552
553        %(op_decl)s;
554        %(op_rd)s;
555
556        if (%(predicate_test)s)
557        {
558            // ARM instructions will not have a pkt if the predicate is false
559            Mem = pkt->get<typeof(Mem)>();
560
561            if (fault == NoFault) {
562                %(memacc_code)s;
563            }
564
565            if (fault == NoFault) {
566                %(op_wb)s;
567            }
568        }
569
570        if (fault == NoFault && machInst.itstateMask != 0) {
571            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
572        }
573
574        return fault;
575    }
576}};
577
578def template NeonLoadCompleteAcc {{
579    template <class Element>
580    Fault %(class_name)s<Element>::completeAcc(
581            PacketPtr pkt, %(CPU_exec_context)s *xc,
582            Trace::InstRecord *traceData) const
583    {
584        Fault fault = NoFault;
585
586        %(mem_decl)s;
587        %(op_decl)s;
588        %(op_rd)s;
589
590        if (%(predicate_test)s)
591        {
592            // ARM instructions will not have a pkt if the predicate is false
593            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
594
595            if (fault == NoFault) {
596                %(memacc_code)s;
597            }
598
599            if (fault == NoFault) {
600                %(op_wb)s;
601            }
602        }
603
604        if (fault == NoFault && machInst.itstateMask != 0) {
605            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
606        }
607
608        return fault;
609    }
610}};
611
612def template StoreCompleteAcc {{
613    Fault %(class_name)s::completeAcc(PacketPtr pkt,
614                                      %(CPU_exec_context)s *xc,
615                                      Trace::InstRecord *traceData) const
616    {
617        Fault fault = NoFault;
618
619        %(op_decl)s;
620        %(op_rd)s;
621
622        if (%(predicate_test)s)
623        {
624            if (fault == NoFault) {
625                %(op_wb)s;
626            }
627        }
628
629        if (fault == NoFault && machInst.itstateMask != 0) {
630            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
631        }
632
633        return fault;
634    }
635}};
636
637def template NeonStoreCompleteAcc {{
638    template <class Element>
639    Fault %(class_name)s<Element>::completeAcc(
640            PacketPtr pkt, %(CPU_exec_context)s *xc,
641            Trace::InstRecord *traceData) const
642    {
643        Fault fault = NoFault;
644
645        %(op_decl)s;
646        %(op_rd)s;
647
648        if (%(predicate_test)s)
649        {
650            if (fault == NoFault) {
651                %(op_wb)s;
652            }
653        }
654
655        if (fault == NoFault && machInst.itstateMask != 0) {
656            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
657        }
658
659        return fault;
660    }
661}};
662
663def template StoreExCompleteAcc {{
664    Fault %(class_name)s::completeAcc(PacketPtr pkt,
665                                      %(CPU_exec_context)s *xc,
666                                      Trace::InstRecord *traceData) const
667    {
668        Fault fault = NoFault;
669
670        %(op_decl)s;
671        %(op_rd)s;
672
673        if (%(predicate_test)s)
674        {
675            uint64_t writeResult = pkt->req->getExtraData();
676            %(postacc_code)s;
677
678            if (fault == NoFault) {
679                %(op_wb)s;
680            }
681        }
682
683        if (fault == NoFault && machInst.itstateMask != 0) {
684            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
685        }
686
687        return fault;
688    }
689}};
690
691def template RfeDeclare {{
692    /**
693     * Static instruction class for "%(mnemonic)s".
694     */
695    class %(class_name)s : public %(base_class)s
696    {
697      public:
698
699        /// Constructor.
700        %(class_name)s(ExtMachInst machInst,
701                uint32_t _base, int _mode, bool _wb);
702
703        %(BasicExecDeclare)s
704
705        %(InitiateAccDeclare)s
706
707        %(CompleteAccDeclare)s
708    };
709}};
710
711def template SrsDeclare {{
712    /**
713     * Static instruction class for "%(mnemonic)s".
714     */
715    class %(class_name)s : public %(base_class)s
716    {
717      public:
718
719        /// Constructor.
720        %(class_name)s(ExtMachInst machInst,
721                uint32_t _regMode, int _mode, bool _wb);
722
723        %(BasicExecDeclare)s
724
725        %(InitiateAccDeclare)s
726
727        %(CompleteAccDeclare)s
728    };
729}};
730
731def template SwapDeclare {{
732    /**
733     * Static instruction class for "%(mnemonic)s".
734     */
735    class %(class_name)s : public %(base_class)s
736    {
737      public:
738
739        /// Constructor.
740        %(class_name)s(ExtMachInst machInst,
741                uint32_t _dest, uint32_t _op1, uint32_t _base);
742
743        %(BasicExecDeclare)s
744
745        %(InitiateAccDeclare)s
746
747        %(CompleteAccDeclare)s
748    };
749}};
750
751def template LoadStoreDImmDeclare {{
752    /**
753     * Static instruction class for "%(mnemonic)s".
754     */
755    class %(class_name)s : public %(base_class)s
756    {
757      public:
758
759        /// Constructor.
760        %(class_name)s(ExtMachInst machInst,
761                uint32_t _dest, uint32_t _dest2,
762                uint32_t _base, bool _add, int32_t _imm);
763
764        %(BasicExecDeclare)s
765
766        %(InitiateAccDeclare)s
767
768        %(CompleteAccDeclare)s
769    };
770}};
771
772def template StoreExDImmDeclare {{
773    /**
774     * Static instruction class for "%(mnemonic)s".
775     */
776    class %(class_name)s : public %(base_class)s
777    {
778      public:
779
780        /// Constructor.
781        %(class_name)s(ExtMachInst machInst,
782                uint32_t _result, uint32_t _dest, uint32_t _dest2,
783                uint32_t _base, bool _add, int32_t _imm);
784
785        %(BasicExecDeclare)s
786
787        %(InitiateAccDeclare)s
788
789        %(CompleteAccDeclare)s
790    };
791}};
792
793def template LoadStoreImmDeclare {{
794    /**
795     * Static instruction class for "%(mnemonic)s".
796     */
797    class %(class_name)s : public %(base_class)s
798    {
799      public:
800
801        /// Constructor.
802        %(class_name)s(ExtMachInst machInst,
803                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
804
805        %(BasicExecDeclare)s
806
807        %(InitiateAccDeclare)s
808
809        %(CompleteAccDeclare)s
810    };
811}};
812
813def template StoreExImmDeclare {{
814    /**
815     * Static instruction class for "%(mnemonic)s".
816     */
817    class %(class_name)s : public %(base_class)s
818    {
819      public:
820
821        /// Constructor.
822        %(class_name)s(ExtMachInst machInst,
823                uint32_t _result, uint32_t _dest, uint32_t _base,
824                bool _add, int32_t _imm);
825
826        %(BasicExecDeclare)s
827
828        %(InitiateAccDeclare)s
829
830        %(CompleteAccDeclare)s
831    };
832}};
833
834def template StoreDRegDeclare {{
835    /**
836     * Static instruction class for "%(mnemonic)s".
837     */
838    class %(class_name)s : public %(base_class)s
839    {
840      public:
841
842        /// Constructor.
843        %(class_name)s(ExtMachInst machInst,
844                uint32_t _dest, uint32_t _dest2,
845                uint32_t _base, bool _add,
846                int32_t _shiftAmt, uint32_t _shiftType,
847                uint32_t _index);
848
849        %(BasicExecDeclare)s
850
851        %(InitiateAccDeclare)s
852
853        %(CompleteAccDeclare)s
854    };
855}};
856
857def template StoreRegDeclare {{
858    /**
859     * Static instruction class for "%(mnemonic)s".
860     */
861    class %(class_name)s : public %(base_class)s
862    {
863      public:
864
865        /// Constructor.
866        %(class_name)s(ExtMachInst machInst,
867                uint32_t _dest, uint32_t _base, bool _add,
868                int32_t _shiftAmt, uint32_t _shiftType,
869                uint32_t _index);
870
871        %(BasicExecDeclare)s
872
873        %(InitiateAccDeclare)s
874
875        %(CompleteAccDeclare)s
876    };
877}};
878
879def template LoadDRegDeclare {{
880    /**
881     * Static instruction class for "%(mnemonic)s".
882     */
883    class %(class_name)s : public %(base_class)s
884    {
885      public:
886
887        /// Constructor.
888        %(class_name)s(ExtMachInst machInst,
889                uint32_t _dest, uint32_t _dest2,
890                uint32_t _base, bool _add,
891                int32_t _shiftAmt, uint32_t _shiftType,
892                uint32_t _index);
893
894        %(BasicExecDeclare)s
895
896        %(InitiateAccDeclare)s
897
898        %(CompleteAccDeclare)s
899    };
900}};
901
902def template LoadRegDeclare {{
903    /**
904     * Static instruction class for "%(mnemonic)s".
905     */
906    class %(class_name)s : public %(base_class)s
907    {
908      public:
909
910        /// Constructor.
911        %(class_name)s(ExtMachInst machInst,
912                uint32_t _dest, uint32_t _base, bool _add,
913                int32_t _shiftAmt, uint32_t _shiftType,
914                uint32_t _index);
915
916        %(BasicExecDeclare)s
917
918        %(InitiateAccDeclare)s
919
920        %(CompleteAccDeclare)s
921    };
922}};
923
924def template LoadImmDeclare {{
925    /**
926     * Static instruction class for "%(mnemonic)s".
927     */
928    class %(class_name)s : public %(base_class)s
929    {
930      public:
931
932        /// Constructor.
933        %(class_name)s(ExtMachInst machInst,
934                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
935
936        %(BasicExecDeclare)s
937
938        %(InitiateAccDeclare)s
939
940        %(CompleteAccDeclare)s
941    };
942}};
943
944def template InitiateAccDeclare {{
945    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
946}};
947
948def template CompleteAccDeclare {{
949    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
950}};
951
952def template RfeConstructor {{
953    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
954            uint32_t _base, int _mode, bool _wb)
955         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
956                 (IntRegIndex)_base, (AddrMode)_mode, _wb)
957    {
958        %(constructor)s;
959#if %(use_uops)d
960        assert(numMicroops >= 2);
961        uops = new StaticInstPtr[numMicroops];
962        uops[0] = new %(acc_name)s(machInst, _base, _mode, _wb);
963        uops[1] = new %(wb_decl)s;
964        uops[1]->setLastMicroop();
965#endif
966    }
967}};
968
969def template SrsConstructor {{
970    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
971            uint32_t _regMode, int _mode, bool _wb)
972         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
973                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
974    {
975        %(constructor)s;
976#if %(use_uops)d
977        assert(numMicroops >= 2);
978        uops = new StaticInstPtr[numMicroops];
979        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
980        uops[1] = new %(wb_decl)s;
981        uops[1]->setLastMicroop();
982#endif
983    }
984}};
985
986def template SwapConstructor {{
987    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
988            uint32_t _dest, uint32_t _op1, uint32_t _base)
989         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
990                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
991    {
992        %(constructor)s;
993    }
994}};
995
996def template LoadStoreDImmConstructor {{
997    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
998            uint32_t _dest, uint32_t _dest2,
999            uint32_t _base, bool _add, int32_t _imm)
1000         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1001                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1002                 (IntRegIndex)_base, _add, _imm)
1003    {
1004        %(constructor)s;
1005#if %(use_uops)d
1006        assert(numMicroops >= 2);
1007        uops = new StaticInstPtr[numMicroops];
1008        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
1009        uops[1] = new %(wb_decl)s;
1010        uops[1]->setLastMicroop();
1011#endif
1012    }
1013}};
1014
1015def template StoreExDImmConstructor {{
1016    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1017            uint32_t _result, uint32_t _dest, uint32_t _dest2,
1018            uint32_t _base, bool _add, int32_t _imm)
1019         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1020                 (IntRegIndex)_result,
1021                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1022                 (IntRegIndex)_base, _add, _imm)
1023    {
1024        %(constructor)s;
1025#if %(use_uops)d
1026        assert(numMicroops >= 2);
1027        uops = new StaticInstPtr[numMicroops];
1028        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
1029                                   _base, _add, _imm);
1030        uops[1] = new %(wb_decl)s;
1031        uops[1]->setLastMicroop();
1032#endif
1033    }
1034}};
1035
1036def template LoadStoreImmConstructor {{
1037    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1038            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1039         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1040                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1041    {
1042        %(constructor)s;
1043#if %(use_uops)d
1044        assert(numMicroops >= 2);
1045        uops = new StaticInstPtr[numMicroops];
1046        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1047        uops[1] = new %(wb_decl)s;
1048        uops[1]->setLastMicroop();
1049#endif
1050    }
1051}};
1052
1053def template StoreExImmConstructor {{
1054    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1055            uint32_t _result, uint32_t _dest, uint32_t _base,
1056            bool _add, int32_t _imm)
1057         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1058                 (IntRegIndex)_result, (IntRegIndex)_dest,
1059                 (IntRegIndex)_base, _add, _imm)
1060    {
1061        %(constructor)s;
1062#if %(use_uops)d
1063        assert(numMicroops >= 2);
1064        uops = new StaticInstPtr[numMicroops];
1065        uops[0] = new %(acc_name)s(machInst, _result, _dest,
1066                                   _base, _add, _imm);
1067        uops[1] = new %(wb_decl)s;
1068        uops[1]->setLastMicroop();
1069#endif
1070    }
1071}};
1072
1073def template StoreDRegConstructor {{
1074    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1075            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1076            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1077         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1078                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1079                 (IntRegIndex)_base, _add,
1080                 _shiftAmt, (ArmShiftType)_shiftType,
1081                 (IntRegIndex)_index)
1082    {
1083        %(constructor)s;
1084#if %(use_uops)d
1085        assert(numMicroops >= 2);
1086        uops = new StaticInstPtr[numMicroops];
1087        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1088                                   _shiftAmt, _shiftType, _index);
1089        uops[1] = new %(wb_decl)s;
1090        uops[1]->setLastMicroop();
1091#endif
1092    }
1093}};
1094
1095def template StoreRegConstructor {{
1096    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1097            uint32_t _dest, uint32_t _base, bool _add,
1098            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1099         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1100                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1101                 _shiftAmt, (ArmShiftType)_shiftType,
1102                 (IntRegIndex)_index)
1103    {
1104        %(constructor)s;
1105#if %(use_uops)d
1106        assert(numMicroops >= 2);
1107        uops = new StaticInstPtr[numMicroops];
1108        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1109                                   _shiftAmt, _shiftType, _index);
1110        uops[1] = new %(wb_decl)s;
1111        uops[1]->setLastMicroop();
1112#endif
1113    }
1114}};
1115
1116def template LoadDRegConstructor {{
1117    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1118            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1119            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1120         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1121                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1122                 (IntRegIndex)_base, _add,
1123                 _shiftAmt, (ArmShiftType)_shiftType,
1124                 (IntRegIndex)_index)
1125    {
1126        %(constructor)s;
1127#if %(use_uops)d
1128        assert(numMicroops >= 2);
1129        uops = new StaticInstPtr[numMicroops];
1130        if ((_dest == _index) || (_dest2 == _index)) {
1131            IntRegIndex wbIndexReg = INTREG_UREG0;
1132            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1133            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1134                                       _shiftAmt, _shiftType, _index);
1135            uops[2] = new %(wb_decl)s;
1136            uops[2]->setLastMicroop();
1137        } else {
1138            IntRegIndex wbIndexReg = index;
1139            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1140                                       _shiftAmt, _shiftType, _index);
1141            uops[1] = new %(wb_decl)s;
1142            uops[1]->setLastMicroop();
1143        }
1144#endif
1145    }
1146}};
1147
1148def template LoadRegConstructor {{
1149    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1150            uint32_t _dest, uint32_t _base, bool _add,
1151            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1152         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1153                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1154                 _shiftAmt, (ArmShiftType)_shiftType,
1155                 (IntRegIndex)_index)
1156    {
1157        %(constructor)s;
1158#if %(use_uops)d
1159        assert(numMicroops >= 2);
1160        uops = new StaticInstPtr[numMicroops];
1161        if (_dest == INTREG_PC) {
1162            IntRegIndex wbIndexReg = index;
1163            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1164                                       _shiftAmt, _shiftType, _index);
1165            uops[1] = new %(wb_decl)s;
1166            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1167            uops[2]->setLastMicroop();
1168        } else if(_dest == _index) {
1169            IntRegIndex wbIndexReg = INTREG_UREG0;
1170            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1171            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1172                                      _shiftAmt, _shiftType, _index);
1173            uops[2] = new %(wb_decl)s;
1174            uops[2]->setLastMicroop();
1175        } else {
1176            IntRegIndex wbIndexReg = index;
1177            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1178                                      _shiftAmt, _shiftType, _index);
1179            uops[1] = new %(wb_decl)s;
1180            uops[1]->setLastMicroop();
1181
1182        }
1183#endif
1184    }
1185}};
1186
1187def template LoadImmConstructor {{
1188    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1189            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1190         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1191                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1192    {
1193        %(constructor)s;
1194#if %(use_uops)d
1195        assert(numMicroops >= 2);
1196        uops = new StaticInstPtr[numMicroops];
1197        if (_dest == INTREG_PC) {
1198            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1199                                   _imm);
1200            uops[1] = new %(wb_decl)s;
1201            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1202            uops[2]->setLastMicroop();
1203        } else {
1204            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1205            uops[1] = new %(wb_decl)s;
1206            uops[1]->setLastMicroop();
1207        }
1208#endif
1209    }
1210}};
1211
1212