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 } else {
73 xc->setPredicate(false);
74 }
75
76 if (fault == NoFault && machInst.itstateMask != 0) {
77 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
78 }
79
80 return fault;
81 }
82}};
83
84def template SwapInitiateAcc {{
85 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
86 Trace::InstRecord *traceData) const
87 {
88 Addr EA;
89 Fault fault = NoFault;
90
91 %(op_decl)s;
92 uint64_t memData = 0;
93 %(op_rd)s;
94 %(ea_code)s;
95
96 if (%(predicate_test)s)
97 {
98 %(preacc_code)s;
99
100 if (fault == NoFault) {
101 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
102 memAccessFlags, &memData);
103 }
104
105 if (fault == NoFault) {
106 %(op_wb)s;
107 }
108 } else {
109 xc->setPredicate(false);
110 }
111
112 if (fault == NoFault && machInst.itstateMask != 0) {
113 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
114 }
115
116 return fault;
117 }
118}};
119
120def template SwapCompleteAcc {{
121 Fault %(class_name)s::completeAcc(PacketPtr pkt,
122 %(CPU_exec_context)s *xc,
123 Trace::InstRecord *traceData) const
124 {
125 Fault fault = NoFault;
126
127 %(op_decl)s;
128 %(op_rd)s;
129
130 if (%(predicate_test)s)
131 {
132 // ARM instructions will not have a pkt if the predicate is false
133 uint64_t memData = pkt->get<typeof(Mem)>();
134
135 %(postacc_code)s;
136
137 if (fault == NoFault) {
138 %(op_wb)s;
139 }
140 }
141
142 if (fault == NoFault && machInst.itstateMask != 0) {
143 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
144 }
145
146 return fault;
147 }
148}};
149
150def template LoadExecute {{
151 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
152 Trace::InstRecord *traceData) const
153 {
154 Addr EA;
155 Fault fault = NoFault;
156
157 %(op_decl)s;
158 %(op_rd)s;
159 %(ea_code)s;
160
161 if (%(predicate_test)s)
162 {
163 if (fault == NoFault) {
164 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
165 %(memacc_code)s;
166 }
167
168 if (fault == NoFault) {
169 %(op_wb)s;
170 }
171 } else {
172 xc->setPredicate(false);
173 }
174
175 if (fault == NoFault && machInst.itstateMask != 0) {
176 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
177 }
178
179 return fault;
180 }
181}};
182
183def template StoreExecute {{
184 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
185 Trace::InstRecord *traceData) const
186 {
187 Addr EA;
188 Fault fault = NoFault;
189
190 %(op_decl)s;
191 %(op_rd)s;
192 %(ea_code)s;
193
194 if (%(predicate_test)s)
195 {
196 if (fault == NoFault) {
197 %(memacc_code)s;
198 }
199
200 if (fault == NoFault) {
201 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
202 memAccessFlags, NULL);
203 if (traceData) { traceData->setData(Mem); }
204 }
205
206 if (fault == NoFault) {
207 %(op_wb)s;
208 }
209 } else {
210 xc->setPredicate(false);
211 }
212
213 if (fault == NoFault && machInst.itstateMask != 0) {
214 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
215 }
216
217 return fault;
218 }
219}};
220
221def template StoreExExecute {{
222 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
223 Trace::InstRecord *traceData) const
224 {
225 Addr EA;
226 Fault fault = NoFault;
227
228 %(op_decl)s;
229 %(op_rd)s;
230 %(ea_code)s;
231
232 if (%(predicate_test)s)
233 {
234 if (fault == NoFault) {
235 %(memacc_code)s;
236 }
237
238 uint64_t writeResult;
239
240 if (fault == NoFault) {
241 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
242 memAccessFlags, &writeResult);
243 if (traceData) { traceData->setData(Mem); }
244 }
245
246 if (fault == NoFault) {
247 %(postacc_code)s;
248 }
249
250 if (fault == NoFault) {
251 %(op_wb)s;
252 }
253 } else {
254 xc->setPredicate(false);
255 }
256
257 if (fault == NoFault && machInst.itstateMask != 0) {
258 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
259 }
260
261 return fault;
262 }
263}};
264
265def template StoreExInitiateAcc {{
266 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
267 Trace::InstRecord *traceData) const
268 {
269 Addr EA;
270 Fault fault = NoFault;
271
272 %(op_decl)s;
273 %(op_rd)s;
274 %(ea_code)s;
275
276 if (%(predicate_test)s)
277 {
278 if (fault == NoFault) {
279 %(memacc_code)s;
280 }
281
282 if (fault == NoFault) {
283 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
284 memAccessFlags, NULL);
285 if (traceData) { traceData->setData(Mem); }
286 }
287
288 // Need to write back any potential address register update
289 if (fault == NoFault) {
290 %(op_wb)s;
291 }
292 } else {
293 xc->setPredicate(false);
294 }
295
296 if (fault == NoFault && machInst.itstateMask != 0) {
297 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
298 }
299
300 return fault;
301 }
302}};
303
304def template StoreInitiateAcc {{
305 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
306 Trace::InstRecord *traceData) const
307 {
308 Addr EA;
309 Fault fault = NoFault;
310
311 %(op_decl)s;
312 %(op_rd)s;
313 %(ea_code)s;
314
315 if (%(predicate_test)s)
316 {
317 if (fault == NoFault) {
318 %(memacc_code)s;
319 }
320
321 if (fault == NoFault) {
322 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
323 memAccessFlags, NULL);
324 if (traceData) { traceData->setData(Mem); }
325 }
326
327 // Need to write back any potential address register update
328 if (fault == NoFault) {
329 %(op_wb)s;
330 }
331 } else {
332 xc->setPredicate(false);
333 }
334
335 if (fault == NoFault && machInst.itstateMask != 0) {
336 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
337 }
338
339 return fault;
340 }
341}};
342
343def template LoadInitiateAcc {{
344 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
345 Trace::InstRecord *traceData) const
346 {
347 Addr EA;
348 Fault fault = NoFault;
349
350 %(op_src_decl)s;
351 %(op_rd)s;
352 %(ea_code)s;
353
354 if (%(predicate_test)s)
355 {
356 if (fault == NoFault) {
357 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
358 }
345 } else if (fault == NoFault && machInst.itstateMask != 0) {
346 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
359 } else {
360 xc->setPredicate(false);
361 if (fault == NoFault && machInst.itstateMask != 0) {
362 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
363 }
364 }
365
366 return fault;
367 }
368}};
369
370def template LoadCompleteAcc {{
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_decl)s;
378 %(op_rd)s;
379
380 if (%(predicate_test)s)
381 {
382 // ARM instructions will not have a pkt if the predicate is false
383 Mem = pkt->get<typeof(Mem)>();
384
385 if (fault == NoFault) {
386 %(memacc_code)s;
387 }
388
389 if (fault == NoFault) {
390 %(op_wb)s;
391 }
392 }
393
394 if (fault == NoFault && machInst.itstateMask != 0) {
395 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
396 }
397
398 return fault;
399 }
400}};
401
402def template StoreCompleteAcc {{
403 Fault %(class_name)s::completeAcc(PacketPtr pkt,
404 %(CPU_exec_context)s *xc,
405 Trace::InstRecord *traceData) const
406 {
407 Fault fault = NoFault;
408
409 %(op_decl)s;
410 %(op_rd)s;
411
412 if (%(predicate_test)s)
413 {
414 if (fault == NoFault) {
415 %(op_wb)s;
416 }
417 }
418
419 if (fault == NoFault && machInst.itstateMask != 0) {
420 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
421 }
422
423 return fault;
424 }
425}};
426
427def template StoreExCompleteAcc {{
428 Fault %(class_name)s::completeAcc(PacketPtr pkt,
429 %(CPU_exec_context)s *xc,
430 Trace::InstRecord *traceData) const
431 {
432 Fault fault = NoFault;
433
434 %(op_decl)s;
435 %(op_rd)s;
436
437 if (%(predicate_test)s)
438 {
439 uint64_t writeResult = pkt->req->getExtraData();
440 %(postacc_code)s;
441
442 if (fault == NoFault) {
443 %(op_wb)s;
444 }
445 }
446
447 if (fault == NoFault && machInst.itstateMask != 0) {
448 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
449 }
450
451 return fault;
452 }
453}};
454
455def template RfeDeclare {{
456 /**
457 * Static instruction class for "%(mnemonic)s".
458 */
459 class %(class_name)s : public %(base_class)s
460 {
461 public:
462
463 /// Constructor.
464 %(class_name)s(ExtMachInst machInst,
465 uint32_t _base, int _mode, bool _wb);
466
467 %(BasicExecDeclare)s
468
469 %(InitiateAccDeclare)s
470
471 %(CompleteAccDeclare)s
472 };
473}};
474
475def template SrsDeclare {{
476 /**
477 * Static instruction class for "%(mnemonic)s".
478 */
479 class %(class_name)s : public %(base_class)s
480 {
481 public:
482
483 /// Constructor.
484 %(class_name)s(ExtMachInst machInst,
485 uint32_t _regMode, int _mode, bool _wb);
486
487 %(BasicExecDeclare)s
488
489 %(InitiateAccDeclare)s
490
491 %(CompleteAccDeclare)s
492 };
493}};
494
495def template SwapDeclare {{
496 /**
497 * Static instruction class for "%(mnemonic)s".
498 */
499 class %(class_name)s : public %(base_class)s
500 {
501 public:
502
503 /// Constructor.
504 %(class_name)s(ExtMachInst machInst,
505 uint32_t _dest, uint32_t _op1, uint32_t _base);
506
507 %(BasicExecDeclare)s
508
509 %(InitiateAccDeclare)s
510
511 %(CompleteAccDeclare)s
512 };
513}};
514
515def template LoadStoreDImmDeclare {{
516 /**
517 * Static instruction class for "%(mnemonic)s".
518 */
519 class %(class_name)s : public %(base_class)s
520 {
521 public:
522
523 /// Constructor.
524 %(class_name)s(ExtMachInst machInst,
525 uint32_t _dest, uint32_t _dest2,
526 uint32_t _base, bool _add, int32_t _imm);
527
528 %(BasicExecDeclare)s
529
530 %(InitiateAccDeclare)s
531
532 %(CompleteAccDeclare)s
533 };
534}};
535
536def template StoreExDImmDeclare {{
537 /**
538 * Static instruction class for "%(mnemonic)s".
539 */
540 class %(class_name)s : public %(base_class)s
541 {
542 public:
543
544 /// Constructor.
545 %(class_name)s(ExtMachInst machInst,
546 uint32_t _result, uint32_t _dest, uint32_t _dest2,
547 uint32_t _base, bool _add, int32_t _imm);
548
549 %(BasicExecDeclare)s
550
551 %(InitiateAccDeclare)s
552
553 %(CompleteAccDeclare)s
554 };
555}};
556
557def template LoadStoreImmDeclare {{
558 /**
559 * Static instruction class for "%(mnemonic)s".
560 */
561 class %(class_name)s : public %(base_class)s
562 {
563 public:
564
565 /// Constructor.
566 %(class_name)s(ExtMachInst machInst,
567 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
568
569 %(BasicExecDeclare)s
570
571 %(InitiateAccDeclare)s
572
573 %(CompleteAccDeclare)s
574 };
575}};
576
577def template StoreExImmDeclare {{
578 /**
579 * Static instruction class for "%(mnemonic)s".
580 */
581 class %(class_name)s : public %(base_class)s
582 {
583 public:
584
585 /// Constructor.
586 %(class_name)s(ExtMachInst machInst,
587 uint32_t _result, uint32_t _dest, uint32_t _base,
588 bool _add, int32_t _imm);
589
590 %(BasicExecDeclare)s
591
592 %(InitiateAccDeclare)s
593
594 %(CompleteAccDeclare)s
595 };
596}};
597
598def template LoadStoreDRegDeclare {{
599 /**
600 * Static instruction class for "%(mnemonic)s".
601 */
602 class %(class_name)s : public %(base_class)s
603 {
604 public:
605
606 /// Constructor.
607 %(class_name)s(ExtMachInst machInst,
608 uint32_t _dest, uint32_t _dest2,
609 uint32_t _base, bool _add,
610 int32_t _shiftAmt, uint32_t _shiftType,
611 uint32_t _index);
612
613 %(BasicExecDeclare)s
614
615 %(InitiateAccDeclare)s
616
617 %(CompleteAccDeclare)s
618 };
619}};
620
621def template LoadStoreRegDeclare {{
622 /**
623 * Static instruction class for "%(mnemonic)s".
624 */
625 class %(class_name)s : public %(base_class)s
626 {
627 public:
628
629 /// Constructor.
630 %(class_name)s(ExtMachInst machInst,
631 uint32_t _dest, uint32_t _base, bool _add,
632 int32_t _shiftAmt, uint32_t _shiftType,
633 uint32_t _index);
634
635 %(BasicExecDeclare)s
636
637 %(InitiateAccDeclare)s
638
639 %(CompleteAccDeclare)s
640 };
641}};
642
643def template InitiateAccDeclare {{
644 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
645}};
646
647def template CompleteAccDeclare {{
648 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
649}};
650
651def template RfeConstructor {{
652 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
653 uint32_t _base, int _mode, bool _wb)
654 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
655 (IntRegIndex)_base, (AddrMode)_mode, _wb)
656 {
657 %(constructor)s;
658 }
659}};
660
661def template SrsConstructor {{
662 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
663 uint32_t _regMode, int _mode, bool _wb)
664 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
665 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
666 {
667 %(constructor)s;
668 }
669}};
670
671def template SwapConstructor {{
672 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
673 uint32_t _dest, uint32_t _op1, uint32_t _base)
674 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
675 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
676 {
677 %(constructor)s;
678 }
679}};
680
681def template LoadStoreDImmConstructor {{
682 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
683 uint32_t _dest, uint32_t _dest2,
684 uint32_t _base, bool _add, int32_t _imm)
685 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
686 (IntRegIndex)_dest, (IntRegIndex)_dest2,
687 (IntRegIndex)_base, _add, _imm)
688 {
689 %(constructor)s;
690 }
691}};
692
693def template StoreExDImmConstructor {{
694 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
695 uint32_t _result, uint32_t _dest, uint32_t _dest2,
696 uint32_t _base, bool _add, int32_t _imm)
697 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
698 (IntRegIndex)_result,
699 (IntRegIndex)_dest, (IntRegIndex)_dest2,
700 (IntRegIndex)_base, _add, _imm)
701 {
702 %(constructor)s;
703 }
704}};
705
706def template LoadStoreImmConstructor {{
707 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
708 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
709 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
710 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
711 {
712 %(constructor)s;
713 }
714}};
715
716def template StoreExImmConstructor {{
717 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
718 uint32_t _result, uint32_t _dest, uint32_t _base,
719 bool _add, int32_t _imm)
720 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
721 (IntRegIndex)_result, (IntRegIndex)_dest,
722 (IntRegIndex)_base, _add, _imm)
723 {
724 %(constructor)s;
725 }
726}};
727
728def template LoadStoreDRegConstructor {{
729 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
730 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
731 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
732 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
733 (IntRegIndex)_dest, (IntRegIndex)_dest2,
734 (IntRegIndex)_base, _add,
735 _shiftAmt, (ArmShiftType)_shiftType,
736 (IntRegIndex)_index)
737 {
738 %(constructor)s;
739 }
740}};
741
742def template LoadStoreRegConstructor {{
743 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
744 uint32_t _dest, uint32_t _base, bool _add,
745 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
746 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
747 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
748 _shiftAmt, (ArmShiftType)_shiftType,
749 (IntRegIndex)_index)
750 {
751 %(constructor)s;
752 }
753}};