mem.isa revision 8205:7ecbffb674aa
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_src_decl)s;
459        %(op_rd)s;
460        %(ea_code)s;
461
462        if (%(predicate_test)s)
463        {
464            if (fault == NoFault) {
465                fault = xc->readBytes(EA, NULL, %(size)d, memAccessFlags);
466            }
467        } else {
468            xc->setPredicate(false);
469        }
470
471        return fault;
472    }
473}};
474
475def template LoadCompleteAcc {{
476    Fault %(class_name)s::completeAcc(PacketPtr pkt,
477                                      %(CPU_exec_context)s *xc,
478                                      Trace::InstRecord *traceData) const
479    {
480        Fault fault = NoFault;
481
482        %(op_decl)s;
483        %(op_rd)s;
484
485        if (%(predicate_test)s)
486        {
487            // ARM instructions will not have a pkt if the predicate is false
488            Mem = pkt->get<typeof(Mem)>();
489
490            if (fault == NoFault) {
491                %(memacc_code)s;
492            }
493
494            if (fault == NoFault) {
495                %(op_wb)s;
496            }
497        }
498
499        return fault;
500    }
501}};
502
503def template NeonLoadCompleteAcc {{
504    template <class Element>
505    Fault %(class_name)s<Element>::completeAcc(
506            PacketPtr pkt, %(CPU_exec_context)s *xc,
507            Trace::InstRecord *traceData) const
508    {
509        Fault fault = NoFault;
510
511        %(mem_decl)s;
512        %(op_decl)s;
513        %(op_rd)s;
514
515        if (%(predicate_test)s)
516        {
517            // ARM instructions will not have a pkt if the predicate is false
518            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
519
520            if (fault == NoFault) {
521                %(memacc_code)s;
522            }
523
524            if (fault == NoFault) {
525                %(op_wb)s;
526            }
527        }
528
529        return fault;
530    }
531}};
532
533def template StoreCompleteAcc {{
534    Fault %(class_name)s::completeAcc(PacketPtr pkt,
535                                      %(CPU_exec_context)s *xc,
536                                      Trace::InstRecord *traceData) const
537    {
538        return NoFault;
539    }
540}};
541
542def template NeonStoreCompleteAcc {{
543    template <class Element>
544    Fault %(class_name)s<Element>::completeAcc(
545            PacketPtr pkt, %(CPU_exec_context)s *xc,
546            Trace::InstRecord *traceData) const
547    {
548        return NoFault;
549    }
550}};
551
552def template StoreExCompleteAcc {{
553    Fault %(class_name)s::completeAcc(PacketPtr pkt,
554                                      %(CPU_exec_context)s *xc,
555                                      Trace::InstRecord *traceData) const
556    {
557        Fault fault = NoFault;
558
559        %(op_decl)s;
560        %(op_rd)s;
561
562        if (%(predicate_test)s)
563        {
564            uint64_t writeResult = pkt->req->getExtraData();
565            %(postacc_code)s;
566
567            if (fault == NoFault) {
568                %(op_wb)s;
569            }
570        }
571
572        return fault;
573    }
574}};
575
576def template RfeDeclare {{
577    /**
578     * Static instruction class for "%(mnemonic)s".
579     */
580    class %(class_name)s : public %(base_class)s
581    {
582      public:
583
584        /// Constructor.
585        %(class_name)s(ExtMachInst machInst,
586                uint32_t _base, int _mode, bool _wb);
587
588        %(BasicExecDeclare)s
589
590        %(InitiateAccDeclare)s
591
592        %(CompleteAccDeclare)s
593    };
594}};
595
596def template SrsDeclare {{
597    /**
598     * Static instruction class for "%(mnemonic)s".
599     */
600    class %(class_name)s : public %(base_class)s
601    {
602      public:
603
604        /// Constructor.
605        %(class_name)s(ExtMachInst machInst,
606                uint32_t _regMode, int _mode, bool _wb);
607
608        %(BasicExecDeclare)s
609
610        %(InitiateAccDeclare)s
611
612        %(CompleteAccDeclare)s
613    };
614}};
615
616def template SwapDeclare {{
617    /**
618     * Static instruction class for "%(mnemonic)s".
619     */
620    class %(class_name)s : public %(base_class)s
621    {
622      public:
623
624        /// Constructor.
625        %(class_name)s(ExtMachInst machInst,
626                uint32_t _dest, uint32_t _op1, uint32_t _base);
627
628        %(BasicExecDeclare)s
629
630        %(InitiateAccDeclare)s
631
632        %(CompleteAccDeclare)s
633    };
634}};
635
636def template LoadStoreDImmDeclare {{
637    /**
638     * Static instruction class for "%(mnemonic)s".
639     */
640    class %(class_name)s : public %(base_class)s
641    {
642      public:
643
644        /// Constructor.
645        %(class_name)s(ExtMachInst machInst,
646                uint32_t _dest, uint32_t _dest2,
647                uint32_t _base, bool _add, int32_t _imm);
648
649        %(BasicExecDeclare)s
650
651        %(InitiateAccDeclare)s
652
653        %(CompleteAccDeclare)s
654    };
655}};
656
657def template StoreExDImmDeclare {{
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 _result, uint32_t _dest, uint32_t _dest2,
668                uint32_t _base, bool _add, int32_t _imm);
669
670        %(BasicExecDeclare)s
671
672        %(InitiateAccDeclare)s
673
674        %(CompleteAccDeclare)s
675    };
676}};
677
678def template LoadStoreImmDeclare {{
679    /**
680     * Static instruction class for "%(mnemonic)s".
681     */
682    class %(class_name)s : public %(base_class)s
683    {
684      public:
685
686        /// Constructor.
687        %(class_name)s(ExtMachInst machInst,
688                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
689
690        %(BasicExecDeclare)s
691
692        %(InitiateAccDeclare)s
693
694        %(CompleteAccDeclare)s
695    };
696}};
697
698def template StoreExImmDeclare {{
699    /**
700     * Static instruction class for "%(mnemonic)s".
701     */
702    class %(class_name)s : public %(base_class)s
703    {
704      public:
705
706        /// Constructor.
707        %(class_name)s(ExtMachInst machInst,
708                uint32_t _result, uint32_t _dest, uint32_t _base,
709                bool _add, int32_t _imm);
710
711        %(BasicExecDeclare)s
712
713        %(InitiateAccDeclare)s
714
715        %(CompleteAccDeclare)s
716    };
717}};
718
719def template StoreDRegDeclare {{
720    /**
721     * Static instruction class for "%(mnemonic)s".
722     */
723    class %(class_name)s : public %(base_class)s
724    {
725      public:
726
727        /// Constructor.
728        %(class_name)s(ExtMachInst machInst,
729                uint32_t _dest, uint32_t _dest2,
730                uint32_t _base, bool _add,
731                int32_t _shiftAmt, uint32_t _shiftType,
732                uint32_t _index);
733
734        %(BasicExecDeclare)s
735
736        %(InitiateAccDeclare)s
737
738        %(CompleteAccDeclare)s
739    };
740}};
741
742def template StoreRegDeclare {{
743    /**
744     * Static instruction class for "%(mnemonic)s".
745     */
746    class %(class_name)s : public %(base_class)s
747    {
748      public:
749
750        /// Constructor.
751        %(class_name)s(ExtMachInst machInst,
752                uint32_t _dest, uint32_t _base, bool _add,
753                int32_t _shiftAmt, uint32_t _shiftType,
754                uint32_t _index);
755
756        %(BasicExecDeclare)s
757
758        %(InitiateAccDeclare)s
759
760        %(CompleteAccDeclare)s
761    };
762}};
763
764def template LoadDRegDeclare {{
765    /**
766     * Static instruction class for "%(mnemonic)s".
767     */
768    class %(class_name)s : public %(base_class)s
769    {
770      public:
771
772        /// Constructor.
773        %(class_name)s(ExtMachInst machInst,
774                uint32_t _dest, uint32_t _dest2,
775                uint32_t _base, bool _add,
776                int32_t _shiftAmt, uint32_t _shiftType,
777                uint32_t _index);
778
779        %(BasicExecDeclare)s
780
781        %(InitiateAccDeclare)s
782
783        %(CompleteAccDeclare)s
784    };
785}};
786
787def template LoadRegDeclare {{
788    /**
789     * Static instruction class for "%(mnemonic)s".
790     */
791    class %(class_name)s : public %(base_class)s
792    {
793      public:
794
795        /// Constructor.
796        %(class_name)s(ExtMachInst machInst,
797                uint32_t _dest, uint32_t _base, bool _add,
798                int32_t _shiftAmt, uint32_t _shiftType,
799                uint32_t _index);
800
801        %(BasicExecDeclare)s
802
803        %(InitiateAccDeclare)s
804
805        %(CompleteAccDeclare)s
806    };
807}};
808
809def template LoadImmDeclare {{
810    /**
811     * Static instruction class for "%(mnemonic)s".
812     */
813    class %(class_name)s : public %(base_class)s
814    {
815      public:
816
817        /// Constructor.
818        %(class_name)s(ExtMachInst machInst,
819                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
820
821        %(BasicExecDeclare)s
822
823        %(InitiateAccDeclare)s
824
825        %(CompleteAccDeclare)s
826    };
827}};
828
829def template InitiateAccDeclare {{
830    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
831}};
832
833def template CompleteAccDeclare {{
834    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
835}};
836
837def template RfeConstructor {{
838    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
839                                          uint32_t _base, int _mode, bool _wb)
840        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
841                         (IntRegIndex)_base, (AddrMode)_mode, _wb)
842    {
843        %(constructor)s;
844        if (!(condCode == COND_AL || condCode == COND_UC)) {
845            for (int x = 0; x < _numDestRegs; x++) {
846                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
847            }
848        }
849#if %(use_uops)d
850        uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
851        int uopIdx = 0;
852        uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
853        uops[uopIdx]->setDelayedCommit();
854#if %(use_wb)d
855        uops[++uopIdx] = new %(wb_decl)s;
856        uops[uopIdx]->setDelayedCommit();
857#endif
858#if %(use_pc)d
859        uops[++uopIdx] = new %(pc_decl)s;
860#endif
861        uops[uopIdx]->setLastMicroop();
862#endif
863    }
864}};
865
866def template SrsConstructor {{
867    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
868            uint32_t _regMode, int _mode, bool _wb)
869         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
870                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
871    {
872        %(constructor)s;
873        if (!(condCode == COND_AL || condCode == COND_UC)) {
874            for (int x = 0; x < _numDestRegs; x++) {
875                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
876            }
877        }
878#if %(use_uops)d
879        assert(numMicroops >= 2);
880        uops = new StaticInstPtr[numMicroops];
881        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
882        uops[0]->setDelayedCommit();
883        uops[1] = new %(wb_decl)s;
884        uops[1]->setLastMicroop();
885#endif
886    }
887}};
888
889def template SwapConstructor {{
890    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
891            uint32_t _dest, uint32_t _op1, uint32_t _base)
892         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
893                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
894    {
895        %(constructor)s;
896        if (!(condCode == COND_AL || condCode == COND_UC)) {
897            for (int x = 0; x < _numDestRegs; x++) {
898                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
899            }
900        }
901    }
902}};
903
904def template LoadStoreDImmConstructor {{
905    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
906            uint32_t _dest, uint32_t _dest2,
907            uint32_t _base, bool _add, int32_t _imm)
908         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
909                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
910                 (IntRegIndex)_base, _add, _imm)
911    {
912        %(constructor)s;
913        if (!(condCode == COND_AL || condCode == COND_UC)) {
914            for (int x = 0; x < _numDestRegs; x++) {
915                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
916            }
917        }
918#if %(use_uops)d
919        assert(numMicroops >= 2);
920        uops = new StaticInstPtr[numMicroops];
921        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
922        uops[0]->setDelayedCommit();
923        uops[1] = new %(wb_decl)s;
924        uops[1]->setLastMicroop();
925#endif
926    }
927}};
928
929def template StoreExDImmConstructor {{
930    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
931            uint32_t _result, uint32_t _dest, uint32_t _dest2,
932            uint32_t _base, bool _add, int32_t _imm)
933         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
934                 (IntRegIndex)_result,
935                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
936                 (IntRegIndex)_base, _add, _imm)
937    {
938        %(constructor)s;
939        if (!(condCode == COND_AL || condCode == COND_UC)) {
940            for (int x = 0; x < _numDestRegs; x++) {
941                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
942            }
943        }
944#if %(use_uops)d
945        assert(numMicroops >= 2);
946        uops = new StaticInstPtr[numMicroops];
947        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
948                                   _base, _add, _imm);
949        uops[0]->setDelayedCommit();
950        uops[1] = new %(wb_decl)s;
951        uops[1]->setLastMicroop();
952#endif
953    }
954}};
955
956def template LoadStoreImmConstructor {{
957    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
958            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
959         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
960                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
961    {
962        %(constructor)s;
963        if (!(condCode == COND_AL || condCode == COND_UC)) {
964            for (int x = 0; x < _numDestRegs; x++) {
965                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
966            }
967        }
968#if %(use_uops)d
969        assert(numMicroops >= 2);
970        uops = new StaticInstPtr[numMicroops];
971        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
972        uops[0]->setDelayedCommit();
973        uops[1] = new %(wb_decl)s;
974        uops[1]->setLastMicroop();
975#endif
976    }
977}};
978
979def template StoreExImmConstructor {{
980    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
981            uint32_t _result, uint32_t _dest, uint32_t _base,
982            bool _add, int32_t _imm)
983         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
984                 (IntRegIndex)_result, (IntRegIndex)_dest,
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, _result, _dest,
997                                   _base, _add, _imm);
998        uops[0]->setDelayedCommit();
999        uops[1] = new %(wb_decl)s;
1000        uops[1]->setLastMicroop();
1001#endif
1002    }
1003}};
1004
1005def template StoreDRegConstructor {{
1006    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1007            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1008            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1009         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1010                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1011                 (IntRegIndex)_base, _add,
1012                 _shiftAmt, (ArmShiftType)_shiftType,
1013                 (IntRegIndex)_index)
1014    {
1015        %(constructor)s;
1016        if (!(condCode == COND_AL || condCode == COND_UC)) {
1017            for (int x = 0; x < _numDestRegs; x++) {
1018                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1019            }
1020        }
1021#if %(use_uops)d
1022        assert(numMicroops >= 2);
1023        uops = new StaticInstPtr[numMicroops];
1024        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1025                                   _shiftAmt, _shiftType, _index);
1026        uops[0]->setDelayedCommit();
1027        uops[1] = new %(wb_decl)s;
1028        uops[1]->setLastMicroop();
1029#endif
1030    }
1031}};
1032
1033def template StoreRegConstructor {{
1034    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1035            uint32_t _dest, uint32_t _base, bool _add,
1036            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1037         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1038                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1039                 _shiftAmt, (ArmShiftType)_shiftType,
1040                 (IntRegIndex)_index)
1041    {
1042        %(constructor)s;
1043        if (!(condCode == COND_AL || condCode == COND_UC)) {
1044            for (int x = 0; x < _numDestRegs; x++) {
1045                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1046            }
1047        }
1048#if %(use_uops)d
1049        assert(numMicroops >= 2);
1050        uops = new StaticInstPtr[numMicroops];
1051        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1052                                   _shiftAmt, _shiftType, _index);
1053        uops[0]->setDelayedCommit();
1054        uops[1] = new %(wb_decl)s;
1055        uops[1]->setLastMicroop();
1056#endif
1057    }
1058}};
1059
1060def template LoadDRegConstructor {{
1061    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1062            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1063            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1064         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1065                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1066                 (IntRegIndex)_base, _add,
1067                 _shiftAmt, (ArmShiftType)_shiftType,
1068                 (IntRegIndex)_index)
1069    {
1070        %(constructor)s;
1071        if (!(condCode == COND_AL || condCode == COND_UC)) {
1072            for (int x = 0; x < _numDestRegs; x++) {
1073                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1074            }
1075        }
1076#if %(use_uops)d
1077        assert(numMicroops >= 2);
1078        uops = new StaticInstPtr[numMicroops];
1079        if ((_dest == _index) || (_dest2 == _index)) {
1080            IntRegIndex wbIndexReg = INTREG_UREG0;
1081            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1082            uops[0]->setDelayedCommit();
1083            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1084                                       _shiftAmt, _shiftType, _index);
1085            uops[1]->setDelayedCommit();
1086            uops[2] = new %(wb_decl)s;
1087            uops[2]->setLastMicroop();
1088        } else {
1089            IntRegIndex wbIndexReg = index;
1090            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1091                                       _shiftAmt, _shiftType, _index);
1092            uops[0]->setDelayedCommit();
1093            uops[1] = new %(wb_decl)s;
1094            uops[1]->setLastMicroop();
1095        }
1096#endif
1097    }
1098}};
1099
1100def template LoadRegConstructor {{
1101    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1102            uint32_t _dest, uint32_t _base, bool _add,
1103            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1104         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1105                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1106                 _shiftAmt, (ArmShiftType)_shiftType,
1107                 (IntRegIndex)_index)
1108    {
1109        %(constructor)s;
1110        bool conditional = false;
1111        if (!(condCode == COND_AL || condCode == COND_UC)) {
1112            conditional = true;
1113            for (int x = 0; x < _numDestRegs; x++) {
1114                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1115            }
1116        }
1117#if %(use_uops)d
1118        assert(numMicroops >= 2);
1119        uops = new StaticInstPtr[numMicroops];
1120        if (_dest == INTREG_PC) {
1121            IntRegIndex wbIndexReg = index;
1122            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1123                                       _shiftAmt, _shiftType, _index);
1124            uops[0]->setDelayedCommit();
1125            uops[1] = new %(wb_decl)s;
1126            uops[1]->setDelayedCommit();
1127            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1128            uops[2]->setFlag(StaticInst::IsControl);
1129            uops[2]->setFlag(StaticInst::IsIndirectControl);
1130            if (conditional)
1131                uops[2]->setFlag(StaticInst::IsCondControl);
1132            else
1133                uops[2]->setFlag(StaticInst::IsUncondControl);
1134            uops[2]->setLastMicroop();
1135        } else if(_dest == _index) {
1136            IntRegIndex wbIndexReg = INTREG_UREG0;
1137            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1138            uops[0]->setDelayedCommit();
1139            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1140                                      _shiftAmt, _shiftType, _index);
1141            uops[1]->setDelayedCommit();
1142            uops[2] = new %(wb_decl)s;
1143            uops[2]->setLastMicroop();
1144        } else {
1145            IntRegIndex wbIndexReg = index;
1146            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1147                                      _shiftAmt, _shiftType, _index);
1148            uops[0]->setDelayedCommit();
1149            uops[1] = new %(wb_decl)s;
1150            uops[1]->setLastMicroop();
1151
1152        }
1153#endif
1154    }
1155}};
1156
1157def template LoadImmConstructor {{
1158    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1159            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1160         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1161                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1162    {
1163        %(constructor)s;
1164        bool conditional = false;
1165        if (!(condCode == COND_AL || condCode == COND_UC)) {
1166            conditional = true;
1167            for (int x = 0; x < _numDestRegs; x++) {
1168                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1169            }
1170        }
1171#if %(use_uops)d
1172        assert(numMicroops >= 2);
1173        uops = new StaticInstPtr[numMicroops];
1174        if (_dest == INTREG_PC) {
1175            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1176                                   _imm);
1177            uops[0]->setDelayedCommit();
1178            uops[1] = new %(wb_decl)s;
1179            uops[1]->setDelayedCommit();
1180            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1181            uops[2]->setFlag(StaticInst::IsControl);
1182            uops[2]->setFlag(StaticInst::IsIndirectControl);
1183            if (conditional)
1184                uops[2]->setFlag(StaticInst::IsCondControl);
1185            else
1186                uops[2]->setFlag(StaticInst::IsUncondControl);
1187            if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s)
1188                uops[2]->setFlag(StaticInst::IsReturn);
1189            uops[2]->setLastMicroop();
1190        } else {
1191            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1192            uops[0]->setDelayedCommit();
1193            uops[1] = new %(wb_decl)s;
1194            uops[1]->setLastMicroop();
1195        }
1196#endif
1197    }
1198}};
1199
1200