mem.isa (12236:126ac9da6050) mem.isa (12616:4b463b4dc098)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010, 2012, 2014, 2016 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 PanicExecute {{
45 Fault %(class_name)s::execute(ExecContext *xc,
46 Trace::InstRecord *traceData) const
47 {
48 panic("Execute function executed when it shouldn't be!\n");
49 return NoFault;
50 }
51}};
52
53def template PanicInitiateAcc {{
54 Fault %(class_name)s::initiateAcc(ExecContext *xc,
55 Trace::InstRecord *traceData) const
56 {
57 panic("InitiateAcc function executed when it shouldn't be!\n");
58 return NoFault;
59 }
60}};
61
62def template PanicCompleteAcc {{
63 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
64 Trace::InstRecord *traceData) const
65 {
66 panic("CompleteAcc function executed when it shouldn't be!\n");
67 return NoFault;
68 }
69}};
70
71
72def template SwapExecute {{
73 Fault %(class_name)s::execute(ExecContext *xc,
74 Trace::InstRecord *traceData) const
75 {
76 Addr EA;
77 Fault fault = NoFault;
78
79 %(op_decl)s;
80 uint64_t memData = 0;
81 %(op_rd)s;
82 %(ea_code)s;
83
84 if (%(predicate_test)s)
85 {
86 %(preacc_code)s;
87
88 if (fault == NoFault) {
89 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
90 &memData);
91 }
92
93 if (fault == NoFault) {
94 %(postacc_code)s;
95 }
96
97 if (fault == NoFault) {
98 %(op_wb)s;
99 }
100 } else {
101 xc->setPredicate(false);
102 }
103
104 return fault;
105 }
106}};
107
108def template SwapInitiateAcc {{
109 Fault %(class_name)s::initiateAcc(ExecContext *xc,
110 Trace::InstRecord *traceData) const
111 {
112 Addr EA;
113 Fault fault = NoFault;
114
115 %(op_decl)s;
116 uint64_t memData = 0;
117 %(op_rd)s;
118 %(ea_code)s;
119
120 if (%(predicate_test)s)
121 {
122 %(preacc_code)s;
123
124 if (fault == NoFault) {
125 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
126 &memData);
127 }
128 } else {
129 xc->setPredicate(false);
130 }
131
132 return fault;
133 }
134}};
135
136def template SwapCompleteAcc {{
137 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
138 Trace::InstRecord *traceData) const
139 {
140 Fault fault = NoFault;
141
142 %(op_decl)s;
143 %(op_rd)s;
144
145 if (%(predicate_test)s)
146 {
147 // ARM instructions will not have a pkt if the predicate is false
148 getMem(pkt, Mem, traceData);
149 uint64_t memData = Mem;
150
151 %(postacc_code)s;
152
153 if (fault == NoFault) {
154 %(op_wb)s;
155 }
156 }
157
158 return fault;
159 }
160}};
161
162def template LoadExecute {{
163 Fault %(class_name)s::execute(ExecContext *xc,
164 Trace::InstRecord *traceData) const
165 {
166 Addr EA;
167 Fault fault = NoFault;
168
169 %(op_decl)s;
170 %(op_rd)s;
171 %(ea_code)s;
172
173 if (%(predicate_test)s)
174 {
175 if (fault == NoFault) {
176 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
177 %(memacc_code)s;
178 }
179
180 if (fault == NoFault) {
181 %(op_wb)s;
182 }
183 } else {
184 xc->setPredicate(false);
185 }
186
187 return fault;
188 }
189}};
190
191def template NeonLoadExecute {{
192 template <class Element>
193 Fault %(class_name)s<Element>::execute(
194 ExecContext *xc, Trace::InstRecord *traceData) const
195 {
196 Addr EA;
197 Fault fault = NoFault;
198
199 %(op_decl)s;
200 %(mem_decl)s;
201 %(op_rd)s;
202 %(ea_code)s;
203
204 MemUnion memUnion;
205 uint8_t *dataPtr = memUnion.bytes;
206
207 if (%(predicate_test)s)
208 {
209 if (fault == NoFault) {
210 fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
211 %(memacc_code)s;
212 }
213
214 if (fault == NoFault) {
215 %(op_wb)s;
216 }
217 } else {
218 xc->setPredicate(false);
219 }
220
221 return fault;
222 }
223}};
224
225def template StoreExecute {{
226 Fault %(class_name)s::execute(ExecContext *xc,
227 Trace::InstRecord *traceData) const
228 {
229 Addr EA;
230 Fault fault = NoFault;
231
232 %(op_decl)s;
233 %(op_rd)s;
234 %(ea_code)s;
235
236 if (%(predicate_test)s)
237 {
238 if (fault == NoFault) {
239 %(memacc_code)s;
240 }
241
242 if (fault == NoFault) {
243 fault = writeMemAtomic(xc, traceData, Mem, EA,
244 memAccessFlags, NULL);
245 }
246
247 if (fault == NoFault) {
248 %(op_wb)s;
249 }
250 } else {
251 xc->setPredicate(false);
252 }
253
254 return fault;
255 }
256}};
257
258def template NeonStoreExecute {{
259 template <class Element>
260 Fault %(class_name)s<Element>::execute(
261 ExecContext *xc, Trace::InstRecord *traceData) const
262 {
263 Addr EA;
264 Fault fault = NoFault;
265
266 %(op_decl)s;
267 %(mem_decl)s;
268 %(op_rd)s;
269 %(ea_code)s;
270
271 MemUnion memUnion;
272 uint8_t *dataPtr = memUnion.bytes;
273
274 if (%(predicate_test)s)
275 {
276 if (fault == NoFault) {
277 %(memacc_code)s;
278 }
279
280 if (fault == NoFault) {
281 fault = xc->writeMem(dataPtr, %(size)d, EA,
282 memAccessFlags, NULL);
283 }
284
285 if (fault == NoFault) {
286 %(op_wb)s;
287 }
288 } else {
289 xc->setPredicate(false);
290 }
291
292 return fault;
293 }
294}};
295
296def template StoreExExecute {{
297 Fault %(class_name)s::execute(ExecContext *xc,
298 Trace::InstRecord *traceData) const
299 {
300 Addr EA;
301 Fault fault = NoFault;
302
303 %(op_decl)s;
304 %(op_rd)s;
305 %(ea_code)s;
306
307 if (%(predicate_test)s)
308 {
309 if (fault == NoFault) {
310 %(memacc_code)s;
311 }
312
313 uint64_t writeResult;
314
315 if (fault == NoFault) {
316 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
317 &writeResult);
318 }
319
320 if (fault == NoFault) {
321 %(postacc_code)s;
322 }
323
324 if (fault == NoFault) {
325 %(op_wb)s;
326 }
327 } else {
328 xc->setPredicate(false);
329 }
330
331 return fault;
332 }
333}};
334
335def template StoreExInitiateAcc {{
336 Fault %(class_name)s::initiateAcc(ExecContext *xc,
337 Trace::InstRecord *traceData) const
338 {
339 Addr EA;
340 Fault fault = NoFault;
341
342 %(op_decl)s;
343 %(op_rd)s;
344 %(ea_code)s;
345
346 if (%(predicate_test)s)
347 {
348 if (fault == NoFault) {
349 %(memacc_code)s;
350 }
351
352 if (fault == NoFault) {
353 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
354 NULL);
355 }
356 } else {
357 xc->setPredicate(false);
358 }
359
360 return fault;
361 }
362}};
363
364def template StoreInitiateAcc {{
365 Fault %(class_name)s::initiateAcc(ExecContext *xc,
366 Trace::InstRecord *traceData) const
367 {
368 Addr EA;
369 Fault fault = NoFault;
370
371 %(op_decl)s;
372 %(op_rd)s;
373 %(ea_code)s;
374
375 if (%(predicate_test)s)
376 {
377 if (fault == NoFault) {
378 %(memacc_code)s;
379 }
380
381 if (fault == NoFault) {
382 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
383 NULL);
384 }
385 } else {
386 xc->setPredicate(false);
387 }
388
389 return fault;
390 }
391}};
392
393def template NeonStoreInitiateAcc {{
394 template <class Element>
395 Fault %(class_name)s<Element>::initiateAcc(
396 ExecContext *xc, Trace::InstRecord *traceData) const
397 {
398 Addr EA;
399 Fault fault = NoFault;
400
401 %(op_decl)s;
402 %(mem_decl)s;
403 %(op_rd)s;
404 %(ea_code)s;
405
406 if (%(predicate_test)s)
407 {
408 MemUnion memUnion;
409 if (fault == NoFault) {
410 %(memacc_code)s;
411 }
412
413 if (fault == NoFault) {
414 fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
415 memAccessFlags, NULL);
416 }
417 } else {
418 xc->setPredicate(false);
419 }
420
421 return fault;
422 }
423}};
424
425def template LoadInitiateAcc {{
426 Fault %(class_name)s::initiateAcc(ExecContext *xc,
427 Trace::InstRecord *traceData) const
428 {
429 Addr EA;
430 Fault fault = NoFault;
431
432 %(op_src_decl)s;
433 %(op_rd)s;
434 %(ea_code)s;
435
436 if (%(predicate_test)s)
437 {
438 if (fault == NoFault) {
439 fault = initiateMemRead(xc, traceData, EA, Mem,
440 memAccessFlags);
441 }
442 } else {
443 xc->setPredicate(false);
444 }
445
446 return fault;
447 }
448}};
449
450def template NeonLoadInitiateAcc {{
451 template <class Element>
452 Fault %(class_name)s<Element>::initiateAcc(
453 ExecContext *xc, Trace::InstRecord *traceData) const
454 {
455 Addr EA;
456 Fault fault = NoFault;
457
458 %(op_decl)s;
459 %(mem_decl)s;
460 %(op_rd)s;
461 %(ea_code)s;
462
463 if (%(predicate_test)s)
464 {
465 if (fault == NoFault) {
466 fault = xc->initiateMemRead(EA, %(size)d, memAccessFlags);
467 }
468 } else {
469 xc->setPredicate(false);
470 }
471
472 return fault;
473 }
474}};
475
476def template LoadCompleteAcc {{
477 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
478 Trace::InstRecord *traceData) const
479 {
480 Fault fault = NoFault;
481
482 %(op_decl)s;
483 %(op_rd)s;
484
485 if (%(predicate_test)s)
486 {
487 // ARM instructions will not have a pkt if the predicate is false
488 getMem(pkt, Mem, traceData);
489
490 if (fault == NoFault) {
491 %(memacc_code)s;
492 }
493
494 if (fault == NoFault) {
495 %(op_wb)s;
496 }
497 }
498
499 return fault;
500 }
501}};
502
503def template NeonLoadCompleteAcc {{
504 template <class Element>
505 Fault %(class_name)s<Element>::completeAcc(
506 PacketPtr pkt, ExecContext *xc,
507 Trace::InstRecord *traceData) const
508 {
509 Fault fault = NoFault;
510
511 %(mem_decl)s;
512 %(op_decl)s;
513 %(op_rd)s;
514
515 if (%(predicate_test)s)
516 {
517 // ARM instructions will not have a pkt if the predicate is false
518 MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
519
520 if (fault == NoFault) {
521 %(memacc_code)s;
522 }
523
524 if (fault == NoFault) {
525 %(op_wb)s;
526 }
527 }
528
529 return fault;
530 }
531}};
532
533def template StoreCompleteAcc {{
534 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
535 Trace::InstRecord *traceData) const
536 {
537 return NoFault;
538 }
539}};
540
541def template NeonStoreCompleteAcc {{
542 template <class Element>
543 Fault %(class_name)s<Element>::completeAcc(
544 PacketPtr pkt, ExecContext *xc, Trace::InstRecord *traceData) const
545 {
546 return NoFault;
547 }
548}};
549
550def template StoreExCompleteAcc {{
551 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
552 Trace::InstRecord *traceData) const
553 {
554 Fault fault = NoFault;
555
556 %(op_decl)s;
557 %(op_rd)s;
558
559 if (%(predicate_test)s)
560 {
561 uint64_t writeResult = pkt->req->getExtraData();
562 %(postacc_code)s;
563
564 if (fault == NoFault) {
565 %(op_wb)s;
566 }
567 }
568
569 return fault;
570 }
571}};
572
573def template RfeDeclare {{
574 /**
575 * Static instruction class for "%(mnemonic)s".
576 */
577 class %(class_name)s : public %(base_class)s
578 {
579 public:
580
581 /// Constructor.
582 %(class_name)s(ExtMachInst machInst,
583 uint32_t _base, int _mode, bool _wb);
584
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010, 2012, 2014, 2016 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 PanicExecute {{
45 Fault %(class_name)s::execute(ExecContext *xc,
46 Trace::InstRecord *traceData) const
47 {
48 panic("Execute function executed when it shouldn't be!\n");
49 return NoFault;
50 }
51}};
52
53def template PanicInitiateAcc {{
54 Fault %(class_name)s::initiateAcc(ExecContext *xc,
55 Trace::InstRecord *traceData) const
56 {
57 panic("InitiateAcc function executed when it shouldn't be!\n");
58 return NoFault;
59 }
60}};
61
62def template PanicCompleteAcc {{
63 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
64 Trace::InstRecord *traceData) const
65 {
66 panic("CompleteAcc function executed when it shouldn't be!\n");
67 return NoFault;
68 }
69}};
70
71
72def template SwapExecute {{
73 Fault %(class_name)s::execute(ExecContext *xc,
74 Trace::InstRecord *traceData) const
75 {
76 Addr EA;
77 Fault fault = NoFault;
78
79 %(op_decl)s;
80 uint64_t memData = 0;
81 %(op_rd)s;
82 %(ea_code)s;
83
84 if (%(predicate_test)s)
85 {
86 %(preacc_code)s;
87
88 if (fault == NoFault) {
89 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
90 &memData);
91 }
92
93 if (fault == NoFault) {
94 %(postacc_code)s;
95 }
96
97 if (fault == NoFault) {
98 %(op_wb)s;
99 }
100 } else {
101 xc->setPredicate(false);
102 }
103
104 return fault;
105 }
106}};
107
108def template SwapInitiateAcc {{
109 Fault %(class_name)s::initiateAcc(ExecContext *xc,
110 Trace::InstRecord *traceData) const
111 {
112 Addr EA;
113 Fault fault = NoFault;
114
115 %(op_decl)s;
116 uint64_t memData = 0;
117 %(op_rd)s;
118 %(ea_code)s;
119
120 if (%(predicate_test)s)
121 {
122 %(preacc_code)s;
123
124 if (fault == NoFault) {
125 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
126 &memData);
127 }
128 } else {
129 xc->setPredicate(false);
130 }
131
132 return fault;
133 }
134}};
135
136def template SwapCompleteAcc {{
137 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
138 Trace::InstRecord *traceData) const
139 {
140 Fault fault = NoFault;
141
142 %(op_decl)s;
143 %(op_rd)s;
144
145 if (%(predicate_test)s)
146 {
147 // ARM instructions will not have a pkt if the predicate is false
148 getMem(pkt, Mem, traceData);
149 uint64_t memData = Mem;
150
151 %(postacc_code)s;
152
153 if (fault == NoFault) {
154 %(op_wb)s;
155 }
156 }
157
158 return fault;
159 }
160}};
161
162def template LoadExecute {{
163 Fault %(class_name)s::execute(ExecContext *xc,
164 Trace::InstRecord *traceData) const
165 {
166 Addr EA;
167 Fault fault = NoFault;
168
169 %(op_decl)s;
170 %(op_rd)s;
171 %(ea_code)s;
172
173 if (%(predicate_test)s)
174 {
175 if (fault == NoFault) {
176 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
177 %(memacc_code)s;
178 }
179
180 if (fault == NoFault) {
181 %(op_wb)s;
182 }
183 } else {
184 xc->setPredicate(false);
185 }
186
187 return fault;
188 }
189}};
190
191def template NeonLoadExecute {{
192 template <class Element>
193 Fault %(class_name)s<Element>::execute(
194 ExecContext *xc, Trace::InstRecord *traceData) const
195 {
196 Addr EA;
197 Fault fault = NoFault;
198
199 %(op_decl)s;
200 %(mem_decl)s;
201 %(op_rd)s;
202 %(ea_code)s;
203
204 MemUnion memUnion;
205 uint8_t *dataPtr = memUnion.bytes;
206
207 if (%(predicate_test)s)
208 {
209 if (fault == NoFault) {
210 fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
211 %(memacc_code)s;
212 }
213
214 if (fault == NoFault) {
215 %(op_wb)s;
216 }
217 } else {
218 xc->setPredicate(false);
219 }
220
221 return fault;
222 }
223}};
224
225def template StoreExecute {{
226 Fault %(class_name)s::execute(ExecContext *xc,
227 Trace::InstRecord *traceData) const
228 {
229 Addr EA;
230 Fault fault = NoFault;
231
232 %(op_decl)s;
233 %(op_rd)s;
234 %(ea_code)s;
235
236 if (%(predicate_test)s)
237 {
238 if (fault == NoFault) {
239 %(memacc_code)s;
240 }
241
242 if (fault == NoFault) {
243 fault = writeMemAtomic(xc, traceData, Mem, EA,
244 memAccessFlags, NULL);
245 }
246
247 if (fault == NoFault) {
248 %(op_wb)s;
249 }
250 } else {
251 xc->setPredicate(false);
252 }
253
254 return fault;
255 }
256}};
257
258def template NeonStoreExecute {{
259 template <class Element>
260 Fault %(class_name)s<Element>::execute(
261 ExecContext *xc, Trace::InstRecord *traceData) const
262 {
263 Addr EA;
264 Fault fault = NoFault;
265
266 %(op_decl)s;
267 %(mem_decl)s;
268 %(op_rd)s;
269 %(ea_code)s;
270
271 MemUnion memUnion;
272 uint8_t *dataPtr = memUnion.bytes;
273
274 if (%(predicate_test)s)
275 {
276 if (fault == NoFault) {
277 %(memacc_code)s;
278 }
279
280 if (fault == NoFault) {
281 fault = xc->writeMem(dataPtr, %(size)d, EA,
282 memAccessFlags, NULL);
283 }
284
285 if (fault == NoFault) {
286 %(op_wb)s;
287 }
288 } else {
289 xc->setPredicate(false);
290 }
291
292 return fault;
293 }
294}};
295
296def template StoreExExecute {{
297 Fault %(class_name)s::execute(ExecContext *xc,
298 Trace::InstRecord *traceData) const
299 {
300 Addr EA;
301 Fault fault = NoFault;
302
303 %(op_decl)s;
304 %(op_rd)s;
305 %(ea_code)s;
306
307 if (%(predicate_test)s)
308 {
309 if (fault == NoFault) {
310 %(memacc_code)s;
311 }
312
313 uint64_t writeResult;
314
315 if (fault == NoFault) {
316 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
317 &writeResult);
318 }
319
320 if (fault == NoFault) {
321 %(postacc_code)s;
322 }
323
324 if (fault == NoFault) {
325 %(op_wb)s;
326 }
327 } else {
328 xc->setPredicate(false);
329 }
330
331 return fault;
332 }
333}};
334
335def template StoreExInitiateAcc {{
336 Fault %(class_name)s::initiateAcc(ExecContext *xc,
337 Trace::InstRecord *traceData) const
338 {
339 Addr EA;
340 Fault fault = NoFault;
341
342 %(op_decl)s;
343 %(op_rd)s;
344 %(ea_code)s;
345
346 if (%(predicate_test)s)
347 {
348 if (fault == NoFault) {
349 %(memacc_code)s;
350 }
351
352 if (fault == NoFault) {
353 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
354 NULL);
355 }
356 } else {
357 xc->setPredicate(false);
358 }
359
360 return fault;
361 }
362}};
363
364def template StoreInitiateAcc {{
365 Fault %(class_name)s::initiateAcc(ExecContext *xc,
366 Trace::InstRecord *traceData) const
367 {
368 Addr EA;
369 Fault fault = NoFault;
370
371 %(op_decl)s;
372 %(op_rd)s;
373 %(ea_code)s;
374
375 if (%(predicate_test)s)
376 {
377 if (fault == NoFault) {
378 %(memacc_code)s;
379 }
380
381 if (fault == NoFault) {
382 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
383 NULL);
384 }
385 } else {
386 xc->setPredicate(false);
387 }
388
389 return fault;
390 }
391}};
392
393def template NeonStoreInitiateAcc {{
394 template <class Element>
395 Fault %(class_name)s<Element>::initiateAcc(
396 ExecContext *xc, Trace::InstRecord *traceData) const
397 {
398 Addr EA;
399 Fault fault = NoFault;
400
401 %(op_decl)s;
402 %(mem_decl)s;
403 %(op_rd)s;
404 %(ea_code)s;
405
406 if (%(predicate_test)s)
407 {
408 MemUnion memUnion;
409 if (fault == NoFault) {
410 %(memacc_code)s;
411 }
412
413 if (fault == NoFault) {
414 fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
415 memAccessFlags, NULL);
416 }
417 } else {
418 xc->setPredicate(false);
419 }
420
421 return fault;
422 }
423}};
424
425def template LoadInitiateAcc {{
426 Fault %(class_name)s::initiateAcc(ExecContext *xc,
427 Trace::InstRecord *traceData) const
428 {
429 Addr EA;
430 Fault fault = NoFault;
431
432 %(op_src_decl)s;
433 %(op_rd)s;
434 %(ea_code)s;
435
436 if (%(predicate_test)s)
437 {
438 if (fault == NoFault) {
439 fault = initiateMemRead(xc, traceData, EA, Mem,
440 memAccessFlags);
441 }
442 } else {
443 xc->setPredicate(false);
444 }
445
446 return fault;
447 }
448}};
449
450def template NeonLoadInitiateAcc {{
451 template <class Element>
452 Fault %(class_name)s<Element>::initiateAcc(
453 ExecContext *xc, Trace::InstRecord *traceData) const
454 {
455 Addr EA;
456 Fault fault = NoFault;
457
458 %(op_decl)s;
459 %(mem_decl)s;
460 %(op_rd)s;
461 %(ea_code)s;
462
463 if (%(predicate_test)s)
464 {
465 if (fault == NoFault) {
466 fault = xc->initiateMemRead(EA, %(size)d, memAccessFlags);
467 }
468 } else {
469 xc->setPredicate(false);
470 }
471
472 return fault;
473 }
474}};
475
476def template LoadCompleteAcc {{
477 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
478 Trace::InstRecord *traceData) const
479 {
480 Fault fault = NoFault;
481
482 %(op_decl)s;
483 %(op_rd)s;
484
485 if (%(predicate_test)s)
486 {
487 // ARM instructions will not have a pkt if the predicate is false
488 getMem(pkt, Mem, traceData);
489
490 if (fault == NoFault) {
491 %(memacc_code)s;
492 }
493
494 if (fault == NoFault) {
495 %(op_wb)s;
496 }
497 }
498
499 return fault;
500 }
501}};
502
503def template NeonLoadCompleteAcc {{
504 template <class Element>
505 Fault %(class_name)s<Element>::completeAcc(
506 PacketPtr pkt, ExecContext *xc,
507 Trace::InstRecord *traceData) const
508 {
509 Fault fault = NoFault;
510
511 %(mem_decl)s;
512 %(op_decl)s;
513 %(op_rd)s;
514
515 if (%(predicate_test)s)
516 {
517 // ARM instructions will not have a pkt if the predicate is false
518 MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
519
520 if (fault == NoFault) {
521 %(memacc_code)s;
522 }
523
524 if (fault == NoFault) {
525 %(op_wb)s;
526 }
527 }
528
529 return fault;
530 }
531}};
532
533def template StoreCompleteAcc {{
534 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
535 Trace::InstRecord *traceData) const
536 {
537 return NoFault;
538 }
539}};
540
541def template NeonStoreCompleteAcc {{
542 template <class Element>
543 Fault %(class_name)s<Element>::completeAcc(
544 PacketPtr pkt, ExecContext *xc, Trace::InstRecord *traceData) const
545 {
546 return NoFault;
547 }
548}};
549
550def template StoreExCompleteAcc {{
551 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
552 Trace::InstRecord *traceData) const
553 {
554 Fault fault = NoFault;
555
556 %(op_decl)s;
557 %(op_rd)s;
558
559 if (%(predicate_test)s)
560 {
561 uint64_t writeResult = pkt->req->getExtraData();
562 %(postacc_code)s;
563
564 if (fault == NoFault) {
565 %(op_wb)s;
566 }
567 }
568
569 return fault;
570 }
571}};
572
573def template RfeDeclare {{
574 /**
575 * Static instruction class for "%(mnemonic)s".
576 */
577 class %(class_name)s : public %(base_class)s
578 {
579 public:
580
581 /// Constructor.
582 %(class_name)s(ExtMachInst machInst,
583 uint32_t _base, int _mode, bool _wb);
584
585 Fault execute(ExecContext *, Trace::InstRecord *) const;
586 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
587 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
585 Fault execute(ExecContext *, Trace::InstRecord *) const override;
586 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
587 Fault completeAcc(PacketPtr, ExecContext *,
588 Trace::InstRecord *) const override;
588 };
589}};
590
591def template SrsDeclare {{
592 /**
593 * Static instruction class for "%(mnemonic)s".
594 */
595 class %(class_name)s : public %(base_class)s
596 {
597 public:
598
599 /// Constructor.
600 %(class_name)s(ExtMachInst machInst,
601 uint32_t _regMode, int _mode, bool _wb);
602
589 };
590}};
591
592def template SrsDeclare {{
593 /**
594 * Static instruction class for "%(mnemonic)s".
595 */
596 class %(class_name)s : public %(base_class)s
597 {
598 public:
599
600 /// Constructor.
601 %(class_name)s(ExtMachInst machInst,
602 uint32_t _regMode, int _mode, bool _wb);
603
603 Fault execute(ExecContext *, Trace::InstRecord *) const;
604 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
605 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
604 Fault execute(ExecContext *, Trace::InstRecord *) const override;
605 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
606 Fault completeAcc(PacketPtr, ExecContext *,
607 Trace::InstRecord *) const override;
606 };
607}};
608
609def template SwapDeclare {{
610 /**
611 * Static instruction class for "%(mnemonic)s".
612 */
613 class %(class_name)s : public %(base_class)s
614 {
615 public:
616
617 /// Constructor.
618 %(class_name)s(ExtMachInst machInst,
619 uint32_t _dest, uint32_t _op1, uint32_t _base);
620
608 };
609}};
610
611def template SwapDeclare {{
612 /**
613 * Static instruction class for "%(mnemonic)s".
614 */
615 class %(class_name)s : public %(base_class)s
616 {
617 public:
618
619 /// Constructor.
620 %(class_name)s(ExtMachInst machInst,
621 uint32_t _dest, uint32_t _op1, uint32_t _base);
622
621 Fault execute(ExecContext *, Trace::InstRecord *) const;
622 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
623 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
623 Fault execute(ExecContext *, Trace::InstRecord *) const override;
624 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
625 Fault completeAcc(PacketPtr, ExecContext *,
626 Trace::InstRecord *) const override;
624 };
625}};
626
627def template LoadStoreDImmDeclare {{
628 /**
629 * Static instruction class for "%(mnemonic)s".
630 */
631 class %(class_name)s : public %(base_class)s
632 {
633 public:
634
635 /// Constructor.
636 %(class_name)s(ExtMachInst machInst,
637 uint32_t _dest, uint32_t _dest2,
638 uint32_t _base, bool _add, int32_t _imm);
639
627 };
628}};
629
630def template LoadStoreDImmDeclare {{
631 /**
632 * Static instruction class for "%(mnemonic)s".
633 */
634 class %(class_name)s : public %(base_class)s
635 {
636 public:
637
638 /// Constructor.
639 %(class_name)s(ExtMachInst machInst,
640 uint32_t _dest, uint32_t _dest2,
641 uint32_t _base, bool _add, int32_t _imm);
642
640 Fault execute(ExecContext *, Trace::InstRecord *) const;
641 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
642 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
643 Fault execute(ExecContext *, Trace::InstRecord *) const override;
644 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
645 Fault completeAcc(PacketPtr, ExecContext *,
646 Trace::InstRecord *) const override;
643 };
644}};
645
646def template StoreExDImmDeclare {{
647 /**
648 * Static instruction class for "%(mnemonic)s".
649 */
650 class %(class_name)s : public %(base_class)s
651 {
652 public:
653
654 /// Constructor.
655 %(class_name)s(ExtMachInst machInst,
656 uint32_t _result, uint32_t _dest, uint32_t _dest2,
657 uint32_t _base, bool _add, int32_t _imm);
658
647 };
648}};
649
650def template StoreExDImmDeclare {{
651 /**
652 * Static instruction class for "%(mnemonic)s".
653 */
654 class %(class_name)s : public %(base_class)s
655 {
656 public:
657
658 /// Constructor.
659 %(class_name)s(ExtMachInst machInst,
660 uint32_t _result, uint32_t _dest, uint32_t _dest2,
661 uint32_t _base, bool _add, int32_t _imm);
662
659 Fault execute(ExecContext *, Trace::InstRecord *) const;
660 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
661 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
663 Fault execute(ExecContext *, Trace::InstRecord *) const override;
664 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
665 Fault completeAcc(PacketPtr, ExecContext *,
666 Trace::InstRecord *) const override;
662 };
663}};
664
665def template LoadStoreImmDeclare {{
666 /**
667 * Static instruction class for "%(mnemonic)s".
668 */
669 class %(class_name)s : public %(base_class)s
670 {
671 public:
672
673 /// Constructor.
674 %(class_name)s(ExtMachInst machInst,
675 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
676
667 };
668}};
669
670def template LoadStoreImmDeclare {{
671 /**
672 * Static instruction class for "%(mnemonic)s".
673 */
674 class %(class_name)s : public %(base_class)s
675 {
676 public:
677
678 /// Constructor.
679 %(class_name)s(ExtMachInst machInst,
680 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
681
677 Fault execute(ExecContext *, Trace::InstRecord *) const;
678 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
679 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
682 Fault execute(ExecContext *, Trace::InstRecord *) const override;
683 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
684 Fault completeAcc(PacketPtr, ExecContext *,
685 Trace::InstRecord *) const override;
680
686
681 virtual void
682 annotateFault(ArmFault *fault) {
687 void
688 annotateFault(ArmFault *fault) override
689 {
683 %(fa_code)s
684 }
685 };
686}};
687
688def template StoreExImmDeclare {{
689 /**
690 * Static instruction class for "%(mnemonic)s".
691 */
692 class %(class_name)s : public %(base_class)s
693 {
694 public:
695
696 /// Constructor.
697 %(class_name)s(ExtMachInst machInst,
698 uint32_t _result, uint32_t _dest, uint32_t _base,
699 bool _add, int32_t _imm);
700
690 %(fa_code)s
691 }
692 };
693}};
694
695def template StoreExImmDeclare {{
696 /**
697 * Static instruction class for "%(mnemonic)s".
698 */
699 class %(class_name)s : public %(base_class)s
700 {
701 public:
702
703 /// Constructor.
704 %(class_name)s(ExtMachInst machInst,
705 uint32_t _result, uint32_t _dest, uint32_t _base,
706 bool _add, int32_t _imm);
707
701 Fault execute(ExecContext *, Trace::InstRecord *) const;
702 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
703 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
708 Fault execute(ExecContext *, Trace::InstRecord *) const override;
709 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
710 Fault completeAcc(PacketPtr, ExecContext *,
711 Trace::InstRecord *) const override;
704 };
705}};
706
707def template StoreDRegDeclare {{
708 /**
709 * Static instruction class for "%(mnemonic)s".
710 */
711 class %(class_name)s : public %(base_class)s
712 {
713 public:
714
715 /// Constructor.
716 %(class_name)s(ExtMachInst machInst,
717 uint32_t _dest, uint32_t _dest2,
718 uint32_t _base, bool _add,
719 int32_t _shiftAmt, uint32_t _shiftType,
720 uint32_t _index);
721
712 };
713}};
714
715def template StoreDRegDeclare {{
716 /**
717 * Static instruction class for "%(mnemonic)s".
718 */
719 class %(class_name)s : public %(base_class)s
720 {
721 public:
722
723 /// Constructor.
724 %(class_name)s(ExtMachInst machInst,
725 uint32_t _dest, uint32_t _dest2,
726 uint32_t _base, bool _add,
727 int32_t _shiftAmt, uint32_t _shiftType,
728 uint32_t _index);
729
722 Fault execute(ExecContext *, Trace::InstRecord *) const;
723 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
724 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
730 Fault execute(ExecContext *, Trace::InstRecord *) const override;
731 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
732 Fault completeAcc(PacketPtr, ExecContext *,
733 Trace::InstRecord *) const override;
725 };
726}};
727
728def template StoreRegDeclare {{
729 /**
730 * Static instruction class for "%(mnemonic)s".
731 */
732 class %(class_name)s : public %(base_class)s
733 {
734 public:
735
736 /// Constructor.
737 %(class_name)s(ExtMachInst machInst,
738 uint32_t _dest, uint32_t _base, bool _add,
739 int32_t _shiftAmt, uint32_t _shiftType,
740 uint32_t _index);
741
734 };
735}};
736
737def template StoreRegDeclare {{
738 /**
739 * Static instruction class for "%(mnemonic)s".
740 */
741 class %(class_name)s : public %(base_class)s
742 {
743 public:
744
745 /// Constructor.
746 %(class_name)s(ExtMachInst machInst,
747 uint32_t _dest, uint32_t _base, bool _add,
748 int32_t _shiftAmt, uint32_t _shiftType,
749 uint32_t _index);
750
742 Fault execute(ExecContext *, Trace::InstRecord *) const;
743 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
744 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
751 Fault execute(ExecContext *, Trace::InstRecord *) const override;
752 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
753 Fault completeAcc(PacketPtr, ExecContext *,
754 Trace::InstRecord *) const override;
745
755
746 virtual void
747 annotateFault(ArmFault *fault) {
756 void
757 annotateFault(ArmFault *fault) override
758 {
748 %(fa_code)s
749 }
750 };
751}};
752
753def template LoadDRegDeclare {{
754 /**
755 * Static instruction class for "%(mnemonic)s".
756 */
757 class %(class_name)s : public %(base_class)s
758 {
759 public:
760
761 /// Constructor.
762 %(class_name)s(ExtMachInst machInst,
763 uint32_t _dest, uint32_t _dest2,
764 uint32_t _base, bool _add,
765 int32_t _shiftAmt, uint32_t _shiftType,
766 uint32_t _index);
767
759 %(fa_code)s
760 }
761 };
762}};
763
764def template LoadDRegDeclare {{
765 /**
766 * Static instruction class for "%(mnemonic)s".
767 */
768 class %(class_name)s : public %(base_class)s
769 {
770 public:
771
772 /// Constructor.
773 %(class_name)s(ExtMachInst machInst,
774 uint32_t _dest, uint32_t _dest2,
775 uint32_t _base, bool _add,
776 int32_t _shiftAmt, uint32_t _shiftType,
777 uint32_t _index);
778
768 Fault execute(ExecContext *, Trace::InstRecord *) const;
769 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
770 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
779 Fault execute(ExecContext *, Trace::InstRecord *) const override;
780 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
781 Fault completeAcc(PacketPtr, ExecContext *,
782 Trace::InstRecord *) const override;
771 };
772}};
773
774def template LoadRegDeclare {{
775 /**
776 * Static instruction class for "%(mnemonic)s".
777 */
778 class %(class_name)s : public %(base_class)s
779 {
780 public:
781
782 /// Constructor.
783 %(class_name)s(ExtMachInst machInst,
784 uint32_t _dest, uint32_t _base, bool _add,
785 int32_t _shiftAmt, uint32_t _shiftType,
786 uint32_t _index);
787
783 };
784}};
785
786def template LoadRegDeclare {{
787 /**
788 * Static instruction class for "%(mnemonic)s".
789 */
790 class %(class_name)s : public %(base_class)s
791 {
792 public:
793
794 /// Constructor.
795 %(class_name)s(ExtMachInst machInst,
796 uint32_t _dest, uint32_t _base, bool _add,
797 int32_t _shiftAmt, uint32_t _shiftType,
798 uint32_t _index);
799
788 Fault execute(ExecContext *, Trace::InstRecord *) const;
789 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
790 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
800 Fault execute(ExecContext *, Trace::InstRecord *) const override;
801 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
802 Fault completeAcc(PacketPtr, ExecContext *,
803 Trace::InstRecord *) const override;
791
804
792 virtual void
793 annotateFault(ArmFault *fault) {
805 void
806 annotateFault(ArmFault *fault) override
807 {
794 %(fa_code)s
795 }
796 };
797}};
798
799def template LoadImmDeclare {{
800 /**
801 * Static instruction class for "%(mnemonic)s".
802 */
803 class %(class_name)s : public %(base_class)s
804 {
805 public:
806
807 /// Constructor.
808 %(class_name)s(ExtMachInst machInst,
809 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
810
808 %(fa_code)s
809 }
810 };
811}};
812
813def template LoadImmDeclare {{
814 /**
815 * Static instruction class for "%(mnemonic)s".
816 */
817 class %(class_name)s : public %(base_class)s
818 {
819 public:
820
821 /// Constructor.
822 %(class_name)s(ExtMachInst machInst,
823 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
824
811 Fault execute(ExecContext *, Trace::InstRecord *) const;
812 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
813 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
825 Fault execute(ExecContext *, Trace::InstRecord *) const override;
826 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
827 Fault completeAcc(PacketPtr, ExecContext *,
828 Trace::InstRecord *) const override;
814
829
815 virtual void
816 annotateFault(ArmFault *fault) {
830 void
831 annotateFault(ArmFault *fault) override
832 {
817 %(fa_code)s
818 }
819 };
820}};
821
822def template RfeConstructor {{
823 %(class_name)s::%(class_name)s(ExtMachInst machInst,
824 uint32_t _base, int _mode, bool _wb)
825 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
826 (IntRegIndex)_base, (AddrMode)_mode, _wb)
827 {
828 %(constructor)s;
829 if (!(condCode == COND_AL || condCode == COND_UC)) {
830 for (int x = 0; x < _numDestRegs; x++) {
831 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
832 }
833 }
834#if %(use_uops)d
835 uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
836 int uopIdx = 0;
837 uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
838 uops[uopIdx]->setDelayedCommit();
839#if %(use_wb)d
840 uops[++uopIdx] = new %(wb_decl)s;
841 uops[uopIdx]->setDelayedCommit();
842#endif
843#if %(use_pc)d
844 uops[++uopIdx] = new %(pc_decl)s;
845#endif
846 uops[0]->setFirstMicroop();
847 uops[uopIdx]->setLastMicroop();
848#endif
849 }
850}};
851
852def template SrsConstructor {{
853 %(class_name)s::%(class_name)s(ExtMachInst machInst,
854 uint32_t _regMode, int _mode, bool _wb)
855 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
856 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
857 {
858 %(constructor)s;
859 if (!(condCode == COND_AL || condCode == COND_UC)) {
860 for (int x = 0; x < _numDestRegs; x++) {
861 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
862 }
863 }
864#if %(use_uops)d
865 assert(numMicroops >= 2);
866 uops = new StaticInstPtr[numMicroops];
867 uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
868 uops[0]->setDelayedCommit();
869 uops[0]->setFirstMicroop();
870 uops[1] = new %(wb_decl)s;
871 uops[1]->setLastMicroop();
872#endif
873 }
874}};
875
876def template SwapConstructor {{
877 %(class_name)s::%(class_name)s(ExtMachInst machInst,
878 uint32_t _dest, uint32_t _op1, uint32_t _base)
879 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
880 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
881 {
882 %(constructor)s;
883 if (!(condCode == COND_AL || condCode == COND_UC)) {
884 for (int x = 0; x < _numDestRegs; x++) {
885 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
886 }
887 }
888 }
889}};
890
891def template LoadStoreDImmConstructor {{
892 %(class_name)s::%(class_name)s(ExtMachInst machInst,
893 uint32_t _dest, uint32_t _dest2,
894 uint32_t _base, bool _add, int32_t _imm)
895 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
896 (IntRegIndex)_dest, (IntRegIndex)_dest2,
897 (IntRegIndex)_base, _add, _imm)
898 {
899 %(constructor)s;
900 if (!(condCode == COND_AL || condCode == COND_UC)) {
901 for (int x = 0; x < _numDestRegs; x++) {
902 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
903 }
904 }
905#if %(use_uops)d
906 assert(numMicroops >= 2);
907 uops = new StaticInstPtr[numMicroops];
908 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
909 uops[0]->setFirstMicroop();
910 uops[0]->setDelayedCommit();
911 uops[1] = new %(wb_decl)s;
912 uops[1]->setLastMicroop();
913#endif
914 }
915}};
916
917def template StoreExDImmConstructor {{
918 %(class_name)s::%(class_name)s(ExtMachInst machInst,
919 uint32_t _result, uint32_t _dest, uint32_t _dest2,
920 uint32_t _base, bool _add, int32_t _imm)
921 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
922 (IntRegIndex)_result,
923 (IntRegIndex)_dest, (IntRegIndex)_dest2,
924 (IntRegIndex)_base, _add, _imm)
925 {
926 %(constructor)s;
927 if (!(condCode == COND_AL || condCode == COND_UC)) {
928 for (int x = 0; x < _numDestRegs; x++) {
929 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
930 }
931 }
932#if %(use_uops)d
933 assert(numMicroops >= 2);
934 uops = new StaticInstPtr[numMicroops];
935 uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
936 _base, _add, _imm);
937 uops[0]->setDelayedCommit();
938 uops[0]->setFirstMicroop();
939 uops[1] = new %(wb_decl)s;
940 uops[1]->setLastMicroop();
941#endif
942 }
943}};
944
945def template LoadStoreImmConstructor {{
946 %(class_name)s::%(class_name)s(ExtMachInst machInst,
947 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
948 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
949 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
950 {
951 %(constructor)s;
952 if (!(condCode == COND_AL || condCode == COND_UC)) {
953 for (int x = 0; x < _numDestRegs; x++) {
954 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
955 }
956 }
957#if %(use_uops)d
958 assert(numMicroops >= 2);
959 uops = new StaticInstPtr[numMicroops];
960 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
961 uops[0]->setDelayedCommit();
962 uops[0]->setFirstMicroop();
963 uops[1] = new %(wb_decl)s;
964 uops[1]->setLastMicroop();
965#endif
966 }
967}};
968
969def template StoreExImmConstructor {{
970 %(class_name)s::%(class_name)s(ExtMachInst machInst,
971 uint32_t _result, uint32_t _dest, uint32_t _base,
972 bool _add, int32_t _imm)
973 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
974 (IntRegIndex)_result, (IntRegIndex)_dest,
975 (IntRegIndex)_base, _add, _imm)
976 {
977 %(constructor)s;
978 if (!(condCode == COND_AL || condCode == COND_UC)) {
979 for (int x = 0; x < _numDestRegs; x++) {
980 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
981 }
982 }
983#if %(use_uops)d
984 assert(numMicroops >= 2);
985 uops = new StaticInstPtr[numMicroops];
986 uops[0] = new %(acc_name)s(machInst, _result, _dest,
987 _base, _add, _imm);
988 uops[0]->setDelayedCommit();
989 uops[0]->setFirstMicroop();
990 uops[1] = new %(wb_decl)s;
991 uops[1]->setLastMicroop();
992#endif
993 }
994}};
995
996def template StoreDRegConstructor {{
997 %(class_name)s::%(class_name)s(ExtMachInst machInst,
998 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
999 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1000 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1001 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1002 (IntRegIndex)_base, _add,
1003 _shiftAmt, (ArmShiftType)_shiftType,
1004 (IntRegIndex)_index)
1005 {
1006 %(constructor)s;
1007 if (!(condCode == COND_AL || condCode == COND_UC)) {
1008 for (int x = 0; x < _numDestRegs; x++) {
1009 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1010 }
1011 }
1012#if %(use_uops)d
1013 assert(numMicroops >= 2);
1014 uops = new StaticInstPtr[numMicroops];
1015 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1016 _shiftAmt, _shiftType, _index);
1017 uops[0]->setDelayedCommit();
1018 uops[0]->setFirstMicroop();
1019 uops[1] = new %(wb_decl)s;
1020 uops[1]->setLastMicroop();
1021#endif
1022 }
1023}};
1024
1025def template StoreRegConstructor {{
1026 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1027 uint32_t _dest, uint32_t _base, bool _add,
1028 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1029 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1030 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1031 _shiftAmt, (ArmShiftType)_shiftType,
1032 (IntRegIndex)_index)
1033 {
1034 %(constructor)s;
1035 if (!(condCode == COND_AL || condCode == COND_UC)) {
1036 for (int x = 0; x < _numDestRegs; x++) {
1037 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1038 }
1039 }
1040#if %(use_uops)d
1041 assert(numMicroops >= 2);
1042 uops = new StaticInstPtr[numMicroops];
1043 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1044 _shiftAmt, _shiftType, _index);
1045 uops[0]->setDelayedCommit();
1046 uops[0]->setFirstMicroop();
1047 uops[1] = new %(wb_decl)s;
1048 uops[1]->setLastMicroop();
1049#endif
1050 }
1051}};
1052
1053def template LoadDRegConstructor {{
1054 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1055 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1056 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1057 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1058 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1059 (IntRegIndex)_base, _add,
1060 _shiftAmt, (ArmShiftType)_shiftType,
1061 (IntRegIndex)_index)
1062 {
1063 %(constructor)s;
1064 if (!(condCode == COND_AL || condCode == COND_UC)) {
1065 for (int x = 0; x < _numDestRegs; x++) {
1066 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1067 }
1068 }
1069#if %(use_uops)d
1070 assert(numMicroops >= 2);
1071 uops = new StaticInstPtr[numMicroops];
1072 if ((_dest == _index) || (_dest2 == _index)) {
1073 IntRegIndex wbIndexReg = INTREG_UREG0;
1074 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1075 uops[0]->setDelayedCommit();
1076 uops[0]->setFirstMicroop();
1077 uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1078 _shiftAmt, _shiftType, _index);
1079 uops[1]->setDelayedCommit();
1080 uops[2] = new %(wb_decl)s;
1081 uops[2]->setLastMicroop();
1082 } else {
1083 IntRegIndex wbIndexReg = index;
1084 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1085 _shiftAmt, _shiftType, _index);
1086 uops[0]->setDelayedCommit();
1087 uops[0]->setFirstMicroop();
1088 uops[1] = new %(wb_decl)s;
1089 uops[1]->setLastMicroop();
1090 }
1091#endif
1092 }
1093}};
1094
1095def template LoadRegConstructor {{
1096 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1097 uint32_t _dest, uint32_t _base, bool _add,
1098 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1099 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1100 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1101 _shiftAmt, (ArmShiftType)_shiftType,
1102 (IntRegIndex)_index)
1103 {
1104 %(constructor)s;
1105 bool conditional M5_VAR_USED = false;
1106 if (!(condCode == COND_AL || condCode == COND_UC)) {
1107 conditional = true;
1108 for (int x = 0; x < _numDestRegs; x++) {
1109 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1110 }
1111 }
1112#if %(use_uops)d
1113 assert(numMicroops >= 2);
1114 uops = new StaticInstPtr[numMicroops];
1115 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1116 IntRegIndex wbIndexReg = index;
1117 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1118 _shiftAmt, _shiftType, _index);
1119 uops[0]->setDelayedCommit();
1120 uops[0]->setFirstMicroop();
1121 uops[1] = new %(wb_decl)s;
1122 uops[1]->setDelayedCommit();
1123 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1124 uops[2]->setFlag(StaticInst::IsControl);
1125 uops[2]->setFlag(StaticInst::IsIndirectControl);
1126 if (conditional)
1127 uops[2]->setFlag(StaticInst::IsCondControl);
1128 else
1129 uops[2]->setFlag(StaticInst::IsUncondControl);
1130 uops[2]->setLastMicroop();
1131 } else if(_dest == _index) {
1132 IntRegIndex wbIndexReg = INTREG_UREG0;
1133 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1134 uops[0]->setDelayedCommit();
1135 uops[0]->setFirstMicroop();
1136 uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1137 _shiftAmt, _shiftType, _index);
1138 uops[1]->setDelayedCommit();
1139 uops[2] = new %(wb_decl)s;
1140 uops[2]->setLastMicroop();
1141 } else {
1142 IntRegIndex wbIndexReg = index;
1143 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1144 _shiftAmt, _shiftType, _index);
1145 uops[0]->setDelayedCommit();
1146 uops[0]->setFirstMicroop();
1147 uops[1] = new %(wb_decl)s;
1148 uops[1]->setLastMicroop();
1149
1150 }
1151#else
1152 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1153 flags[IsControl] = true;
1154 flags[IsIndirectControl] = true;
1155 if (conditional)
1156 flags[IsCondControl] = true;
1157 else
1158 flags[IsUncondControl] = true;
1159 }
1160#endif
1161 }
1162}};
1163
1164def template LoadImmConstructor {{
1165 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1166 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1167 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1168 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1169 {
1170 %(constructor)s;
1171 bool conditional M5_VAR_USED = false;
1172 if (!(condCode == COND_AL || condCode == COND_UC)) {
1173 conditional = true;
1174 for (int x = 0; x < _numDestRegs; x++) {
1175 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1176 }
1177 }
1178#if %(use_uops)d
1179 assert(numMicroops >= 2);
1180 uops = new StaticInstPtr[numMicroops];
1181 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1182 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1183 _imm);
1184 uops[0]->setDelayedCommit();
1185 uops[0]->setFirstMicroop();
1186 uops[1] = new %(wb_decl)s;
1187 uops[1]->setDelayedCommit();
1188 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1189 uops[2]->setFlag(StaticInst::IsControl);
1190 uops[2]->setFlag(StaticInst::IsIndirectControl);
1191 /* Also set flags on the macroop so that pre-microop decomposition
1192 branch prediction can work */
1193 setFlag(StaticInst::IsControl);
1194 setFlag(StaticInst::IsIndirectControl);
1195 if (conditional) {
1196 uops[2]->setFlag(StaticInst::IsCondControl);
1197 setFlag(StaticInst::IsCondControl);
1198 } else {
1199 uops[2]->setFlag(StaticInst::IsUncondControl);
1200 setFlag(StaticInst::IsUncondControl);
1201 }
1202 if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s) {
1203 uops[2]->setFlag(StaticInst::IsReturn);
1204 setFlag(StaticInst::IsReturn);
1205 }
1206 uops[2]->setLastMicroop();
1207 } else {
1208 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1209 uops[0]->setDelayedCommit();
1210 uops[0]->setFirstMicroop();
1211 uops[1] = new %(wb_decl)s;
1212 uops[1]->setLastMicroop();
1213 }
1214#else
1215 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1216 flags[IsControl] = true;
1217 flags[IsIndirectControl] = true;
1218 if (conditional)
1219 flags[IsCondControl] = true;
1220 else
1221 flags[IsUncondControl] = true;
1222 }
1223#endif
1224 }
1225}};
1226
833 %(fa_code)s
834 }
835 };
836}};
837
838def template RfeConstructor {{
839 %(class_name)s::%(class_name)s(ExtMachInst machInst,
840 uint32_t _base, int _mode, bool _wb)
841 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
842 (IntRegIndex)_base, (AddrMode)_mode, _wb)
843 {
844 %(constructor)s;
845 if (!(condCode == COND_AL || condCode == COND_UC)) {
846 for (int x = 0; x < _numDestRegs; x++) {
847 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
848 }
849 }
850#if %(use_uops)d
851 uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
852 int uopIdx = 0;
853 uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
854 uops[uopIdx]->setDelayedCommit();
855#if %(use_wb)d
856 uops[++uopIdx] = new %(wb_decl)s;
857 uops[uopIdx]->setDelayedCommit();
858#endif
859#if %(use_pc)d
860 uops[++uopIdx] = new %(pc_decl)s;
861#endif
862 uops[0]->setFirstMicroop();
863 uops[uopIdx]->setLastMicroop();
864#endif
865 }
866}};
867
868def template SrsConstructor {{
869 %(class_name)s::%(class_name)s(ExtMachInst machInst,
870 uint32_t _regMode, int _mode, bool _wb)
871 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
872 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
873 {
874 %(constructor)s;
875 if (!(condCode == COND_AL || condCode == COND_UC)) {
876 for (int x = 0; x < _numDestRegs; x++) {
877 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
878 }
879 }
880#if %(use_uops)d
881 assert(numMicroops >= 2);
882 uops = new StaticInstPtr[numMicroops];
883 uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
884 uops[0]->setDelayedCommit();
885 uops[0]->setFirstMicroop();
886 uops[1] = new %(wb_decl)s;
887 uops[1]->setLastMicroop();
888#endif
889 }
890}};
891
892def template SwapConstructor {{
893 %(class_name)s::%(class_name)s(ExtMachInst machInst,
894 uint32_t _dest, uint32_t _op1, uint32_t _base)
895 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
896 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
897 {
898 %(constructor)s;
899 if (!(condCode == COND_AL || condCode == COND_UC)) {
900 for (int x = 0; x < _numDestRegs; x++) {
901 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
902 }
903 }
904 }
905}};
906
907def template LoadStoreDImmConstructor {{
908 %(class_name)s::%(class_name)s(ExtMachInst machInst,
909 uint32_t _dest, uint32_t _dest2,
910 uint32_t _base, bool _add, int32_t _imm)
911 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
912 (IntRegIndex)_dest, (IntRegIndex)_dest2,
913 (IntRegIndex)_base, _add, _imm)
914 {
915 %(constructor)s;
916 if (!(condCode == COND_AL || condCode == COND_UC)) {
917 for (int x = 0; x < _numDestRegs; x++) {
918 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
919 }
920 }
921#if %(use_uops)d
922 assert(numMicroops >= 2);
923 uops = new StaticInstPtr[numMicroops];
924 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
925 uops[0]->setFirstMicroop();
926 uops[0]->setDelayedCommit();
927 uops[1] = new %(wb_decl)s;
928 uops[1]->setLastMicroop();
929#endif
930 }
931}};
932
933def template StoreExDImmConstructor {{
934 %(class_name)s::%(class_name)s(ExtMachInst machInst,
935 uint32_t _result, uint32_t _dest, uint32_t _dest2,
936 uint32_t _base, bool _add, int32_t _imm)
937 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
938 (IntRegIndex)_result,
939 (IntRegIndex)_dest, (IntRegIndex)_dest2,
940 (IntRegIndex)_base, _add, _imm)
941 {
942 %(constructor)s;
943 if (!(condCode == COND_AL || condCode == COND_UC)) {
944 for (int x = 0; x < _numDestRegs; x++) {
945 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
946 }
947 }
948#if %(use_uops)d
949 assert(numMicroops >= 2);
950 uops = new StaticInstPtr[numMicroops];
951 uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
952 _base, _add, _imm);
953 uops[0]->setDelayedCommit();
954 uops[0]->setFirstMicroop();
955 uops[1] = new %(wb_decl)s;
956 uops[1]->setLastMicroop();
957#endif
958 }
959}};
960
961def template LoadStoreImmConstructor {{
962 %(class_name)s::%(class_name)s(ExtMachInst machInst,
963 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
964 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
965 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
966 {
967 %(constructor)s;
968 if (!(condCode == COND_AL || condCode == COND_UC)) {
969 for (int x = 0; x < _numDestRegs; x++) {
970 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
971 }
972 }
973#if %(use_uops)d
974 assert(numMicroops >= 2);
975 uops = new StaticInstPtr[numMicroops];
976 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
977 uops[0]->setDelayedCommit();
978 uops[0]->setFirstMicroop();
979 uops[1] = new %(wb_decl)s;
980 uops[1]->setLastMicroop();
981#endif
982 }
983}};
984
985def template StoreExImmConstructor {{
986 %(class_name)s::%(class_name)s(ExtMachInst machInst,
987 uint32_t _result, uint32_t _dest, uint32_t _base,
988 bool _add, int32_t _imm)
989 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
990 (IntRegIndex)_result, (IntRegIndex)_dest,
991 (IntRegIndex)_base, _add, _imm)
992 {
993 %(constructor)s;
994 if (!(condCode == COND_AL || condCode == COND_UC)) {
995 for (int x = 0; x < _numDestRegs; x++) {
996 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
997 }
998 }
999#if %(use_uops)d
1000 assert(numMicroops >= 2);
1001 uops = new StaticInstPtr[numMicroops];
1002 uops[0] = new %(acc_name)s(machInst, _result, _dest,
1003 _base, _add, _imm);
1004 uops[0]->setDelayedCommit();
1005 uops[0]->setFirstMicroop();
1006 uops[1] = new %(wb_decl)s;
1007 uops[1]->setLastMicroop();
1008#endif
1009 }
1010}};
1011
1012def template StoreDRegConstructor {{
1013 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1014 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1015 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1016 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1017 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1018 (IntRegIndex)_base, _add,
1019 _shiftAmt, (ArmShiftType)_shiftType,
1020 (IntRegIndex)_index)
1021 {
1022 %(constructor)s;
1023 if (!(condCode == COND_AL || condCode == COND_UC)) {
1024 for (int x = 0; x < _numDestRegs; x++) {
1025 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1026 }
1027 }
1028#if %(use_uops)d
1029 assert(numMicroops >= 2);
1030 uops = new StaticInstPtr[numMicroops];
1031 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1032 _shiftAmt, _shiftType, _index);
1033 uops[0]->setDelayedCommit();
1034 uops[0]->setFirstMicroop();
1035 uops[1] = new %(wb_decl)s;
1036 uops[1]->setLastMicroop();
1037#endif
1038 }
1039}};
1040
1041def template StoreRegConstructor {{
1042 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1043 uint32_t _dest, uint32_t _base, bool _add,
1044 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1045 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1046 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1047 _shiftAmt, (ArmShiftType)_shiftType,
1048 (IntRegIndex)_index)
1049 {
1050 %(constructor)s;
1051 if (!(condCode == COND_AL || condCode == COND_UC)) {
1052 for (int x = 0; x < _numDestRegs; x++) {
1053 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1054 }
1055 }
1056#if %(use_uops)d
1057 assert(numMicroops >= 2);
1058 uops = new StaticInstPtr[numMicroops];
1059 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1060 _shiftAmt, _shiftType, _index);
1061 uops[0]->setDelayedCommit();
1062 uops[0]->setFirstMicroop();
1063 uops[1] = new %(wb_decl)s;
1064 uops[1]->setLastMicroop();
1065#endif
1066 }
1067}};
1068
1069def template LoadDRegConstructor {{
1070 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1071 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1072 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1073 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1074 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1075 (IntRegIndex)_base, _add,
1076 _shiftAmt, (ArmShiftType)_shiftType,
1077 (IntRegIndex)_index)
1078 {
1079 %(constructor)s;
1080 if (!(condCode == COND_AL || condCode == COND_UC)) {
1081 for (int x = 0; x < _numDestRegs; x++) {
1082 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1083 }
1084 }
1085#if %(use_uops)d
1086 assert(numMicroops >= 2);
1087 uops = new StaticInstPtr[numMicroops];
1088 if ((_dest == _index) || (_dest2 == _index)) {
1089 IntRegIndex wbIndexReg = INTREG_UREG0;
1090 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1091 uops[0]->setDelayedCommit();
1092 uops[0]->setFirstMicroop();
1093 uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1094 _shiftAmt, _shiftType, _index);
1095 uops[1]->setDelayedCommit();
1096 uops[2] = new %(wb_decl)s;
1097 uops[2]->setLastMicroop();
1098 } else {
1099 IntRegIndex wbIndexReg = index;
1100 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1101 _shiftAmt, _shiftType, _index);
1102 uops[0]->setDelayedCommit();
1103 uops[0]->setFirstMicroop();
1104 uops[1] = new %(wb_decl)s;
1105 uops[1]->setLastMicroop();
1106 }
1107#endif
1108 }
1109}};
1110
1111def template LoadRegConstructor {{
1112 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1113 uint32_t _dest, uint32_t _base, bool _add,
1114 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1115 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1116 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1117 _shiftAmt, (ArmShiftType)_shiftType,
1118 (IntRegIndex)_index)
1119 {
1120 %(constructor)s;
1121 bool conditional M5_VAR_USED = false;
1122 if (!(condCode == COND_AL || condCode == COND_UC)) {
1123 conditional = true;
1124 for (int x = 0; x < _numDestRegs; x++) {
1125 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1126 }
1127 }
1128#if %(use_uops)d
1129 assert(numMicroops >= 2);
1130 uops = new StaticInstPtr[numMicroops];
1131 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1132 IntRegIndex wbIndexReg = index;
1133 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1134 _shiftAmt, _shiftType, _index);
1135 uops[0]->setDelayedCommit();
1136 uops[0]->setFirstMicroop();
1137 uops[1] = new %(wb_decl)s;
1138 uops[1]->setDelayedCommit();
1139 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1140 uops[2]->setFlag(StaticInst::IsControl);
1141 uops[2]->setFlag(StaticInst::IsIndirectControl);
1142 if (conditional)
1143 uops[2]->setFlag(StaticInst::IsCondControl);
1144 else
1145 uops[2]->setFlag(StaticInst::IsUncondControl);
1146 uops[2]->setLastMicroop();
1147 } else if(_dest == _index) {
1148 IntRegIndex wbIndexReg = INTREG_UREG0;
1149 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1150 uops[0]->setDelayedCommit();
1151 uops[0]->setFirstMicroop();
1152 uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1153 _shiftAmt, _shiftType, _index);
1154 uops[1]->setDelayedCommit();
1155 uops[2] = new %(wb_decl)s;
1156 uops[2]->setLastMicroop();
1157 } else {
1158 IntRegIndex wbIndexReg = index;
1159 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1160 _shiftAmt, _shiftType, _index);
1161 uops[0]->setDelayedCommit();
1162 uops[0]->setFirstMicroop();
1163 uops[1] = new %(wb_decl)s;
1164 uops[1]->setLastMicroop();
1165
1166 }
1167#else
1168 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1169 flags[IsControl] = true;
1170 flags[IsIndirectControl] = true;
1171 if (conditional)
1172 flags[IsCondControl] = true;
1173 else
1174 flags[IsUncondControl] = true;
1175 }
1176#endif
1177 }
1178}};
1179
1180def template LoadImmConstructor {{
1181 %(class_name)s::%(class_name)s(ExtMachInst machInst,
1182 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1183 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1184 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1185 {
1186 %(constructor)s;
1187 bool conditional M5_VAR_USED = false;
1188 if (!(condCode == COND_AL || condCode == COND_UC)) {
1189 conditional = true;
1190 for (int x = 0; x < _numDestRegs; x++) {
1191 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1192 }
1193 }
1194#if %(use_uops)d
1195 assert(numMicroops >= 2);
1196 uops = new StaticInstPtr[numMicroops];
1197 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1198 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1199 _imm);
1200 uops[0]->setDelayedCommit();
1201 uops[0]->setFirstMicroop();
1202 uops[1] = new %(wb_decl)s;
1203 uops[1]->setDelayedCommit();
1204 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1205 uops[2]->setFlag(StaticInst::IsControl);
1206 uops[2]->setFlag(StaticInst::IsIndirectControl);
1207 /* Also set flags on the macroop so that pre-microop decomposition
1208 branch prediction can work */
1209 setFlag(StaticInst::IsControl);
1210 setFlag(StaticInst::IsIndirectControl);
1211 if (conditional) {
1212 uops[2]->setFlag(StaticInst::IsCondControl);
1213 setFlag(StaticInst::IsCondControl);
1214 } else {
1215 uops[2]->setFlag(StaticInst::IsUncondControl);
1216 setFlag(StaticInst::IsUncondControl);
1217 }
1218 if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s) {
1219 uops[2]->setFlag(StaticInst::IsReturn);
1220 setFlag(StaticInst::IsReturn);
1221 }
1222 uops[2]->setLastMicroop();
1223 } else {
1224 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1225 uops[0]->setDelayedCommit();
1226 uops[0]->setFirstMicroop();
1227 uops[1] = new %(wb_decl)s;
1228 uops[1]->setLastMicroop();
1229 }
1230#else
1231 if (_dest == INTREG_PC && !isFloating() && !isVector()) {
1232 flags[IsControl] = true;
1233 flags[IsIndirectControl] = true;
1234 if (conditional)
1235 flags[IsCondControl] = true;
1236 else
1237 flags[IsUncondControl] = true;
1238 }
1239#endif
1240 }
1241}};
1242