mem.isa revision 11303:f694764d656d
18914Sandreas.hansson@arm.com// -*- mode:c++ -*-
28914Sandreas.hansson@arm.com
38914Sandreas.hansson@arm.com// Copyright (c) 2010, 2012, 2014 ARM Limited
48914Sandreas.hansson@arm.com// All rights reserved
58914Sandreas.hansson@arm.com//
68914Sandreas.hansson@arm.com// The license below extends only to copyright in the software and shall
78914Sandreas.hansson@arm.com// not be construed as granting a license to any other intellectual
88914Sandreas.hansson@arm.com// property including but not limited to intellectual property relating
98914Sandreas.hansson@arm.com// to a hardware implementation of the functionality of the software
108914Sandreas.hansson@arm.com// licensed hereunder.  You may use the software subject to the license
118914Sandreas.hansson@arm.com// terms below provided that you ensure that this notice is replicated
128914Sandreas.hansson@arm.com// unmodified and in its entirety in all distributions of the software,
138914Sandreas.hansson@arm.com// modified or unmodified, in source code or in binary form.
148914Sandreas.hansson@arm.com//
158914Sandreas.hansson@arm.com// Copyright (c) 2007-2008 The Florida State University
168914Sandreas.hansson@arm.com// All rights reserved.
178914Sandreas.hansson@arm.com//
188914Sandreas.hansson@arm.com// Redistribution and use in source and binary forms, with or without
198914Sandreas.hansson@arm.com// modification, are permitted provided that the following conditions are
208914Sandreas.hansson@arm.com// met: redistributions of source code must retain the above copyright
218914Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer;
228914Sandreas.hansson@arm.com// redistributions in binary form must reproduce the above copyright
238914Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer in the
248914Sandreas.hansson@arm.com// documentation and/or other materials provided with the distribution;
258914Sandreas.hansson@arm.com// neither the name of the copyright holders nor the names of its
268914Sandreas.hansson@arm.com// contributors may be used to endorse or promote products derived from
278914Sandreas.hansson@arm.com// this software without specific prior written permission.
288914Sandreas.hansson@arm.com//
298914Sandreas.hansson@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
308914Sandreas.hansson@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
318914Sandreas.hansson@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
328914Sandreas.hansson@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
338914Sandreas.hansson@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
348914Sandreas.hansson@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
358914Sandreas.hansson@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
368914Sandreas.hansson@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
378914Sandreas.hansson@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
388914Sandreas.hansson@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
398914Sandreas.hansson@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
408914Sandreas.hansson@arm.com//
418914Sandreas.hansson@arm.com// Authors: Stephen Hines
428914Sandreas.hansson@arm.com
438914Sandreas.hansson@arm.com
448914Sandreas.hansson@arm.comdef template PanicExecute {{
458914Sandreas.hansson@arm.com    Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
468914Sandreas.hansson@arm.com                                  Trace::InstRecord *traceData) const
478914Sandreas.hansson@arm.com    {
488914Sandreas.hansson@arm.com        panic("Execute function executed when it shouldn't be!\n");
498914Sandreas.hansson@arm.com        return NoFault;
508914Sandreas.hansson@arm.com    }
518914Sandreas.hansson@arm.com}};
528914Sandreas.hansson@arm.com
538914Sandreas.hansson@arm.comdef template PanicInitiateAcc {{
548914Sandreas.hansson@arm.com    Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
558914Sandreas.hansson@arm.com                                      Trace::InstRecord *traceData) const
568914Sandreas.hansson@arm.com    {
578914Sandreas.hansson@arm.com        panic("InitiateAcc function executed when it shouldn't be!\n");
588914Sandreas.hansson@arm.com        return NoFault;
598922Swilliam.wang@arm.com    }
608914Sandreas.hansson@arm.com}};
618914Sandreas.hansson@arm.com
628914Sandreas.hansson@arm.comdef template PanicCompleteAcc {{
638914Sandreas.hansson@arm.com    Fault %(class_name)s::completeAcc(PacketPtr pkt,
648914Sandreas.hansson@arm.com                                      CPU_EXEC_CONTEXT *xc,
658914Sandreas.hansson@arm.com                                      Trace::InstRecord *traceData) const
668914Sandreas.hansson@arm.com    {
678914Sandreas.hansson@arm.com        panic("CompleteAcc function executed when it shouldn't be!\n");
688914Sandreas.hansson@arm.com        return NoFault;
698914Sandreas.hansson@arm.com    }
708914Sandreas.hansson@arm.com}};
718922Swilliam.wang@arm.com
728922Swilliam.wang@arm.com
738922Swilliam.wang@arm.comdef template SwapExecute {{
748922Swilliam.wang@arm.com    Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
758922Swilliam.wang@arm.com                                  Trace::InstRecord *traceData) const
768922Swilliam.wang@arm.com    {
778922Swilliam.wang@arm.com        Addr EA;
788922Swilliam.wang@arm.com        Fault fault = NoFault;
798922Swilliam.wang@arm.com
808922Swilliam.wang@arm.com        %(op_decl)s;
818922Swilliam.wang@arm.com        uint64_t memData = 0;
828922Swilliam.wang@arm.com        %(op_rd)s;
838922Swilliam.wang@arm.com        %(ea_code)s;
848922Swilliam.wang@arm.com
858922Swilliam.wang@arm.com        if (%(predicate_test)s)
868922Swilliam.wang@arm.com        {
878922Swilliam.wang@arm.com            %(preacc_code)s;
888922Swilliam.wang@arm.com
898922Swilliam.wang@arm.com            if (fault == NoFault) {
908922Swilliam.wang@arm.com                fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
918922Swilliam.wang@arm.com                        &memData);
928922Swilliam.wang@arm.com            }
938922Swilliam.wang@arm.com
948922Swilliam.wang@arm.com            if (fault == NoFault) {
958922Swilliam.wang@arm.com                %(postacc_code)s;
968922Swilliam.wang@arm.com            }
978922Swilliam.wang@arm.com
988922Swilliam.wang@arm.com            if (fault == NoFault) {
998922Swilliam.wang@arm.com                %(op_wb)s;
1008922Swilliam.wang@arm.com            }
1018922Swilliam.wang@arm.com        } else {
1028922Swilliam.wang@arm.com            xc->setPredicate(false);
1038922Swilliam.wang@arm.com        }
1048922Swilliam.wang@arm.com
1058922Swilliam.wang@arm.com        return fault;
1068922Swilliam.wang@arm.com    }
1078922Swilliam.wang@arm.com}};
1088922Swilliam.wang@arm.com
1098922Swilliam.wang@arm.comdef template SwapInitiateAcc {{
1108922Swilliam.wang@arm.com    Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
1118914Sandreas.hansson@arm.com                                      Trace::InstRecord *traceData) const
1128914Sandreas.hansson@arm.com    {
1138914Sandreas.hansson@arm.com        Addr EA;
1148914Sandreas.hansson@arm.com        Fault fault = NoFault;
1158914Sandreas.hansson@arm.com
1168914Sandreas.hansson@arm.com        %(op_decl)s;
1178914Sandreas.hansson@arm.com        uint64_t memData = 0;
1188914Sandreas.hansson@arm.com        %(op_rd)s;
1198914Sandreas.hansson@arm.com        %(ea_code)s;
1208914Sandreas.hansson@arm.com
1218922Swilliam.wang@arm.com        if (%(predicate_test)s)
1228922Swilliam.wang@arm.com        {
1238922Swilliam.wang@arm.com            %(preacc_code)s;
1248914Sandreas.hansson@arm.com
1258914Sandreas.hansson@arm.com            if (fault == NoFault) {
1268922Swilliam.wang@arm.com                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
1278914Sandreas.hansson@arm.com                        &memData);
1288914Sandreas.hansson@arm.com            }
1298914Sandreas.hansson@arm.com        } else {
1308914Sandreas.hansson@arm.com            xc->setPredicate(false);
1318914Sandreas.hansson@arm.com        }
1328914Sandreas.hansson@arm.com
1338914Sandreas.hansson@arm.com        return fault;
1348914Sandreas.hansson@arm.com    }
1358914Sandreas.hansson@arm.com}};
1368914Sandreas.hansson@arm.com
1378914Sandreas.hansson@arm.comdef template SwapCompleteAcc {{
1388914Sandreas.hansson@arm.com    Fault %(class_name)s::completeAcc(PacketPtr pkt,
1398914Sandreas.hansson@arm.com                                      CPU_EXEC_CONTEXT *xc,
1408914Sandreas.hansson@arm.com                                      Trace::InstRecord *traceData) const
1418914Sandreas.hansson@arm.com    {
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            getMem(pkt, Mem, traceData);
151            uint64_t memData = Mem;
152
153            %(postacc_code)s;
154
155            if (fault == NoFault) {
156                %(op_wb)s;
157            }
158        }
159
160        return fault;
161    }
162}};
163
164def template LoadExecute {{
165    Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
166                                  Trace::InstRecord *traceData) const
167    {
168        Addr EA;
169        Fault fault = NoFault;
170
171        %(op_decl)s;
172        %(op_rd)s;
173        %(ea_code)s;
174
175        if (%(predicate_test)s)
176        {
177            if (fault == NoFault) {
178                fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
179                %(memacc_code)s;
180            }
181
182            if (fault == NoFault) {
183                %(op_wb)s;
184            }
185        } else {
186            xc->setPredicate(false);
187        }
188
189        return fault;
190    }
191}};
192
193def template NeonLoadExecute {{
194    template <class Element>
195    Fault %(class_name)s<Element>::execute(
196            CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
197    {
198        Addr EA;
199        Fault fault = NoFault;
200
201        %(op_decl)s;
202        %(mem_decl)s;
203        %(op_rd)s;
204        %(ea_code)s;
205
206        MemUnion memUnion;
207        uint8_t *dataPtr = memUnion.bytes;
208
209        if (%(predicate_test)s)
210        {
211            if (fault == NoFault) {
212                fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
213                %(memacc_code)s;
214            }
215
216            if (fault == NoFault) {
217                %(op_wb)s;
218            }
219        } else {
220            xc->setPredicate(false);
221        }
222
223        return fault;
224    }
225}};
226
227def template StoreExecute {{
228    Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
229                                  Trace::InstRecord *traceData) const
230    {
231        Addr EA;
232        Fault fault = NoFault;
233
234        %(op_decl)s;
235        %(op_rd)s;
236        %(ea_code)s;
237
238        if (%(predicate_test)s)
239        {
240            if (fault == NoFault) {
241                %(memacc_code)s;
242            }
243
244            if (fault == NoFault) {
245                fault = writeMemAtomic(xc, traceData, Mem, EA,
246                        memAccessFlags, NULL);
247            }
248
249            if (fault == NoFault) {
250                %(op_wb)s;
251            }
252        } else {
253            xc->setPredicate(false);
254        }
255
256        return fault;
257    }
258}};
259
260def template NeonStoreExecute {{
261    template <class Element>
262    Fault %(class_name)s<Element>::execute(
263            CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
264    {
265        Addr EA;
266        Fault fault = NoFault;
267
268        %(op_decl)s;
269        %(mem_decl)s;
270        %(op_rd)s;
271        %(ea_code)s;
272
273        MemUnion memUnion;
274        uint8_t *dataPtr = memUnion.bytes;
275
276        if (%(predicate_test)s)
277        {
278            if (fault == NoFault) {
279                %(memacc_code)s;
280            }
281
282            if (fault == NoFault) {
283                fault = xc->writeMem(dataPtr, %(size)d, EA,
284                                     memAccessFlags, NULL);
285            }
286
287            if (fault == NoFault) {
288                %(op_wb)s;
289            }
290        } else {
291            xc->setPredicate(false);
292        }
293
294        return fault;
295    }
296}};
297
298def template StoreExExecute {{
299    Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
300                                  Trace::InstRecord *traceData) const
301    {
302        Addr EA;
303        Fault fault = NoFault;
304
305        %(op_decl)s;
306        %(op_rd)s;
307        %(ea_code)s;
308
309        if (%(predicate_test)s)
310        {
311            if (fault == NoFault) {
312                %(memacc_code)s;
313            }
314
315            uint64_t writeResult;
316
317            if (fault == NoFault) {
318                fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
319                        &writeResult);
320            }
321
322            if (fault == NoFault) {
323                %(postacc_code)s;
324            }
325
326            if (fault == NoFault) {
327                %(op_wb)s;
328            }
329        } else {
330            xc->setPredicate(false);
331        }
332
333        return fault;
334    }
335}};
336
337def template StoreExInitiateAcc {{
338    Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
339                                      Trace::InstRecord *traceData) const
340    {
341        Addr EA;
342        Fault fault = NoFault;
343
344        %(op_decl)s;
345        %(op_rd)s;
346        %(ea_code)s;
347
348        if (%(predicate_test)s)
349        {
350            if (fault == NoFault) {
351                %(memacc_code)s;
352            }
353
354            if (fault == NoFault) {
355                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
356                        NULL);
357            }
358        } else {
359            xc->setPredicate(false);
360        }
361
362        return fault;
363    }
364}};
365
366def template StoreInitiateAcc {{
367    Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
368                                      Trace::InstRecord *traceData) const
369    {
370        Addr EA;
371        Fault fault = NoFault;
372
373        %(op_decl)s;
374        %(op_rd)s;
375        %(ea_code)s;
376
377        if (%(predicate_test)s)
378        {
379            if (fault == NoFault) {
380                %(memacc_code)s;
381            }
382
383            if (fault == NoFault) {
384                fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
385                        NULL);
386            }
387        } else {
388            xc->setPredicate(false);
389        }
390
391        return fault;
392    }
393}};
394
395def template NeonStoreInitiateAcc {{
396    template <class Element>
397    Fault %(class_name)s<Element>::initiateAcc(
398            CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
399    {
400        Addr EA;
401        Fault fault = NoFault;
402
403        %(op_decl)s;
404        %(mem_decl)s;
405        %(op_rd)s;
406        %(ea_code)s;
407
408        if (%(predicate_test)s)
409        {
410            MemUnion memUnion;
411            if (fault == NoFault) {
412                %(memacc_code)s;
413            }
414
415            if (fault == NoFault) {
416                fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
417                                     memAccessFlags, NULL);
418            }
419        } else {
420            xc->setPredicate(false);
421        }
422
423        return fault;
424    }
425}};
426
427def template LoadInitiateAcc {{
428    Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc,
429                                      Trace::InstRecord *traceData) const
430    {
431        Addr EA;
432        Fault fault = NoFault;
433
434        %(op_src_decl)s;
435        %(op_rd)s;
436        %(ea_code)s;
437
438        if (%(predicate_test)s)
439        {
440            if (fault == NoFault) {
441                fault = initiateMemRead(xc, traceData, EA, Mem,
442                                        memAccessFlags);
443            }
444        } else {
445            xc->setPredicate(false);
446        }
447
448        return fault;
449    }
450}};
451
452def template NeonLoadInitiateAcc {{
453    template <class Element>
454    Fault %(class_name)s<Element>::initiateAcc(
455            CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const
456    {
457        Addr EA;
458        Fault fault = NoFault;
459
460        %(op_decl)s;
461        %(mem_decl)s;
462        %(op_rd)s;
463        %(ea_code)s;
464
465        if (%(predicate_test)s)
466        {
467            if (fault == NoFault) {
468                fault = xc->initiateMemRead(EA, %(size)d, memAccessFlags);
469            }
470        } else {
471            xc->setPredicate(false);
472        }
473
474        return fault;
475    }
476}};
477
478def template LoadCompleteAcc {{
479    Fault %(class_name)s::completeAcc(PacketPtr pkt,
480                                      CPU_EXEC_CONTEXT *xc,
481                                      Trace::InstRecord *traceData) const
482    {
483        Fault fault = NoFault;
484
485        %(op_decl)s;
486        %(op_rd)s;
487
488        if (%(predicate_test)s)
489        {
490            // ARM instructions will not have a pkt if the predicate is false
491            getMem(pkt, Mem, traceData);
492
493            if (fault == NoFault) {
494                %(memacc_code)s;
495            }
496
497            if (fault == NoFault) {
498                %(op_wb)s;
499            }
500        }
501
502        return fault;
503    }
504}};
505
506def template NeonLoadCompleteAcc {{
507    template <class Element>
508    Fault %(class_name)s<Element>::completeAcc(
509            PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
510            Trace::InstRecord *traceData) const
511    {
512        Fault fault = NoFault;
513
514        %(mem_decl)s;
515        %(op_decl)s;
516        %(op_rd)s;
517
518        if (%(predicate_test)s)
519        {
520            // ARM instructions will not have a pkt if the predicate is false
521            MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
522
523            if (fault == NoFault) {
524                %(memacc_code)s;
525            }
526
527            if (fault == NoFault) {
528                %(op_wb)s;
529            }
530        }
531
532        return fault;
533    }
534}};
535
536def template StoreCompleteAcc {{
537    Fault %(class_name)s::completeAcc(PacketPtr pkt,
538                                      CPU_EXEC_CONTEXT *xc,
539                                      Trace::InstRecord *traceData) const
540    {
541        return NoFault;
542    }
543}};
544
545def template NeonStoreCompleteAcc {{
546    template <class Element>
547    Fault %(class_name)s<Element>::completeAcc(
548            PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
549            Trace::InstRecord *traceData) const
550    {
551        return NoFault;
552    }
553}};
554
555def template StoreExCompleteAcc {{
556    Fault %(class_name)s::completeAcc(PacketPtr pkt,
557                                      CPU_EXEC_CONTEXT *xc,
558                                      Trace::InstRecord *traceData) const
559    {
560        Fault fault = NoFault;
561
562        %(op_decl)s;
563        %(op_rd)s;
564
565        if (%(predicate_test)s)
566        {
567            uint64_t writeResult = pkt->req->getExtraData();
568            %(postacc_code)s;
569
570            if (fault == NoFault) {
571                %(op_wb)s;
572            }
573        }
574
575        return fault;
576    }
577}};
578
579def template RfeDeclare {{
580    /**
581     * Static instruction class for "%(mnemonic)s".
582     */
583    class %(class_name)s : public %(base_class)s
584    {
585      public:
586
587        /// Constructor.
588        %(class_name)s(ExtMachInst machInst,
589                uint32_t _base, int _mode, bool _wb);
590
591        %(BasicExecDeclare)s
592
593        %(InitiateAccDeclare)s
594
595        %(CompleteAccDeclare)s
596    };
597}};
598
599def template SrsDeclare {{
600    /**
601     * Static instruction class for "%(mnemonic)s".
602     */
603    class %(class_name)s : public %(base_class)s
604    {
605      public:
606
607        /// Constructor.
608        %(class_name)s(ExtMachInst machInst,
609                uint32_t _regMode, int _mode, bool _wb);
610
611        %(BasicExecDeclare)s
612
613        %(InitiateAccDeclare)s
614
615        %(CompleteAccDeclare)s
616    };
617}};
618
619def template SwapDeclare {{
620    /**
621     * Static instruction class for "%(mnemonic)s".
622     */
623    class %(class_name)s : public %(base_class)s
624    {
625      public:
626
627        /// Constructor.
628        %(class_name)s(ExtMachInst machInst,
629                uint32_t _dest, uint32_t _op1, uint32_t _base);
630
631        %(BasicExecDeclare)s
632
633        %(InitiateAccDeclare)s
634
635        %(CompleteAccDeclare)s
636    };
637}};
638
639def template LoadStoreDImmDeclare {{
640    /**
641     * Static instruction class for "%(mnemonic)s".
642     */
643    class %(class_name)s : public %(base_class)s
644    {
645      public:
646
647        /// Constructor.
648        %(class_name)s(ExtMachInst machInst,
649                uint32_t _dest, uint32_t _dest2,
650                uint32_t _base, bool _add, int32_t _imm);
651
652        %(BasicExecDeclare)s
653
654        %(InitiateAccDeclare)s
655
656        %(CompleteAccDeclare)s
657    };
658}};
659
660def template StoreExDImmDeclare {{
661    /**
662     * Static instruction class for "%(mnemonic)s".
663     */
664    class %(class_name)s : public %(base_class)s
665    {
666      public:
667
668        /// Constructor.
669        %(class_name)s(ExtMachInst machInst,
670                uint32_t _result, uint32_t _dest, uint32_t _dest2,
671                uint32_t _base, bool _add, int32_t _imm);
672
673        %(BasicExecDeclare)s
674
675        %(InitiateAccDeclare)s
676
677        %(CompleteAccDeclare)s
678    };
679}};
680
681def template LoadStoreImmDeclare {{
682    /**
683     * Static instruction class for "%(mnemonic)s".
684     */
685    class %(class_name)s : public %(base_class)s
686    {
687      public:
688
689        /// Constructor.
690        %(class_name)s(ExtMachInst machInst,
691                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
692
693        %(BasicExecDeclare)s
694
695        %(InitiateAccDeclare)s
696
697        %(CompleteAccDeclare)s
698
699        virtual void
700        annotateFault(ArmFault *fault) {
701            %(fa_code)s
702        }
703    };
704}};
705
706def template StoreExImmDeclare {{
707    /**
708     * Static instruction class for "%(mnemonic)s".
709     */
710    class %(class_name)s : public %(base_class)s
711    {
712      public:
713
714        /// Constructor.
715        %(class_name)s(ExtMachInst machInst,
716                uint32_t _result, uint32_t _dest, uint32_t _base,
717                bool _add, int32_t _imm);
718
719        %(BasicExecDeclare)s
720
721        %(InitiateAccDeclare)s
722
723        %(CompleteAccDeclare)s
724    };
725}};
726
727def template StoreDRegDeclare {{
728    /**
729     * Static instruction class for "%(mnemonic)s".
730     */
731    class %(class_name)s : public %(base_class)s
732    {
733      public:
734
735        /// Constructor.
736        %(class_name)s(ExtMachInst machInst,
737                uint32_t _dest, uint32_t _dest2,
738                uint32_t _base, bool _add,
739                int32_t _shiftAmt, uint32_t _shiftType,
740                uint32_t _index);
741
742        %(BasicExecDeclare)s
743
744        %(InitiateAccDeclare)s
745
746        %(CompleteAccDeclare)s
747    };
748}};
749
750def template StoreRegDeclare {{
751    /**
752     * Static instruction class for "%(mnemonic)s".
753     */
754    class %(class_name)s : public %(base_class)s
755    {
756      public:
757
758        /// Constructor.
759        %(class_name)s(ExtMachInst machInst,
760                uint32_t _dest, uint32_t _base, bool _add,
761                int32_t _shiftAmt, uint32_t _shiftType,
762                uint32_t _index);
763
764        %(BasicExecDeclare)s
765
766        %(InitiateAccDeclare)s
767
768        %(CompleteAccDeclare)s
769
770        virtual void
771        annotateFault(ArmFault *fault) {
772            %(fa_code)s
773        }
774    };
775}};
776
777def template LoadDRegDeclare {{
778    /**
779     * Static instruction class for "%(mnemonic)s".
780     */
781    class %(class_name)s : public %(base_class)s
782    {
783      public:
784
785        /// Constructor.
786        %(class_name)s(ExtMachInst machInst,
787                uint32_t _dest, uint32_t _dest2,
788                uint32_t _base, bool _add,
789                int32_t _shiftAmt, uint32_t _shiftType,
790                uint32_t _index);
791
792        %(BasicExecDeclare)s
793
794        %(InitiateAccDeclare)s
795
796        %(CompleteAccDeclare)s
797    };
798}};
799
800def template LoadRegDeclare {{
801    /**
802     * Static instruction class for "%(mnemonic)s".
803     */
804    class %(class_name)s : public %(base_class)s
805    {
806      public:
807
808        /// Constructor.
809        %(class_name)s(ExtMachInst machInst,
810                uint32_t _dest, uint32_t _base, bool _add,
811                int32_t _shiftAmt, uint32_t _shiftType,
812                uint32_t _index);
813
814        %(BasicExecDeclare)s
815
816        %(InitiateAccDeclare)s
817
818        %(CompleteAccDeclare)s
819
820        virtual void
821        annotateFault(ArmFault *fault) {
822            %(fa_code)s
823        }
824    };
825}};
826
827def template LoadImmDeclare {{
828    /**
829     * Static instruction class for "%(mnemonic)s".
830     */
831    class %(class_name)s : public %(base_class)s
832    {
833      public:
834
835        /// Constructor.
836        %(class_name)s(ExtMachInst machInst,
837                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
838
839        %(BasicExecDeclare)s
840
841        %(InitiateAccDeclare)s
842
843        %(CompleteAccDeclare)s
844
845        virtual void
846        annotateFault(ArmFault *fault) {
847            %(fa_code)s
848        }
849    };
850}};
851
852def template InitiateAccDeclare {{
853    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
854}};
855
856def template CompleteAccDeclare {{
857    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
858}};
859
860def template RfeConstructor {{
861    %(class_name)s::%(class_name)s(ExtMachInst machInst,
862                                          uint32_t _base, int _mode, bool _wb)
863        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
864                         (IntRegIndex)_base, (AddrMode)_mode, _wb)
865    {
866        %(constructor)s;
867        if (!(condCode == COND_AL || condCode == COND_UC)) {
868            for (int x = 0; x < _numDestRegs; x++) {
869                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
870            }
871        }
872#if %(use_uops)d
873        uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
874        int uopIdx = 0;
875        uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
876        uops[uopIdx]->setDelayedCommit();
877#if %(use_wb)d
878        uops[++uopIdx] = new %(wb_decl)s;
879        uops[uopIdx]->setDelayedCommit();
880#endif
881#if %(use_pc)d
882        uops[++uopIdx] = new %(pc_decl)s;
883#endif
884        uops[0]->setFirstMicroop();
885        uops[uopIdx]->setLastMicroop();
886#endif
887    }
888}};
889
890def template SrsConstructor {{
891    %(class_name)s::%(class_name)s(ExtMachInst machInst,
892            uint32_t _regMode, int _mode, bool _wb)
893         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
894                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
895    {
896        %(constructor)s;
897        if (!(condCode == COND_AL || condCode == COND_UC)) {
898            for (int x = 0; x < _numDestRegs; x++) {
899                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
900            }
901        }
902#if %(use_uops)d
903        assert(numMicroops >= 2);
904        uops = new StaticInstPtr[numMicroops];
905        uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
906        uops[0]->setDelayedCommit();
907        uops[0]->setFirstMicroop();
908        uops[1] = new %(wb_decl)s;
909        uops[1]->setLastMicroop();
910#endif
911    }
912}};
913
914def template SwapConstructor {{
915    %(class_name)s::%(class_name)s(ExtMachInst machInst,
916            uint32_t _dest, uint32_t _op1, uint32_t _base)
917         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
918                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
919    {
920        %(constructor)s;
921        if (!(condCode == COND_AL || condCode == COND_UC)) {
922            for (int x = 0; x < _numDestRegs; x++) {
923                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
924            }
925        }
926    }
927}};
928
929def template LoadStoreDImmConstructor {{
930    %(class_name)s::%(class_name)s(ExtMachInst machInst,
931            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)_dest, (IntRegIndex)_dest2,
935                 (IntRegIndex)_base, _add, _imm)
936    {
937        %(constructor)s;
938        if (!(condCode == COND_AL || condCode == COND_UC)) {
939            for (int x = 0; x < _numDestRegs; x++) {
940                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
941            }
942        }
943#if %(use_uops)d
944        assert(numMicroops >= 2);
945        uops = new StaticInstPtr[numMicroops];
946        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
947        uops[0]->setFirstMicroop();
948        uops[0]->setDelayedCommit();
949        uops[1] = new %(wb_decl)s;
950        uops[1]->setLastMicroop();
951#endif
952    }
953}};
954
955def template StoreExDImmConstructor {{
956    %(class_name)s::%(class_name)s(ExtMachInst machInst,
957            uint32_t _result, uint32_t _dest, uint32_t _dest2,
958            uint32_t _base, bool _add, int32_t _imm)
959         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
960                 (IntRegIndex)_result,
961                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
962                 (IntRegIndex)_base, _add, _imm)
963    {
964        %(constructor)s;
965        if (!(condCode == COND_AL || condCode == COND_UC)) {
966            for (int x = 0; x < _numDestRegs; x++) {
967                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
968            }
969        }
970#if %(use_uops)d
971        assert(numMicroops >= 2);
972        uops = new StaticInstPtr[numMicroops];
973        uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
974                                   _base, _add, _imm);
975        uops[0]->setDelayedCommit();
976        uops[0]->setFirstMicroop();
977        uops[1] = new %(wb_decl)s;
978        uops[1]->setLastMicroop();
979#endif
980    }
981}};
982
983def template LoadStoreImmConstructor {{
984    %(class_name)s::%(class_name)s(ExtMachInst machInst,
985            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
986         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
987                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
988    {
989        %(constructor)s;
990        if (!(condCode == COND_AL || condCode == COND_UC)) {
991            for (int x = 0; x < _numDestRegs; x++) {
992                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
993            }
994        }
995#if %(use_uops)d
996        assert(numMicroops >= 2);
997        uops = new StaticInstPtr[numMicroops];
998        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
999        uops[0]->setDelayedCommit();
1000        uops[0]->setFirstMicroop();
1001        uops[1] = new %(wb_decl)s;
1002        uops[1]->setLastMicroop();
1003#endif
1004    }
1005}};
1006
1007def template StoreExImmConstructor {{
1008    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1009            uint32_t _result, uint32_t _dest, uint32_t _base,
1010            bool _add, int32_t _imm)
1011         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1012                 (IntRegIndex)_result, (IntRegIndex)_dest,
1013                 (IntRegIndex)_base, _add, _imm)
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, _result, _dest,
1025                                   _base, _add, _imm);
1026        uops[0]->setDelayedCommit();
1027        uops[0]->setFirstMicroop();
1028        uops[1] = new %(wb_decl)s;
1029        uops[1]->setLastMicroop();
1030#endif
1031    }
1032}};
1033
1034def template StoreDRegConstructor {{
1035    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1036            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1037            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1038         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1039                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1040                 (IntRegIndex)_base, _add,
1041                 _shiftAmt, (ArmShiftType)_shiftType,
1042                 (IntRegIndex)_index)
1043    {
1044        %(constructor)s;
1045        if (!(condCode == COND_AL || condCode == COND_UC)) {
1046            for (int x = 0; x < _numDestRegs; x++) {
1047                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1048            }
1049        }
1050#if %(use_uops)d
1051        assert(numMicroops >= 2);
1052        uops = new StaticInstPtr[numMicroops];
1053        uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1054                                   _shiftAmt, _shiftType, _index);
1055        uops[0]->setDelayedCommit();
1056        uops[0]->setFirstMicroop();
1057        uops[1] = new %(wb_decl)s;
1058        uops[1]->setLastMicroop();
1059#endif
1060    }
1061}};
1062
1063def template StoreRegConstructor {{
1064    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1065            uint32_t _dest, uint32_t _base, bool _add,
1066            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1067         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1068                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1069                 _shiftAmt, (ArmShiftType)_shiftType,
1070                 (IntRegIndex)_index)
1071    {
1072        %(constructor)s;
1073        if (!(condCode == COND_AL || condCode == COND_UC)) {
1074            for (int x = 0; x < _numDestRegs; x++) {
1075                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1076            }
1077        }
1078#if %(use_uops)d
1079        assert(numMicroops >= 2);
1080        uops = new StaticInstPtr[numMicroops];
1081        uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1082                                   _shiftAmt, _shiftType, _index);
1083        uops[0]->setDelayedCommit();
1084        uops[0]->setFirstMicroop();
1085        uops[1] = new %(wb_decl)s;
1086        uops[1]->setLastMicroop();
1087#endif
1088    }
1089}};
1090
1091def template LoadDRegConstructor {{
1092    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1093            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1094            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1095         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1096                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1097                 (IntRegIndex)_base, _add,
1098                 _shiftAmt, (ArmShiftType)_shiftType,
1099                 (IntRegIndex)_index)
1100    {
1101        %(constructor)s;
1102        if (!(condCode == COND_AL || condCode == COND_UC)) {
1103            for (int x = 0; x < _numDestRegs; x++) {
1104                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1105            }
1106        }
1107#if %(use_uops)d
1108        assert(numMicroops >= 2);
1109        uops = new StaticInstPtr[numMicroops];
1110        if ((_dest == _index) || (_dest2 == _index)) {
1111            IntRegIndex wbIndexReg = INTREG_UREG0;
1112            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1113            uops[0]->setDelayedCommit();
1114            uops[0]->setFirstMicroop();
1115            uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1116                                       _shiftAmt, _shiftType, _index);
1117            uops[1]->setDelayedCommit();
1118            uops[2] = new %(wb_decl)s;
1119            uops[2]->setLastMicroop();
1120        } else {
1121            IntRegIndex wbIndexReg = index;
1122            uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1123                                       _shiftAmt, _shiftType, _index);
1124            uops[0]->setDelayedCommit();
1125            uops[0]->setFirstMicroop();
1126            uops[1] = new %(wb_decl)s;
1127            uops[1]->setLastMicroop();
1128        }
1129#endif
1130    }
1131}};
1132
1133def template LoadRegConstructor {{
1134    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1135            uint32_t _dest, uint32_t _base, bool _add,
1136            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1137         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1138                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1139                 _shiftAmt, (ArmShiftType)_shiftType,
1140                 (IntRegIndex)_index)
1141    {
1142        %(constructor)s;
1143        bool conditional M5_VAR_USED = false;
1144        if (!(condCode == COND_AL || condCode == COND_UC)) {
1145            conditional = true;
1146            for (int x = 0; x < _numDestRegs; x++) {
1147                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1148            }
1149        }
1150#if %(use_uops)d
1151        assert(numMicroops >= 2);
1152        uops = new StaticInstPtr[numMicroops];
1153        if (_dest == INTREG_PC && !isFloating()) {
1154            IntRegIndex wbIndexReg = index;
1155            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1156                                       _shiftAmt, _shiftType, _index);
1157            uops[0]->setDelayedCommit();
1158            uops[0]->setFirstMicroop();
1159            uops[1] = new %(wb_decl)s;
1160            uops[1]->setDelayedCommit();
1161            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1162            uops[2]->setFlag(StaticInst::IsControl);
1163            uops[2]->setFlag(StaticInst::IsIndirectControl);
1164            if (conditional)
1165                uops[2]->setFlag(StaticInst::IsCondControl);
1166            else
1167                uops[2]->setFlag(StaticInst::IsUncondControl);
1168            uops[2]->setLastMicroop();
1169        } else if(_dest == _index) {
1170            IntRegIndex wbIndexReg = INTREG_UREG0;
1171            uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1172            uops[0]->setDelayedCommit();
1173            uops[0]->setFirstMicroop();
1174            uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1175                                      _shiftAmt, _shiftType, _index);
1176            uops[1]->setDelayedCommit();
1177            uops[2] = new %(wb_decl)s;
1178            uops[2]->setLastMicroop();
1179        } else {
1180            IntRegIndex wbIndexReg = index;
1181            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1182                                      _shiftAmt, _shiftType, _index);
1183            uops[0]->setDelayedCommit();
1184            uops[0]->setFirstMicroop();
1185            uops[1] = new %(wb_decl)s;
1186            uops[1]->setLastMicroop();
1187
1188        }
1189#else
1190        if (_dest == INTREG_PC && !isFloating()) {
1191            flags[IsControl] = true;
1192            flags[IsIndirectControl] = true;
1193            if (conditional)
1194                flags[IsCondControl] = true;
1195            else
1196                flags[IsUncondControl] = true;
1197        }
1198#endif
1199    }
1200}};
1201
1202def template LoadImmConstructor {{
1203    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1204            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1205         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1206                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1207    {
1208        %(constructor)s;
1209        bool conditional M5_VAR_USED = false;
1210        if (!(condCode == COND_AL || condCode == COND_UC)) {
1211            conditional = true;
1212            for (int x = 0; x < _numDestRegs; x++) {
1213                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1214            }
1215        }
1216#if %(use_uops)d
1217        assert(numMicroops >= 2);
1218        uops = new StaticInstPtr[numMicroops];
1219        if (_dest == INTREG_PC && !isFloating()) {
1220            uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1221                                   _imm);
1222            uops[0]->setDelayedCommit();
1223            uops[0]->setFirstMicroop();
1224            uops[1] = new %(wb_decl)s;
1225            uops[1]->setDelayedCommit();
1226            uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1227            uops[2]->setFlag(StaticInst::IsControl);
1228            uops[2]->setFlag(StaticInst::IsIndirectControl);
1229            /* Also set flags on the macroop so that pre-microop decomposition
1230                branch prediction can work */
1231            setFlag(StaticInst::IsControl);
1232            setFlag(StaticInst::IsIndirectControl);
1233            if (conditional) {
1234                uops[2]->setFlag(StaticInst::IsCondControl);
1235                setFlag(StaticInst::IsCondControl);
1236            } else {
1237                uops[2]->setFlag(StaticInst::IsUncondControl);
1238                setFlag(StaticInst::IsUncondControl);
1239            }
1240            if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s) {
1241                uops[2]->setFlag(StaticInst::IsReturn);
1242                setFlag(StaticInst::IsReturn);
1243            }
1244            uops[2]->setLastMicroop();
1245        } else {
1246            uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1247            uops[0]->setDelayedCommit();
1248            uops[0]->setFirstMicroop();
1249            uops[1] = new %(wb_decl)s;
1250            uops[1]->setLastMicroop();
1251        }
1252#else
1253        if (_dest == INTREG_PC && !isFloating()) {
1254            flags[IsControl] = true;
1255            flags[IsIndirectControl] = true;
1256            if (conditional)
1257                flags[IsCondControl] = true;
1258            else
1259                flags[IsUncondControl] = true;
1260        }
1261#endif
1262    }
1263}};
1264
1265