mem.isa revision 7291
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 StoreInitiateAcc {{
194    Fault %(class_name)s::initiateAcc(%(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            if (fault == NoFault) {
211                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
212                                  memAccessFlags, NULL);
213                if (traceData) { traceData->setData(Mem); }
214            }
215
216            // Need to write back any potential address register update
217            if (fault == NoFault) {
218                %(op_wb)s;
219            }
220        }
221
222        return fault;
223    }
224}};
225
226def template LoadInitiateAcc {{
227    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
228                                      Trace::InstRecord *traceData) const
229    {
230        Addr EA;
231        Fault fault = NoFault;
232
233        %(op_src_decl)s;
234        %(op_rd)s;
235        %(ea_code)s;
236
237        if (%(predicate_test)s)
238        {
239            if (fault == NoFault) {
240                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
241            }
242        }
243
244        return fault;
245    }
246}};
247
248def template LoadCompleteAcc {{
249    Fault %(class_name)s::completeAcc(PacketPtr pkt,
250                                      %(CPU_exec_context)s *xc,
251                                      Trace::InstRecord *traceData) const
252    {
253        Fault fault = NoFault;
254
255        %(op_decl)s;
256        %(op_rd)s;
257
258        if (%(predicate_test)s)
259        {
260            // ARM instructions will not have a pkt if the predicate is false
261            Mem = pkt->get<typeof(Mem)>();
262
263            if (fault == NoFault) {
264                %(memacc_code)s;
265            }
266
267            if (fault == NoFault) {
268                %(op_wb)s;
269            }
270        }
271
272        return fault;
273    }
274}};
275
276def template StoreCompleteAcc {{
277    Fault %(class_name)s::completeAcc(PacketPtr pkt,
278                                      %(CPU_exec_context)s *xc,
279                                      Trace::InstRecord *traceData) const
280    {
281        Fault fault = NoFault;
282
283        %(op_decl)s;
284        %(op_rd)s;
285
286        if (%(predicate_test)s)
287        {
288            if (fault == NoFault) {
289                %(op_wb)s;
290            }
291        }
292
293        return fault;
294    }
295}};
296
297def template RfeDeclare {{
298    /**
299     * Static instruction class for "%(mnemonic)s".
300     */
301    class %(class_name)s : public %(base_class)s
302    {
303      public:
304
305        /// Constructor.
306        %(class_name)s(ExtMachInst machInst,
307                uint32_t _base, int _mode, bool _wb);
308
309        %(BasicExecDeclare)s
310
311        %(InitiateAccDeclare)s
312
313        %(CompleteAccDeclare)s
314    };
315}};
316
317def template SwapDeclare {{
318    /**
319     * Static instruction class for "%(mnemonic)s".
320     */
321    class %(class_name)s : public %(base_class)s
322    {
323      public:
324
325        /// Constructor.
326        %(class_name)s(ExtMachInst machInst,
327                uint32_t _dest, uint32_t _op1, uint32_t _base);
328
329        %(BasicExecDeclare)s
330
331        %(InitiateAccDeclare)s
332
333        %(CompleteAccDeclare)s
334    };
335}};
336
337def template LoadStoreDImmDeclare {{
338    /**
339     * Static instruction class for "%(mnemonic)s".
340     */
341    class %(class_name)s : public %(base_class)s
342    {
343      public:
344
345        /// Constructor.
346        %(class_name)s(ExtMachInst machInst,
347                uint32_t _dest, uint32_t _dest2,
348                uint32_t _base, bool _add, int32_t _imm);
349
350        %(BasicExecDeclare)s
351
352        %(InitiateAccDeclare)s
353
354        %(CompleteAccDeclare)s
355    };
356}};
357
358def template LoadStoreImmDeclare {{
359    /**
360     * Static instruction class for "%(mnemonic)s".
361     */
362    class %(class_name)s : public %(base_class)s
363    {
364      public:
365
366        /// Constructor.
367        %(class_name)s(ExtMachInst machInst,
368                uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
369
370        %(BasicExecDeclare)s
371
372        %(InitiateAccDeclare)s
373
374        %(CompleteAccDeclare)s
375    };
376}};
377
378def template LoadStoreDRegDeclare {{
379    /**
380     * Static instruction class for "%(mnemonic)s".
381     */
382    class %(class_name)s : public %(base_class)s
383    {
384      public:
385
386        /// Constructor.
387        %(class_name)s(ExtMachInst machInst,
388                uint32_t _dest, uint32_t _dest2,
389                uint32_t _base, bool _add,
390                int32_t _shiftAmt, uint32_t _shiftType,
391                uint32_t _index);
392
393        %(BasicExecDeclare)s
394
395        %(InitiateAccDeclare)s
396
397        %(CompleteAccDeclare)s
398    };
399}};
400
401def template LoadStoreRegDeclare {{
402    /**
403     * Static instruction class for "%(mnemonic)s".
404     */
405    class %(class_name)s : public %(base_class)s
406    {
407      public:
408
409        /// Constructor.
410        %(class_name)s(ExtMachInst machInst,
411                uint32_t _dest, uint32_t _base, bool _add,
412                int32_t _shiftAmt, uint32_t _shiftType,
413                uint32_t _index);
414
415        %(BasicExecDeclare)s
416
417        %(InitiateAccDeclare)s
418
419        %(CompleteAccDeclare)s
420    };
421}};
422
423def template InitiateAccDeclare {{
424    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
425}};
426
427def template CompleteAccDeclare {{
428    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
429}};
430
431def template RfeConstructor {{
432    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
433            uint32_t _base, int _mode, bool _wb)
434         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
435                 (IntRegIndex)_base, (AddrMode)_mode, _wb)
436    {
437        %(constructor)s;
438    }
439}};
440
441def template SwapConstructor {{
442    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
443            uint32_t _dest, uint32_t _op1, uint32_t _base)
444         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
445                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
446    {
447        %(constructor)s;
448    }
449}};
450
451def template LoadStoreDImmConstructor {{
452    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
453            uint32_t _dest, uint32_t _dest2,
454            uint32_t _base, bool _add, int32_t _imm)
455         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
456                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
457                 (IntRegIndex)_base, _add, _imm)
458    {
459        %(constructor)s;
460    }
461}};
462
463def template LoadStoreImmConstructor {{
464    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
465            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
466         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
467                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
468    {
469        %(constructor)s;
470    }
471}};
472
473def template LoadStoreDRegConstructor {{
474    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
475            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
476            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
477         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
478                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
479                 (IntRegIndex)_base, _add,
480                 _shiftAmt, (ArmShiftType)_shiftType,
481                 (IntRegIndex)_index)
482    {
483        %(constructor)s;
484    }
485}};
486
487def template LoadStoreRegConstructor {{
488    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
489            uint32_t _dest, uint32_t _base, bool _add,
490            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
491         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
492                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
493                 _shiftAmt, (ArmShiftType)_shiftType,
494                 (IntRegIndex)_index)
495    {
496        %(constructor)s;
497    }
498}};
499