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