mem.isa revision 7610:ebae85c30d32
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            }
204
205            if (fault == NoFault) {
206                %(op_wb)s;
207            }
208        } else {
209            xc->setPredicate(false);
210        }
211
212        if (fault == NoFault && machInst.itstateMask != 0) {
213            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
214        }
215
216        return fault;
217    }
218}};
219
220def template StoreExExecute {{
221    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
222                                  Trace::InstRecord *traceData) const
223    {
224        Addr EA;
225        Fault fault = NoFault;
226
227        %(op_decl)s;
228        %(op_rd)s;
229        %(ea_code)s;
230
231        if (%(predicate_test)s)
232        {
233            if (fault == NoFault) {
234                %(memacc_code)s;
235            }
236
237            uint64_t writeResult;
238
239            if (fault == NoFault) {
240                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
241                                  memAccessFlags, &writeResult);
242            }
243
244            if (fault == NoFault) {
245                %(postacc_code)s;
246            }
247
248            if (fault == NoFault) {
249                %(op_wb)s;
250            }
251        } else {
252            xc->setPredicate(false);
253        }
254
255        if (fault == NoFault && machInst.itstateMask != 0) {
256            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
257        }
258
259        return fault;
260    }
261}};
262
263def template StoreExInitiateAcc {{
264    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
265                                      Trace::InstRecord *traceData) const
266    {
267        Addr EA;
268        Fault fault = NoFault;
269
270        %(op_decl)s;
271        %(op_rd)s;
272        %(ea_code)s;
273
274        if (%(predicate_test)s)
275        {
276            if (fault == NoFault) {
277                %(memacc_code)s;
278            }
279
280            if (fault == NoFault) {
281                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
282                                  memAccessFlags, NULL);
283            }
284
285            // Need to write back any potential address register update
286            if (fault == NoFault) {
287                %(op_wb)s;
288            }
289        } else {
290            xc->setPredicate(false);
291        }
292
293        if (fault == NoFault && machInst.itstateMask != 0) {
294            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
295        }
296
297        return fault;
298    }
299}};
300
301def template StoreInitiateAcc {{
302    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
303                                      Trace::InstRecord *traceData) const
304    {
305        Addr EA;
306        Fault fault = NoFault;
307
308        %(op_decl)s;
309        %(op_rd)s;
310        %(ea_code)s;
311
312        if (%(predicate_test)s)
313        {
314            if (fault == NoFault) {
315                %(memacc_code)s;
316            }
317
318            if (fault == NoFault) {
319                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
320                                  memAccessFlags, NULL);
321            }
322
323            // Need to write back any potential address register update
324            if (fault == NoFault) {
325                %(op_wb)s;
326            }
327        } else {
328            xc->setPredicate(false);
329        }
330
331        if (fault == NoFault && machInst.itstateMask != 0) {
332            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
333        }
334
335        return fault;
336    }
337}};
338
339def template LoadInitiateAcc {{
340    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
341                                      Trace::InstRecord *traceData) const
342    {
343        Addr EA;
344        Fault fault = NoFault;
345
346        %(op_src_decl)s;
347        %(op_rd)s;
348        %(ea_code)s;
349
350        if (%(predicate_test)s)
351        {
352            if (fault == NoFault) {
353                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
354            }
355        } else {
356            xc->setPredicate(false);
357            if (fault == NoFault && machInst.itstateMask != 0) {
358                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
359            }
360        }
361
362        return fault;
363    }
364}};
365
366def template LoadCompleteAcc {{
367    Fault %(class_name)s::completeAcc(PacketPtr pkt,
368                                      %(CPU_exec_context)s *xc,
369                                      Trace::InstRecord *traceData) const
370    {
371        Fault fault = NoFault;
372
373        %(op_decl)s;
374        %(op_rd)s;
375
376        if (%(predicate_test)s)
377        {
378            // ARM instructions will not have a pkt if the predicate is false
379            Mem = pkt->get<typeof(Mem)>();
380
381            if (fault == NoFault) {
382                %(memacc_code)s;
383            }
384
385            if (fault == NoFault) {
386                %(op_wb)s;
387            }
388        }
389
390        if (fault == NoFault && machInst.itstateMask != 0) {
391            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
392        }
393
394        return fault;
395    }
396}};
397
398def template StoreCompleteAcc {{
399    Fault %(class_name)s::completeAcc(PacketPtr pkt,
400                                      %(CPU_exec_context)s *xc,
401                                      Trace::InstRecord *traceData) const
402    {
403        Fault fault = NoFault;
404
405        %(op_decl)s;
406        %(op_rd)s;
407
408        if (%(predicate_test)s)
409        {
410            if (fault == NoFault) {
411                %(op_wb)s;
412            }
413        }
414
415        if (fault == NoFault && machInst.itstateMask != 0) {
416            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
417        }
418
419        return fault;
420    }
421}};
422
423def template StoreExCompleteAcc {{
424    Fault %(class_name)s::completeAcc(PacketPtr pkt,
425                                      %(CPU_exec_context)s *xc,
426                                      Trace::InstRecord *traceData) const
427    {
428        Fault fault = NoFault;
429
430        %(op_decl)s;
431        %(op_rd)s;
432
433        if (%(predicate_test)s)
434        {
435            uint64_t writeResult = pkt->req->getExtraData();
436            %(postacc_code)s;
437
438            if (fault == NoFault) {
439                %(op_wb)s;
440            }
441        }
442
443        if (fault == NoFault && machInst.itstateMask != 0) {
444            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
445        }
446
447        return fault;
448    }
449}};
450
451def template RfeDeclare {{
452    /**
453     * Static instruction class for "%(mnemonic)s".
454     */
455    class %(class_name)s : public %(base_class)s
456    {
457      public:
458
459        /// Constructor.
460        %(class_name)s(ExtMachInst machInst,
461                uint32_t _base, int _mode, bool _wb);
462
463        %(BasicExecDeclare)s
464
465        %(InitiateAccDeclare)s
466
467        %(CompleteAccDeclare)s
468    };
469}};
470
471def template SrsDeclare {{
472    /**
473     * Static instruction class for "%(mnemonic)s".
474     */
475    class %(class_name)s : public %(base_class)s
476    {
477      public:
478
479        /// Constructor.
480        %(class_name)s(ExtMachInst machInst,
481                uint32_t _regMode, int _mode, bool _wb);
482
483        %(BasicExecDeclare)s
484
485        %(InitiateAccDeclare)s
486
487        %(CompleteAccDeclare)s
488    };
489}};
490
491def template SwapDeclare {{
492    /**
493     * Static instruction class for "%(mnemonic)s".
494     */
495    class %(class_name)s : public %(base_class)s
496    {
497      public:
498
499        /// Constructor.
500        %(class_name)s(ExtMachInst machInst,
501                uint32_t _dest, uint32_t _op1, uint32_t _base);
502
503        %(BasicExecDeclare)s
504
505        %(InitiateAccDeclare)s
506
507        %(CompleteAccDeclare)s
508    };
509}};
510
511def template LoadStoreDImmDeclare {{
512    /**
513     * Static instruction class for "%(mnemonic)s".
514     */
515    class %(class_name)s : public %(base_class)s
516    {
517      public:
518
519        /// Constructor.
520        %(class_name)s(ExtMachInst machInst,
521                uint32_t _dest, uint32_t _dest2,
522                uint32_t _base, bool _add, int32_t _imm);
523
524        %(BasicExecDeclare)s
525
526        %(InitiateAccDeclare)s
527
528        %(CompleteAccDeclare)s
529    };
530}};
531
532def template StoreExDImmDeclare {{
533    /**
534     * Static instruction class for "%(mnemonic)s".
535     */
536    class %(class_name)s : public %(base_class)s
537    {
538      public:
539
540        /// Constructor.
541        %(class_name)s(ExtMachInst machInst,
542                uint32_t _result, uint32_t _dest, uint32_t _dest2,
543                uint32_t _base, bool _add, int32_t _imm);
544
545        %(BasicExecDeclare)s
546
547        %(InitiateAccDeclare)s
548
549        %(CompleteAccDeclare)s
550    };
551}};
552
553def template LoadStoreImmDeclare {{
554    /**
555     * Static instruction class for "%(mnemonic)s".
556     */
557    class %(class_name)s : public %(base_class)s
558    {
559      public:
560
561        /// Constructor.
562        %(class_name)s(ExtMachInst machInst,
563                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
564
565        %(BasicExecDeclare)s
566
567        %(InitiateAccDeclare)s
568
569        %(CompleteAccDeclare)s
570    };
571}};
572
573def template StoreExImmDeclare {{
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 _result, uint32_t _dest, uint32_t _base,
584                bool _add, int32_t _imm);
585
586        %(BasicExecDeclare)s
587
588        %(InitiateAccDeclare)s
589
590        %(CompleteAccDeclare)s
591    };
592}};
593
594def template LoadStoreDRegDeclare {{
595    /**
596     * Static instruction class for "%(mnemonic)s".
597     */
598    class %(class_name)s : public %(base_class)s
599    {
600      public:
601
602        /// Constructor.
603        %(class_name)s(ExtMachInst machInst,
604                uint32_t _dest, uint32_t _dest2,
605                uint32_t _base, bool _add,
606                int32_t _shiftAmt, uint32_t _shiftType,
607                uint32_t _index);
608
609        %(BasicExecDeclare)s
610
611        %(InitiateAccDeclare)s
612
613        %(CompleteAccDeclare)s
614    };
615}};
616
617def template LoadStoreRegDeclare {{
618    /**
619     * Static instruction class for "%(mnemonic)s".
620     */
621    class %(class_name)s : public %(base_class)s
622    {
623      public:
624
625        /// Constructor.
626        %(class_name)s(ExtMachInst machInst,
627                uint32_t _dest, uint32_t _base, bool _add,
628                int32_t _shiftAmt, uint32_t _shiftType,
629                uint32_t _index);
630
631        %(BasicExecDeclare)s
632
633        %(InitiateAccDeclare)s
634
635        %(CompleteAccDeclare)s
636    };
637}};
638
639def template InitiateAccDeclare {{
640    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
641}};
642
643def template CompleteAccDeclare {{
644    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
645}};
646
647def template RfeConstructor {{
648    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
649            uint32_t _base, int _mode, bool _wb)
650         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
651                 (IntRegIndex)_base, (AddrMode)_mode, _wb)
652    {
653        %(constructor)s;
654    }
655}};
656
657def template SrsConstructor {{
658    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
659            uint32_t _regMode, int _mode, bool _wb)
660         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
661                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
662    {
663        %(constructor)s;
664    }
665}};
666
667def template SwapConstructor {{
668    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
669            uint32_t _dest, uint32_t _op1, uint32_t _base)
670         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
671                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
672    {
673        %(constructor)s;
674    }
675}};
676
677def template LoadStoreDImmConstructor {{
678    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
679            uint32_t _dest, uint32_t _dest2,
680            uint32_t _base, bool _add, int32_t _imm)
681         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
682                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
683                 (IntRegIndex)_base, _add, _imm)
684    {
685        %(constructor)s;
686    }
687}};
688
689def template StoreExDImmConstructor {{
690    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
691            uint32_t _result, uint32_t _dest, uint32_t _dest2,
692            uint32_t _base, bool _add, int32_t _imm)
693         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
694                 (IntRegIndex)_result,
695                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
696                 (IntRegIndex)_base, _add, _imm)
697    {
698        %(constructor)s;
699    }
700}};
701
702def template LoadStoreImmConstructor {{
703    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
704            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
705         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
706                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
707    {
708        %(constructor)s;
709    }
710}};
711
712def template StoreExImmConstructor {{
713    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
714            uint32_t _result, uint32_t _dest, uint32_t _base,
715            bool _add, int32_t _imm)
716         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
717                 (IntRegIndex)_result, (IntRegIndex)_dest,
718                 (IntRegIndex)_base, _add, _imm)
719    {
720        %(constructor)s;
721    }
722}};
723
724def template LoadStoreDRegConstructor {{
725    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
726            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
727            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
728         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
729                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
730                 (IntRegIndex)_base, _add,
731                 _shiftAmt, (ArmShiftType)_shiftType,
732                 (IntRegIndex)_index)
733    {
734        %(constructor)s;
735    }
736}};
737
738def template LoadStoreRegConstructor {{
739    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
740            uint32_t _dest, uint32_t _base, bool _add,
741            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
742         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
743                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
744                 _shiftAmt, (ArmShiftType)_shiftType,
745                 (IntRegIndex)_index)
746    {
747        %(constructor)s;
748    }
749}};
750