mem.isa revision 7848:cc5e64f8423f
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 (!(condCode == COND_AL || condCode == COND_UC)) {
917            for (int x = 0; x < _numDestRegs; x++) {
918                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
919            }
920        }
921#if %(use_uops)d
922        assert(numMicroops >= 2);
923        uops = new StaticInstPtr[numMicroops];
924        uops[0] = new %(acc_name)s(machInst, _base, _mode, _wb);
925        uops[0]->setDelayedCommit();
926        uops[1] = new %(wb_decl)s;
927        uops[1]->setLastMicroop();
928#endif
929    }
930}};
931
932def template SrsConstructor {{
933    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
934            uint32_t _regMode, int _mode, bool _wb)
935         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
936                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
937    {
938        %(constructor)s;
939        if (!(condCode == COND_AL || condCode == COND_UC)) {
940            for (int x = 0; x < _numDestRegs; x++) {
941                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
942            }
943        }
944#if %(use_uops)d
945        assert(numMicroops >= 2);
946        uops = new StaticInstPtr[numMicroops];
947        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
948        uops[0]->setDelayedCommit();
949        uops[1] = new %(wb_decl)s;
950        uops[1]->setLastMicroop();
951#endif
952    }
953}};
954
955def template SwapConstructor {{
956    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
957            uint32_t _dest, uint32_t _op1, uint32_t _base)
958         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
959                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
960    {
961        %(constructor)s;
962        if (!(condCode == COND_AL || condCode == COND_UC)) {
963            for (int x = 0; x < _numDestRegs; x++) {
964                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
965            }
966        }
967    }
968}};
969
970def template LoadStoreDImmConstructor {{
971    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
972            uint32_t _dest, uint32_t _dest2,
973            uint32_t _base, bool _add, int32_t _imm)
974         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
975                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
976                 (IntRegIndex)_base, _add, _imm)
977    {
978        %(constructor)s;
979        if (!(condCode == COND_AL || condCode == COND_UC)) {
980            for (int x = 0; x < _numDestRegs; x++) {
981                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
982            }
983        }
984#if %(use_uops)d
985        assert(numMicroops >= 2);
986        uops = new StaticInstPtr[numMicroops];
987        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
988        uops[0]->setDelayedCommit();
989        uops[1] = new %(wb_decl)s;
990        uops[1]->setLastMicroop();
991#endif
992    }
993}};
994
995def template StoreExDImmConstructor {{
996    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
997            uint32_t _result, uint32_t _dest, uint32_t _dest2,
998            uint32_t _base, bool _add, int32_t _imm)
999         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1000                 (IntRegIndex)_result,
1001                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1002                 (IntRegIndex)_base, _add, _imm)
1003    {
1004        %(constructor)s;
1005        if (!(condCode == COND_AL || condCode == COND_UC)) {
1006            for (int x = 0; x < _numDestRegs; x++) {
1007                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1008            }
1009        }
1010#if %(use_uops)d
1011        assert(numMicroops >= 2);
1012        uops = new StaticInstPtr[numMicroops];
1013        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
1014                                   _base, _add, _imm);
1015        uops[0]->setDelayedCommit();
1016        uops[1] = new %(wb_decl)s;
1017        uops[1]->setLastMicroop();
1018#endif
1019    }
1020}};
1021
1022def template LoadStoreImmConstructor {{
1023    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1024            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1025         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1026                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1027    {
1028        %(constructor)s;
1029        if (!(condCode == COND_AL || condCode == COND_UC)) {
1030            for (int x = 0; x < _numDestRegs; x++) {
1031                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1032            }
1033        }
1034#if %(use_uops)d
1035        assert(numMicroops >= 2);
1036        uops = new StaticInstPtr[numMicroops];
1037        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1038        uops[0]->setDelayedCommit();
1039        uops[1] = new %(wb_decl)s;
1040        uops[1]->setLastMicroop();
1041#endif
1042    }
1043}};
1044
1045def template StoreExImmConstructor {{
1046    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1047            uint32_t _result, uint32_t _dest, uint32_t _base,
1048            bool _add, int32_t _imm)
1049         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1050                 (IntRegIndex)_result, (IntRegIndex)_dest,
1051                 (IntRegIndex)_base, _add, _imm)
1052    {
1053        %(constructor)s;
1054        if (!(condCode == COND_AL || condCode == COND_UC)) {
1055            for (int x = 0; x < _numDestRegs; x++) {
1056                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1057            }
1058        }
1059#if %(use_uops)d
1060        assert(numMicroops >= 2);
1061        uops = new StaticInstPtr[numMicroops];
1062        uops[0] = new %(acc_name)s(machInst, _result, _dest,
1063                                   _base, _add, _imm);
1064        uops[0]->setDelayedCommit();
1065        uops[1] = new %(wb_decl)s;
1066        uops[1]->setLastMicroop();
1067#endif
1068    }
1069}};
1070
1071def template StoreDRegConstructor {{
1072    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1073            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1074            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1075         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1076                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1077                 (IntRegIndex)_base, _add,
1078                 _shiftAmt, (ArmShiftType)_shiftType,
1079                 (IntRegIndex)_index)
1080    {
1081        %(constructor)s;
1082        if (!(condCode == COND_AL || condCode == COND_UC)) {
1083            for (int x = 0; x < _numDestRegs; x++) {
1084                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1085            }
1086        }
1087#if %(use_uops)d
1088        assert(numMicroops >= 2);
1089        uops = new StaticInstPtr[numMicroops];
1090        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1091                                   _shiftAmt, _shiftType, _index);
1092        uops[0]->setDelayedCommit();
1093        uops[1] = new %(wb_decl)s;
1094        uops[1]->setLastMicroop();
1095#endif
1096    }
1097}};
1098
1099def template StoreRegConstructor {{
1100    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1101            uint32_t _dest, uint32_t _base, bool _add,
1102            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1103         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1104                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1105                 _shiftAmt, (ArmShiftType)_shiftType,
1106                 (IntRegIndex)_index)
1107    {
1108        %(constructor)s;
1109        if (!(condCode == COND_AL || condCode == COND_UC)) {
1110            for (int x = 0; x < _numDestRegs; x++) {
1111                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1112            }
1113        }
1114#if %(use_uops)d
1115        assert(numMicroops >= 2);
1116        uops = new StaticInstPtr[numMicroops];
1117        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1118                                   _shiftAmt, _shiftType, _index);
1119        uops[0]->setDelayedCommit();
1120        uops[1] = new %(wb_decl)s;
1121        uops[1]->setLastMicroop();
1122#endif
1123    }
1124}};
1125
1126def template LoadDRegConstructor {{
1127    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1128            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1129            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1130         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1131                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1132                 (IntRegIndex)_base, _add,
1133                 _shiftAmt, (ArmShiftType)_shiftType,
1134                 (IntRegIndex)_index)
1135    {
1136        %(constructor)s;
1137        if (!(condCode == COND_AL || condCode == COND_UC)) {
1138            for (int x = 0; x < _numDestRegs; x++) {
1139                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1140            }
1141        }
1142#if %(use_uops)d
1143        assert(numMicroops >= 2);
1144        uops = new StaticInstPtr[numMicroops];
1145        if ((_dest == _index) || (_dest2 == _index)) {
1146            IntRegIndex wbIndexReg = INTREG_UREG0;
1147            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1148            uops[0]->setDelayedCommit();
1149            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1150                                       _shiftAmt, _shiftType, _index);
1151            uops[1]->setDelayedCommit();
1152            uops[2] = new %(wb_decl)s;
1153            uops[2]->setLastMicroop();
1154        } else {
1155            IntRegIndex wbIndexReg = index;
1156            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1157                                       _shiftAmt, _shiftType, _index);
1158            uops[0]->setDelayedCommit();
1159            uops[1] = new %(wb_decl)s;
1160            uops[1]->setLastMicroop();
1161        }
1162#endif
1163    }
1164}};
1165
1166def template LoadRegConstructor {{
1167    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1168            uint32_t _dest, uint32_t _base, bool _add,
1169            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1170         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1171                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1172                 _shiftAmt, (ArmShiftType)_shiftType,
1173                 (IntRegIndex)_index)
1174    {
1175        %(constructor)s;
1176        if (!(condCode == COND_AL || condCode == COND_UC)) {
1177            for (int x = 0; x < _numDestRegs; x++) {
1178                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1179            }
1180        }
1181#if %(use_uops)d
1182        assert(numMicroops >= 2);
1183        uops = new StaticInstPtr[numMicroops];
1184        if (_dest == INTREG_PC) {
1185            IntRegIndex wbIndexReg = index;
1186            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1187                                       _shiftAmt, _shiftType, _index);
1188            uops[0]->setDelayedCommit();
1189            uops[1] = new %(wb_decl)s;
1190            uops[1]->setDelayedCommit();
1191            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1192            uops[2]->setLastMicroop();
1193        } else if(_dest == _index) {
1194            IntRegIndex wbIndexReg = INTREG_UREG0;
1195            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1196            uops[0]->setDelayedCommit();
1197            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1198                                      _shiftAmt, _shiftType, _index);
1199            uops[1]->setDelayedCommit();
1200            uops[2] = new %(wb_decl)s;
1201            uops[2]->setLastMicroop();
1202        } else {
1203            IntRegIndex wbIndexReg = index;
1204            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1205                                      _shiftAmt, _shiftType, _index);
1206            uops[0]->setDelayedCommit();
1207            uops[1] = new %(wb_decl)s;
1208            uops[1]->setLastMicroop();
1209
1210        }
1211#endif
1212    }
1213}};
1214
1215def template LoadImmConstructor {{
1216    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1217            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1218         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1219                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1220    {
1221        %(constructor)s;
1222        if (!(condCode == COND_AL || condCode == COND_UC)) {
1223            for (int x = 0; x < _numDestRegs; x++) {
1224                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1225            }
1226        }
1227#if %(use_uops)d
1228        assert(numMicroops >= 2);
1229        uops = new StaticInstPtr[numMicroops];
1230        if (_dest == INTREG_PC) {
1231            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1232                                   _imm);
1233            uops[0]->setDelayedCommit();
1234            uops[1] = new %(wb_decl)s;
1235            uops[1]->setDelayedCommit();
1236            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1237            uops[2]->setLastMicroop();
1238        } else {
1239            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1240            uops[0]->setDelayedCommit();
1241            uops[1] = new %(wb_decl)s;
1242            uops[1]->setLastMicroop();
1243        }
1244#endif
1245    }
1246}};
1247
1248