gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
vector.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 PLCT Lab
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
30
31#include <sstream>
32#include <string>
33
35#include "arch/riscv/isa.hh"
38#include "arch/riscv/utility.hh"
39#include "cpu/static_inst.hh"
40
41namespace gem5
42{
43
44namespace RiscvISA
45{
46
61float
62getVflmul(uint32_t vlmul_encoding)
63{
64 int vlmul = sext<3>(vlmul_encoding & 7);
65 float vflmul = vlmul >= 0 ? 1 << vlmul : 1.0 / (1 << -vlmul);
66 return vflmul;
67}
68
69uint32_t
70getVlmax(VTYPE vtype, uint32_t vlen)
71{
72 uint32_t sew = getSew(vtype.vsew);
73 // vlmax is defined in RVV 1.0 spec p12 chapter 3.4.2.
74 uint32_t vlmax = (vlen/sew) * getVflmul(vtype.vlmul);
75 return vlmax;
76}
77
78std::string
80{
81 std::stringstream ss;
82 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
83 if (bit31 && bit30 == 0) {
84 ss << registerName(srcRegIdx(0)) << ", " << registerName(srcRegIdx(1));
85 } else if (bit31 && bit30) {
86 ss << uimm << ", " << generateZimmDisassembly();
87 } else {
89 }
90 return ss.str();
91}
92
93std::string
95{
96 std::stringstream s;
97
98 // VSETIVLI uses ZIMM10 and VSETVLI uses ZIMM11
99 uint64_t zimm = (bit31 && bit30) ? zimm10 : zimm11;
100
101 bool frac_lmul = bits(zimm, 2);
102 int sew = 1 << (bits(zimm, 5, 3) + 3);
103 int lmul = bits(zimm, 1, 0);
104 auto vta = bits(zimm, 6) == 1 ? "ta" : "tu";
105 auto vma = bits(zimm, 7) == 1 ? "ma" : "mu";
106 s << "e" << sew;
107 if (frac_lmul) {
108 std::string lmul_str = "";
109 switch(lmul){
110 case 3:
111 lmul_str = "f2";
112 break;
113 case 2:
114 lmul_str = "f4";
115 break;
116 case 1:
117 lmul_str = "f8";
118 break;
119 default:
120 panic("Unsupport fractional LMUL");
121 }
122 s << ", m" << lmul_str;
123 } else {
124 s << ", m" << (1 << lmul);
125 }
126 s << ", " << vta << ", " << vma;
127 return s.str();
128}
129
130std::string
132 const loader::SymbolTable *symtab) const
133{
134 std::stringstream ss;
135 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
136 << registerName(srcRegIdx(0));
137 if (machInst.vm == 0) ss << ", v0.t";
138 return ss.str();
139}
140
142 const loader::SymbolTable *symtab) const
143{
144 std::stringstream ss;
145 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
146 if (machInst.funct3 == 0x3) {
147 // OPIVI
148 ss << registerName(srcRegIdx(0)) << ", " << machInst.vecimm;
149 } else {
150 ss << registerName(srcRegIdx(1)) << ", " << registerName(srcRegIdx(0));
151 }
152 if (machInst.vm == 0) ss << ", v0.t";
153 return ss.str();
154}
155
157 const loader::SymbolTable *symtab) const
158{
159 std::stringstream ss;
160 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
161 if (machInst.funct3 == 0x3) {
162 // OPIVI
163 ss << registerName(srcRegIdx(0)) << ", " << machInst.vecimm;
164 } else {
165 ss << registerName(srcRegIdx(1)) << ", " << registerName(srcRegIdx(0));
166 }
167 if (machInst.vm == 0) ss << ", v0.t";
168 return ss.str();
169}
170
172 const loader::SymbolTable *symtab) const
173{
174 std::stringstream ss;
175 ss << mnemonic << ' ' << registerName(destRegIdx(0));
176 if (machInst.vm == 0) ss << ", v0.t";
177 return ss.str();
178}
179
181 const loader::SymbolTable *symtab) const
182{
183 std::stringstream ss;
184 ss << mnemonic << ' ' << registerName(destRegIdx(0));
185 if (machInst.vm == 0) ss << ", v0.t";
186 return ss.str();
187}
188
190 const loader::SymbolTable *symtab) const
191{
192 std::stringstream ss;
193 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
194 if (machInst.funct3 == 0x3) {
195 ss << registerName(srcRegIdx(0)) << ", " << machInst.vecimm;
196 } else {
197 ss << registerName(srcRegIdx(1)) << ", " << registerName(srcRegIdx(0));
198 }
199 if (machInst.vm == 0) ss << ", v0.t";
200 return ss.str();
201}
202
204 const loader::SymbolTable *symtab) const
205{
206 std::stringstream ss;
207 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
208 if (machInst.funct3 == 0x3) {
209 ss << registerName(srcRegIdx(0)) << ", " << machInst.vecimm;
210 } else {
211 ss << registerName(srcRegIdx(1)) << ", " << registerName(srcRegIdx(0));
212 }
213 if (machInst.vm == 0) ss << ", v0.t";
214 return ss.str();
215}
216
218 const loader::SymbolTable *symtab) const
219{
220 std::stringstream ss;
221 unsigned vlenb = vlen >> 3;
222 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
223 << vlenb * microIdx << '(' << registerName(srcRegIdx(0)) << ')' << ", "
224 << registerName(srcRegIdx(1));
225 if (!machInst.vm) ss << ", v0.t";
226 return ss.str();
227}
228
230 const loader::SymbolTable *symtab) const
231{
232 std::stringstream ss;
233 unsigned vlenb = vlen >> 3;
234 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
235 << vlenb * microIdx << '(' << registerName(srcRegIdx(0)) << ')';
236 return ss.str();
237}
238
240 const loader::SymbolTable *symtab) const
241{
242 std::stringstream ss;
243 unsigned vlenb = vlen >> 3;
244 ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", "
245 << vlenb * microIdx << '(' << registerName(srcRegIdx(0)) << ')';
246 if (!machInst.vm) ss << ", v0.t";
247 return ss.str();
248}
249
251 const loader::SymbolTable *symtab) const
252{
253 std::stringstream ss;
254 unsigned vlenb = vlen >> 3;
255 ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", "
256 << vlenb * microIdx << '(' << registerName(srcRegIdx(0)) << ')';
257 return ss.str();
258}
259
261 const loader::SymbolTable *symtab) const
262{
263 std::stringstream ss;
264 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
265 '(' << registerName(srcRegIdx(0)) << ')';
266 if (!machInst.vm) ss << ", v0.t";
267 return ss.str();
268}
269
271 const loader::SymbolTable *symtab) const
272{
273 std::stringstream ss;
274 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
275 '(' << registerName(srcRegIdx(0)) << ')';
276 return ss.str();
277}
278
280 const loader::SymbolTable *symtab) const
281{
282 std::stringstream ss;
283 ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", " <<
284 '(' << registerName(srcRegIdx(0)) << ')';
285 if (!machInst.vm) ss << ", v0.t";
286 return ss.str();
287}
288
290 const loader::SymbolTable *symtab) const
291{
292 std::stringstream ss;
293 ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", " <<
294 '(' << registerName(srcRegIdx(0)) << ')';
295 return ss.str();
296}
297
299 const loader::SymbolTable *symtab) const
300{
301 std::stringstream ss;
302 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
303 '(' << registerName(srcRegIdx(0)) << ')' <<
304 ", " << registerName(srcRegIdx(1));
305 if (!machInst.vm) ss << ", v0.t";
306 return ss.str();
307}
308
310 const loader::SymbolTable *symtab) const
311{
312 std::stringstream ss;
313 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
314 '(' << registerName(srcRegIdx(0)) << ')' <<
315 ", "<< registerName(srcRegIdx(1));
316 if (microIdx != 0 || machInst.vtype8.vma == 0 || machInst.vtype8.vta == 0)
317 ss << ", " << registerName(srcRegIdx(2));
318 if (!machInst.vm) ss << ", v0.t";
319 return ss.str();
320}
321
323 const loader::SymbolTable *symtab) const
324{
325 std::stringstream ss;
326 ss << mnemonic << ' ' << registerName(srcRegIdx(2)) << ", " <<
327 '(' << registerName(srcRegIdx(0)) << ')' <<
328 ", " << registerName(srcRegIdx(1));
329 if (!machInst.vm) ss << ", v0.t";
330 return ss.str();
331}
332
334 const loader::SymbolTable *symtab) const
335{
336 std::stringstream ss;
337 ss << mnemonic << ' ' << registerName(srcRegIdx(2)) << ", " <<
338 '(' << registerName(srcRegIdx(0)) << ')' <<
339 ", "<< registerName(srcRegIdx(1));
340 if (microIdx != 0 || machInst.vtype8.vma == 0 || machInst.vtype8.vta == 0)
341 ss << ", " << registerName(srcRegIdx(2));
342 if (!machInst.vm) ss << ", v0.t";
343 return ss.str();
344}
345
347 const loader::SymbolTable *symtab) const
348{
349 std::stringstream ss;
350 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
351 << '(' << registerName(srcRegIdx(0)) << "),"
352 << registerName(srcRegIdx(1));
353 if (!machInst.vm) ss << ", v0.t";
354 return ss.str();
355}
356
358 const loader::SymbolTable *symtab) const
359{
360 std::stringstream ss;
361 ss << mnemonic << ' '
362 << registerName(destRegIdx(0)) << "[" << uint16_t(vdElemIdx) << "], "
363 << '(' << registerName(srcRegIdx(0)) << "), "
364 << registerName(srcRegIdx(1)) << "[" << uint16_t(vs2ElemIdx) << "]";
365 if (microIdx != 0 || machInst.vtype8.vma == 0 || machInst.vtype8.vta == 0)
366 ss << ", " << registerName(srcRegIdx(2));
367 if (!machInst.vm) ss << ", v0.t";
368 return ss.str();
369}
370
372 const loader::SymbolTable *symtab) const
373{
374 std::stringstream ss;
375 ss << mnemonic << ' ' << registerName(srcRegIdx(2)) << ", "
376 << '(' << registerName(srcRegIdx(0)) << "),"
377 << registerName(srcRegIdx(1));
378 if (!machInst.vm) ss << ", v0.t";
379 return ss.str();
380}
381
383 const loader::SymbolTable *symtab) const
384{
385 std::stringstream ss;
386 ss << mnemonic << ' '
387 << registerName(srcRegIdx(2)) << "[" << uint16_t(vs3ElemIdx) << "], "
388 << '(' << registerName(srcRegIdx(0)) << "), "
389 << registerName(srcRegIdx(1)) << "[" << uint16_t(vs2ElemIdx) << "]";
390 if (!machInst.vm) ss << ", v0.t";
391 return ss.str();
392}
393
394std::string
396 const loader::SymbolTable *symtab) const
397{
398 std::stringstream ss;
399 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
401 return ss.str();
402}
403
404std::string
406 const loader::SymbolTable *symtab) const
407{
408 std::stringstream ss;
409 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
411 return ss.str();
412}
413
415 uint8_t _dstReg, uint8_t _numSrcs, uint32_t _elen, uint32_t _vlen,
416 size_t _elemSize)
417 : VectorArithMicroInst("vmask_mv_micro", extMachInst,
418 SimdAddOp, 0, 0, _elen, _vlen),
419 elemSize(_elemSize)
420{
422 reinterpret_cast<RegIdArrayPtr>(
423 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
424 reinterpret_cast<RegIdArrayPtr>(
425 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
426
427 _numSrcRegs = 0;
428 _numDestRegs = 0;
429
432 for (uint8_t i=0; i<_numSrcs; i++) {
434 }
435}
436
437Fault
439 trace::InstRecord* traceData) const
440{
441 vreg_t& tmp_d0 = *(vreg_t *)xc->getWritableRegOperand(this, 0);
442 auto Vd = tmp_d0.as<uint8_t>();
443 uint32_t vlenb = vlen >> 3;
444 const uint32_t elems_per_vreg = vlenb / elemSize;
445 size_t bit_cnt = elems_per_vreg;
446
447 // mask tails are always treated as agnostic: writting 1s
448 tmp_d0.set(0xff);
449
450 vreg_t tmp_s;
451 for (uint8_t i = 0; i < this->_numSrcRegs; i++) {
452 xc->getRegOperand(this, i, &tmp_s);
453 auto s = tmp_s.as<uint8_t>();
454 if (elems_per_vreg < 8) {
455 const uint32_t m = (1 << elems_per_vreg) - 1;
456 const uint32_t mask = m << (i * elems_per_vreg % 8);
457 // clr & ext bits
458 Vd[bit_cnt/8] ^= Vd[bit_cnt/8] & mask;
459 Vd[bit_cnt/8] |= s[bit_cnt/8] & mask;
460 bit_cnt += elems_per_vreg;
461 } else {
462 const uint32_t byte_offset = elems_per_vreg / 8;
463 memcpy(Vd + i * byte_offset, s + i * byte_offset, byte_offset);
464 }
465 }
466 if (traceData) {
467 traceData->setData(vecRegClass, &tmp_d0);
468 }
469 return NoFault;
470}
471
472std::string
474 const loader::SymbolTable *symtab) const
475{
476 std::stringstream ss;
477 ss << mnemonic << ' ' << registerName(destRegIdx(0));
478 for (uint8_t i = 0; i < this->_numSrcRegs; i++) {
479 ss << ", " << registerName(srcRegIdx(i));
480 }
481 unsigned vlenb = vlen >> 3;
482 ss << ", offset:" << vlenb / elemSize;
483 return ss.str();
484}
485
486Fault
488{
490 auto vcsr = xc->readMiscReg(MISCREG_VCSR);
491 xc->setMiscReg(MISCREG_VCSR, ((vcsr&~1)|*vxsat));
492 return NoFault;
493}
494
495std::string
497 const loader::SymbolTable *symtab) const
498{
499 std::stringstream ss;
500 ss << mnemonic << ' ' << "VXSAT" << ", " << (*vxsat ? "0x1" : "0x0");
501 return ss.str();
502}
503
505 uint32_t _microIdx, uint32_t _elen, uint32_t _vlen,
507 : VectorMicroInst("vlff_trimvl_v_micro", _machInst, SimdConfigOp,
508 _microVl, _microIdx, _elen, _vlen),
509 microops(_microops)
510{
512 reinterpret_cast<RegIdArrayPtr>(
513 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
514 nullptr
515 );
516
517 // Create data dependency with load micros
518 for (uint8_t i=0; i<microIdx; i++) {
519 setSrcRegIdx(_numSrcRegs++, vecRegClass[_machInst.vd + i]);
520 }
521
522 this->flags[IsControl] = true;
523 this->flags[IsIndirectControl] = true;
524 this->flags[IsInteger] = true;
525 this->flags[IsUncondControl] = true;
526}
527
528uint32_t
530{
531 uint32_t vl = 0;
532 for (uint8_t i=0; i<microIdx; i++) {
533 VleMicroInst& micro = static_cast<VleMicroInst&>(*microops[i]);
534 vl += micro.faultIdx;
535
536 if (micro.trimVl)
537 break;
538 }
539 return vl;
540}
541
542Fault
544{
545 auto tc = xc->tcBase();
546 MISA misa = xc->readMiscReg(MISCREG_ISA);
547 STATUS status = xc->readMiscReg(MISCREG_STATUS);
548 if (!misa.rvv || status.vs == VPUStatus::OFF) {
549 return std::make_shared<IllegalInstFault>(
550 "RVV is disabled or VPU is off", machInst);
551 }
552
553 PCState pc;
554 set(pc, xc->pcState());
555
556 uint32_t new_vl = calcVl();
557
558 tc->setMiscReg(MISCREG_VSTART, 0);
559
560 RegVal final_val = new_vl;
561 if (traceData) {
562 traceData->setData(miscRegClass, final_val);
563 }
564
565 pc.vl(new_vl);
566 pc.new_vconf(true);
567 xc->pcState(pc);
568
569 return NoFault;
570}
571
572std::unique_ptr<PCStateBase>
574{
575 PCStateBase *pc_ptr = tc->pcState().clone();
576
577 uint32_t new_vl = calcVl();
578
579 pc_ptr->as<PCState>().vl(new_vl);
580 return std::unique_ptr<PCStateBase>{pc_ptr};
581}
582
583std::string
585 const loader::SymbolTable *symtab) const
586{
587 std::stringstream ss;
588 ss << mnemonic << " vl";
589 return ss.str();
590}
591
593 const loader::SymbolTable *symtab) const
594{
595 std::stringstream ss;
596 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
597 '(' << registerName(srcRegIdx(0)) << ')' <<
598 ", " << registerName(srcRegIdx(1));
599 if (!machInst.vm)
600 ss << ", v0.t";
601 return ss.str();
602}
603
605 const loader::SymbolTable *symtab) const
606{
607 std::stringstream ss;
608 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
609 '(' << registerName(srcRegIdx(0)) << ')' <<
610 ", "<< registerName(srcRegIdx(1));
611 if (microIdx != 0 || machInst.vtype8.vma == 0 || machInst.vtype8.vta == 0)
612 ss << ", " << registerName(srcRegIdx(2));
613 if (!machInst.vm)
614 ss << ", v0.t";
615 return ss.str();
616}
617
619 uint32_t _micro_vl, uint32_t _dstReg,
620 uint32_t _numSrcs, uint32_t _microIdx,
621 uint32_t _numMicroops, uint32_t _field, uint32_t _elen,
622 uint32_t _vlen, uint32_t _sizeOfElement)
623 : VectorArithMicroInst("vlseg_deintrlv_micro", extMachInst,
624 SimdAddOp, 0, 0, _elen, _vlen)
625{
627 reinterpret_cast<RegIdArrayPtr>(
628 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
629 reinterpret_cast<RegIdArrayPtr>(
630 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
631
632 _numSrcRegs = 0;
633 _numDestRegs = 0;
634 numSrcs = _numSrcs;
635 numMicroops = _numMicroops;
636 field =_field;
637 sizeOfElement = _sizeOfElement;
638 microIdx = _microIdx;
639 micro_vl = _micro_vl;
640
643 for (uint32_t i=0; i < _numSrcs; i++) {
644 uint32_t index = VecMemInternalReg0 + i + (microIdx * _numSrcs);
646 }
647}
648
649Fault
651{
652 vreg_t& tmp_d0 = *(vreg_t *)xc->getWritableRegOperand(this, 0);
653 auto Vd = tmp_d0.as<uint8_t>();
654 const uint32_t elems_per_vreg = micro_vl;
655 vreg_t tmp_s;
656 auto s = tmp_s.as<uint8_t>();
657 uint32_t elem = 0;
658 uint32_t index = field;
659 for (uint32_t i = 0; i < numSrcs; i++) {
660 xc->getRegOperand(this, i, &tmp_s);
661 s = tmp_s.as<uint8_t>();
662
663 // copy tail/inactive elements from vtmp src
664 if (i == field) {
665 tmp_d0 = tmp_s;
666 }
667
668 while (index < (i + 1) * elems_per_vreg)
669 {
670 memcpy(Vd + (elem * sizeOfElement),
671 s + ((index % elems_per_vreg) * sizeOfElement),
673 index += numSrcs;
674 elem++;
675 }
676 }
677 if (traceData) {
678 traceData->setData(vecRegClass, &tmp_d0);
679 }
680 return NoFault;
681}
682
683std::string
685 const
686{
687 std::stringstream ss;
688 ss << mnemonic << ' ' << registerName(destRegIdx(0));
689 for (uint8_t i = 0; i < this->_numSrcRegs; i++) {
690 ss << ", " << registerName(srcRegIdx(i));
691 }
692 ss << ", field: " << field;
693 return ss.str();
694}
695
697 const loader::SymbolTable *symtab) const
698{
699 std::stringstream ss;
700 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
701 '(' << registerName(srcRegIdx(0)) << ')' <<
702 ", " << registerName(srcRegIdx(1));
703 if (!machInst.vm)
704 ss << ", v0.t";
705 return ss.str();
706}
707
709 const loader::SymbolTable *symtab) const
710{
711 std::stringstream ss;
712 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
713 '(' << registerName(srcRegIdx(0)) << ')' <<
714 ", "<< registerName(srcRegIdx(1));
715 if (!machInst.vm)
716 ss << ", v0.t";
717 return ss.str();
718}
719
721 uint32_t _micro_vl, uint32_t _dstReg,
722 uint32_t _numSrcs, uint32_t _microIdx,
723 uint32_t _numMicroops, uint32_t _field, uint32_t _elen,
724 uint32_t _vlen, uint32_t _sizeOfElement)
725 : VectorArithMicroInst("vsseg_reintrlv_micro", extMachInst,
726 SimdAddOp, 0, 0, _elen, _vlen)
727{
729 reinterpret_cast<RegIdArrayPtr>(
730 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
731 reinterpret_cast<RegIdArrayPtr>(
732 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
733
734 _numSrcRegs = 0;
735 _numDestRegs = 0;
736 numSrcs = _numSrcs;
737 numMicroops = _numMicroops;
738 field =_field;
739 sizeOfElement = _sizeOfElement;
740 microIdx = _microIdx;
741 micro_vl = _micro_vl;
742
744 (_microIdx * numSrcs)]);
745
747 for (uint8_t i=0; i<_numSrcs; i++) {
749 (microIdx)]);
750 }
751}
752
753Fault
755 trace::InstRecord* traceData) const
756{
757 const uint32_t elems_per_vreg = micro_vl;
758 vreg_t& tmp_d0 = *(vreg_t *)xc->getWritableRegOperand(this, 0);
759 auto Vd = tmp_d0.as<uint8_t>();
760
761 vreg_t tmp_s;
762 auto s = tmp_s.as<uint8_t>();
763 xc->getRegOperand(this, 0, &tmp_s);
764 s = tmp_s.as<uint8_t>();
765
766 uint32_t indexVd = 0;
767 uint32_t srcReg = (field * elems_per_vreg) % numSrcs;
768 uint32_t indexs = (field * elems_per_vreg) / numSrcs;
769
770 while (indexVd < elems_per_vreg) {
771 xc->getRegOperand(this, srcReg, &tmp_s);
772 s = tmp_s.as<uint8_t>();
773
774 memcpy(Vd + (indexVd * sizeOfElement),
775 s + (indexs * sizeOfElement),
777
778 indexVd++;
779 srcReg++;
780 if (srcReg >= numSrcs) {
781 srcReg = 0;
782 indexs++;
783 }
784 }
785
786 if (traceData) {
787 traceData->setData(vecRegClass, &tmp_d0);
788 }
789 return NoFault;
790}
791
792std::string
794 const loader::SymbolTable *symtab) const
795{
796 std::stringstream ss;
797 ss << mnemonic << ' ' << registerName(destRegIdx(0));
798 for (uint8_t i = 0; i < this->_numSrcRegs; i++) {
799 ss << ", " << registerName(srcRegIdx(i));
800 }
801 ss << ", field: " << field;
802 return ss.str();
803}
804
805VCpyVsMicroInst::VCpyVsMicroInst(ExtMachInst _machInst, uint32_t _microIdx,
806 uint8_t _vsRegIdx, uint32_t _elen,
807 uint32_t _vlen)
808 : VectorArithMicroInst("vcpyvs_v_micro", _machInst, SimdMiscOp, 0,
809 _microIdx, _elen, _vlen)
810{
812 reinterpret_cast<RegIdArrayPtr>(
813 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
814 reinterpret_cast<RegIdArrayPtr>(
815 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
816
817 _numSrcRegs = 0;
818 _numDestRegs = 0;
821 setSrcRegIdx(_numSrcRegs++, vecRegClass[_vsRegIdx + _microIdx]);
822}
823
824Fault
826{
827 MISA misa = xc->readMiscReg(MISCREG_ISA);
828 STATUS status = xc->readMiscReg(MISCREG_STATUS);
829
830 if (!misa.rvv || status.vs == VPUStatus::OFF) {
831 return std::make_shared<IllegalInstFault>(
832 "RVV is disabled or VPU is off", machInst);
833 }
834
837
838 // copy vector source reg to vtmp
839 vreg_t& vtmp = *(vreg_t *)xc->getWritableRegOperand(this, 0);
840 vreg_t vs;
841 xc->getRegOperand(this, 0, &vs);
842 vtmp = vs;
843
844 if (traceData) {
845 traceData->setData(vecRegClass, &vtmp);
846 }
847
848 return NoFault;
849}
850
851std::string
853 const loader::SymbolTable *symtab) const
854{
855 std::stringstream ss;
856 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
857 << registerName(srcRegIdx(0));
858 return ss.str();
859}
860
861VPinVdMicroInst::VPinVdMicroInst(ExtMachInst _machInst, uint32_t _microIdx,
862 uint32_t _numVdPins, uint32_t _elen,
863 uint32_t _vlen, bool _hasVdOffset)
864 : VectorArithMicroInst("vpinvd_v_micro", _machInst, SimdMiscOp, 0,
865 _microIdx, _elen, _vlen)
866 , hasVdOffset(_hasVdOffset)
867{
869 reinterpret_cast<RegIdArrayPtr>(
870 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
871 reinterpret_cast<RegIdArrayPtr>(
872 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
873
874 _numSrcRegs = 0;
875 _numDestRegs = 0;
876 setDestRegIdx(_numDestRegs++, vecRegClass[_machInst.vd + _microIdx]);
878 if (!_machInst.vtype8.vta || (!_machInst.vm && !_machInst.vtype8.vma)
879 || hasVdOffset) {
880 setSrcRegIdx(_numSrcRegs++, vecRegClass[_machInst.vd + _microIdx]);
881 }
882 RegId Vd = destRegIdx(0);
883 Vd.setNumPinnedWrites(_numVdPins);
884 setDestRegIdx(0, Vd);
885}
886
887Fault
889{
890 MISA misa = xc->readMiscReg(MISCREG_ISA);
891 STATUS status = xc->readMiscReg(MISCREG_STATUS);
892
893 if (!misa.rvv || status.vs == VPUStatus::OFF) {
894 return std::make_shared<IllegalInstFault>(
895 "RVV is disabled or VPU is off", machInst);
896 }
897
900
901 // tail/mask policy: both undisturbed if one is, 1s if none
902 vreg_t& vd = *(vreg_t *)xc->getWritableRegOperand(this, 0);
903 if (!machInst.vtype8.vta || (!machInst.vm && !machInst.vtype8.vma)
904 || hasVdOffset) {
905 vreg_t old_vd;
906 xc->getRegOperand(this, 0, &old_vd);
907 vd = old_vd;
908 } else {
909 vd.set(0xff);
910 }
911
912 if (traceData) {
913 traceData->setData(vecRegClass, &vd);
914 }
915
916 return NoFault;
917}
918
919std::string
921 const loader::SymbolTable *symtab) const
922{
923 std::stringstream ss;
924 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
925
926 if (!machInst.vtype8.vta || (!machInst.vm && !machInst.vtype8.vma)
927 || hasVdOffset) {
929 } else {
930 ss << "~0";
931 }
932
933 return ss.str();
934}
935
936} // namespace RiscvISA
937} // namespace gem5
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
virtual void * getWritableRegOperand(const StaticInst *si, int idx)=0
virtual ThreadContext * tcBase() const =0
Returns a pointer to the ThreadContext.
virtual RegVal readMiscReg(int misc_reg)=0
Reads a miscellaneous register, handling any architectural side effects due to reading that register.
virtual void setMiscReg(int misc_reg, RegVal val)=0
Sets a miscellaneous register, handling any architectural side effects due to writing that register.
virtual const PCStateBase & pcState() const =0
virtual RegVal getRegOperand(const StaticInst *si, int idx)=0
Target & as()
Definition pcstate.hh:73
virtual PCStateBase * clone() const =0
Register ID: describe an architectural register with its class and index.
Definition reg_class.hh:94
void setNumPinnedWrites(int num_writes)
Definition reg_class.hh:163
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:79
std::string generateZimmDisassembly() const
Definition vector.cc:94
VCpyVsMicroInst(ExtMachInst _machInst, uint32_t _microIdx, uint8_t _vsRegIdx, uint32_t _elen, uint32_t _vlen)
Definition vector.cc:805
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:825
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:852
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:473
VMaskMergeMicroInst(ExtMachInst extMachInst, uint8_t _dstReg, uint8_t _numSrcs, uint32_t _elen, uint32_t _vlen, size_t _elemSize)
Definition vector.cc:414
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:438
RegId srcRegIdxArr[NumVecInternalRegs]
Definition vector.hh:576
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:395
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:405
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:888
VPinVdMicroInst(ExtMachInst _machInst, uint32_t _microIdx, uint32_t _numVdPins, uint32_t _elen, uint32_t _vlen, bool _hasVdOffset=false)
Definition vector.cc:861
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:920
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:156
VectorArithMicroInst(const char *mnem, ExtMachInst _machInst, OpClass __opClass, uint32_t _microVl, uint32_t _microIdx, uint32_t _elen, uint32_t _vlen)
Definition vector.hh:191
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:141
VectorMicroInst(const char *mnem, ExtMachInst _machInst, OpClass __opClass, uint32_t _microVl, uint32_t _microIdx, uint32_t _elen, uint32_t _vlen)
Definition vector.hh:153
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:131
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:203
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:189
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:180
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:171
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:543
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:584
VlFFTrimVlMicroOp(ExtMachInst _machInst, uint32_t _microVl, uint32_t _microIdx, uint32_t _elen, uint32_t _vlen, std::vector< StaticInstPtr > &_microops)
Definition vector.cc:504
std::unique_ptr< PCStateBase > branchTarget(ThreadContext *) const override
Return the target address for an indirect branch (jump).
Definition vector.cc:573
std::vector< StaticInstPtr > & microops
Definition vector.hh:611
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:346
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:357
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:650
RegId srcRegIdxArr[NumVecInternalRegs]
Definition vector.hh:660
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:684
VlSegDeIntrlvMicroInst(ExtMachInst extMachInst, uint32_t _micro_vl, uint32_t _dstReg, uint32_t _numSrcs, uint32_t _microIdx, uint32_t _numMicroops, uint32_t _field, uint32_t _elen, uint32_t _vlen, uint32_t _sizeOfElement)
Definition vector.cc:618
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:592
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:604
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:298
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:309
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:270
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:229
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:260
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:217
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:371
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:382
VsSegIntrlvMicroInst(ExtMachInst extMachInst, uint32_t _micro_vl, uint32_t _dstReg, uint32_t _numSrcs, uint32_t _microIdx, uint32_t _numMicroops, uint32_t _field, uint32_t _elen, uint32_t _vlen, uint32_t _sizeOfElement)
Definition vector.cc:720
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:793
RegId srcRegIdxArr[NumVecInternalRegs]
Definition vector.hh:717
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:754
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:696
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:708
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:322
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:333
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:289
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:250
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:279
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:239
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:487
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:496
void setDestRegIdx(int i, const RegId &val)
void setRegIdxArrays(RegIdArrayPtr src, RegIdArrayPtr dest)
Set the pointers which point to the arrays of source and destination register indices.
std::array< uint8_t, MiscRegClass+1 > _numTypedDestRegs
RegId(StaticInst::*)[] RegIdArrayPtr
uint8_t _numSrcRegs
See numSrcRegs().
uint8_t _numDestRegs
See numDestRegs().
const RegId & destRegIdx(int i) const
Return logical index (architectural reg num) of i'th destination reg.
void setSrcRegIdx(int i, const RegId &val)
const char * mnemonic
Base mnemonic (e.g., "add").
std::bitset< Num_Flags > flags
Flag values for this instruction.
const RegId & srcRegIdx(int i) const
Return logical index (architectural reg num) of i'th source reg.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual const PCStateBase & pcState() const =0
void set(uint8_t val)
Set the container.
Definition vec_reg.hh:144
VecElem * as()
View interposers.
Definition vec_reg.hh:194
void setData(std::array< T, N > d)
STL vector class.
Definition stl.hh:37
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
Definition bitfield.hh:129
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
Bitfield< 5, 0 > status
Bitfield< 12, 11 > set
Bitfield< 0 > m
float getVflmul(uint32_t vlmul_encoding)
This function translates the 3-bit value of vlmul bits to the corresponding lmul value as specified i...
Definition vector.cc:62
Bitfield< 7 > vma
Definition vector.hh:79
const int VecMemInternalReg0
Definition vector.hh:67
Bitfield< 6 > vta
Definition vector.hh:80
Bitfield< 30, 0 > index
uint32_t getVlmax(VTYPE vtype, uint32_t vlen)
Definition vector.cc:70
Bitfield< 11, 7 > vd
Definition types.hh:169
std::string registerName(RegId reg)
Definition utility.hh:130
Bitfield< 2 > i
Bitfield< 57, 41 > vl
Definition types.hh:63
VecRegContainer vreg_t
Definition vector.hh:51
Bitfield< 2 > s
Bitfield< 2, 0 > vlmul
Definition vector.hh:82
constexpr RegClass vecRegClass
Definition vector.hh:71
Bitfield< 11, 8 > ss
@ MISCREG_STATUS
Definition misc.hh:76
Bitfield< 9, 5 > vs
Bitfield< 4 > pc
uint32_t getSew(uint32_t vsew)
Definition vector.hh:52
constexpr RegClass miscRegClass(MiscRegClass, MiscRegClassName, NUM_MISCREGS, debug::MiscRegs)
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
uint64_t RegVal
Definition types.hh:173
static const OpClass SimdAddOp
Definition op_class.hh:67
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
static const OpClass SimdMiscOp
Definition op_class.hh:72
static const OpClass SimdConfigOp
Definition op_class.hh:134
constexpr decltype(nullptr) NoFault
Definition types.hh:253
@ VecRegClass
Vector Register.
Definition reg_class.hh:64

Generated on Mon May 26 2025 09:19:06 for gem5 by doxygen 1.13.2