gem5 v25.0.0.1
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)) << ", "
196 << registerName(srcRegIdx(1)) << ", " << machInst.vecimm;
197 } else {
198 ss << registerName(srcRegIdx(1)) << ", "
199 << registerName(srcRegIdx(2)) << ", " << registerName(srcRegIdx(0));
200 }
201 if (machInst.vm == 0) ss << ", v0.t";
202 return ss.str();
203}
204
206 const loader::SymbolTable *symtab) const
207{
208 std::stringstream ss;
209 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
210 if (machInst.funct3 == 0x3) {
211 ss << registerName(srcRegIdx(0)) << ", " << machInst.vecimm;
212 } else {
213 ss << registerName(srcRegIdx(1)) << ", " << registerName(srcRegIdx(0));
214 }
215 if (machInst.vm == 0) ss << ", v0.t";
216 return ss.str();
217}
218
220 const loader::SymbolTable *symtab) const
221{
222 std::stringstream ss;
223 unsigned vlenb = vlen >> 3;
224 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
225 << vlenb * microIdx << '(' << registerName(srcRegIdx(0)) << ')' << ", "
226 << registerName(srcRegIdx(1));
227 if (!machInst.vm) ss << ", v0.t";
228 return ss.str();
229}
230
232 const loader::SymbolTable *symtab) const
233{
234 std::stringstream ss;
235 unsigned vlenb = vlen >> 3;
236 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
237 << vlenb * microIdx << '(' << registerName(srcRegIdx(0)) << ')';
238 return ss.str();
239}
240
242 const loader::SymbolTable *symtab) const
243{
244 std::stringstream ss;
245 unsigned vlenb = vlen >> 3;
246 ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", "
247 << vlenb * microIdx << '(' << registerName(srcRegIdx(0)) << ')';
248 if (!machInst.vm) ss << ", v0.t";
249 return ss.str();
250}
251
253 const loader::SymbolTable *symtab) const
254{
255 std::stringstream ss;
256 unsigned vlenb = vlen >> 3;
257 ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", "
258 << vlenb * microIdx << '(' << registerName(srcRegIdx(0)) << ')';
259 return ss.str();
260}
261
263 const loader::SymbolTable *symtab) const
264{
265 std::stringstream ss;
266 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
267 '(' << registerName(srcRegIdx(0)) << ')';
268 if (!machInst.vm) ss << ", v0.t";
269 return ss.str();
270}
271
273 const loader::SymbolTable *symtab) const
274{
275 std::stringstream ss;
276 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
277 '(' << registerName(srcRegIdx(0)) << ')';
278 return ss.str();
279}
280
282 const loader::SymbolTable *symtab) const
283{
284 std::stringstream ss;
285 ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", " <<
286 '(' << registerName(srcRegIdx(0)) << ')';
287 if (!machInst.vm) ss << ", v0.t";
288 return ss.str();
289}
290
292 const loader::SymbolTable *symtab) const
293{
294 std::stringstream ss;
295 ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", " <<
296 '(' << registerName(srcRegIdx(0)) << ')';
297 return ss.str();
298}
299
301 const loader::SymbolTable *symtab) const
302{
303 std::stringstream ss;
304 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
305 '(' << registerName(srcRegIdx(0)) << ')';
306 if (has_rs2) {
307 ss << ", " << registerName(srcRegIdx(1));
308 }
309 if (!machInst.vm)
310 ss << ", v0.t";
311 return ss.str();
312}
313
315 const loader::SymbolTable *symtab) const
316{
317 std::stringstream ss;
318 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
319 '(' << registerName(srcRegIdx(0)) << ')';
320 if (has_rs2) {
321 ss << ", " << registerName(srcRegIdx(1));
322 }
323 if (microIdx != 0 || machInst.vtype8.vma == 0 || machInst.vtype8.vta == 0)
324 ss << ", " << registerName(srcRegIdx(has_rs2 ? 2 : 1));
325 if (!machInst.vm)
326 ss << ", v0.t";
327 return ss.str();
328}
329
331 const loader::SymbolTable *symtab) const
332{
333 std::stringstream ss;
334 ss << mnemonic << ' ' << registerName(srcRegIdx(has_rs2 ? 2 : 1))
335 << ", " << '(' << registerName(srcRegIdx(0)) << ')';
336 if (has_rs2) {
337 ss << ", " << registerName(srcRegIdx(1));
338 }
339 if (!machInst.vm) ss << ", v0.t";
340 return ss.str();
341}
342
344 const loader::SymbolTable *symtab) const
345{
346 std::stringstream ss;
347 ss << mnemonic << ' ' << registerName(srcRegIdx(2)) << ", " <<
348 '(' << registerName(srcRegIdx(0)) << ')';
349 if (has_rs2) {
350 ss << ", " << registerName(srcRegIdx(1));
351 }
352 if (microIdx != 0 || machInst.vtype8.vma == 0 || machInst.vtype8.vta == 0)
353 ss << ", " << registerName(srcRegIdx(has_rs2 ? 2 : 1));
354 if (!machInst.vm) ss << ", v0.t";
355 return ss.str();
356}
357
359 const loader::SymbolTable *symtab) const
360{
361 std::stringstream ss;
362 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
363 << '(' << registerName(srcRegIdx(0)) << "),"
364 << registerName(srcRegIdx(1));
365 if (!machInst.vm) ss << ", v0.t";
366 return ss.str();
367}
368
370 const loader::SymbolTable *symtab) const
371{
372 std::stringstream ss;
373 ss << mnemonic << ' '
374 << registerName(destRegIdx(0)) << "[" << uint16_t(vdElemIdx) << "], "
375 << '(' << registerName(srcRegIdx(0)) << "), "
376 << registerName(srcRegIdx(1)) << "[" << uint16_t(vs2ElemIdx) << "]";
377 if (microIdx != 0 || machInst.vtype8.vma == 0 || machInst.vtype8.vta == 0)
378 ss << ", " << registerName(srcRegIdx(2));
379 if (!machInst.vm) ss << ", v0.t";
380 return ss.str();
381}
382
384 const loader::SymbolTable *symtab) const
385{
386 std::stringstream ss;
387 ss << mnemonic << ' ' << registerName(srcRegIdx(2)) << ", "
388 << '(' << registerName(srcRegIdx(0)) << "),"
389 << registerName(srcRegIdx(1));
390 if (!machInst.vm) ss << ", v0.t";
391 return ss.str();
392}
393
395 const loader::SymbolTable *symtab) const
396{
397 std::stringstream ss;
398 ss << mnemonic << ' '
399 << registerName(srcRegIdx(2)) << "[" << uint16_t(vs3ElemIdx) << "], "
400 << '(' << registerName(srcRegIdx(0)) << "), "
401 << registerName(srcRegIdx(1)) << "[" << uint16_t(vs2ElemIdx) << "]";
402 if (!machInst.vm) ss << ", v0.t";
403 return ss.str();
404}
405
406std::string
408 const loader::SymbolTable *symtab) const
409{
410 std::stringstream ss;
411 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
413 return ss.str();
414}
415
416std::string
418 const loader::SymbolTable *symtab) const
419{
420 std::stringstream ss;
421 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
423 return ss.str();
424}
425
427 uint8_t _dstReg, uint8_t _numSrcs, uint32_t _elen, uint32_t _vlen,
428 size_t _elemSize)
429 : VectorArithMicroInst("vmask_mv_micro", extMachInst,
430 SimdAddOp, 0, 0, _elen, _vlen),
431 elemSize(_elemSize)
432{
434 reinterpret_cast<RegIdArrayPtr>(
435 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
436 reinterpret_cast<RegIdArrayPtr>(
437 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
438
439 _numSrcRegs = 0;
440 _numDestRegs = 0;
441
444 for (uint8_t i=0; i<_numSrcs; i++) {
446 }
447}
448
449Fault
451 trace::InstRecord* traceData) const
452{
453 vreg_t& tmp_d0 = *(vreg_t *)xc->getWritableRegOperand(this, 0);
454 auto Vd = tmp_d0.as<uint8_t>();
455 uint32_t vlenb = vlen >> 3;
456 const uint32_t elems_per_vreg = vlenb / elemSize;
457 size_t bit_cnt = elems_per_vreg;
458
459 // mask tails are always treated as agnostic: writting 1s
460 tmp_d0.set(0xff);
461
462 vreg_t tmp_s;
463 for (uint8_t i = 0; i < this->_numSrcRegs; i++) {
464 xc->getRegOperand(this, i, &tmp_s);
465 auto s = tmp_s.as<uint8_t>();
466 if (elems_per_vreg < 8) {
467 const uint32_t m = (1 << elems_per_vreg) - 1;
468 const uint32_t mask = m << (i * elems_per_vreg % 8);
469 // clr & ext bits
470 Vd[bit_cnt/8] ^= Vd[bit_cnt/8] & mask;
471 Vd[bit_cnt/8] |= s[bit_cnt/8] & mask;
472 bit_cnt += elems_per_vreg;
473 } else {
474 const uint32_t byte_offset = elems_per_vreg / 8;
475 memcpy(Vd + i * byte_offset, s + i * byte_offset, byte_offset);
476 }
477 }
478 if (traceData) {
479 traceData->setData(vecRegClass, &tmp_d0);
480 }
481 return NoFault;
482}
483
484std::string
486 const loader::SymbolTable *symtab) const
487{
488 std::stringstream ss;
489 ss << mnemonic << ' ' << registerName(destRegIdx(0));
490 for (uint8_t i = 0; i < this->_numSrcRegs; i++) {
491 ss << ", " << registerName(srcRegIdx(i));
492 }
493 unsigned vlenb = vlen >> 3;
494 ss << ", offset:" << vlenb / elemSize;
495 return ss.str();
496}
497
498Fault
500{
502 auto vcsr = xc->readMiscReg(MISCREG_VCSR);
503 xc->setMiscReg(MISCREG_VCSR, ((vcsr&~1)|*vxsat));
504 return NoFault;
505}
506
507std::string
509 const loader::SymbolTable *symtab) const
510{
511 std::stringstream ss;
512 ss << mnemonic << ' ' << "VXSAT" << ", " << (*vxsat ? "0x1" : "0x0");
513 return ss.str();
514}
515
517 uint32_t _microIdx, uint32_t _elen, uint32_t _vlen,
519 : VectorMicroInst("vlff_trimvl_v_micro", _machInst, SimdConfigOp,
520 _microVl, _microIdx, _elen, _vlen),
521 microops(_microops)
522{
524 reinterpret_cast<RegIdArrayPtr>(
525 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
526 nullptr
527 );
528
529 // Create data dependency with load micros
530 for (uint8_t i=0; i<microIdx; i++) {
531 setSrcRegIdx(_numSrcRegs++, vecRegClass[_machInst.vd + i]);
532 }
533
534 this->flags[IsControl] = true;
535 this->flags[IsIndirectControl] = true;
536 this->flags[IsInteger] = true;
537 this->flags[IsUncondControl] = true;
538}
539
540uint32_t
542{
543 uint32_t vl = 0;
544 for (uint8_t i=0; i<microIdx; i++) {
545 VleMicroInst& micro = static_cast<VleMicroInst&>(*microops[i]);
546 vl += micro.faultIdx;
547
548 if (micro.trimVl)
549 break;
550 }
551 return vl;
552}
553
554Fault
556{
557 auto tc = xc->tcBase();
558 bool set_dirty = false;
559 bool check_vill = false;
560 Fault update_fault = updateVPUStatus(xc, machInst, set_dirty, check_vill);
561 if (update_fault != NoFault) { return update_fault; }
562
563 PCState pc;
564 set(pc, xc->pcState());
565
566 uint32_t new_vl = calcVl();
567
568 tc->setMiscReg(MISCREG_VSTART, 0);
569
570 RegVal final_val = new_vl;
571 if (traceData) {
572 traceData->setData(miscRegClass, final_val);
573 }
574
575 pc.vl(new_vl);
576 pc.new_vconf(true);
577 xc->pcState(pc);
578
579 return NoFault;
580}
581
582std::unique_ptr<PCStateBase>
584{
585 PCStateBase *pc_ptr = tc->pcState().clone();
586
587 uint32_t new_vl = calcVl();
588
589 pc_ptr->as<PCState>().vl(new_vl);
590 return std::unique_ptr<PCStateBase>{pc_ptr};
591}
592
593std::string
595 const loader::SymbolTable *symtab) const
596{
597 std::stringstream ss;
598 ss << mnemonic << " vl";
599 return ss.str();
600}
601
603 const loader::SymbolTable *symtab) const
604{
605 std::stringstream ss;
606 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
607 '(' << registerName(srcRegIdx(0)) << ')' <<
608 ", " << registerName(srcRegIdx(1));
609 if (!machInst.vm)
610 ss << ", v0.t";
611 return ss.str();
612}
613
615 const loader::SymbolTable *symtab) const
616{
617 std::stringstream ss;
618 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
619 '(' << registerName(srcRegIdx(0)) << ')' <<
620 ", "<< registerName(srcRegIdx(1));
621 if (microIdx != 0 || machInst.vtype8.vma == 0 || machInst.vtype8.vta == 0)
622 ss << ", " << registerName(srcRegIdx(2));
623 if (!machInst.vm)
624 ss << ", v0.t";
625 return ss.str();
626}
627
629 uint32_t _micro_vl, uint32_t _dstReg,
630 uint32_t _numSrcs, uint32_t _microIdx,
631 uint32_t _numMicroops, uint32_t _field, uint32_t _elen,
632 uint32_t _vlen, uint32_t _sizeOfElement)
633 : VectorArithMicroInst("vlseg_deintrlv_micro", extMachInst,
634 SimdAddOp, 0, 0, _elen, _vlen)
635{
637 reinterpret_cast<RegIdArrayPtr>(
638 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
639 reinterpret_cast<RegIdArrayPtr>(
640 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
641
642 _numSrcRegs = 0;
643 _numDestRegs = 0;
644 numSrcs = _numSrcs;
645 numMicroops = _numMicroops;
646 field =_field;
647 sizeOfElement = _sizeOfElement;
648 microIdx = _microIdx;
649 micro_vl = _micro_vl;
650
653 for (uint32_t i=0; i < _numSrcs; i++) {
654 uint32_t index = VecMemInternalReg0 + i + (microIdx * _numSrcs);
656 }
657
658 if (!extMachInst.vtype8.vta
659 || (!extMachInst.vm && !extMachInst.vtype8.vma)) {
662 }
663 if (!extMachInst.vm) {
666 }
667}
668
669Fault
671{
672 vreg_t& tmp_d0 = *(vreg_t *)xc->getWritableRegOperand(this, 0);
673 auto Vd = tmp_d0.as<uint8_t>();
674 const uint32_t elems_per_vreg = micro_vl;
675 vreg_t tmp_s;
676 auto s = tmp_s.as<uint8_t>();
677 uint32_t elem = 0;
678 uint32_t index = field;
679
680 vreg_t tmp_v0;
681 uint8_t *v0;
682 if (!machInst.vm) {
683 xc->getRegOperand(this, vmsrcIdx, &tmp_v0);
684 v0 = tmp_v0.as<uint8_t>();
685 }
686
687 const size_t micro_vlmax = vlen / width_EEW(machInst.width);
688
689 if (!machInst.vtype8.vta || (!machInst.vm && !machInst.vtype8.vma)) {
690 RiscvISA::vreg_t old_vd;
691 xc->getRegOperand(this, oldDstIdx, &old_vd);
692 tmp_d0 = old_vd;
693 } else {
694 tmp_d0.set(0xff);
695 }
696
697 for (uint32_t i = 0; i < numSrcs; i++) {
698 xc->getRegOperand(this, i, &tmp_s);
699 s = tmp_s.as<uint8_t>();
700
701 while (index < (i + 1) * elems_per_vreg)
702 {
703 size_t ei = elem + micro_vlmax * microIdx;
704 if (machInst.vm || elem_mask(v0, ei)) {
705 memcpy(Vd + (elem * sizeOfElement),
706 s + ((index % elems_per_vreg) * sizeOfElement),
708 }
709 index += numSrcs;
710 elem++;
711 }
712 }
713
714 if (traceData) {
715 traceData->setData(vecRegClass, &tmp_d0);
716 }
717 return NoFault;
718}
719
720std::string
722 const
723{
724 std::stringstream ss;
725 ss << mnemonic << ' ' << registerName(destRegIdx(0));
726 for (uint8_t i = 0; i < this->_numSrcRegs; i++) {
727 ss << ", " << registerName(srcRegIdx(i));
728 }
729 ss << ", field: " << field;
730 return ss.str();
731}
732
734 const loader::SymbolTable *symtab) const
735{
736 std::stringstream ss;
737 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
738 '(' << registerName(srcRegIdx(0)) << ')' <<
739 ", " << registerName(srcRegIdx(1));
740 if (!machInst.vm)
741 ss << ", v0.t";
742 return ss.str();
743}
744
746 const loader::SymbolTable *symtab) const
747{
748 std::stringstream ss;
749 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
750 '(' << registerName(srcRegIdx(0)) << ')' <<
751 ", "<< registerName(srcRegIdx(1));
752 if (!machInst.vm)
753 ss << ", v0.t";
754 return ss.str();
755}
756
758 uint32_t _micro_vl, uint32_t _dstReg,
759 uint32_t _numSrcs, uint32_t _microIdx,
760 uint32_t _numMicroops, uint32_t _field, uint32_t _elen,
761 uint32_t _vlen, uint32_t _sizeOfElement)
762 : VectorArithMicroInst("vsseg_reintrlv_micro", extMachInst,
763 SimdAddOp, 0, 0, _elen, _vlen)
764{
766 reinterpret_cast<RegIdArrayPtr>(
767 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
768 reinterpret_cast<RegIdArrayPtr>(
769 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
770
771 _numSrcRegs = 0;
772 _numDestRegs = 0;
773 numSrcs = _numSrcs;
774 numMicroops = _numMicroops;
775 field =_field;
776 sizeOfElement = _sizeOfElement;
777 microIdx = _microIdx;
778 micro_vl = _micro_vl;
779
781 (_microIdx * numSrcs)]);
782
784 for (uint8_t i=0; i<_numSrcs; i++) {
786 (microIdx)]);
787 }
788}
789
790Fault
792 trace::InstRecord* traceData) const
793{
794 const uint32_t elems_per_vreg = micro_vl;
795 vreg_t& tmp_d0 = *(vreg_t *)xc->getWritableRegOperand(this, 0);
796 auto Vd = tmp_d0.as<uint8_t>();
797
798 vreg_t tmp_s;
799 auto s = tmp_s.as<uint8_t>();
800 xc->getRegOperand(this, 0, &tmp_s);
801 s = tmp_s.as<uint8_t>();
802
803 uint32_t indexVd = 0;
804 uint32_t srcReg = (field * elems_per_vreg) % numSrcs;
805 uint32_t indexs = (field * elems_per_vreg) / numSrcs;
806
807 while (indexVd < elems_per_vreg) {
808 xc->getRegOperand(this, srcReg, &tmp_s);
809 s = tmp_s.as<uint8_t>();
810
811 memcpy(Vd + (indexVd * sizeOfElement),
812 s + (indexs * sizeOfElement),
814
815 indexVd++;
816 srcReg++;
817 if (srcReg >= numSrcs) {
818 srcReg = 0;
819 indexs++;
820 }
821 }
822
823 if (traceData) {
824 traceData->setData(vecRegClass, &tmp_d0);
825 }
826 return NoFault;
827}
828
829std::string
831 const loader::SymbolTable *symtab) const
832{
833 std::stringstream ss;
834 ss << mnemonic << ' ' << registerName(destRegIdx(0));
835 for (uint8_t i = 0; i < this->_numSrcRegs; i++) {
836 ss << ", " << registerName(srcRegIdx(i));
837 }
838 ss << ", field: " << field;
839 return ss.str();
840}
841
842VCpyVsMicroInst::VCpyVsMicroInst(ExtMachInst _machInst, uint32_t _microIdx,
843 uint8_t _vsRegIdx, uint32_t _elen,
844 uint32_t _vlen)
845 : VectorArithMicroInst("vcpyvs_v_micro", _machInst, SimdMiscOp, 0,
846 _microIdx, _elen, _vlen)
847{
849 reinterpret_cast<RegIdArrayPtr>(
850 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
851 reinterpret_cast<RegIdArrayPtr>(
852 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
853
854 _numSrcRegs = 0;
855 _numDestRegs = 0;
858 setSrcRegIdx(_numSrcRegs++, vecRegClass[_vsRegIdx + _microIdx]);
859}
860
861Fault
863{
864 bool set_dirty = true;
865 bool check_vill = false;
866 Fault update_fault = updateVPUStatus(xc, machInst, set_dirty, check_vill);
867 if (update_fault != NoFault) { return update_fault; }
868
869 // copy vector source reg to vtmp
870 vreg_t& vtmp = *(vreg_t *)xc->getWritableRegOperand(this, 0);
871 vreg_t vs;
872 xc->getRegOperand(this, 0, &vs);
873 vtmp = vs;
874
875 if (traceData) {
876 traceData->setData(vecRegClass, &vtmp);
877 }
878
879 return NoFault;
880}
881
882std::string
884 const loader::SymbolTable *symtab) const
885{
886 std::stringstream ss;
887 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", "
888 << registerName(srcRegIdx(0));
889 return ss.str();
890}
891
892VPinVdMicroInst::VPinVdMicroInst(ExtMachInst _machInst, uint32_t _microIdx,
893 uint32_t _numVdPins, uint32_t _elen,
894 uint32_t _vlen, bool _hasVdOffset,
895 bool _copyVs, uint32_t _vsIdx)
896 : VectorArithMicroInst("vpinvd_v_micro", _machInst, SimdMiscOp, 0,
897 _microIdx, _elen, _vlen)
898 , hasVdOffset(_hasVdOffset)
899 , copyVs(_copyVs)
900{
902 reinterpret_cast<RegIdArrayPtr>(
903 &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
904 reinterpret_cast<RegIdArrayPtr>(
905 &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
906
907 _numSrcRegs = 0;
908 _numDestRegs = 0;
909 setDestRegIdx(_numDestRegs++, vecRegClass[_machInst.vd + _microIdx]);
911 if (!_machInst.vtype8.vta || (!_machInst.vm && !_machInst.vtype8.vma)
912 || hasVdOffset) {
913 setSrcRegIdx(_numSrcRegs++, vecRegClass[_machInst.vd + _microIdx]);
914 }
915 RegId Vd = destRegIdx(0);
916 Vd.setNumPinnedWrites(_numVdPins);
917 setDestRegIdx(0, Vd);
918
919 if (copyVs) {
921 }
922}
923
924Fault
926{
927 bool set_dirty = true;
928 bool check_vill = false;
929 Fault update_fault = updateVPUStatus(xc, machInst, set_dirty, check_vill);
930 if (update_fault != NoFault) { return update_fault; }
931
932 // tail/mask policy: both undisturbed if one is, 1s if none
933 vreg_t& vd = *(vreg_t *)xc->getWritableRegOperand(this, 0);
934 if (!machInst.vtype8.vta || (!machInst.vm && !machInst.vtype8.vma)
935 || hasVdOffset) {
936 vreg_t old_vd;
937 xc->getRegOperand(this, 0, &old_vd);
938 vd = old_vd;
939 } else {
940 vd.set(0xff);
941 }
942
943 if (traceData) {
944 traceData->setData(vecRegClass, xc->getWritableRegOperand(this, 0));
945 }
946
947 if (copyVs) {
948 vreg_t& vs = *(vreg_t *)xc->getWritableRegOperand(this, 1);
949 vreg_t old_vs;
950 xc->getRegOperand(this, 1, &old_vs);
951 vs = old_vs;
952 }
953
954 return NoFault;
955}
956
957std::string
959 const loader::SymbolTable *symtab) const
960{
961 std::stringstream ss;
962 ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", ";
963
964 if (!machInst.vtype8.vta || (!machInst.vm && !machInst.vtype8.vma)
965 || hasVdOffset) {
967 } else {
968 ss << "~0";
969 }
970
971 return ss.str();
972}
973
974} // namespace RiscvISA
975} // 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:842
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:862
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:883
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:485
VMaskMergeMicroInst(ExtMachInst extMachInst, uint8_t _dstReg, uint8_t _numSrcs, uint32_t _elen, uint32_t _vlen, size_t _elemSize)
Definition vector.cc:426
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:450
RegId srcRegIdxArr[NumVecInternalRegs]
Definition vector.hh:629
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:407
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:417
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:925
VPinVdMicroInst(ExtMachInst _machInst, uint32_t _microIdx, uint32_t _numVdPins, uint32_t _elen, uint32_t _vlen, bool _hasVdOffset=false, bool _copyVs=false, uint32_t _vsIdx=0)
Definition vector.cc:892
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:958
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:223
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:178
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:205
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
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:300
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:314
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:555
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:594
VlFFTrimVlMicroOp(ExtMachInst _machInst, uint32_t _microVl, uint32_t _microIdx, uint32_t _elen, uint32_t _vlen, std::vector< StaticInstPtr > &_microops)
Definition vector.cc:516
std::unique_ptr< PCStateBase > branchTarget(ThreadContext *) const override
Return the target address for an indirect branch (jump).
Definition vector.cc:583
std::vector< StaticInstPtr > & microops
Definition vector.hh:664
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:358
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:369
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:670
RegId srcRegIdxArr[NumVecInternalRegs]
Definition vector.hh:716
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:721
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:628
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:602
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:614
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:272
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:231
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:262
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:219
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:330
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:343
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:383
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:394
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:757
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:830
RegId srcRegIdxArr[NumVecInternalRegs]
Definition vector.hh:773
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:791
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:733
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:745
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:291
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:252
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:281
std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override
Internal function to generate disassembly string.
Definition vector.cc:241
Fault execute(ExecContext *, trace::InstRecord *) const override
Definition vector.cc:499
std::string generateDisassembly(Addr, const loader::SymbolTable *) const override
Internal function to generate disassembly string.
Definition vector.cc:508
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< 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
Fault updateVPUStatus(ExecContext *xc, ExtMachInst machInst, bool set_dirty, bool check_vill)
Definition isa.cc:1385
int elem_mask(const T *vs, const int index)
Definition utility.hh:307
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
Bitfield< 9, 5 > vs
Bitfield< 4 > pc
uint64_t width_EEW(uint64_t width)
Definition utility.hh:289
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:140
constexpr decltype(nullptr) NoFault
Definition types.hh:253
@ VecRegClass
Vector Register.
Definition reg_class.hh:64

Generated on Sat Oct 18 2025 08:06:41 for gem5 by doxygen 1.14.0