mem.isa revision 7408
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        }
346
347        return fault;
348    }
349}};
350
351def template LoadCompleteAcc {{
352    Fault %(class_name)s::completeAcc(PacketPtr pkt,
353                                      %(CPU_exec_context)s *xc,
354                                      Trace::InstRecord *traceData) const
355    {
356        Fault fault = NoFault;
357
358        %(op_decl)s;
359        %(op_rd)s;
360
361        if (%(predicate_test)s)
362        {
363            // ARM instructions will not have a pkt if the predicate is false
364            Mem = pkt->get<typeof(Mem)>();
365
366            if (fault == NoFault) {
367                %(memacc_code)s;
368            }
369
370            if (fault == NoFault) {
371                %(op_wb)s;
372            }
373        }
374
375        if (fault == NoFault && machInst.itstateMask != 0) {
376            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
377        }
378
379        return fault;
380    }
381}};
382
383def template StoreCompleteAcc {{
384    Fault %(class_name)s::completeAcc(PacketPtr pkt,
385                                      %(CPU_exec_context)s *xc,
386                                      Trace::InstRecord *traceData) const
387    {
388        Fault fault = NoFault;
389
390        %(op_decl)s;
391        %(op_rd)s;
392
393        if (%(predicate_test)s)
394        {
395            if (fault == NoFault) {
396                %(op_wb)s;
397            }
398        }
399
400        if (fault == NoFault && machInst.itstateMask != 0) {
401            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
402        }
403
404        return fault;
405    }
406}};
407
408def template StoreExCompleteAcc {{
409    Fault %(class_name)s::completeAcc(PacketPtr pkt,
410                                      %(CPU_exec_context)s *xc,
411                                      Trace::InstRecord *traceData) const
412    {
413        Fault fault = NoFault;
414
415        %(op_decl)s;
416        %(op_rd)s;
417
418        if (%(predicate_test)s)
419        {
420            uint64_t writeResult = pkt->req->getExtraData();
421            %(postacc_code)s;
422
423            if (fault == NoFault) {
424                %(op_wb)s;
425            }
426        }
427
428        if (fault == NoFault && machInst.itstateMask != 0) {
429            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
430        }
431
432        return fault;
433    }
434}};
435
436def template RfeDeclare {{
437    /**
438     * Static instruction class for "%(mnemonic)s".
439     */
440    class %(class_name)s : public %(base_class)s
441    {
442      public:
443
444        /// Constructor.
445        %(class_name)s(ExtMachInst machInst,
446                uint32_t _base, int _mode, bool _wb);
447
448        %(BasicExecDeclare)s
449
450        %(InitiateAccDeclare)s
451
452        %(CompleteAccDeclare)s
453    };
454}};
455
456def template SrsDeclare {{
457    /**
458     * Static instruction class for "%(mnemonic)s".
459     */
460    class %(class_name)s : public %(base_class)s
461    {
462      public:
463
464        /// Constructor.
465        %(class_name)s(ExtMachInst machInst,
466                uint32_t _regMode, int _mode, bool _wb);
467
468        %(BasicExecDeclare)s
469
470        %(InitiateAccDeclare)s
471
472        %(CompleteAccDeclare)s
473    };
474}};
475
476def template SwapDeclare {{
477    /**
478     * Static instruction class for "%(mnemonic)s".
479     */
480    class %(class_name)s : public %(base_class)s
481    {
482      public:
483
484        /// Constructor.
485        %(class_name)s(ExtMachInst machInst,
486                uint32_t _dest, uint32_t _op1, uint32_t _base);
487
488        %(BasicExecDeclare)s
489
490        %(InitiateAccDeclare)s
491
492        %(CompleteAccDeclare)s
493    };
494}};
495
496def template LoadStoreDImmDeclare {{
497    /**
498     * Static instruction class for "%(mnemonic)s".
499     */
500    class %(class_name)s : public %(base_class)s
501    {
502      public:
503
504        /// Constructor.
505        %(class_name)s(ExtMachInst machInst,
506                uint32_t _dest, uint32_t _dest2,
507                uint32_t _base, bool _add, int32_t _imm);
508
509        %(BasicExecDeclare)s
510
511        %(InitiateAccDeclare)s
512
513        %(CompleteAccDeclare)s
514    };
515}};
516
517def template StoreExDImmDeclare {{
518    /**
519     * Static instruction class for "%(mnemonic)s".
520     */
521    class %(class_name)s : public %(base_class)s
522    {
523      public:
524
525        /// Constructor.
526        %(class_name)s(ExtMachInst machInst,
527                uint32_t _result, uint32_t _dest, uint32_t _dest2,
528                uint32_t _base, bool _add, int32_t _imm);
529
530        %(BasicExecDeclare)s
531
532        %(InitiateAccDeclare)s
533
534        %(CompleteAccDeclare)s
535    };
536}};
537
538def template LoadStoreImmDeclare {{
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, int32_t _imm);
549
550        %(BasicExecDeclare)s
551
552        %(InitiateAccDeclare)s
553
554        %(CompleteAccDeclare)s
555    };
556}};
557
558def template StoreExImmDeclare {{
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 _result, uint32_t _dest, uint32_t _base,
569                bool _add, int32_t _imm);
570
571        %(BasicExecDeclare)s
572
573        %(InitiateAccDeclare)s
574
575        %(CompleteAccDeclare)s
576    };
577}};
578
579def template LoadStoreDRegDeclare {{
580    /**
581     * Static instruction class for "%(mnemonic)s".
582     */
583    class %(class_name)s : public %(base_class)s
584    {
585      public:
586
587        /// Constructor.
588        %(class_name)s(ExtMachInst machInst,
589                uint32_t _dest, uint32_t _dest2,
590                uint32_t _base, bool _add,
591                int32_t _shiftAmt, uint32_t _shiftType,
592                uint32_t _index);
593
594        %(BasicExecDeclare)s
595
596        %(InitiateAccDeclare)s
597
598        %(CompleteAccDeclare)s
599    };
600}};
601
602def template LoadStoreRegDeclare {{
603    /**
604     * Static instruction class for "%(mnemonic)s".
605     */
606    class %(class_name)s : public %(base_class)s
607    {
608      public:
609
610        /// Constructor.
611        %(class_name)s(ExtMachInst machInst,
612                uint32_t _dest, uint32_t _base, bool _add,
613                int32_t _shiftAmt, uint32_t _shiftType,
614                uint32_t _index);
615
616        %(BasicExecDeclare)s
617
618        %(InitiateAccDeclare)s
619
620        %(CompleteAccDeclare)s
621    };
622}};
623
624def template InitiateAccDeclare {{
625    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
626}};
627
628def template CompleteAccDeclare {{
629    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
630}};
631
632def template RfeConstructor {{
633    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
634            uint32_t _base, int _mode, bool _wb)
635         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
636                 (IntRegIndex)_base, (AddrMode)_mode, _wb)
637    {
638        %(constructor)s;
639    }
640}};
641
642def template SrsConstructor {{
643    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
644            uint32_t _regMode, int _mode, bool _wb)
645         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
646                 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
647    {
648        %(constructor)s;
649    }
650}};
651
652def template SwapConstructor {{
653    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
654            uint32_t _dest, uint32_t _op1, uint32_t _base)
655         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
656                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
657    {
658        %(constructor)s;
659    }
660}};
661
662def template LoadStoreDImmConstructor {{
663    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
664            uint32_t _dest, uint32_t _dest2,
665            uint32_t _base, bool _add, int32_t _imm)
666         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
667                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
668                 (IntRegIndex)_base, _add, _imm)
669    {
670        %(constructor)s;
671    }
672}};
673
674def template StoreExDImmConstructor {{
675    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
676            uint32_t _result, uint32_t _dest, uint32_t _dest2,
677            uint32_t _base, bool _add, int32_t _imm)
678         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
679                 (IntRegIndex)_result,
680                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
681                 (IntRegIndex)_base, _add, _imm)
682    {
683        %(constructor)s;
684    }
685}};
686
687def template LoadStoreImmConstructor {{
688    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
689            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
690         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
691                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
692    {
693        %(constructor)s;
694    }
695}};
696
697def template StoreExImmConstructor {{
698    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
699            uint32_t _result, uint32_t _dest, uint32_t _base,
700            bool _add, int32_t _imm)
701         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
702                 (IntRegIndex)_result, (IntRegIndex)_dest,
703                 (IntRegIndex)_base, _add, _imm)
704    {
705        %(constructor)s;
706    }
707}};
708
709def template LoadStoreDRegConstructor {{
710    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
711            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
712            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
713         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
714                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
715                 (IntRegIndex)_base, _add,
716                 _shiftAmt, (ArmShiftType)_shiftType,
717                 (IntRegIndex)_index)
718    {
719        %(constructor)s;
720    }
721}};
722
723def template LoadStoreRegConstructor {{
724    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
725            uint32_t _dest, uint32_t _base, bool _add,
726            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
727         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
728                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
729                 _shiftAmt, (ArmShiftType)_shiftType,
730                 (IntRegIndex)_index)
731    {
732        %(constructor)s;
733    }
734}};
735