mem.isa revision 7303:6b70985664c8
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 SwapDeclare {{
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 _dest, uint32_t _op1, uint32_t _base);
423
424        %(BasicExecDeclare)s
425
426        %(InitiateAccDeclare)s
427
428        %(CompleteAccDeclare)s
429    };
430}};
431
432def template LoadStoreDImmDeclare {{
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 _dest2,
443                uint32_t _base, bool _add, int32_t _imm);
444
445        %(BasicExecDeclare)s
446
447        %(InitiateAccDeclare)s
448
449        %(CompleteAccDeclare)s
450    };
451}};
452
453def template StoreExDImmDeclare {{
454    /**
455     * Static instruction class for "%(mnemonic)s".
456     */
457    class %(class_name)s : public %(base_class)s
458    {
459      public:
460
461        /// Constructor.
462        %(class_name)s(ExtMachInst machInst,
463                uint32_t _result, uint32_t _dest, uint32_t _dest2,
464                uint32_t _base, bool _add, int32_t _imm);
465
466        %(BasicExecDeclare)s
467
468        %(InitiateAccDeclare)s
469
470        %(CompleteAccDeclare)s
471    };
472}};
473
474def template LoadStoreImmDeclare {{
475    /**
476     * Static instruction class for "%(mnemonic)s".
477     */
478    class %(class_name)s : public %(base_class)s
479    {
480      public:
481
482        /// Constructor.
483        %(class_name)s(ExtMachInst machInst,
484                uint32_t _dest, 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 StoreExImmDeclare {{
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 _result, uint32_t _dest, uint32_t _base,
505                bool _add, int32_t _imm);
506
507        %(BasicExecDeclare)s
508
509        %(InitiateAccDeclare)s
510
511        %(CompleteAccDeclare)s
512    };
513}};
514
515def template LoadStoreDRegDeclare {{
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,
527                int32_t _shiftAmt, uint32_t _shiftType,
528                uint32_t _index);
529
530        %(BasicExecDeclare)s
531
532        %(InitiateAccDeclare)s
533
534        %(CompleteAccDeclare)s
535    };
536}};
537
538def template LoadStoreRegDeclare {{
539    /**
540     * Static instruction class for "%(mnemonic)s".
541     */
542    class %(class_name)s : public %(base_class)s
543    {
544      public:
545
546        /// Constructor.
547        %(class_name)s(ExtMachInst machInst,
548                uint32_t _dest, uint32_t _base, bool _add,
549                int32_t _shiftAmt, uint32_t _shiftType,
550                uint32_t _index);
551
552        %(BasicExecDeclare)s
553
554        %(InitiateAccDeclare)s
555
556        %(CompleteAccDeclare)s
557    };
558}};
559
560def template InitiateAccDeclare {{
561    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
562}};
563
564def template CompleteAccDeclare {{
565    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
566}};
567
568def template RfeConstructor {{
569    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
570            uint32_t _base, int _mode, bool _wb)
571         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
572                 (IntRegIndex)_base, (AddrMode)_mode, _wb)
573    {
574        %(constructor)s;
575    }
576}};
577
578def template SwapConstructor {{
579    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
580            uint32_t _dest, uint32_t _op1, uint32_t _base)
581         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
582                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
583    {
584        %(constructor)s;
585    }
586}};
587
588def template LoadStoreDImmConstructor {{
589    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
590            uint32_t _dest, uint32_t _dest2,
591            uint32_t _base, bool _add, int32_t _imm)
592         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
593                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
594                 (IntRegIndex)_base, _add, _imm)
595    {
596        %(constructor)s;
597    }
598}};
599
600def template StoreExDImmConstructor {{
601    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
602            uint32_t _result, uint32_t _dest, uint32_t _dest2,
603            uint32_t _base, bool _add, int32_t _imm)
604         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
605                 (IntRegIndex)_result,
606                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
607                 (IntRegIndex)_base, _add, _imm)
608    {
609        %(constructor)s;
610    }
611}};
612
613def template LoadStoreImmConstructor {{
614    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
615            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
616         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
617                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
618    {
619        %(constructor)s;
620    }
621}};
622
623def template StoreExImmConstructor {{
624    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
625            uint32_t _result, uint32_t _dest, uint32_t _base,
626            bool _add, int32_t _imm)
627         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
628                 (IntRegIndex)_result, (IntRegIndex)_dest,
629                 (IntRegIndex)_base, _add, _imm)
630    {
631        %(constructor)s;
632    }
633}};
634
635def template LoadStoreDRegConstructor {{
636    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
637            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
638            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
639         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
640                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
641                 (IntRegIndex)_base, _add,
642                 _shiftAmt, (ArmShiftType)_shiftType,
643                 (IntRegIndex)_index)
644    {
645        %(constructor)s;
646    }
647}};
648
649def template LoadStoreRegConstructor {{
650    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
651            uint32_t _dest, uint32_t _base, bool _add,
652            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
653         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
654                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
655                 _shiftAmt, (ArmShiftType)_shiftType,
656                 (IntRegIndex)_index)
657    {
658        %(constructor)s;
659    }
660}};
661