Deleted Added
sdiff udiff text old ( 6250:1cc6e860d95f ) new ( 6253:988a001820f8 )
full compact
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