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