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