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