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