gem5 [DEVELOP-FOR-25.1]
Loading...
Searching...
No Matches
sve_macromem.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018, 2025 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef __ARCH_ARM_SVE_MACROMEM_HH__
39#define __ARCH_ARM_SVE_MACROMEM_HH__
40
41#include "arch/arm/generated/decoder.hh"
43
44namespace gem5
45{
46
47namespace ArmISA {
48
49template <typename Element,
50 template <typename> class MicroopLdMemType,
51 template <typename> class MicroopDeIntrlvType>
53{
54 protected:
59 uint8_t numregs;
60
61 public:
62 SveLdStructSS(const char* mnem, ExtMachInst machInst, OpClass __opClass,
63 RegIndex _dest, RegIndex _gp, RegIndex _base,
64 RegIndex _offset, uint8_t _numregs)
65 : PredMacroOp(mnem, machInst, __opClass),
66 dest(_dest), gp(_gp), base(_base), offset(_offset), numregs(_numregs)
67 {
68 numMicroops = numregs * 2;
69
71
72 for (int i = 0; i < numregs; ++i) {
73 microOps[i] = new MicroopLdMemType<Element>(
74 mnem, machInst, static_cast<RegIndex>(INTRLVREG0 + i),
75 _gp, _base, _offset, _numregs, i);
76 }
77 for (int i = 0; i < numregs; ++i) {
78 microOps[i + numregs] = new MicroopDeIntrlvType<Element>(
79 mnem, machInst, static_cast<RegIndex>((_dest + i) % 32),
80 _numregs, i, this);
81 }
82
83 microOps[0]->setFirstMicroop();
84 microOps[numMicroops - 1]->setLastMicroop();
85
86 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
87 (*uop)->setDelayedCommit();
88 }
89 }
90
91 Fault
93 {
94 panic("Execute method called when it shouldn't!");
95 return NoFault;
96 }
97
98 std::string
100 const loader::SymbolTable *symtab) const override
101 {
102 std::stringstream ss;
103 printMnemonic(ss, "", false);
104 ccprintf(ss, "{");
105 for (int i = 0; i < numregs; ++i) {
106 printVecReg(ss, (dest + i) % 32, true);
107 if (i < numregs - 1)
108 ccprintf(ss, ", ");
109 }
110 ccprintf(ss, "}, ");
112 ccprintf(ss, "/z, [");
114 ccprintf(ss, ", ");
116 ccprintf(ss, "]");
117 return ss.str();
118 }
119};
120
121template <typename Element,
122 template <typename> class MicroopStMemType,
123 template <typename> class MicroopIntrlvType>
125{
126 protected:
131 uint8_t numregs;
132
133 public:
134 SveStStructSS(const char* mnem, ExtMachInst machInst, OpClass __opClass,
135 RegIndex _dest, RegIndex _gp, RegIndex _base,
136 RegIndex _offset, uint8_t _numregs)
137 : PredMacroOp(mnem, machInst, __opClass),
138 dest(_dest), gp(_gp), base(_base), offset(_offset), numregs(_numregs)
139 {
140 numMicroops = numregs * 2;
141
143
144 for (int i = 0; i < numregs; ++i) {
145 microOps[i] = new MicroopIntrlvType<Element>(
146 mnem, machInst, static_cast<RegIndex>(INTRLVREG0 + i),
147 _dest, _numregs, i, this);
148 }
149
150 for (int i = 0; i < numregs; ++i) {
151 microOps[i + numregs] = new MicroopStMemType<Element>(
152 mnem, machInst, static_cast<RegIndex>(INTRLVREG0 + i),
153 _gp, _base, _offset, _numregs, i);
154 }
155
156 microOps[0]->setFirstMicroop();
157 microOps[numMicroops - 1]->setLastMicroop();
158
159 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
160 (*uop)->setDelayedCommit();
161 }
162 }
163
164 Fault
166 {
167 panic("Execute method called when it shouldn't!");
168 return NoFault;
169 }
170
171 std::string
173 const loader::SymbolTable *symtab) const override
174 {
175 std::stringstream ss;
176 printMnemonic(ss, "", false);
177 ccprintf(ss, "{");
178 for (int i = 0; i < numregs; ++i) {
179 printVecReg(ss, (dest + i) % 32, true);
180 if (i < numregs - 1)
181 ccprintf(ss, ", ");
182 }
183 ccprintf(ss, "}, ");
185 ccprintf(ss, ", [");
187 ccprintf(ss, ", ");
189 ccprintf(ss, "]");
190 return ss.str();
191 }
192};
193
194
195template <typename Element,
196 template <typename> class MicroopLdMemType,
197 template <typename> class MicroopDeIntrlvType>
199{
200 protected:
204 int64_t imm;
205 uint8_t numregs;
206
207 public:
208 SveLdStructSI(const char* mnem, ExtMachInst machInst, OpClass __opClass,
209 RegIndex _dest, RegIndex _gp, RegIndex _base,
210 int64_t _imm, uint8_t _numregs)
211 : PredMacroOp(mnem, machInst, __opClass),
212 dest(_dest), gp(_gp), base(_base), imm(_imm), numregs(_numregs)
213 {
214 numMicroops = numregs * 2;
215
217
218 for (int i = 0; i < numregs; ++i) {
219 microOps[i] = new MicroopLdMemType<Element>(
220 mnem, machInst, static_cast<RegIndex>(INTRLVREG0 + i),
221 _gp, _base, _imm, _numregs, i);
222 }
223 for (int i = 0; i < numregs; ++i) {
224 microOps[i + numregs] = new MicroopDeIntrlvType<Element>(
225 mnem, machInst, static_cast<RegIndex>((_dest + i) % 32),
226 _numregs, i, this);
227 }
228
229 microOps[0]->setFirstMicroop();
230 microOps[numMicroops - 1]->setLastMicroop();
231
232 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
233 (*uop)->setDelayedCommit();
234 }
235 }
236
237 Fault
239 {
240 panic("Execute method called when it shouldn't!");
241 return NoFault;
242 }
243
244 std::string
246 const loader::SymbolTable *symtab) const override
247 {
248 std::stringstream ss;
249 printMnemonic(ss, "", false);
250 ccprintf(ss, "{");
251 for (int i = 0; i < numregs; ++i) {
252 printVecReg(ss, (dest + i) % 32, true);
253 if (i < numregs - 1)
254 ccprintf(ss, ", ");
255 }
256 ccprintf(ss, "}, ");
258 ccprintf(ss, "/z, [");
260 if (imm != 0) {
261 ccprintf(ss, ", #%d, MUL VL", imm);
262 }
263 ccprintf(ss, "]");
264 return ss.str();
265 }
266};
267
268template <typename Element,
269 template <typename> class MicroopStMemType,
270 template <typename> class MicroopIntrlvType>
272{
273 protected:
277 int64_t imm;
278 uint8_t numregs;
279
280 public:
281 SveStStructSI(const char* mnem, ExtMachInst machInst, OpClass __opClass,
282 RegIndex _dest, RegIndex _gp, RegIndex _base,
283 int64_t _imm, uint8_t _numregs)
284 : PredMacroOp(mnem, machInst, __opClass),
285 dest(_dest), gp(_gp), base(_base), imm(_imm), numregs(_numregs)
286 {
287 numMicroops = numregs * 2;
288
290
291 for (int i = 0; i < numregs; ++i) {
292 microOps[i] = new MicroopIntrlvType<Element>(
293 mnem, machInst, static_cast<RegIndex>(INTRLVREG0 + i),
294 _dest, _numregs, i, this);
295 }
296
297 for (int i = 0; i < numregs; ++i) {
298 microOps[i + numregs] = new MicroopStMemType<Element>(
299 mnem, machInst, static_cast<RegIndex>(INTRLVREG0 + i),
300 _gp, _base, _imm, _numregs, i);
301 }
302
303 microOps[0]->setFirstMicroop();
304 microOps[numMicroops - 1]->setLastMicroop();
305
306 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
307 (*uop)->setDelayedCommit();
308 }
309 }
310
311 Fault
313 {
314 panic("Execute method called when it shouldn't!");
315 return NoFault;
316 }
317
318 std::string
320 const loader::SymbolTable *symtab) const override
321 {
322 std::stringstream ss;
323 printMnemonic(ss, "", false);
324 ccprintf(ss, "{");
325 for (int i = 0; i < numregs; ++i) {
326 printVecReg(ss, (dest + i) % 32, true);
327 if (i < numregs - 1)
328 ccprintf(ss, ", ");
329 }
330 ccprintf(ss, "}, ");
332 ccprintf(ss, ", [");
334 if (imm != 0) {
335 ccprintf(ss, ", #%d, MUL VL", imm);
336 }
337 ccprintf(ss, "]");
338 return ss.str();
339 }
340};
341
342template <typename Element, template <typename> class MicroopLdMemType>
344{
345 protected:
350 uint8_t numregs;
351
352 public:
354 OpClass __opClass, RegIndex _dest, RegIndex _gp,
355 RegIndex _base, RegIndex _offset, uint8_t _numregs)
356 : PredMacroOp(mnem, machInst, __opClass),
357 dest(_dest),
358 gp(_gp),
359 base(_base),
360 offset(_offset),
361 numregs(_numregs)
362 {
364
366
367 for (int i = 0; i < numregs; ++i) {
368 RegIndex uop_dest = (RegIndex)((dest + i) % 32);
369 microOps[i] = new MicroopLdMemType<Element>(
370 mnem, machInst, uop_dest, _gp, _base, _offset, _numregs, i);
371 }
372
373 microOps[0]->setFirstMicroop();
374 microOps[numMicroops - 1]->setLastMicroop();
375
376 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
377 (*uop)->setDelayedCommit();
378 }
379 }
380
381 Fault
383 {
384 panic("Execute method called when it shouldn't!");
385 return NoFault;
386 }
387
388 std::string
390 const loader::SymbolTable *symtab) const override
391 {
392 std::stringstream ss;
393 printMnemonic(ss, "", false);
394 ccprintf(ss, "{");
395 for (int i = 0; i < numregs; ++i) {
396 printVecReg(ss, (dest + i) % 32, true);
397 if (i < numregs - 1) {
398 ccprintf(ss, ", ");
399 }
400 }
401 ccprintf(ss, "}, ");
402 printVecPredReg(ss, gp, true);
403 ccprintf(ss, "/z, [");
405 ccprintf(ss, ", ");
407 ccprintf(ss, "]");
408 return ss.str();
409 }
410};
411
412template <typename Element, template <typename> class MicroopStMemType>
414{
415 protected:
420 uint8_t numregs;
421
422 public:
424 OpClass __opClass, RegIndex _dest, RegIndex _gp,
425 RegIndex _base, RegIndex _offset, uint8_t _numregs)
426 : PredMacroOp(mnem, machInst, __opClass),
427 dest(_dest),
428 gp(_gp),
429 base(_base),
430 offset(_offset),
431 numregs(_numregs)
432 {
434
436
437 for (int i = 0; i < numregs; ++i) {
438 RegIndex uop_dest = (RegIndex)((dest + i) % 32);
439 microOps[i] = new MicroopStMemType<Element>(
440 mnem, machInst, uop_dest, _gp, _base, _offset, _numregs, i);
441 }
442
443 microOps[0]->setFirstMicroop();
444 microOps[numMicroops - 1]->setLastMicroop();
445
446 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
447 (*uop)->setDelayedCommit();
448 }
449 }
450
451 Fault
453 {
454 panic("Execute method called when it shouldn't!");
455 return NoFault;
456 }
457
458 std::string
460 const loader::SymbolTable *symtab) const override
461 {
462 std::stringstream ss;
463 printMnemonic(ss, "", false);
464 ccprintf(ss, "{");
465 for (int i = 0; i < numregs; ++i) {
466 printVecReg(ss, (dest + i) % 32, true);
467 if (i < numregs - 1) {
468 ccprintf(ss, ", ");
469 }
470 }
471 ccprintf(ss, "}, ");
472 printVecPredReg(ss, gp, true);
473 ccprintf(ss, ", [");
475 ccprintf(ss, ", ");
477 ccprintf(ss, "]");
478 return ss.str();
479 }
480};
481
482template <typename Element, template <typename> class MicroopLdMemType>
484{
485 protected:
489 int64_t imm;
490 uint8_t numregs;
491
492 public:
494 OpClass __opClass, RegIndex _dest, RegIndex _gp,
495 RegIndex _base, int64_t _imm, uint8_t _numregs)
496 : PredMacroOp(mnem, machInst, __opClass),
497 dest(_dest),
498 gp(_gp),
499 base(_base),
500 imm(_imm),
501 numregs(_numregs)
502 {
504
506
507 for (int i = 0; i < numregs; ++i) {
508 RegIndex uop_dest = (RegIndex)((dest + i) % 32);
509 microOps[i] = new MicroopLdMemType<Element>(
510 mnem, machInst, uop_dest, _gp, _base, _imm, _numregs, i);
511 }
512
513 microOps[0]->setFirstMicroop();
514 microOps[numMicroops - 1]->setLastMicroop();
515
516 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
517 (*uop)->setDelayedCommit();
518 }
519 }
520
521 Fault
523 {
524 panic("Execute method called when it shouldn't!");
525 return NoFault;
526 }
527
528 std::string
530 const loader::SymbolTable *symtab) const override
531 {
532 std::stringstream ss;
533 printMnemonic(ss, "", false);
534 ccprintf(ss, "{");
535 for (int i = 0; i < numregs; ++i) {
536 printVecReg(ss, (dest + i) % 32, true);
537 if (i < numregs - 1) {
538 ccprintf(ss, ", ");
539 }
540 }
541 ccprintf(ss, "}, ");
542 printVecPredReg(ss, gp, true);
543 ccprintf(ss, "/z, [");
545 if (imm != 0) {
546 ccprintf(ss, ", #%d, MUL VL", imm);
547 }
548 ccprintf(ss, "]");
549 return ss.str();
550 }
551};
552
553template <typename Element, template <typename> class MicroopStMemType>
555{
556 protected:
560 int64_t imm;
561 uint8_t numregs;
562
563 public:
565 OpClass __opClass, RegIndex _dest, RegIndex _gp,
566 RegIndex _base, int64_t _imm, uint8_t _numregs)
567 : PredMacroOp(mnem, machInst, __opClass),
568 dest(_dest),
569 gp(_gp),
570 base(_base),
571 imm(_imm),
572 numregs(_numregs)
573 {
575
577
578 for (int i = 0; i < numregs; ++i) {
579 RegIndex uop_dest = (RegIndex)((dest + i) % 32);
580 microOps[i] = new MicroopStMemType<Element>(
581 mnem, machInst, uop_dest, _gp, _base, _imm, _numregs, i);
582 }
583
584 microOps[0]->setFirstMicroop();
585 microOps[numMicroops - 1]->setLastMicroop();
586
587 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
588 (*uop)->setDelayedCommit();
589 }
590 }
591
592 Fault
594 {
595 panic("Execute method called when it shouldn't!");
596 return NoFault;
597 }
598
599 std::string
601 const loader::SymbolTable *symtab) const override
602 {
603 std::stringstream ss;
604 printMnemonic(ss, "", false);
605 ccprintf(ss, "{");
606 for (int i = 0; i < numregs; ++i) {
607 printVecReg(ss, (dest + i) % 32, true);
608 if (i < numregs - 1) {
609 ccprintf(ss, ", ");
610 }
611 }
612 ccprintf(ss, "}, ");
613 printVecPredReg(ss, gp, true);
614 ccprintf(ss, ", [");
616 if (imm != 0) {
617 ccprintf(ss, ", #%d, MUL VL", imm);
618 }
619 ccprintf(ss, "]");
620 return ss.str();
621 }
622};
623
624template <typename RegElemType, typename MemElemType,
625 template <typename, typename> class MicroopType,
626 template <typename> class FirstFaultWritebackMicroopType>
628{
629 protected:
633 uint64_t imm;
634
635 public:
636 SveIndexedMemVI(const char *mnem, ExtMachInst machInst, OpClass __opClass,
637 RegIndex _dest, RegIndex _gp, RegIndex _base,
638 uint64_t _imm, bool firstFault)
639 : PredMacroOp(mnem, machInst, __opClass),
640 dest(_dest), gp(_gp), base(_base), imm(_imm)
641 {
642 bool isLoad = (__opClass == MemReadOp);
643 assert(!firstFault || isLoad);
644
645 int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
646
647 numMicroops = num_elems;
648 if (isLoad) {
649 if (firstFault) {
650 numMicroops += 2;
651 } else {
652 numMicroops++;
653 }
654 }
655
657
658 StaticInstPtr *uop = microOps;
659
660 for (int i = 0; i < num_elems; i++, uop++) {
661 *uop = new MicroopType<RegElemType, MemElemType>(
662 mnem, machInst, __opClass,
663 isLoad ? (RegIndex)VECREG_UREG0 : _dest, _gp, _base, _imm, i,
664 num_elems, firstFault);
665 }
666
667 if (isLoad) {
668 // The last microop of a gather load copies the auxiliary register
669 // to the destination vector register. Because when any fault
670 // occurs, the destination should keept the same.
671 *uop = new ArmISAInst::SveGatherLoadCpyDstVecMicroop(
672 mnem, machInst, _dest, this);
673 uop++;
674 }
675
676 if (firstFault) {
677 *uop = new FirstFaultWritebackMicroopType<RegElemType>(
678 mnem, machInst, __opClass, num_elems, this);
679 } else {
680 --uop;
681 }
682
683 (*uop)->setLastMicroop();
684 microOps[0]->setFirstMicroop();
685
686 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
687 (*uop)->setDelayedCommit();
688 }
689 }
690
691 Fault
693 {
694 panic("Execute method called when it shouldn't!");
695 return NoFault;
696 }
697
698 std::string
700 const loader::SymbolTable *symtab) const override
701 {
702 // TODO: add suffix to transfer and base registers
703 std::stringstream ss;
704 printMnemonic(ss, "", false);
705 ccprintf(ss, "{");
706 printVecReg(ss, dest, true);
707 ccprintf(ss, "}, ");
709 ccprintf(ss, "/z, [");
710 printVecReg(ss, base, true);
711 if (imm != 0) {
712 ccprintf(ss, ", #%d", imm * sizeof(MemElemType));
713 }
714 ccprintf(ss, "]");
715 return ss.str();
716 }
717};
718
719template <typename RegElemType, typename MemElemType,
720 template <typename, typename> class MicroopType,
721 template <typename> class FirstFaultWritebackMicroopType>
723{
724 protected:
729
733
734 public:
735 SveIndexedMemSV(const char *mnem, ExtMachInst machInst, OpClass __opClass,
736 RegIndex _dest, RegIndex _gp, RegIndex _base,
737 RegIndex _offset, bool _offsetIs32,
738 bool _offsetIsSigned, bool _offsetIsScaled,
739 bool firstFault)
740 : PredMacroOp(mnem, machInst, __opClass),
741 dest(_dest), gp(_gp), base(_base), offset(_offset),
742 offsetIs32(_offsetIs32), offsetIsSigned(_offsetIsSigned),
743 offsetIsScaled(_offsetIsScaled)
744 {
745 bool isLoad = (__opClass == MemReadOp);
746 assert(!firstFault || isLoad);
747
748 int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
749
750 numMicroops = num_elems;
751 if (isLoad) {
752 if (firstFault) {
753 numMicroops += 2;
754 } else {
755 numMicroops++;
756 }
757 }
758
760
761 StaticInstPtr *uop = microOps;
762
763 for (int i = 0; i < num_elems; i++, uop++) {
764 *uop = new MicroopType<RegElemType, MemElemType>(
765 mnem, machInst, __opClass,
766 isLoad ? (RegIndex)VECREG_UREG0 : _dest, _gp, _base, _offset,
767 _offsetIs32, _offsetIsSigned, _offsetIsScaled, i, num_elems,
768 firstFault);
769 }
770
771 if (isLoad) {
772 // The last microop of a gather load copies the auxiliary register
773 // to the destination vector register. Because when any fault
774 // occurs, the destination should keept the same.
775 *uop = new ArmISAInst::SveGatherLoadCpyDstVecMicroop(
776 mnem, machInst, _dest, this);
777 uop++;
778 }
779
780 if (firstFault) {
781 *uop = new FirstFaultWritebackMicroopType<RegElemType>(
782 mnem, machInst, __opClass, num_elems, this);
783 } else {
784 --uop;
785 }
786
787 (*uop)->setLastMicroop();
788 microOps[0]->setFirstMicroop();
789
790 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
791 (*uop)->setDelayedCommit();
792 }
793 }
794
795 Fault
797 {
798 panic("Execute method called when it shouldn't!");
799 return NoFault;
800 }
801
802 std::string
804 const loader::SymbolTable *symtab) const override
805 {
806 // TODO: add suffix to transfer and base registers
807 std::stringstream ss;
808 printMnemonic(ss, "", false);
809 ccprintf(ss, "{");
810 printVecReg(ss, dest, true);
811 ccprintf(ss, "}, ");
813 ccprintf(ss, "/z, [");
815 ccprintf(ss, ", ");
816 printVecReg(ss, offset, true);
817 ccprintf(ss, "]");
818 return ss.str();
819 }
820};
821
822template <typename RegElemType, typename MemElemType,
823 template <typename, typename> class MicroopType,
824 template <typename> class FirstFaultWritebackMicroopType>
826{
827 protected:
832
834
835 public:
836 SveIndexedMemVS(const char *mnem, ExtMachInst machInst, OpClass __opClass,
837 RegIndex _dest, RegIndex _gp, RegIndex _base,
838 RegIndex _offset, bool _offsetIs32)
839 : PredMacroOp(mnem, machInst, __opClass),
840 dest(_dest),
841 gp(_gp),
842 base(_base),
843 offset(_offset),
844 offsetIs32(_offsetIs32)
845 {
846 bool isLoad = (__opClass == MemReadOp);
847
848 int num_elems = ((machInst.sveLen + 1) * 16) / sizeof(RegElemType);
849
850 numMicroops = num_elems;
851 if (isLoad) {
852 numMicroops++;
853 }
854
856
857 StaticInstPtr *uop = microOps;
858
859 for (int i = 0; i < num_elems; i++, uop++) {
860 *uop = new MicroopType<RegElemType, MemElemType>(
861 mnem, machInst, __opClass,
862 isLoad ? (RegIndex)VECREG_UREG0 : _dest, _gp, _base, _offset,
863 _offsetIs32, i, num_elems);
864 }
865
866 if (isLoad) {
867 // The last microop of a gather load copies the auxiliary register
868 // to the destination vector register. Because when any fault
869 // occurs, the destination should keept the same.
870 *uop = new ArmISAInst::SveGatherLoadCpyDstVecMicroop(
871 mnem, machInst, _dest, this);
872 uop++;
873 }
874
875 --uop;
876
877 (*uop)->setLastMicroop();
878 microOps[0]->setFirstMicroop();
879
880 for (StaticInstPtr *uop = microOps; !(*uop)->isLastMicroop(); uop++) {
881 (*uop)->setDelayedCommit();
882 }
883 }
884
885 Fault
887 {
888 panic("Execute method called when it shouldn't!");
889 return NoFault;
890 }
891
892 std::string
894 const loader::SymbolTable *symtab) const override
895 {
896 // TODO: add suffix to transfer and base registers
897 std::stringstream ss;
898 printMnemonic(ss, "", false);
899 ccprintf(ss, "{");
900 printVecReg(ss, dest, true);
901 ccprintf(ss, "}, ");
903 ccprintf(ss, "/z, [");
905 ccprintf(ss, ", ");
906 printIntReg(ss, offset, true);
907 ccprintf(ss, "]");
908 return ss.str();
909 }
910};
911
912} // namespace ArmISA
913} // namespace gem5
914
915#endif // __ARCH_ARM_SVE_MACROMEM_HH__
void printMnemonic(std::ostream &os, const std::string &suffix="", bool withPred=true, bool withCond64=false, ConditionCode cond64=COND_UC) const
void printVecPredReg(std::ostream &os, RegIndex reg_idx, bool is_png=false) const
void printVecReg(std::ostream &os, RegIndex reg_idx, bool isSveVecReg=false) const
void printIntReg(std::ostream &os, RegIndex reg_idx, uint8_t opWidth=0) const
Print a register name for disassembly given the unique dependence tag number (FP or int).
StaticInstPtr * microOps
Definition pred_inst.hh:347
PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
Constructor.
Definition pred_inst.hh:350
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
SveIndexedMemSV(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, RegIndex _offset, bool _offsetIs32, bool _offsetIsSigned, bool _offsetIsScaled, bool firstFault)
Fault execute(ExecContext *, trace::InstRecord *) const override
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
SveIndexedMemVI(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, uint64_t _imm, bool firstFault)
Fault execute(ExecContext *, trace::InstRecord *) const override
SveIndexedMemVS(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, RegIndex _offset, bool _offsetIs32)
Fault execute(ExecContext *, trace::InstRecord *) const override
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Fault execute(ExecContext *, trace::InstRecord *) const override
SveLdContigConseSI(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, int64_t _imm, uint8_t _numregs)
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
SveLdContigConseSS(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, RegIndex _offset, uint8_t _numregs)
Fault execute(ExecContext *, trace::InstRecord *) const override
SveLdStructSI(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, int64_t _imm, uint8_t _numregs)
Fault execute(ExecContext *, trace::InstRecord *) const override
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
SveLdStructSS(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, RegIndex _offset, uint8_t _numregs)
Fault execute(ExecContext *, trace::InstRecord *) const override
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Fault execute(ExecContext *, trace::InstRecord *) const override
SveStContigConseSI(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, int64_t _imm, uint8_t _numregs)
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
SveStContigConseSS(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, RegIndex _offset, uint8_t _numregs)
Fault execute(ExecContext *, trace::InstRecord *) const override
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
SveStStructSI(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, int64_t _imm, uint8_t _numregs)
Fault execute(ExecContext *, trace::InstRecord *) const override
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Fault execute(ExecContext *, trace::InstRecord *) const override
SveStStructSS(const char *mnem, ExtMachInst machInst, OpClass __opClass, RegIndex _dest, RegIndex _gp, RegIndex _base, RegIndex _offset, uint8_t _numregs)
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
bool isLoad() const
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
Bitfield< 7 > i
Definition misc_types.hh:67
const int VECREG_UREG0
Definition vec.hh:92
Bitfield< 21 > ss
Definition misc_types.hh:60
const int INTRLVREG0
Definition vec.hh:88
Bitfield< 4 > pc
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
uint16_t RegIndex
Definition types.hh:176
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
RefCountingPtr< StaticInst > StaticInstPtr
constexpr decltype(nullptr) NoFault
Definition types.hh:253
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
static const OpClass MemReadOp
Definition op_class.hh:107

Generated on Mon Oct 27 2025 04:12:55 for gem5 by doxygen 1.14.0