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