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