mem.isa (8444:56de1f9320df) mem.isa (8607:5fb918115c07)
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 PanicExecute {{
45 Fault %(class_name)s::execute(%(CPU_exec_context)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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}};
702
703def template StoreExImmDeclare {{
704 /**
705 * Static instruction class for "%(mnemonic)s".
706 */
707 class %(class_name)s : public %(base_class)s
708 {
709 public:
710
711 /// Constructor.
712 %(class_name)s(ExtMachInst machInst,
713 uint32_t _result, uint32_t _dest, uint32_t _base,
714 bool _add, int32_t _imm);
715
716 %(BasicExecDeclare)s
717
718 %(InitiateAccDeclare)s
719
720 %(CompleteAccDeclare)s
721 };
722}};
723
724def template StoreDRegDeclare {{
725 /**
726 * Static instruction class for "%(mnemonic)s".
727 */
728 class %(class_name)s : public %(base_class)s
729 {
730 public:
731
732 /// Constructor.
733 %(class_name)s(ExtMachInst machInst,
734 uint32_t _dest, uint32_t _dest2,
735 uint32_t _base, bool _add,
736 int32_t _shiftAmt, uint32_t _shiftType,
737 uint32_t _index);
738
739 %(BasicExecDeclare)s
740
741 %(InitiateAccDeclare)s
742
743 %(CompleteAccDeclare)s
744 };
745}};
746
747def template StoreRegDeclare {{
748 /**
749 * Static instruction class for "%(mnemonic)s".
750 */
751 class %(class_name)s : public %(base_class)s
752 {
753 public:
754
755 /// Constructor.
756 %(class_name)s(ExtMachInst machInst,
757 uint32_t _dest, uint32_t _base, bool _add,
758 int32_t _shiftAmt, uint32_t _shiftType,
759 uint32_t _index);
760
761 %(BasicExecDeclare)s
762
763 %(InitiateAccDeclare)s
764
765 %(CompleteAccDeclare)s
766 };
767}};
768
769def template LoadDRegDeclare {{
770 /**
771 * Static instruction class for "%(mnemonic)s".
772 */
773 class %(class_name)s : public %(base_class)s
774 {
775 public:
776
777 /// Constructor.
778 %(class_name)s(ExtMachInst machInst,
779 uint32_t _dest, uint32_t _dest2,
780 uint32_t _base, bool _add,
781 int32_t _shiftAmt, uint32_t _shiftType,
782 uint32_t _index);
783
784 %(BasicExecDeclare)s
785
786 %(InitiateAccDeclare)s
787
788 %(CompleteAccDeclare)s
789 };
790}};
791
792def template LoadRegDeclare {{
793 /**
794 * Static instruction class for "%(mnemonic)s".
795 */
796 class %(class_name)s : public %(base_class)s
797 {
798 public:
799
800 /// Constructor.
801 %(class_name)s(ExtMachInst machInst,
802 uint32_t _dest, uint32_t _base, bool _add,
803 int32_t _shiftAmt, uint32_t _shiftType,
804 uint32_t _index);
805
806 %(BasicExecDeclare)s
807
808 %(InitiateAccDeclare)s
809
810 %(CompleteAccDeclare)s
811 };
812}};
813
814def template LoadImmDeclare {{
815 /**
816 * Static instruction class for "%(mnemonic)s".
817 */
818 class %(class_name)s : public %(base_class)s
819 {
820 public:
821
822 /// Constructor.
823 %(class_name)s(ExtMachInst machInst,
824 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
825
826 %(BasicExecDeclare)s
827
828 %(InitiateAccDeclare)s
829
830 %(CompleteAccDeclare)s
831 };
832}};
833
834def template InitiateAccDeclare {{
835 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
836}};
837
838def template CompleteAccDeclare {{
839 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
840}};
841
842def template RfeConstructor {{
843 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
844 uint32_t _base, int _mode, bool _wb)
845 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
846 (IntRegIndex)_base, (AddrMode)_mode, _wb)
847 {
848 %(constructor)s;
849 if (!(condCode == COND_AL || condCode == COND_UC)) {
850 for (int x = 0; x < _numDestRegs; x++) {
851 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
852 }
853 }
854#if %(use_uops)d
855 uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
856 int uopIdx = 0;
857 uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
858 uops[uopIdx]->setDelayedCommit();
859#if %(use_wb)d
860 uops[++uopIdx] = new %(wb_decl)s;
861 uops[uopIdx]->setDelayedCommit();
862#endif
863#if %(use_pc)d
864 uops[++uopIdx] = new %(pc_decl)s;
865#endif
866 uops[uopIdx]->setLastMicroop();
867#endif
868 }
869}};
870
871def template SrsConstructor {{
872 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
873 uint32_t _regMode, int _mode, bool _wb)
874 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
875 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
876 {
877 %(constructor)s;
878 if (!(condCode == COND_AL || condCode == COND_UC)) {
879 for (int x = 0; x < _numDestRegs; x++) {
880 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
881 }
882 }
883#if %(use_uops)d
884 assert(numMicroops >= 2);
885 uops = new StaticInstPtr[numMicroops];
886 uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
887 uops[0]->setDelayedCommit();
888 uops[1] = new %(wb_decl)s;
889 uops[1]->setLastMicroop();
890#endif
891 }
892}};
893
894def template SwapConstructor {{
895 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
896 uint32_t _dest, uint32_t _op1, uint32_t _base)
897 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
898 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
899 {
900 %(constructor)s;
901 if (!(condCode == COND_AL || condCode == COND_UC)) {
902 for (int x = 0; x < _numDestRegs; x++) {
903 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
904 }
905 }
906 }
907}};
908
909def template LoadStoreDImmConstructor {{
910 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
911 uint32_t _dest, uint32_t _dest2,
912 uint32_t _base, bool _add, int32_t _imm)
913 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
914 (IntRegIndex)_dest, (IntRegIndex)_dest2,
915 (IntRegIndex)_base, _add, _imm)
916 {
917 %(constructor)s;
918 if (!(condCode == COND_AL || condCode == COND_UC)) {
919 for (int x = 0; x < _numDestRegs; x++) {
920 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
921 }
922 }
923#if %(use_uops)d
924 assert(numMicroops >= 2);
925 uops = new StaticInstPtr[numMicroops];
926 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
927 uops[0]->setDelayedCommit();
928 uops[1] = new %(wb_decl)s;
929 uops[1]->setLastMicroop();
930#endif
931 }
932}};
933
934def template StoreExDImmConstructor {{
935 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
936 uint32_t _result, uint32_t _dest, uint32_t _dest2,
937 uint32_t _base, bool _add, int32_t _imm)
938 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
939 (IntRegIndex)_result,
940 (IntRegIndex)_dest, (IntRegIndex)_dest2,
941 (IntRegIndex)_base, _add, _imm)
942 {
943 %(constructor)s;
944 if (!(condCode == COND_AL || condCode == COND_UC)) {
945 for (int x = 0; x < _numDestRegs; x++) {
946 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
947 }
948 }
949#if %(use_uops)d
950 assert(numMicroops >= 2);
951 uops = new StaticInstPtr[numMicroops];
952 uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
953 _base, _add, _imm);
954 uops[0]->setDelayedCommit();
955 uops[1] = new %(wb_decl)s;
956 uops[1]->setLastMicroop();
957#endif
958 }
959}};
960
961def template LoadStoreImmConstructor {{
962 inline %(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[1] = new %(wb_decl)s;
979 uops[1]->setLastMicroop();
980#endif
981 }
982}};
983
984def template StoreExImmConstructor {{
985 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
986 uint32_t _result, uint32_t _dest, uint32_t _base,
987 bool _add, int32_t _imm)
988 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
989 (IntRegIndex)_result, (IntRegIndex)_dest,
990 (IntRegIndex)_base, _add, _imm)
991 {
992 %(constructor)s;
993 if (!(condCode == COND_AL || condCode == COND_UC)) {
994 for (int x = 0; x < _numDestRegs; x++) {
995 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
996 }
997 }
998#if %(use_uops)d
999 assert(numMicroops >= 2);
1000 uops = new StaticInstPtr[numMicroops];
1001 uops[0] = new %(acc_name)s(machInst, _result, _dest,
1002 _base, _add, _imm);
1003 uops[0]->setDelayedCommit();
1004 uops[1] = new %(wb_decl)s;
1005 uops[1]->setLastMicroop();
1006#endif
1007 }
1008}};
1009
1010def template StoreDRegConstructor {{
1011 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1012 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1013 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1014 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1015 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1016 (IntRegIndex)_base, _add,
1017 _shiftAmt, (ArmShiftType)_shiftType,
1018 (IntRegIndex)_index)
1019 {
1020 %(constructor)s;
1021 if (!(condCode == COND_AL || condCode == COND_UC)) {
1022 for (int x = 0; x < _numDestRegs; x++) {
1023 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1024 }
1025 }
1026#if %(use_uops)d
1027 assert(numMicroops >= 2);
1028 uops = new StaticInstPtr[numMicroops];
1029 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1030 _shiftAmt, _shiftType, _index);
1031 uops[0]->setDelayedCommit();
1032 uops[1] = new %(wb_decl)s;
1033 uops[1]->setLastMicroop();
1034#endif
1035 }
1036}};
1037
1038def template StoreRegConstructor {{
1039 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1040 uint32_t _dest, uint32_t _base, bool _add,
1041 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1042 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1043 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1044 _shiftAmt, (ArmShiftType)_shiftType,
1045 (IntRegIndex)_index)
1046 {
1047 %(constructor)s;
1048 if (!(condCode == COND_AL || condCode == COND_UC)) {
1049 for (int x = 0; x < _numDestRegs; x++) {
1050 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1051 }
1052 }
1053#if %(use_uops)d
1054 assert(numMicroops >= 2);
1055 uops = new StaticInstPtr[numMicroops];
1056 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1057 _shiftAmt, _shiftType, _index);
1058 uops[0]->setDelayedCommit();
1059 uops[1] = new %(wb_decl)s;
1060 uops[1]->setLastMicroop();
1061#endif
1062 }
1063}};
1064
1065def template LoadDRegConstructor {{
1066 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1067 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1068 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1069 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1070 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1071 (IntRegIndex)_base, _add,
1072 _shiftAmt, (ArmShiftType)_shiftType,
1073 (IntRegIndex)_index)
1074 {
1075 %(constructor)s;
1076 if (!(condCode == COND_AL || condCode == COND_UC)) {
1077 for (int x = 0; x < _numDestRegs; x++) {
1078 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1079 }
1080 }
1081#if %(use_uops)d
1082 assert(numMicroops >= 2);
1083 uops = new StaticInstPtr[numMicroops];
1084 if ((_dest == _index) || (_dest2 == _index)) {
1085 IntRegIndex wbIndexReg = INTREG_UREG0;
1086 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1087 uops[0]->setDelayedCommit();
1088 uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1089 _shiftAmt, _shiftType, _index);
1090 uops[1]->setDelayedCommit();
1091 uops[2] = new %(wb_decl)s;
1092 uops[2]->setLastMicroop();
1093 } else {
1094 IntRegIndex wbIndexReg = index;
1095 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1096 _shiftAmt, _shiftType, _index);
1097 uops[0]->setDelayedCommit();
1098 uops[1] = new %(wb_decl)s;
1099 uops[1]->setLastMicroop();
1100 }
1101#endif
1102 }
1103}};
1104
1105def template LoadRegConstructor {{
1106 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1107 uint32_t _dest, uint32_t _base, bool _add,
1108 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1109 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1110 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1111 _shiftAmt, (ArmShiftType)_shiftType,
1112 (IntRegIndex)_index)
1113 {
1114 %(constructor)s;
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 PanicExecute {{
45 Fault %(class_name)s::execute(%(CPU_exec_context)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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)s *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}};
702
703def template StoreExImmDeclare {{
704 /**
705 * Static instruction class for "%(mnemonic)s".
706 */
707 class %(class_name)s : public %(base_class)s
708 {
709 public:
710
711 /// Constructor.
712 %(class_name)s(ExtMachInst machInst,
713 uint32_t _result, uint32_t _dest, uint32_t _base,
714 bool _add, int32_t _imm);
715
716 %(BasicExecDeclare)s
717
718 %(InitiateAccDeclare)s
719
720 %(CompleteAccDeclare)s
721 };
722}};
723
724def template StoreDRegDeclare {{
725 /**
726 * Static instruction class for "%(mnemonic)s".
727 */
728 class %(class_name)s : public %(base_class)s
729 {
730 public:
731
732 /// Constructor.
733 %(class_name)s(ExtMachInst machInst,
734 uint32_t _dest, uint32_t _dest2,
735 uint32_t _base, bool _add,
736 int32_t _shiftAmt, uint32_t _shiftType,
737 uint32_t _index);
738
739 %(BasicExecDeclare)s
740
741 %(InitiateAccDeclare)s
742
743 %(CompleteAccDeclare)s
744 };
745}};
746
747def template StoreRegDeclare {{
748 /**
749 * Static instruction class for "%(mnemonic)s".
750 */
751 class %(class_name)s : public %(base_class)s
752 {
753 public:
754
755 /// Constructor.
756 %(class_name)s(ExtMachInst machInst,
757 uint32_t _dest, uint32_t _base, bool _add,
758 int32_t _shiftAmt, uint32_t _shiftType,
759 uint32_t _index);
760
761 %(BasicExecDeclare)s
762
763 %(InitiateAccDeclare)s
764
765 %(CompleteAccDeclare)s
766 };
767}};
768
769def template LoadDRegDeclare {{
770 /**
771 * Static instruction class for "%(mnemonic)s".
772 */
773 class %(class_name)s : public %(base_class)s
774 {
775 public:
776
777 /// Constructor.
778 %(class_name)s(ExtMachInst machInst,
779 uint32_t _dest, uint32_t _dest2,
780 uint32_t _base, bool _add,
781 int32_t _shiftAmt, uint32_t _shiftType,
782 uint32_t _index);
783
784 %(BasicExecDeclare)s
785
786 %(InitiateAccDeclare)s
787
788 %(CompleteAccDeclare)s
789 };
790}};
791
792def template LoadRegDeclare {{
793 /**
794 * Static instruction class for "%(mnemonic)s".
795 */
796 class %(class_name)s : public %(base_class)s
797 {
798 public:
799
800 /// Constructor.
801 %(class_name)s(ExtMachInst machInst,
802 uint32_t _dest, uint32_t _base, bool _add,
803 int32_t _shiftAmt, uint32_t _shiftType,
804 uint32_t _index);
805
806 %(BasicExecDeclare)s
807
808 %(InitiateAccDeclare)s
809
810 %(CompleteAccDeclare)s
811 };
812}};
813
814def template LoadImmDeclare {{
815 /**
816 * Static instruction class for "%(mnemonic)s".
817 */
818 class %(class_name)s : public %(base_class)s
819 {
820 public:
821
822 /// Constructor.
823 %(class_name)s(ExtMachInst machInst,
824 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
825
826 %(BasicExecDeclare)s
827
828 %(InitiateAccDeclare)s
829
830 %(CompleteAccDeclare)s
831 };
832}};
833
834def template InitiateAccDeclare {{
835 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
836}};
837
838def template CompleteAccDeclare {{
839 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
840}};
841
842def template RfeConstructor {{
843 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
844 uint32_t _base, int _mode, bool _wb)
845 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
846 (IntRegIndex)_base, (AddrMode)_mode, _wb)
847 {
848 %(constructor)s;
849 if (!(condCode == COND_AL || condCode == COND_UC)) {
850 for (int x = 0; x < _numDestRegs; x++) {
851 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
852 }
853 }
854#if %(use_uops)d
855 uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d];
856 int uopIdx = 0;
857 uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb);
858 uops[uopIdx]->setDelayedCommit();
859#if %(use_wb)d
860 uops[++uopIdx] = new %(wb_decl)s;
861 uops[uopIdx]->setDelayedCommit();
862#endif
863#if %(use_pc)d
864 uops[++uopIdx] = new %(pc_decl)s;
865#endif
866 uops[uopIdx]->setLastMicroop();
867#endif
868 }
869}};
870
871def template SrsConstructor {{
872 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
873 uint32_t _regMode, int _mode, bool _wb)
874 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
875 (OperatingMode)_regMode, (AddrMode)_mode, _wb)
876 {
877 %(constructor)s;
878 if (!(condCode == COND_AL || condCode == COND_UC)) {
879 for (int x = 0; x < _numDestRegs; x++) {
880 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
881 }
882 }
883#if %(use_uops)d
884 assert(numMicroops >= 2);
885 uops = new StaticInstPtr[numMicroops];
886 uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
887 uops[0]->setDelayedCommit();
888 uops[1] = new %(wb_decl)s;
889 uops[1]->setLastMicroop();
890#endif
891 }
892}};
893
894def template SwapConstructor {{
895 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
896 uint32_t _dest, uint32_t _op1, uint32_t _base)
897 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
898 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
899 {
900 %(constructor)s;
901 if (!(condCode == COND_AL || condCode == COND_UC)) {
902 for (int x = 0; x < _numDestRegs; x++) {
903 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
904 }
905 }
906 }
907}};
908
909def template LoadStoreDImmConstructor {{
910 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
911 uint32_t _dest, uint32_t _dest2,
912 uint32_t _base, bool _add, int32_t _imm)
913 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
914 (IntRegIndex)_dest, (IntRegIndex)_dest2,
915 (IntRegIndex)_base, _add, _imm)
916 {
917 %(constructor)s;
918 if (!(condCode == COND_AL || condCode == COND_UC)) {
919 for (int x = 0; x < _numDestRegs; x++) {
920 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
921 }
922 }
923#if %(use_uops)d
924 assert(numMicroops >= 2);
925 uops = new StaticInstPtr[numMicroops];
926 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
927 uops[0]->setDelayedCommit();
928 uops[1] = new %(wb_decl)s;
929 uops[1]->setLastMicroop();
930#endif
931 }
932}};
933
934def template StoreExDImmConstructor {{
935 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
936 uint32_t _result, uint32_t _dest, uint32_t _dest2,
937 uint32_t _base, bool _add, int32_t _imm)
938 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
939 (IntRegIndex)_result,
940 (IntRegIndex)_dest, (IntRegIndex)_dest2,
941 (IntRegIndex)_base, _add, _imm)
942 {
943 %(constructor)s;
944 if (!(condCode == COND_AL || condCode == COND_UC)) {
945 for (int x = 0; x < _numDestRegs; x++) {
946 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
947 }
948 }
949#if %(use_uops)d
950 assert(numMicroops >= 2);
951 uops = new StaticInstPtr[numMicroops];
952 uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
953 _base, _add, _imm);
954 uops[0]->setDelayedCommit();
955 uops[1] = new %(wb_decl)s;
956 uops[1]->setLastMicroop();
957#endif
958 }
959}};
960
961def template LoadStoreImmConstructor {{
962 inline %(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[1] = new %(wb_decl)s;
979 uops[1]->setLastMicroop();
980#endif
981 }
982}};
983
984def template StoreExImmConstructor {{
985 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
986 uint32_t _result, uint32_t _dest, uint32_t _base,
987 bool _add, int32_t _imm)
988 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
989 (IntRegIndex)_result, (IntRegIndex)_dest,
990 (IntRegIndex)_base, _add, _imm)
991 {
992 %(constructor)s;
993 if (!(condCode == COND_AL || condCode == COND_UC)) {
994 for (int x = 0; x < _numDestRegs; x++) {
995 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
996 }
997 }
998#if %(use_uops)d
999 assert(numMicroops >= 2);
1000 uops = new StaticInstPtr[numMicroops];
1001 uops[0] = new %(acc_name)s(machInst, _result, _dest,
1002 _base, _add, _imm);
1003 uops[0]->setDelayedCommit();
1004 uops[1] = new %(wb_decl)s;
1005 uops[1]->setLastMicroop();
1006#endif
1007 }
1008}};
1009
1010def template StoreDRegConstructor {{
1011 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1012 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1013 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1014 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1015 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1016 (IntRegIndex)_base, _add,
1017 _shiftAmt, (ArmShiftType)_shiftType,
1018 (IntRegIndex)_index)
1019 {
1020 %(constructor)s;
1021 if (!(condCode == COND_AL || condCode == COND_UC)) {
1022 for (int x = 0; x < _numDestRegs; x++) {
1023 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1024 }
1025 }
1026#if %(use_uops)d
1027 assert(numMicroops >= 2);
1028 uops = new StaticInstPtr[numMicroops];
1029 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1030 _shiftAmt, _shiftType, _index);
1031 uops[0]->setDelayedCommit();
1032 uops[1] = new %(wb_decl)s;
1033 uops[1]->setLastMicroop();
1034#endif
1035 }
1036}};
1037
1038def template StoreRegConstructor {{
1039 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1040 uint32_t _dest, uint32_t _base, bool _add,
1041 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1042 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1043 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1044 _shiftAmt, (ArmShiftType)_shiftType,
1045 (IntRegIndex)_index)
1046 {
1047 %(constructor)s;
1048 if (!(condCode == COND_AL || condCode == COND_UC)) {
1049 for (int x = 0; x < _numDestRegs; x++) {
1050 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1051 }
1052 }
1053#if %(use_uops)d
1054 assert(numMicroops >= 2);
1055 uops = new StaticInstPtr[numMicroops];
1056 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1057 _shiftAmt, _shiftType, _index);
1058 uops[0]->setDelayedCommit();
1059 uops[1] = new %(wb_decl)s;
1060 uops[1]->setLastMicroop();
1061#endif
1062 }
1063}};
1064
1065def template LoadDRegConstructor {{
1066 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1067 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
1068 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1069 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1070 (IntRegIndex)_dest, (IntRegIndex)_dest2,
1071 (IntRegIndex)_base, _add,
1072 _shiftAmt, (ArmShiftType)_shiftType,
1073 (IntRegIndex)_index)
1074 {
1075 %(constructor)s;
1076 if (!(condCode == COND_AL || condCode == COND_UC)) {
1077 for (int x = 0; x < _numDestRegs; x++) {
1078 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1079 }
1080 }
1081#if %(use_uops)d
1082 assert(numMicroops >= 2);
1083 uops = new StaticInstPtr[numMicroops];
1084 if ((_dest == _index) || (_dest2 == _index)) {
1085 IntRegIndex wbIndexReg = INTREG_UREG0;
1086 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1087 uops[0]->setDelayedCommit();
1088 uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1089 _shiftAmt, _shiftType, _index);
1090 uops[1]->setDelayedCommit();
1091 uops[2] = new %(wb_decl)s;
1092 uops[2]->setLastMicroop();
1093 } else {
1094 IntRegIndex wbIndexReg = index;
1095 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
1096 _shiftAmt, _shiftType, _index);
1097 uops[0]->setDelayedCommit();
1098 uops[1] = new %(wb_decl)s;
1099 uops[1]->setLastMicroop();
1100 }
1101#endif
1102 }
1103}};
1104
1105def template LoadRegConstructor {{
1106 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1107 uint32_t _dest, uint32_t _base, bool _add,
1108 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
1109 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1110 (IntRegIndex)_dest, (IntRegIndex)_base, _add,
1111 _shiftAmt, (ArmShiftType)_shiftType,
1112 (IntRegIndex)_index)
1113 {
1114 %(constructor)s;
1115 bool conditional = false;
1115 bool conditional M5_VAR_USED = false;
1116 if (!(condCode == COND_AL || condCode == COND_UC)) {
1117 conditional = true;
1118 for (int x = 0; x < _numDestRegs; x++) {
1119 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1120 }
1121 }
1122#if %(use_uops)d
1123 assert(numMicroops >= 2);
1124 uops = new StaticInstPtr[numMicroops];
1125 if (_dest == INTREG_PC) {
1126 IntRegIndex wbIndexReg = index;
1127 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1128 _shiftAmt, _shiftType, _index);
1129 uops[0]->setDelayedCommit();
1130 uops[1] = new %(wb_decl)s;
1131 uops[1]->setDelayedCommit();
1132 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1133 uops[2]->setFlag(StaticInst::IsControl);
1134 uops[2]->setFlag(StaticInst::IsIndirectControl);
1135 if (conditional)
1136 uops[2]->setFlag(StaticInst::IsCondControl);
1137 else
1138 uops[2]->setFlag(StaticInst::IsUncondControl);
1139 uops[2]->setLastMicroop();
1140 } else if(_dest == _index) {
1141 IntRegIndex wbIndexReg = INTREG_UREG0;
1142 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1143 uops[0]->setDelayedCommit();
1144 uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1145 _shiftAmt, _shiftType, _index);
1146 uops[1]->setDelayedCommit();
1147 uops[2] = new %(wb_decl)s;
1148 uops[2]->setLastMicroop();
1149 } else {
1150 IntRegIndex wbIndexReg = index;
1151 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1152 _shiftAmt, _shiftType, _index);
1153 uops[0]->setDelayedCommit();
1154 uops[1] = new %(wb_decl)s;
1155 uops[1]->setLastMicroop();
1156
1157 }
1158#endif
1159 }
1160}};
1161
1162def template LoadImmConstructor {{
1163 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1164 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1165 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1166 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1167 {
1168 %(constructor)s;
1116 if (!(condCode == COND_AL || condCode == COND_UC)) {
1117 conditional = true;
1118 for (int x = 0; x < _numDestRegs; x++) {
1119 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1120 }
1121 }
1122#if %(use_uops)d
1123 assert(numMicroops >= 2);
1124 uops = new StaticInstPtr[numMicroops];
1125 if (_dest == INTREG_PC) {
1126 IntRegIndex wbIndexReg = index;
1127 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1128 _shiftAmt, _shiftType, _index);
1129 uops[0]->setDelayedCommit();
1130 uops[1] = new %(wb_decl)s;
1131 uops[1]->setDelayedCommit();
1132 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1133 uops[2]->setFlag(StaticInst::IsControl);
1134 uops[2]->setFlag(StaticInst::IsIndirectControl);
1135 if (conditional)
1136 uops[2]->setFlag(StaticInst::IsCondControl);
1137 else
1138 uops[2]->setFlag(StaticInst::IsUncondControl);
1139 uops[2]->setLastMicroop();
1140 } else if(_dest == _index) {
1141 IntRegIndex wbIndexReg = INTREG_UREG0;
1142 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
1143 uops[0]->setDelayedCommit();
1144 uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
1145 _shiftAmt, _shiftType, _index);
1146 uops[1]->setDelayedCommit();
1147 uops[2] = new %(wb_decl)s;
1148 uops[2]->setLastMicroop();
1149 } else {
1150 IntRegIndex wbIndexReg = index;
1151 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
1152 _shiftAmt, _shiftType, _index);
1153 uops[0]->setDelayedCommit();
1154 uops[1] = new %(wb_decl)s;
1155 uops[1]->setLastMicroop();
1156
1157 }
1158#endif
1159 }
1160}};
1161
1162def template LoadImmConstructor {{
1163 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
1164 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
1165 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1166 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
1167 {
1168 %(constructor)s;
1169 bool conditional = false;
1169 bool conditional M5_VAR_USED = false;
1170 if (!(condCode == COND_AL || condCode == COND_UC)) {
1171 conditional = true;
1172 for (int x = 0; x < _numDestRegs; x++) {
1173 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1174 }
1175 }
1176#if %(use_uops)d
1177 assert(numMicroops >= 2);
1178 uops = new StaticInstPtr[numMicroops];
1179 if (_dest == INTREG_PC) {
1180 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1181 _imm);
1182 uops[0]->setDelayedCommit();
1183 uops[1] = new %(wb_decl)s;
1184 uops[1]->setDelayedCommit();
1185 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1186 uops[2]->setFlag(StaticInst::IsControl);
1187 uops[2]->setFlag(StaticInst::IsIndirectControl);
1188 if (conditional)
1189 uops[2]->setFlag(StaticInst::IsCondControl);
1190 else
1191 uops[2]->setFlag(StaticInst::IsUncondControl);
1192 if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s)
1193 uops[2]->setFlag(StaticInst::IsReturn);
1194 uops[2]->setLastMicroop();
1195 } else {
1196 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1197 uops[0]->setDelayedCommit();
1198 uops[1] = new %(wb_decl)s;
1199 uops[1]->setLastMicroop();
1200 }
1201#endif
1202 }
1203}};
1204
1170 if (!(condCode == COND_AL || condCode == COND_UC)) {
1171 conditional = true;
1172 for (int x = 0; x < _numDestRegs; x++) {
1173 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1174 }
1175 }
1176#if %(use_uops)d
1177 assert(numMicroops >= 2);
1178 uops = new StaticInstPtr[numMicroops];
1179 if (_dest == INTREG_PC) {
1180 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
1181 _imm);
1182 uops[0]->setDelayedCommit();
1183 uops[1] = new %(wb_decl)s;
1184 uops[1]->setDelayedCommit();
1185 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
1186 uops[2]->setFlag(StaticInst::IsControl);
1187 uops[2]->setFlag(StaticInst::IsIndirectControl);
1188 if (conditional)
1189 uops[2]->setFlag(StaticInst::IsCondControl);
1190 else
1191 uops[2]->setFlag(StaticInst::IsUncondControl);
1192 if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s)
1193 uops[2]->setFlag(StaticInst::IsReturn);
1194 uops[2]->setLastMicroop();
1195 } else {
1196 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
1197 uops[0]->setDelayedCommit();
1198 uops[1] = new %(wb_decl)s;
1199 uops[1]->setLastMicroop();
1200 }
1201#endif
1202 }
1203}};
1204