mem.isa revision 7712:7733c562e5e3
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        if (machInst.itstateMask != 0) {
599            warn_once("Complete acc isn't called on normal stores in O3.");
600            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
601        }
602        return NoFault;
603    }
604}};
605
606def template NeonStoreCompleteAcc {{
607    template <class Element>
608    Fault %(class_name)s<Element>::completeAcc(
609            PacketPtr pkt, %(CPU_exec_context)s *xc,
610            Trace::InstRecord *traceData) const
611    {
612        if (machInst.itstateMask != 0) {
613            warn_once("Complete acc isn't called on normal stores in O3.");
614            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
615        }
616        return NoFault;
617    }
618}};
619
620def template StoreExCompleteAcc {{
621    Fault %(class_name)s::completeAcc(PacketPtr pkt,
622                                      %(CPU_exec_context)s *xc,
623                                      Trace::InstRecord *traceData) const
624    {
625        Fault fault = NoFault;
626
627        %(op_decl)s;
628        %(op_rd)s;
629
630        if (%(predicate_test)s)
631        {
632            uint64_t writeResult = pkt->req->getExtraData();
633            %(postacc_code)s;
634
635            if (fault == NoFault) {
636                %(op_wb)s;
637            }
638        }
639
640        if (fault == NoFault && machInst.itstateMask != 0) {
641            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
642        }
643
644        return fault;
645    }
646}};
647
648def template RfeDeclare {{
649    /**
650     * Static instruction class for "%(mnemonic)s".
651     */
652    class %(class_name)s : public %(base_class)s
653    {
654      public:
655
656        /// Constructor.
657        %(class_name)s(ExtMachInst machInst,
658                uint32_t _base, int _mode, bool _wb);
659
660        %(BasicExecDeclare)s
661
662        %(InitiateAccDeclare)s
663
664        %(CompleteAccDeclare)s
665    };
666}};
667
668def template SrsDeclare {{
669    /**
670     * Static instruction class for "%(mnemonic)s".
671     */
672    class %(class_name)s : public %(base_class)s
673    {
674      public:
675
676        /// Constructor.
677        %(class_name)s(ExtMachInst machInst,
678                uint32_t _regMode, int _mode, bool _wb);
679
680        %(BasicExecDeclare)s
681
682        %(InitiateAccDeclare)s
683
684        %(CompleteAccDeclare)s
685    };
686}};
687
688def template SwapDeclare {{
689    /**
690     * Static instruction class for "%(mnemonic)s".
691     */
692    class %(class_name)s : public %(base_class)s
693    {
694      public:
695
696        /// Constructor.
697        %(class_name)s(ExtMachInst machInst,
698                uint32_t _dest, uint32_t _op1, uint32_t _base);
699
700        %(BasicExecDeclare)s
701
702        %(InitiateAccDeclare)s
703
704        %(CompleteAccDeclare)s
705    };
706}};
707
708def template LoadStoreDImmDeclare {{
709    /**
710     * Static instruction class for "%(mnemonic)s".
711     */
712    class %(class_name)s : public %(base_class)s
713    {
714      public:
715
716        /// Constructor.
717        %(class_name)s(ExtMachInst machInst,
718                uint32_t _dest, uint32_t _dest2,
719                uint32_t _base, bool _add, int32_t _imm);
720
721        %(BasicExecDeclare)s
722
723        %(InitiateAccDeclare)s
724
725        %(CompleteAccDeclare)s
726    };
727}};
728
729def template StoreExDImmDeclare {{
730    /**
731     * Static instruction class for "%(mnemonic)s".
732     */
733    class %(class_name)s : public %(base_class)s
734    {
735      public:
736
737        /// Constructor.
738        %(class_name)s(ExtMachInst machInst,
739                uint32_t _result, uint32_t _dest, uint32_t _dest2,
740                uint32_t _base, bool _add, int32_t _imm);
741
742        %(BasicExecDeclare)s
743
744        %(InitiateAccDeclare)s
745
746        %(CompleteAccDeclare)s
747    };
748}};
749
750def template LoadStoreImmDeclare {{
751    /**
752     * Static instruction class for "%(mnemonic)s".
753     */
754    class %(class_name)s : public %(base_class)s
755    {
756      public:
757
758        /// Constructor.
759        %(class_name)s(ExtMachInst machInst,
760                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
761
762        %(BasicExecDeclare)s
763
764        %(InitiateAccDeclare)s
765
766        %(CompleteAccDeclare)s
767    };
768}};
769
770def template StoreExImmDeclare {{
771    /**
772     * Static instruction class for "%(mnemonic)s".
773     */
774    class %(class_name)s : public %(base_class)s
775    {
776      public:
777
778        /// Constructor.
779        %(class_name)s(ExtMachInst machInst,
780                uint32_t _result, uint32_t _dest, uint32_t _base,
781                bool _add, int32_t _imm);
782
783        %(BasicExecDeclare)s
784
785        %(InitiateAccDeclare)s
786
787        %(CompleteAccDeclare)s
788    };
789}};
790
791def template StoreDRegDeclare {{
792    /**
793     * Static instruction class for "%(mnemonic)s".
794     */
795    class %(class_name)s : public %(base_class)s
796    {
797      public:
798
799        /// Constructor.
800        %(class_name)s(ExtMachInst machInst,
801                uint32_t _dest, uint32_t _dest2,
802                uint32_t _base, bool _add,
803                int32_t _shiftAmt, uint32_t _shiftType,
804                uint32_t _index);
805
806        %(BasicExecDeclare)s
807
808        %(InitiateAccDeclare)s
809
810        %(CompleteAccDeclare)s
811    };
812}};
813
814def template StoreRegDeclare {{
815    /**
816     * Static instruction class for "%(mnemonic)s".
817     */
818    class %(class_name)s : public %(base_class)s
819    {
820      public:
821
822        /// Constructor.
823        %(class_name)s(ExtMachInst machInst,
824                uint32_t _dest, uint32_t _base, bool _add,
825                int32_t _shiftAmt, uint32_t _shiftType,
826                uint32_t _index);
827
828        %(BasicExecDeclare)s
829
830        %(InitiateAccDeclare)s
831
832        %(CompleteAccDeclare)s
833    };
834}};
835
836def template LoadDRegDeclare {{
837    /**
838     * Static instruction class for "%(mnemonic)s".
839     */
840    class %(class_name)s : public %(base_class)s
841    {
842      public:
843
844        /// Constructor.
845        %(class_name)s(ExtMachInst machInst,
846                uint32_t _dest, uint32_t _dest2,
847                uint32_t _base, bool _add,
848                int32_t _shiftAmt, uint32_t _shiftType,
849                uint32_t _index);
850
851        %(BasicExecDeclare)s
852
853        %(InitiateAccDeclare)s
854
855        %(CompleteAccDeclare)s
856    };
857}};
858
859def template LoadRegDeclare {{
860    /**
861     * Static instruction class for "%(mnemonic)s".
862     */
863    class %(class_name)s : public %(base_class)s
864    {
865      public:
866
867        /// Constructor.
868        %(class_name)s(ExtMachInst machInst,
869                uint32_t _dest, uint32_t _base, bool _add,
870                int32_t _shiftAmt, uint32_t _shiftType,
871                uint32_t _index);
872
873        %(BasicExecDeclare)s
874
875        %(InitiateAccDeclare)s
876
877        %(CompleteAccDeclare)s
878    };
879}};
880
881def template LoadImmDeclare {{
882    /**
883     * Static instruction class for "%(mnemonic)s".
884     */
885    class %(class_name)s : public %(base_class)s
886    {
887      public:
888
889        /// Constructor.
890        %(class_name)s(ExtMachInst machInst,
891                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
892
893        %(BasicExecDeclare)s
894
895        %(InitiateAccDeclare)s
896
897        %(CompleteAccDeclare)s
898    };
899}};
900
901def template InitiateAccDeclare {{
902    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
903}};
904
905def template CompleteAccDeclare {{
906    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
907}};
908
909def template RfeConstructor {{
910    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
911            uint32_t _base, int _mode, bool _wb)
912         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
913                 (IntRegIndex)_base, (AddrMode)_mode, _wb)
914    {
915        %(constructor)s;
916#if %(use_uops)d
917        assert(numMicroops >= 2);
918        uops = new StaticInstPtr[numMicroops];
919        uops[0] = new %(acc_name)s(machInst, _base, _mode, _wb);
920        uops[1] = new %(wb_decl)s;
921        uops[1]->setLastMicroop();
922#endif
923    }
924}};
925
926def template SrsConstructor {{
927    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
928            uint32_t _regMode, int _mode, bool _wb)
929         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
930                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
931    {
932        %(constructor)s;
933#if %(use_uops)d
934        assert(numMicroops >= 2);
935        uops = new StaticInstPtr[numMicroops];
936        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
937        uops[1] = new %(wb_decl)s;
938        uops[1]->setLastMicroop();
939#endif
940    }
941}};
942
943def template SwapConstructor {{
944    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
945            uint32_t _dest, uint32_t _op1, uint32_t _base)
946         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
947                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
948    {
949        %(constructor)s;
950    }
951}};
952
953def template LoadStoreDImmConstructor {{
954    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
955            uint32_t _dest, uint32_t _dest2,
956            uint32_t _base, bool _add, int32_t _imm)
957         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
958                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
959                 (IntRegIndex)_base, _add, _imm)
960    {
961        %(constructor)s;
962#if %(use_uops)d
963        assert(numMicroops >= 2);
964        uops = new StaticInstPtr[numMicroops];
965        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
966        uops[1] = new %(wb_decl)s;
967        uops[1]->setLastMicroop();
968#endif
969    }
970}};
971
972def template StoreExDImmConstructor {{
973    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
974            uint32_t _result, uint32_t _dest, uint32_t _dest2,
975            uint32_t _base, bool _add, int32_t _imm)
976         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
977                 (IntRegIndex)_result,
978                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
979                 (IntRegIndex)_base, _add, _imm)
980    {
981        %(constructor)s;
982#if %(use_uops)d
983        assert(numMicroops >= 2);
984        uops = new StaticInstPtr[numMicroops];
985        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
986                                   _base, _add, _imm);
987        uops[1] = new %(wb_decl)s;
988        uops[1]->setLastMicroop();
989#endif
990    }
991}};
992
993def template LoadStoreImmConstructor {{
994    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
995            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
996         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
997                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
998    {
999        %(constructor)s;
1000#if %(use_uops)d
1001        assert(numMicroops >= 2);
1002        uops = new StaticInstPtr[numMicroops];
1003        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1004        uops[1] = new %(wb_decl)s;
1005        uops[1]->setLastMicroop();
1006#endif
1007    }
1008}};
1009
1010def template StoreExImmConstructor {{
1011    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1012            uint32_t _result, uint32_t _dest, uint32_t _base,
1013            bool _add, int32_t _imm)
1014         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1015                 (IntRegIndex)_result, (IntRegIndex)_dest,
1016                 (IntRegIndex)_base, _add, _imm)
1017    {
1018        %(constructor)s;
1019#if %(use_uops)d
1020        assert(numMicroops >= 2);
1021        uops = new StaticInstPtr[numMicroops];
1022        uops[0] = new %(acc_name)s(machInst, _result, _dest,
1023                                   _base, _add, _imm);
1024        uops[1] = new %(wb_decl)s;
1025        uops[1]->setLastMicroop();
1026#endif
1027    }
1028}};
1029
1030def template StoreDRegConstructor {{
1031    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1032            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1033            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1034         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1035                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1036                 (IntRegIndex)_base, _add,
1037                 _shiftAmt, (ArmShiftType)_shiftType,
1038                 (IntRegIndex)_index)
1039    {
1040        %(constructor)s;
1041#if %(use_uops)d
1042        assert(numMicroops >= 2);
1043        uops = new StaticInstPtr[numMicroops];
1044        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1045                                   _shiftAmt, _shiftType, _index);
1046        uops[1] = new %(wb_decl)s;
1047        uops[1]->setLastMicroop();
1048#endif
1049    }
1050}};
1051
1052def template StoreRegConstructor {{
1053    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1054            uint32_t _dest, uint32_t _base, bool _add,
1055            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1056         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1057                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1058                 _shiftAmt, (ArmShiftType)_shiftType,
1059                 (IntRegIndex)_index)
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, _dest, _base, _add,
1066                                   _shiftAmt, _shiftType, _index);
1067        uops[1] = new %(wb_decl)s;
1068        uops[1]->setLastMicroop();
1069#endif
1070    }
1071}};
1072
1073def template LoadDRegConstructor {{
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        if ((_dest == _index) || (_dest2 == _index)) {
1088            IntRegIndex wbIndexReg = INTREG_UREG0;
1089            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1090            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1091                                       _shiftAmt, _shiftType, _index);
1092            uops[2] = new %(wb_decl)s;
1093            uops[2]->setLastMicroop();
1094        } else {
1095            IntRegIndex wbIndexReg = index;
1096            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1097                                       _shiftAmt, _shiftType, _index);
1098            uops[1] = new %(wb_decl)s;
1099            uops[1]->setLastMicroop();
1100        }
1101#endif
1102    }
1103}};
1104
1105def template LoadRegConstructor {{
1106    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1107            uint32_t _dest, uint32_t _base, bool _add,
1108            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1109         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1110                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1111                 _shiftAmt, (ArmShiftType)_shiftType,
1112                 (IntRegIndex)_index)
1113    {
1114        %(constructor)s;
1115#if %(use_uops)d
1116        assert(numMicroops >= 2);
1117        uops = new StaticInstPtr[numMicroops];
1118        if (_dest == INTREG_PC) {
1119            IntRegIndex wbIndexReg = index;
1120            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1121                                       _shiftAmt, _shiftType, _index);
1122            uops[1] = new %(wb_decl)s;
1123            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1124            uops[2]->setLastMicroop();
1125        } else if(_dest == _index) {
1126            IntRegIndex wbIndexReg = INTREG_UREG0;
1127            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1128            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1129                                      _shiftAmt, _shiftType, _index);
1130            uops[2] = new %(wb_decl)s;
1131            uops[2]->setLastMicroop();
1132        } else {
1133            IntRegIndex wbIndexReg = index;
1134            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1135                                      _shiftAmt, _shiftType, _index);
1136            uops[1] = new %(wb_decl)s;
1137            uops[1]->setLastMicroop();
1138
1139        }
1140#endif
1141    }
1142}};
1143
1144def template LoadImmConstructor {{
1145    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1146            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1147         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1148                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1149    {
1150        %(constructor)s;
1151#if %(use_uops)d
1152        assert(numMicroops >= 2);
1153        uops = new StaticInstPtr[numMicroops];
1154        if (_dest == INTREG_PC) {
1155            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1156                                   _imm);
1157            uops[1] = new %(wb_decl)s;
1158            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1159            uops[2]->setLastMicroop();
1160        } else {
1161            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1162            uops[1] = new %(wb_decl)s;
1163            uops[1]->setLastMicroop();
1164        }
1165#endif
1166    }
1167}};
1168
1169