mem.isa revision 7597:063f160e8b50
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 SwapExecute {{
45    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
46                                  Trace::InstRecord *traceData) const
47    {
48        Addr EA;
49        Fault fault = NoFault;
50
51        %(op_decl)s;
52        uint64_t memData = 0;
53        %(op_rd)s;
54        %(ea_code)s;
55
56        if (%(predicate_test)s)
57        {
58            %(preacc_code)s;
59
60            if (fault == NoFault) {
61                fault = xc->write((uint%(mem_acc_size)d_t&)Mem,
62                        EA, memAccessFlags, &memData);
63            }
64
65            if (fault == NoFault) {
66                %(postacc_code)s;
67            }
68
69            if (fault == NoFault) {
70                %(op_wb)s;
71            }
72        } else {
73            xc->setPredicate(false);
74        }
75
76        if (fault == NoFault && machInst.itstateMask != 0) {
77            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
78        }
79
80        return fault;
81    }
82}};
83
84def template SwapInitiateAcc {{
85    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
86                                      Trace::InstRecord *traceData) const
87    {
88        Addr EA;
89        Fault fault = NoFault;
90
91        %(op_decl)s;
92        uint64_t memData = 0;
93        %(op_rd)s;
94        %(ea_code)s;
95
96        if (%(predicate_test)s)
97        {
98            %(preacc_code)s;
99
100            if (fault == NoFault) {
101                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
102                                  memAccessFlags, &memData);
103            }
104
105            if (fault == NoFault) {
106                %(op_wb)s;
107            }
108        } else {
109            xc->setPredicate(false);
110        }
111
112        if (fault == NoFault && machInst.itstateMask != 0) {
113            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
114        }
115
116        return fault;
117    }
118}};
119
120def template SwapCompleteAcc {{
121    Fault %(class_name)s::completeAcc(PacketPtr pkt,
122                                      %(CPU_exec_context)s *xc,
123                                      Trace::InstRecord *traceData) const
124    {
125        Fault fault = NoFault;
126
127        %(op_decl)s;
128        %(op_rd)s;
129
130        if (%(predicate_test)s)
131        {
132            // ARM instructions will not have a pkt if the predicate is false
133            uint64_t memData = pkt->get<typeof(Mem)>();
134
135            %(postacc_code)s;
136
137            if (fault == NoFault) {
138                %(op_wb)s;
139            }
140        }
141
142        if (fault == NoFault && machInst.itstateMask != 0) {
143            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
144        }
145
146        return fault;
147    }
148}};
149
150def template LoadExecute {{
151    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
152                                  Trace::InstRecord *traceData) const
153    {
154        Addr EA;
155        Fault fault = NoFault;
156
157        %(op_decl)s;
158        %(op_rd)s;
159        %(ea_code)s;
160
161        if (%(predicate_test)s)
162        {
163            if (fault == NoFault) {
164                fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
165                %(memacc_code)s;
166            }
167
168            if (fault == NoFault) {
169                %(op_wb)s;
170            }
171        } else {
172            xc->setPredicate(false);
173        }
174
175        if (fault == NoFault && machInst.itstateMask != 0) {
176            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
177        }
178
179        return fault;
180    }
181}};
182
183def template StoreExecute {{
184    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
185                                  Trace::InstRecord *traceData) const
186    {
187        Addr EA;
188        Fault fault = NoFault;
189
190        %(op_decl)s;
191        %(op_rd)s;
192        %(ea_code)s;
193
194        if (%(predicate_test)s)
195        {
196            if (fault == NoFault) {
197                %(memacc_code)s;
198            }
199
200            if (fault == NoFault) {
201                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
202                                  memAccessFlags, NULL);
203                if (traceData) { traceData->setData(Mem); }
204            }
205
206            if (fault == NoFault) {
207                %(op_wb)s;
208            }
209        } else {
210            xc->setPredicate(false);
211        }
212
213        if (fault == NoFault && machInst.itstateMask != 0) {
214            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
215        }
216
217        return fault;
218    }
219}};
220
221def template StoreExExecute {{
222    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
223                                  Trace::InstRecord *traceData) const
224    {
225        Addr EA;
226        Fault fault = NoFault;
227
228        %(op_decl)s;
229        %(op_rd)s;
230        %(ea_code)s;
231
232        if (%(predicate_test)s)
233        {
234            if (fault == NoFault) {
235                %(memacc_code)s;
236            }
237
238            uint64_t writeResult;
239
240            if (fault == NoFault) {
241                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
242                                  memAccessFlags, &writeResult);
243                if (traceData) { traceData->setData(Mem); }
244            }
245
246            if (fault == NoFault) {
247                %(postacc_code)s;
248            }
249
250            if (fault == NoFault) {
251                %(op_wb)s;
252            }
253        } else {
254            xc->setPredicate(false);
255        }
256
257        if (fault == NoFault && machInst.itstateMask != 0) {
258            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
259        }
260
261        return fault;
262    }
263}};
264
265def template StoreExInitiateAcc {{
266    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
267                                      Trace::InstRecord *traceData) const
268    {
269        Addr EA;
270        Fault fault = NoFault;
271
272        %(op_decl)s;
273        %(op_rd)s;
274        %(ea_code)s;
275
276        if (%(predicate_test)s)
277        {
278            if (fault == NoFault) {
279                %(memacc_code)s;
280            }
281
282            if (fault == NoFault) {
283                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
284                                  memAccessFlags, NULL);
285                if (traceData) { traceData->setData(Mem); }
286            }
287
288            // Need to write back any potential address register update
289            if (fault == NoFault) {
290                %(op_wb)s;
291            }
292        } else {
293            xc->setPredicate(false);
294        }
295
296        if (fault == NoFault && machInst.itstateMask != 0) {
297            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
298        }
299
300        return fault;
301    }
302}};
303
304def template StoreInitiateAcc {{
305    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
306                                      Trace::InstRecord *traceData) const
307    {
308        Addr EA;
309        Fault fault = NoFault;
310
311        %(op_decl)s;
312        %(op_rd)s;
313        %(ea_code)s;
314
315        if (%(predicate_test)s)
316        {
317            if (fault == NoFault) {
318                %(memacc_code)s;
319            }
320
321            if (fault == NoFault) {
322                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
323                                  memAccessFlags, NULL);
324                if (traceData) { traceData->setData(Mem); }
325            }
326
327            // Need to write back any potential address register update
328            if (fault == NoFault) {
329                %(op_wb)s;
330            }
331        } else {
332            xc->setPredicate(false);
333        }
334
335        if (fault == NoFault && machInst.itstateMask != 0) {
336            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
337        }
338
339        return fault;
340    }
341}};
342
343def template LoadInitiateAcc {{
344    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
345                                      Trace::InstRecord *traceData) const
346    {
347        Addr EA;
348        Fault fault = NoFault;
349
350        %(op_src_decl)s;
351        %(op_rd)s;
352        %(ea_code)s;
353
354        if (%(predicate_test)s)
355        {
356            if (fault == NoFault) {
357                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
358            }
359        } else {
360            xc->setPredicate(false);
361            if (fault == NoFault && machInst.itstateMask != 0) {
362                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
363            }
364        }
365
366        return fault;
367    }
368}};
369
370def template LoadCompleteAcc {{
371    Fault %(class_name)s::completeAcc(PacketPtr pkt,
372                                      %(CPU_exec_context)s *xc,
373                                      Trace::InstRecord *traceData) const
374    {
375        Fault fault = NoFault;
376
377        %(op_decl)s;
378        %(op_rd)s;
379
380        if (%(predicate_test)s)
381        {
382            // ARM instructions will not have a pkt if the predicate is false
383            Mem = pkt->get<typeof(Mem)>();
384
385            if (fault == NoFault) {
386                %(memacc_code)s;
387            }
388
389            if (fault == NoFault) {
390                %(op_wb)s;
391            }
392        }
393
394        if (fault == NoFault && machInst.itstateMask != 0) {
395            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
396        }
397
398        return fault;
399    }
400}};
401
402def template StoreCompleteAcc {{
403    Fault %(class_name)s::completeAcc(PacketPtr pkt,
404                                      %(CPU_exec_context)s *xc,
405                                      Trace::InstRecord *traceData) const
406    {
407        Fault fault = NoFault;
408
409        %(op_decl)s;
410        %(op_rd)s;
411
412        if (%(predicate_test)s)
413        {
414            if (fault == NoFault) {
415                %(op_wb)s;
416            }
417        }
418
419        if (fault == NoFault && machInst.itstateMask != 0) {
420            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
421        }
422
423        return fault;
424    }
425}};
426
427def template StoreExCompleteAcc {{
428    Fault %(class_name)s::completeAcc(PacketPtr pkt,
429                                      %(CPU_exec_context)s *xc,
430                                      Trace::InstRecord *traceData) const
431    {
432        Fault fault = NoFault;
433
434        %(op_decl)s;
435        %(op_rd)s;
436
437        if (%(predicate_test)s)
438        {
439            uint64_t writeResult = pkt->req->getExtraData();
440            %(postacc_code)s;
441
442            if (fault == NoFault) {
443                %(op_wb)s;
444            }
445        }
446
447        if (fault == NoFault && machInst.itstateMask != 0) {
448            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
449        }
450
451        return fault;
452    }
453}};
454
455def template RfeDeclare {{
456    /**
457     * Static instruction class for "%(mnemonic)s".
458     */
459    class %(class_name)s : public %(base_class)s
460    {
461      public:
462
463        /// Constructor.
464        %(class_name)s(ExtMachInst machInst,
465                uint32_t _base, int _mode, bool _wb);
466
467        %(BasicExecDeclare)s
468
469        %(InitiateAccDeclare)s
470
471        %(CompleteAccDeclare)s
472    };
473}};
474
475def template SrsDeclare {{
476    /**
477     * Static instruction class for "%(mnemonic)s".
478     */
479    class %(class_name)s : public %(base_class)s
480    {
481      public:
482
483        /// Constructor.
484        %(class_name)s(ExtMachInst machInst,
485                uint32_t _regMode, int _mode, bool _wb);
486
487        %(BasicExecDeclare)s
488
489        %(InitiateAccDeclare)s
490
491        %(CompleteAccDeclare)s
492    };
493}};
494
495def template SwapDeclare {{
496    /**
497     * Static instruction class for "%(mnemonic)s".
498     */
499    class %(class_name)s : public %(base_class)s
500    {
501      public:
502
503        /// Constructor.
504        %(class_name)s(ExtMachInst machInst,
505                uint32_t _dest, uint32_t _op1, uint32_t _base);
506
507        %(BasicExecDeclare)s
508
509        %(InitiateAccDeclare)s
510
511        %(CompleteAccDeclare)s
512    };
513}};
514
515def template LoadStoreDImmDeclare {{
516    /**
517     * Static instruction class for "%(mnemonic)s".
518     */
519    class %(class_name)s : public %(base_class)s
520    {
521      public:
522
523        /// Constructor.
524        %(class_name)s(ExtMachInst machInst,
525                uint32_t _dest, uint32_t _dest2,
526                uint32_t _base, bool _add, int32_t _imm);
527
528        %(BasicExecDeclare)s
529
530        %(InitiateAccDeclare)s
531
532        %(CompleteAccDeclare)s
533    };
534}};
535
536def template StoreExDImmDeclare {{
537    /**
538     * Static instruction class for "%(mnemonic)s".
539     */
540    class %(class_name)s : public %(base_class)s
541    {
542      public:
543
544        /// Constructor.
545        %(class_name)s(ExtMachInst machInst,
546                uint32_t _result, uint32_t _dest, uint32_t _dest2,
547                uint32_t _base, bool _add, int32_t _imm);
548
549        %(BasicExecDeclare)s
550
551        %(InitiateAccDeclare)s
552
553        %(CompleteAccDeclare)s
554    };
555}};
556
557def template LoadStoreImmDeclare {{
558    /**
559     * Static instruction class for "%(mnemonic)s".
560     */
561    class %(class_name)s : public %(base_class)s
562    {
563      public:
564
565        /// Constructor.
566        %(class_name)s(ExtMachInst machInst,
567                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
568
569        %(BasicExecDeclare)s
570
571        %(InitiateAccDeclare)s
572
573        %(CompleteAccDeclare)s
574    };
575}};
576
577def template StoreExImmDeclare {{
578    /**
579     * Static instruction class for "%(mnemonic)s".
580     */
581    class %(class_name)s : public %(base_class)s
582    {
583      public:
584
585        /// Constructor.
586        %(class_name)s(ExtMachInst machInst,
587                uint32_t _result, uint32_t _dest, uint32_t _base,
588                bool _add, int32_t _imm);
589
590        %(BasicExecDeclare)s
591
592        %(InitiateAccDeclare)s
593
594        %(CompleteAccDeclare)s
595    };
596}};
597
598def template LoadStoreDRegDeclare {{
599    /**
600     * Static instruction class for "%(mnemonic)s".
601     */
602    class %(class_name)s : public %(base_class)s
603    {
604      public:
605
606        /// Constructor.
607        %(class_name)s(ExtMachInst machInst,
608                uint32_t _dest, uint32_t _dest2,
609                uint32_t _base, bool _add,
610                int32_t _shiftAmt, uint32_t _shiftType,
611                uint32_t _index);
612
613        %(BasicExecDeclare)s
614
615        %(InitiateAccDeclare)s
616
617        %(CompleteAccDeclare)s
618    };
619}};
620
621def template LoadStoreRegDeclare {{
622    /**
623     * Static instruction class for "%(mnemonic)s".
624     */
625    class %(class_name)s : public %(base_class)s
626    {
627      public:
628
629        /// Constructor.
630        %(class_name)s(ExtMachInst machInst,
631                uint32_t _dest, uint32_t _base, bool _add,
632                int32_t _shiftAmt, uint32_t _shiftType,
633                uint32_t _index);
634
635        %(BasicExecDeclare)s
636
637        %(InitiateAccDeclare)s
638
639        %(CompleteAccDeclare)s
640    };
641}};
642
643def template InitiateAccDeclare {{
644    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
645}};
646
647def template CompleteAccDeclare {{
648    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
649}};
650
651def template RfeConstructor {{
652    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
653            uint32_t _base, int _mode, bool _wb)
654         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
655                 (IntRegIndex)_base, (AddrMode)_mode, _wb)
656    {
657        %(constructor)s;
658    }
659}};
660
661def template SrsConstructor {{
662    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
663            uint32_t _regMode, int _mode, bool _wb)
664         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
665                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
666    {
667        %(constructor)s;
668    }
669}};
670
671def template SwapConstructor {{
672    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
673            uint32_t _dest, uint32_t _op1, uint32_t _base)
674         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
675                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
676    {
677        %(constructor)s;
678    }
679}};
680
681def template LoadStoreDImmConstructor {{
682    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
683            uint32_t _dest, uint32_t _dest2,
684            uint32_t _base, bool _add, int32_t _imm)
685         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
686                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
687                 (IntRegIndex)_base, _add, _imm)
688    {
689        %(constructor)s;
690    }
691}};
692
693def template StoreExDImmConstructor {{
694    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
695            uint32_t _result, uint32_t _dest, uint32_t _dest2,
696            uint32_t _base, bool _add, int32_t _imm)
697         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
698                 (IntRegIndex)_result,
699                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
700                 (IntRegIndex)_base, _add, _imm)
701    {
702        %(constructor)s;
703    }
704}};
705
706def template LoadStoreImmConstructor {{
707    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
708            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
709         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
710                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
711    {
712        %(constructor)s;
713    }
714}};
715
716def template StoreExImmConstructor {{
717    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
718            uint32_t _result, uint32_t _dest, uint32_t _base,
719            bool _add, int32_t _imm)
720         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
721                 (IntRegIndex)_result, (IntRegIndex)_dest,
722                 (IntRegIndex)_base, _add, _imm)
723    {
724        %(constructor)s;
725    }
726}};
727
728def template LoadStoreDRegConstructor {{
729    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
730            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
731            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
732         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
733                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
734                 (IntRegIndex)_base, _add,
735                 _shiftAmt, (ArmShiftType)_shiftType,
736                 (IntRegIndex)_index)
737    {
738        %(constructor)s;
739    }
740}};
741
742def template LoadStoreRegConstructor {{
743    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
744            uint32_t _dest, uint32_t _base, bool _add,
745            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
746         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
747                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
748                 _shiftAmt, (ArmShiftType)_shiftType,
749                 (IntRegIndex)_index)
750    {
751        %(constructor)s;
752    }
753}};
754