mem.isa revision 7711:fe91d5e2c374
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        } else {
135            xc->setPredicate(false);
136        }
137
138        if (fault == NoFault && machInst.itstateMask != 0 &&
139                (!isMicroop() || isLastMicroop())) {
140            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
141        }
142
143        return fault;
144    }
145}};
146
147def template SwapCompleteAcc {{
148    Fault %(class_name)s::completeAcc(PacketPtr pkt,
149                                      %(CPU_exec_context)s *xc,
150                                      Trace::InstRecord *traceData) const
151    {
152        Fault fault = NoFault;
153
154        %(op_decl)s;
155        %(op_rd)s;
156
157        if (%(predicate_test)s)
158        {
159            // ARM instructions will not have a pkt if the predicate is false
160            uint64_t memData = pkt->get<typeof(Mem)>();
161
162            %(postacc_code)s;
163
164            if (fault == NoFault) {
165                %(op_wb)s;
166            }
167        }
168
169        if (fault == NoFault && machInst.itstateMask != 0) {
170            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
171        }
172
173        return fault;
174    }
175}};
176
177def template LoadExecute {{
178    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
179                                  Trace::InstRecord *traceData) const
180    {
181        Addr EA;
182        Fault fault = NoFault;
183
184        %(op_decl)s;
185        %(op_rd)s;
186        %(ea_code)s;
187
188        if (%(predicate_test)s)
189        {
190            if (fault == NoFault) {
191                fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
192                %(memacc_code)s;
193            }
194
195            if (fault == NoFault) {
196                %(op_wb)s;
197            }
198        } else {
199            xc->setPredicate(false);
200        }
201
202        if (fault == NoFault && machInst.itstateMask != 0 &&
203                (!isMicroop() || isLastMicroop())) {
204            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
205        }
206
207        return fault;
208    }
209}};
210
211def template NeonLoadExecute {{
212    template <class Element>
213    Fault %(class_name)s<Element>::execute(
214            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
215    {
216        Addr EA;
217        Fault fault = NoFault;
218
219        %(op_decl)s;
220        %(mem_decl)s;
221        %(op_rd)s;
222        %(ea_code)s;
223
224        MemUnion memUnion;
225        uint8_t *dataPtr = memUnion.bytes;
226
227        if (%(predicate_test)s)
228        {
229            if (fault == NoFault) {
230                fault = xc->readBytes(EA, dataPtr, %(size)d, memAccessFlags);
231                %(memacc_code)s;
232            }
233
234            if (fault == NoFault) {
235                %(op_wb)s;
236            }
237        }
238
239        if (fault == NoFault && machInst.itstateMask != 0 &&
240                (!isMicroop() || isLastMicroop())) {
241            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
242        }
243
244        return fault;
245    }
246}};
247
248def template StoreExecute {{
249    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
250                                  Trace::InstRecord *traceData) const
251    {
252        Addr EA;
253        Fault fault = NoFault;
254
255        %(op_decl)s;
256        %(op_rd)s;
257        %(ea_code)s;
258
259        if (%(predicate_test)s)
260        {
261            if (fault == NoFault) {
262                %(memacc_code)s;
263            }
264
265            if (fault == NoFault) {
266                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
267                                  memAccessFlags, NULL);
268            }
269
270            if (fault == NoFault) {
271                %(op_wb)s;
272            }
273        } else {
274            xc->setPredicate(false);
275        }
276
277        if (fault == NoFault && machInst.itstateMask != 0 &&
278                (!isMicroop() || isLastMicroop())) {
279            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
280        }
281
282        return fault;
283    }
284}};
285
286def template NeonStoreExecute {{
287    template <class Element>
288    Fault %(class_name)s<Element>::execute(
289            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
290    {
291        Addr EA;
292        Fault fault = NoFault;
293
294        %(op_decl)s;
295        %(mem_decl)s;
296        %(op_rd)s;
297        %(ea_code)s;
298
299        MemUnion memUnion;
300        uint8_t *dataPtr = memUnion.bytes;
301
302        if (%(predicate_test)s)
303        {
304            if (fault == NoFault) {
305                %(memacc_code)s;
306            }
307
308            if (fault == NoFault) {
309                fault = xc->writeBytes(dataPtr, %(size)d, EA,
310                                       memAccessFlags, NULL);
311            }
312
313            if (fault == NoFault) {
314                %(op_wb)s;
315            }
316        }
317
318        if (fault == NoFault && machInst.itstateMask != 0 &&
319                (!isMicroop() || isLastMicroop())) {
320            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
321        }
322
323        return fault;
324    }
325}};
326
327def template StoreExExecute {{
328    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
329                                  Trace::InstRecord *traceData) const
330    {
331        Addr EA;
332        Fault fault = NoFault;
333
334        %(op_decl)s;
335        %(op_rd)s;
336        %(ea_code)s;
337
338        if (%(predicate_test)s)
339        {
340            if (fault == NoFault) {
341                %(memacc_code)s;
342            }
343
344            uint64_t writeResult;
345
346            if (fault == NoFault) {
347                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
348                                  memAccessFlags, &writeResult);
349            }
350
351            if (fault == NoFault) {
352                %(postacc_code)s;
353            }
354
355            if (fault == NoFault) {
356                %(op_wb)s;
357            }
358        } else {
359            xc->setPredicate(false);
360        }
361
362        if (fault == NoFault && machInst.itstateMask != 0 &&
363                (!isMicroop() || isLastMicroop())) {
364            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
365        }
366
367        return fault;
368    }
369}};
370
371def template StoreExInitiateAcc {{
372    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
373                                      Trace::InstRecord *traceData) const
374    {
375        Addr EA;
376        Fault fault = NoFault;
377
378        %(op_decl)s;
379        %(op_rd)s;
380        %(ea_code)s;
381
382        if (%(predicate_test)s)
383        {
384            if (fault == NoFault) {
385                %(memacc_code)s;
386            }
387
388            if (fault == NoFault) {
389                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
390                                  memAccessFlags, NULL);
391            }
392        } else {
393            xc->setPredicate(false);
394        }
395        if (fault == NoFault && machInst.itstateMask != 0 &&
396                (!isMicroop() || isLastMicroop())) {
397            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
398        }
399
400        return fault;
401    }
402}};
403
404def template StoreInitiateAcc {{
405    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
406                                      Trace::InstRecord *traceData) const
407    {
408        Addr EA;
409        Fault fault = NoFault;
410
411        %(op_decl)s;
412        %(op_rd)s;
413        %(ea_code)s;
414
415        if (%(predicate_test)s)
416        {
417            if (fault == NoFault) {
418                %(memacc_code)s;
419            }
420
421            if (fault == NoFault) {
422                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
423                                  memAccessFlags, NULL);
424            }
425        } else {
426            xc->setPredicate(false);
427        }
428
429        if (fault == NoFault && machInst.itstateMask != 0 &&
430                (!isMicroop() || isLastMicroop())) {
431            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
432        }
433
434        return fault;
435    }
436}};
437
438def template NeonStoreInitiateAcc {{
439    template <class Element>
440    Fault %(class_name)s<Element>::initiateAcc(
441            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
442    {
443        Addr EA;
444        Fault fault = NoFault;
445
446        %(op_decl)s;
447        %(mem_decl)s;
448        %(op_rd)s;
449        %(ea_code)s;
450
451        if (%(predicate_test)s)
452        {
453            MemUnion memUnion;
454            if (fault == NoFault) {
455                %(memacc_code)s;
456            }
457
458            if (fault == NoFault) {
459                fault = xc->writeBytes(memUnion.bytes, %(size)d, EA,
460                                       memAccessFlags, NULL);
461            }
462        }
463
464        if (fault == NoFault && machInst.itstateMask != 0 &&
465                (!isMicroop() || isLastMicroop())) {
466            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
467        }
468
469        return fault;
470    }
471}};
472
473def template LoadInitiateAcc {{
474    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
475                                      Trace::InstRecord *traceData) const
476    {
477        Addr EA;
478        Fault fault = NoFault;
479
480        %(op_src_decl)s;
481        %(op_rd)s;
482        %(ea_code)s;
483
484        if (%(predicate_test)s)
485        {
486            if (fault == NoFault) {
487                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
488            }
489        } else {
490            xc->setPredicate(false);
491            if (fault == NoFault && machInst.itstateMask != 0 &&
492                    (!isMicroop() || isLastMicroop())) {
493                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
494            }
495        }
496
497        return fault;
498    }
499}};
500
501def template NeonLoadInitiateAcc {{
502    template <class Element>
503    Fault %(class_name)s<Element>::initiateAcc(
504            %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
505    {
506        Addr EA;
507        Fault fault = NoFault;
508
509        %(op_src_decl)s;
510        %(op_rd)s;
511        %(ea_code)s;
512
513        if (%(predicate_test)s)
514        {
515            if (fault == NoFault) {
516                fault = xc->readBytes(EA, NULL, %(size)d, memAccessFlags);
517            }
518        } else if (fault == NoFault && machInst.itstateMask != 0 &&
519                (!isMicroop() || isLastMicroop())) {
520            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
521        }
522
523        return fault;
524    }
525}};
526
527def template LoadCompleteAcc {{
528    Fault %(class_name)s::completeAcc(PacketPtr pkt,
529                                      %(CPU_exec_context)s *xc,
530                                      Trace::InstRecord *traceData) const
531    {
532        Fault fault = NoFault;
533
534        %(op_decl)s;
535        %(op_rd)s;
536
537        if (%(predicate_test)s)
538        {
539            // ARM instructions will not have a pkt if the predicate is false
540            Mem = pkt->get<typeof(Mem)>();
541
542            if (fault == NoFault) {
543                %(memacc_code)s;
544            }
545
546            if (fault == NoFault) {
547                %(op_wb)s;
548            }
549        }
550
551        if (fault == NoFault && machInst.itstateMask != 0) {
552            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
553        }
554
555        return fault;
556    }
557}};
558
559def template NeonLoadCompleteAcc {{
560    template <class Element>
561    Fault %(class_name)s<Element>::completeAcc(
562            PacketPtr pkt, %(CPU_exec_context)s *xc,
563            Trace::InstRecord *traceData) const
564    {
565        Fault fault = NoFault;
566
567        %(mem_decl)s;
568        %(op_decl)s;
569        %(op_rd)s;
570
571        if (%(predicate_test)s)
572        {
573            // ARM instructions will not have a pkt if the predicate is false
574            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
575
576            if (fault == NoFault) {
577                %(memacc_code)s;
578            }
579
580            if (fault == NoFault) {
581                %(op_wb)s;
582            }
583        }
584
585        if (fault == NoFault && machInst.itstateMask != 0) {
586            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
587        }
588
589        return fault;
590    }
591}};
592
593def template StoreCompleteAcc {{
594    Fault %(class_name)s::completeAcc(PacketPtr pkt,
595                                      %(CPU_exec_context)s *xc,
596                                      Trace::InstRecord *traceData) const
597    {
598        Fault fault = NoFault;
599
600        %(op_decl)s;
601        %(op_rd)s;
602
603        if (%(predicate_test)s)
604        {
605            if (fault == NoFault) {
606                %(op_wb)s;
607            }
608        }
609
610        if (fault == NoFault && machInst.itstateMask != 0) {
611            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
612        }
613
614        return fault;
615    }
616}};
617
618def template NeonStoreCompleteAcc {{
619    template <class Element>
620    Fault %(class_name)s<Element>::completeAcc(
621            PacketPtr pkt, %(CPU_exec_context)s *xc,
622            Trace::InstRecord *traceData) const
623    {
624        Fault fault = NoFault;
625
626        %(op_decl)s;
627        %(op_rd)s;
628
629        if (%(predicate_test)s)
630        {
631            if (fault == NoFault) {
632                %(op_wb)s;
633            }
634        }
635
636        if (fault == NoFault && machInst.itstateMask != 0) {
637            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
638        }
639
640        return fault;
641    }
642}};
643
644def template StoreExCompleteAcc {{
645    Fault %(class_name)s::completeAcc(PacketPtr pkt,
646                                      %(CPU_exec_context)s *xc,
647                                      Trace::InstRecord *traceData) const
648    {
649        Fault fault = NoFault;
650
651        %(op_decl)s;
652        %(op_rd)s;
653
654        if (%(predicate_test)s)
655        {
656            uint64_t writeResult = pkt->req->getExtraData();
657            %(postacc_code)s;
658
659            if (fault == NoFault) {
660                %(op_wb)s;
661            }
662        }
663
664        if (fault == NoFault && machInst.itstateMask != 0) {
665            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
666        }
667
668        return fault;
669    }
670}};
671
672def template RfeDeclare {{
673    /**
674     * Static instruction class for "%(mnemonic)s".
675     */
676    class %(class_name)s : public %(base_class)s
677    {
678      public:
679
680        /// Constructor.
681        %(class_name)s(ExtMachInst machInst,
682                uint32_t _base, int _mode, bool _wb);
683
684        %(BasicExecDeclare)s
685
686        %(InitiateAccDeclare)s
687
688        %(CompleteAccDeclare)s
689    };
690}};
691
692def template SrsDeclare {{
693    /**
694     * Static instruction class for "%(mnemonic)s".
695     */
696    class %(class_name)s : public %(base_class)s
697    {
698      public:
699
700        /// Constructor.
701        %(class_name)s(ExtMachInst machInst,
702                uint32_t _regMode, int _mode, bool _wb);
703
704        %(BasicExecDeclare)s
705
706        %(InitiateAccDeclare)s
707
708        %(CompleteAccDeclare)s
709    };
710}};
711
712def template SwapDeclare {{
713    /**
714     * Static instruction class for "%(mnemonic)s".
715     */
716    class %(class_name)s : public %(base_class)s
717    {
718      public:
719
720        /// Constructor.
721        %(class_name)s(ExtMachInst machInst,
722                uint32_t _dest, uint32_t _op1, uint32_t _base);
723
724        %(BasicExecDeclare)s
725
726        %(InitiateAccDeclare)s
727
728        %(CompleteAccDeclare)s
729    };
730}};
731
732def template LoadStoreDImmDeclare {{
733    /**
734     * Static instruction class for "%(mnemonic)s".
735     */
736    class %(class_name)s : public %(base_class)s
737    {
738      public:
739
740        /// Constructor.
741        %(class_name)s(ExtMachInst machInst,
742                uint32_t _dest, uint32_t _dest2,
743                uint32_t _base, bool _add, int32_t _imm);
744
745        %(BasicExecDeclare)s
746
747        %(InitiateAccDeclare)s
748
749        %(CompleteAccDeclare)s
750    };
751}};
752
753def template StoreExDImmDeclare {{
754    /**
755     * Static instruction class for "%(mnemonic)s".
756     */
757    class %(class_name)s : public %(base_class)s
758    {
759      public:
760
761        /// Constructor.
762        %(class_name)s(ExtMachInst machInst,
763                uint32_t _result, uint32_t _dest, uint32_t _dest2,
764                uint32_t _base, bool _add, int32_t _imm);
765
766        %(BasicExecDeclare)s
767
768        %(InitiateAccDeclare)s
769
770        %(CompleteAccDeclare)s
771    };
772}};
773
774def template LoadStoreImmDeclare {{
775    /**
776     * Static instruction class for "%(mnemonic)s".
777     */
778    class %(class_name)s : public %(base_class)s
779    {
780      public:
781
782        /// Constructor.
783        %(class_name)s(ExtMachInst machInst,
784                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
785
786        %(BasicExecDeclare)s
787
788        %(InitiateAccDeclare)s
789
790        %(CompleteAccDeclare)s
791    };
792}};
793
794def template StoreExImmDeclare {{
795    /**
796     * Static instruction class for "%(mnemonic)s".
797     */
798    class %(class_name)s : public %(base_class)s
799    {
800      public:
801
802        /// Constructor.
803        %(class_name)s(ExtMachInst machInst,
804                uint32_t _result, uint32_t _dest, uint32_t _base,
805                bool _add, int32_t _imm);
806
807        %(BasicExecDeclare)s
808
809        %(InitiateAccDeclare)s
810
811        %(CompleteAccDeclare)s
812    };
813}};
814
815def template StoreDRegDeclare {{
816    /**
817     * Static instruction class for "%(mnemonic)s".
818     */
819    class %(class_name)s : public %(base_class)s
820    {
821      public:
822
823        /// Constructor.
824        %(class_name)s(ExtMachInst machInst,
825                uint32_t _dest, uint32_t _dest2,
826                uint32_t _base, bool _add,
827                int32_t _shiftAmt, uint32_t _shiftType,
828                uint32_t _index);
829
830        %(BasicExecDeclare)s
831
832        %(InitiateAccDeclare)s
833
834        %(CompleteAccDeclare)s
835    };
836}};
837
838def template StoreRegDeclare {{
839    /**
840     * Static instruction class for "%(mnemonic)s".
841     */
842    class %(class_name)s : public %(base_class)s
843    {
844      public:
845
846        /// Constructor.
847        %(class_name)s(ExtMachInst machInst,
848                uint32_t _dest, uint32_t _base, bool _add,
849                int32_t _shiftAmt, uint32_t _shiftType,
850                uint32_t _index);
851
852        %(BasicExecDeclare)s
853
854        %(InitiateAccDeclare)s
855
856        %(CompleteAccDeclare)s
857    };
858}};
859
860def template LoadDRegDeclare {{
861    /**
862     * Static instruction class for "%(mnemonic)s".
863     */
864    class %(class_name)s : public %(base_class)s
865    {
866      public:
867
868        /// Constructor.
869        %(class_name)s(ExtMachInst machInst,
870                uint32_t _dest, uint32_t _dest2,
871                uint32_t _base, bool _add,
872                int32_t _shiftAmt, uint32_t _shiftType,
873                uint32_t _index);
874
875        %(BasicExecDeclare)s
876
877        %(InitiateAccDeclare)s
878
879        %(CompleteAccDeclare)s
880    };
881}};
882
883def template LoadRegDeclare {{
884    /**
885     * Static instruction class for "%(mnemonic)s".
886     */
887    class %(class_name)s : public %(base_class)s
888    {
889      public:
890
891        /// Constructor.
892        %(class_name)s(ExtMachInst machInst,
893                uint32_t _dest, uint32_t _base, bool _add,
894                int32_t _shiftAmt, uint32_t _shiftType,
895                uint32_t _index);
896
897        %(BasicExecDeclare)s
898
899        %(InitiateAccDeclare)s
900
901        %(CompleteAccDeclare)s
902    };
903}};
904
905def template LoadImmDeclare {{
906    /**
907     * Static instruction class for "%(mnemonic)s".
908     */
909    class %(class_name)s : public %(base_class)s
910    {
911      public:
912
913        /// Constructor.
914        %(class_name)s(ExtMachInst machInst,
915                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
916
917        %(BasicExecDeclare)s
918
919        %(InitiateAccDeclare)s
920
921        %(CompleteAccDeclare)s
922    };
923}};
924
925def template InitiateAccDeclare {{
926    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
927}};
928
929def template CompleteAccDeclare {{
930    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
931}};
932
933def template RfeConstructor {{
934    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
935            uint32_t _base, int _mode, bool _wb)
936         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
937                 (IntRegIndex)_base, (AddrMode)_mode, _wb)
938    {
939        %(constructor)s;
940#if %(use_uops)d
941        assert(numMicroops >= 2);
942        uops = new StaticInstPtr[numMicroops];
943        uops[0] = new %(acc_name)s(machInst, _base, _mode, _wb);
944        uops[1] = new %(wb_decl)s;
945        uops[1]->setLastMicroop();
946#endif
947    }
948}};
949
950def template SrsConstructor {{
951    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
952            uint32_t _regMode, int _mode, bool _wb)
953         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
954                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
955    {
956        %(constructor)s;
957#if %(use_uops)d
958        assert(numMicroops >= 2);
959        uops = new StaticInstPtr[numMicroops];
960        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
961        uops[1] = new %(wb_decl)s;
962        uops[1]->setLastMicroop();
963#endif
964    }
965}};
966
967def template SwapConstructor {{
968    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
969            uint32_t _dest, uint32_t _op1, uint32_t _base)
970         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
971                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
972    {
973        %(constructor)s;
974    }
975}};
976
977def template LoadStoreDImmConstructor {{
978    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
979            uint32_t _dest, uint32_t _dest2,
980            uint32_t _base, bool _add, int32_t _imm)
981         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
982                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
983                 (IntRegIndex)_base, _add, _imm)
984    {
985        %(constructor)s;
986#if %(use_uops)d
987        assert(numMicroops >= 2);
988        uops = new StaticInstPtr[numMicroops];
989        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
990        uops[1] = new %(wb_decl)s;
991        uops[1]->setLastMicroop();
992#endif
993    }
994}};
995
996def template StoreExDImmConstructor {{
997    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
998            uint32_t _result, 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)_result,
1002                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1003                 (IntRegIndex)_base, _add, _imm)
1004    {
1005        %(constructor)s;
1006#if %(use_uops)d
1007        assert(numMicroops >= 2);
1008        uops = new StaticInstPtr[numMicroops];
1009        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
1010                                   _base, _add, _imm);
1011        uops[1] = new %(wb_decl)s;
1012        uops[1]->setLastMicroop();
1013#endif
1014    }
1015}};
1016
1017def template LoadStoreImmConstructor {{
1018    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1019            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1020         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1021                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1022    {
1023        %(constructor)s;
1024#if %(use_uops)d
1025        assert(numMicroops >= 2);
1026        uops = new StaticInstPtr[numMicroops];
1027        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1028        uops[1] = new %(wb_decl)s;
1029        uops[1]->setLastMicroop();
1030#endif
1031    }
1032}};
1033
1034def template StoreExImmConstructor {{
1035    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1036            uint32_t _result, uint32_t _dest, uint32_t _base,
1037            bool _add, int32_t _imm)
1038         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1039                 (IntRegIndex)_result, (IntRegIndex)_dest,
1040                 (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, _result, _dest,
1047                                   _base, _add, _imm);
1048        uops[1] = new %(wb_decl)s;
1049        uops[1]->setLastMicroop();
1050#endif
1051    }
1052}};
1053
1054def template StoreDRegConstructor {{
1055    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1056            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1057            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1058         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1059                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1060                 (IntRegIndex)_base, _add,
1061                 _shiftAmt, (ArmShiftType)_shiftType,
1062                 (IntRegIndex)_index)
1063    {
1064        %(constructor)s;
1065#if %(use_uops)d
1066        assert(numMicroops >= 2);
1067        uops = new StaticInstPtr[numMicroops];
1068        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1069                                   _shiftAmt, _shiftType, _index);
1070        uops[1] = new %(wb_decl)s;
1071        uops[1]->setLastMicroop();
1072#endif
1073    }
1074}};
1075
1076def template StoreRegConstructor {{
1077    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1078            uint32_t _dest, uint32_t _base, bool _add,
1079            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1080         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1081                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1082                 _shiftAmt, (ArmShiftType)_shiftType,
1083                 (IntRegIndex)_index)
1084    {
1085        %(constructor)s;
1086#if %(use_uops)d
1087        assert(numMicroops >= 2);
1088        uops = new StaticInstPtr[numMicroops];
1089        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1090                                   _shiftAmt, _shiftType, _index);
1091        uops[1] = new %(wb_decl)s;
1092        uops[1]->setLastMicroop();
1093#endif
1094    }
1095}};
1096
1097def template LoadDRegConstructor {{
1098    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1099            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1100            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1101         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1102                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1103                 (IntRegIndex)_base, _add,
1104                 _shiftAmt, (ArmShiftType)_shiftType,
1105                 (IntRegIndex)_index)
1106    {
1107        %(constructor)s;
1108#if %(use_uops)d
1109        assert(numMicroops >= 2);
1110        uops = new StaticInstPtr[numMicroops];
1111        if ((_dest == _index) || (_dest2 == _index)) {
1112            IntRegIndex wbIndexReg = INTREG_UREG0;
1113            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1114            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1115                                       _shiftAmt, _shiftType, _index);
1116            uops[2] = new %(wb_decl)s;
1117            uops[2]->setLastMicroop();
1118        } else {
1119            IntRegIndex wbIndexReg = index;
1120            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1121                                       _shiftAmt, _shiftType, _index);
1122            uops[1] = new %(wb_decl)s;
1123            uops[1]->setLastMicroop();
1124        }
1125#endif
1126    }
1127}};
1128
1129def template LoadRegConstructor {{
1130    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1131            uint32_t _dest, uint32_t _base, bool _add,
1132            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1133         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1134                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1135                 _shiftAmt, (ArmShiftType)_shiftType,
1136                 (IntRegIndex)_index)
1137    {
1138        %(constructor)s;
1139#if %(use_uops)d
1140        assert(numMicroops >= 2);
1141        uops = new StaticInstPtr[numMicroops];
1142        if (_dest == INTREG_PC) {
1143            IntRegIndex wbIndexReg = index;
1144            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1145                                       _shiftAmt, _shiftType, _index);
1146            uops[1] = new %(wb_decl)s;
1147            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1148            uops[2]->setLastMicroop();
1149        } else if(_dest == _index) {
1150            IntRegIndex wbIndexReg = INTREG_UREG0;
1151            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1152            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1153                                      _shiftAmt, _shiftType, _index);
1154            uops[2] = new %(wb_decl)s;
1155            uops[2]->setLastMicroop();
1156        } else {
1157            IntRegIndex wbIndexReg = index;
1158            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1159                                      _shiftAmt, _shiftType, _index);
1160            uops[1] = new %(wb_decl)s;
1161            uops[1]->setLastMicroop();
1162
1163        }
1164#endif
1165    }
1166}};
1167
1168def template LoadImmConstructor {{
1169    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1170            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1171         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1172                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1173    {
1174        %(constructor)s;
1175#if %(use_uops)d
1176        assert(numMicroops >= 2);
1177        uops = new StaticInstPtr[numMicroops];
1178        if (_dest == INTREG_PC) {
1179            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1180                                   _imm);
1181            uops[1] = new %(wb_decl)s;
1182            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1183            uops[2]->setLastMicroop();
1184        } else {
1185            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1186            uops[1] = new %(wb_decl)s;
1187            uops[1]->setLastMicroop();
1188        }
1189#endif
1190    }
1191}};
1192
1193