mem.isa revision 7279:157b02cc0ba1
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 SwapDeclare {{
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 _dest, uint32_t _op1, uint32_t _base);
308
309        %(BasicExecDeclare)s
310
311        %(InitiateAccDeclare)s
312
313        %(CompleteAccDeclare)s
314    };
315}};
316
317def template LoadStoreDImmDeclare {{
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 _dest2,
328                uint32_t _base, bool _add, int32_t _imm);
329
330        %(BasicExecDeclare)s
331
332        %(InitiateAccDeclare)s
333
334        %(CompleteAccDeclare)s
335    };
336}};
337
338def template LoadStoreImmDeclare {{
339    /**
340     * Static instruction class for "%(mnemonic)s".
341     */
342    class %(class_name)s : public %(base_class)s
343    {
344      public:
345
346        /// Constructor.
347        %(class_name)s(ExtMachInst machInst,
348                uint32_t _dest, 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 LoadStoreDRegDeclare {{
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 _dest2,
369                uint32_t _base, bool _add,
370                int32_t _shiftAmt, uint32_t _shiftType,
371                uint32_t _index);
372
373        %(BasicExecDeclare)s
374
375        %(InitiateAccDeclare)s
376
377        %(CompleteAccDeclare)s
378    };
379}};
380
381def template LoadStoreRegDeclare {{
382    /**
383     * Static instruction class for "%(mnemonic)s".
384     */
385    class %(class_name)s : public %(base_class)s
386    {
387      public:
388
389        /// Constructor.
390        %(class_name)s(ExtMachInst machInst,
391                uint32_t _dest, uint32_t _base, bool _add,
392                int32_t _shiftAmt, uint32_t _shiftType,
393                uint32_t _index);
394
395        %(BasicExecDeclare)s
396
397        %(InitiateAccDeclare)s
398
399        %(CompleteAccDeclare)s
400    };
401}};
402
403def template InitiateAccDeclare {{
404    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
405}};
406
407def template CompleteAccDeclare {{
408    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
409}};
410
411def template SwapConstructor {{
412    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
413            uint32_t _dest, uint32_t _op1, uint32_t _base)
414         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
415                 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
416    {
417        %(constructor)s;
418    }
419}};
420
421def template LoadStoreDImmConstructor {{
422    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
423            uint32_t _dest, uint32_t _dest2,
424            uint32_t _base, bool _add, int32_t _imm)
425         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
426                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
427                 (IntRegIndex)_base, _add, _imm)
428    {
429        %(constructor)s;
430    }
431}};
432
433def template LoadStoreImmConstructor {{
434    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
435            uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
436         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
437                 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
438    {
439        %(constructor)s;
440    }
441}};
442
443def template LoadStoreDRegConstructor {{
444    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
445            uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
446            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
447         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
448                 (IntRegIndex)_dest, (IntRegIndex)_dest2,
449                 (IntRegIndex)_base, _add,
450                 _shiftAmt, (ArmShiftType)_shiftType,
451                 (IntRegIndex)_index)
452    {
453        %(constructor)s;
454    }
455}};
456
457def template LoadStoreRegConstructor {{
458    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
459            uint32_t _dest, uint32_t _base, bool _add,
460            int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
461         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
462                 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
463                 _shiftAmt, (ArmShiftType)_shiftType,
464                 (IntRegIndex)_index)
465    {
466        %(constructor)s;
467    }
468}};
469