mem.isa revision 6253:988a001820f8
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007-2008 The Florida State University
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Stephen Hines
30
31////////////////////////////////////////////////////////////////////
32//
33// Memory-format instructions
34//
35
36def template LoadStoreDeclare {{
37    /**
38     * Static instruction class for "%(mnemonic)s".
39     */
40    class %(class_name)s : public %(base_class)s
41    {
42      protected:
43
44        /**
45         * "Fake" effective address computation class for "%(mnemonic)s".
46         */
47        class EAComp : public %(base_class)s
48        {
49          public:
50            /// Constructor
51            EAComp(ExtMachInst machInst);
52
53            %(BasicExecDeclare)s
54        };
55
56        /**
57         * "Fake" memory access instruction class for "%(mnemonic)s".
58         */
59        class MemAcc : public %(base_class)s
60        {
61          public:
62            /// Constructor
63            MemAcc(ExtMachInst machInst);
64
65            %(BasicExecDeclare)s
66        };
67
68      public:
69
70        /// Constructor.
71        %(class_name)s(ExtMachInst machInst);
72
73        %(BasicExecDeclare)s
74
75        %(InitiateAccDeclare)s
76
77        %(CompleteAccDeclare)s
78    };
79}};
80
81
82def template InitiateAccDeclare {{
83    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
84}};
85
86
87def template CompleteAccDeclare {{
88    Fault completeAcc(PacketPtr,  %(CPU_exec_context)s *, Trace::InstRecord *) const;
89}};
90
91
92def template EACompConstructor {{
93    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
94        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
95    {
96        %(constructor)s;
97    }
98}};
99
100
101def template MemAccConstructor {{
102    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
103        : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
104    {
105        %(constructor)s;
106    }
107}};
108
109
110def template LoadStoreConstructor {{
111    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
112         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
113                          new EAComp(machInst), new MemAcc(machInst))
114    {
115        %(constructor)s;
116    }
117}};
118
119
120def template EACompExecute {{
121    Fault
122    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
123                                   Trace::InstRecord *traceData) const
124    {
125        Addr EA;
126        Fault fault = NoFault;
127
128        %(op_decl)s;
129        %(op_rd)s;
130        %(ea_code)s;
131
132        if (%(predicate_test)s)
133        {
134            if (fault == NoFault) {
135                %(op_wb)s;
136                xc->setEA(EA);
137            }
138        }
139
140        return fault;
141    }
142}};
143
144def template LoadMemAccExecute {{
145    Fault
146    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
147                                   Trace::InstRecord *traceData) const
148    {
149        Addr EA;
150        Fault fault = NoFault;
151
152        %(op_decl)s;
153        %(op_rd)s;
154        EA = xc->getEA();
155
156        if (%(predicate_test)s)
157        {
158            if (fault == NoFault) {
159                fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
160                %(memacc_code)s;
161            }
162
163            if (fault == NoFault) {
164                %(op_wb)s;
165            }
166        }
167
168        return fault;
169    }
170}};
171
172
173def template LoadExecute {{
174    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
175                                  Trace::InstRecord *traceData) const
176    {
177        Addr EA;
178        Fault fault = NoFault;
179
180        %(op_decl)s;
181        %(op_rd)s;
182        %(ea_code)s;
183
184        if (%(predicate_test)s)
185        {
186            if (fault == NoFault) {
187                fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
188                %(memacc_code)s;
189            }
190
191            if (fault == NoFault) {
192                %(op_wb)s;
193            }
194        }
195
196        return fault;
197    }
198}};
199
200
201def template LoadInitiateAcc {{
202    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
203                                      Trace::InstRecord *traceData) const
204    {
205        Addr EA;
206        Fault fault = NoFault;
207
208        %(op_src_decl)s;
209        %(op_rd)s;
210        %(ea_code)s;
211
212        if (%(predicate_test)s)
213        {
214            if (fault == NoFault) {
215                fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
216            }
217        }
218
219        return fault;
220    }
221}};
222
223
224def template LoadCompleteAcc {{
225    Fault %(class_name)s::completeAcc(PacketPtr pkt,
226                                      %(CPU_exec_context)s *xc,
227                                      Trace::InstRecord *traceData) const
228    {
229        Fault fault = NoFault;
230
231        %(op_decl)s;
232        %(op_rd)s;
233
234        if (%(predicate_test)s)
235        {
236            // ARM instructions will not have a pkt if the predicate is false
237            Mem = pkt->get<typeof(Mem)>();
238
239            if (fault == NoFault) {
240                %(memacc_code)s;
241            }
242
243            if (fault == NoFault) {
244                %(op_wb)s;
245            }
246        }
247
248        return fault;
249    }
250}};
251
252
253def template StoreMemAccExecute {{
254    Fault
255    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
256                                   Trace::InstRecord *traceData) const
257    {
258        Addr EA;
259        Fault fault = NoFault;
260
261        %(op_decl)s;
262        %(op_rd)s;
263
264        if (%(predicate_test)s)
265        {
266            EA = xc->getEA();
267
268            if (fault == NoFault) {
269                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
270                                  memAccessFlags, NULL);
271                if (traceData) { traceData->setData(Mem); }
272            }
273
274            if (fault == NoFault) {
275                %(op_wb)s;
276            }
277        }
278
279        return fault;
280    }
281}};
282
283
284def template StoreExecute {{
285    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
286                                  Trace::InstRecord *traceData) const
287    {
288        Addr EA;
289        Fault fault = NoFault;
290
291        %(op_decl)s;
292        %(op_rd)s;
293        %(ea_code)s;
294
295        if (%(predicate_test)s)
296        {
297            if (fault == NoFault) {
298                %(memacc_code)s;
299            }
300
301            if (fault == NoFault) {
302                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
303                                  memAccessFlags, NULL);
304                if (traceData) { traceData->setData(Mem); }
305            }
306
307            if (fault == NoFault) {
308                %(op_wb)s;
309            }
310        }
311
312        return fault;
313    }
314}};
315
316def template StoreInitiateAcc {{
317    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
318                                      Trace::InstRecord *traceData) const
319    {
320        Addr EA;
321        Fault fault = NoFault;
322
323        %(op_decl)s;
324        %(op_rd)s;
325        %(ea_code)s;
326
327        if (%(predicate_test)s)
328        {
329            if (fault == NoFault) {
330                %(memacc_code)s;
331            }
332
333            if (fault == NoFault) {
334                fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
335                                  memAccessFlags, NULL);
336                if (traceData) { traceData->setData(Mem); }
337            }
338
339            // Need to write back any potential address register update
340            if (fault == NoFault) {
341                %(op_wb)s;
342            }
343        }
344
345        return fault;
346    }
347}};
348
349
350def template StoreCompleteAcc {{
351    Fault %(class_name)s::completeAcc(PacketPtr pkt,
352                                      %(CPU_exec_context)s *xc,
353                                      Trace::InstRecord *traceData) const
354    {
355        Fault fault = NoFault;
356
357        %(op_dest_decl)s;
358
359        if (%(predicate_test)s)
360        {
361            if (fault == NoFault) {
362                %(op_wb)s;
363            }
364        }
365
366        return fault;
367    }
368}};
369
370def template StoreCondCompleteAcc {{
371    Fault %(class_name)s::completeAcc(PacketPtr pkt,
372                                      %(CPU_exec_context)s *xc,
373                                      Trace::InstRecord *traceData) const
374    {
375        Fault fault = NoFault;
376
377        %(op_dest_decl)s;
378
379        if (%(predicate_test)s)
380        {
381            if (fault == NoFault) {
382                %(op_wb)s;
383            }
384        }
385
386        return fault;
387    }
388}};
389
390
391def template MiscMemAccExecute {{
392    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
393                                          Trace::InstRecord *traceData) const
394    {
395        Addr EA;
396        Fault fault = NoFault;
397
398        %(op_decl)s;
399        %(op_rd)s;
400
401        if (%(predicate_test)s)
402        {
403            EA = xc->getEA();
404
405            if (fault == NoFault) {
406                %(memacc_code)s;
407            }
408        }
409
410        return NoFault;
411    }
412}};
413
414def template MiscExecute {{
415    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
416                                  Trace::InstRecord *traceData) const
417    {
418        Addr EA;
419        Fault fault = NoFault;
420
421        %(op_decl)s;
422        %(op_rd)s;
423        %(ea_code)s;
424
425        if (%(predicate_test)s)
426        {
427            if (fault == NoFault) {
428                %(memacc_code)s;
429            }
430        }
431
432        return NoFault;
433    }
434}};
435
436def template MiscInitiateAcc {{
437    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
438                                      Trace::InstRecord *traceData) const
439    {
440        panic("Misc instruction does not support split access method!");
441        return NoFault;
442    }
443}};
444
445
446def template MiscCompleteAcc {{
447    Fault %(class_name)s::completeAcc(PacketPtr pkt,
448                                      %(CPU_exec_context)s *xc,
449                                      Trace::InstRecord *traceData) const
450    {
451        panic("Misc instruction does not support split access method!");
452
453        return NoFault;
454    }
455}};
456
457def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }},
458                     mem_flags = [], inst_flags = []) {{
459    ea_code = ArmGenericCodeSubs(ea_code)
460    memacc_code = ArmGenericCodeSubs(memacc_code)
461    (header_output, decoder_output, decode_block, exec_output) = \
462        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
463                      decode_template = BasicDecode,
464                      exec_template_base = 'Load')
465}};
466
467def format ArmStoreMemory(memacc_code, ea_code = {{ EA = Rn + disp; }},
468                     mem_flags = [], inst_flags = []) {{
469    ea_code = ArmGenericCodeSubs(ea_code)
470    memacc_code = ArmGenericCodeSubs(memacc_code)
471    (header_output, decoder_output, decode_block, exec_output) = \
472        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
473                      exec_template_base = 'Store')
474}};
475
476