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