gem5 v23.0.0.1
Loading...
Searching...
No Matches
inst_util.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015-2021 Advanced Micro Devices, Inc.
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 met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef __ARCH_GCN3_INSTS_INST_UTIL_HH__
33#define __ARCH_GCN3_INSTS_INST_UTIL_HH__
34
35#include <cmath>
36
38
39namespace gem5
40{
41
42// values for SDWA select operations
43enum SDWASelVals : int
44{
45 SDWA_BYTE_0 = 0, /* select data[7:0] */
46 SDWA_BYTE_1 = 1, /* select data[15:8] */
47 SDWA_BYTE_2 = 2, /* select data[23:16] */
48 SDWA_BYTE_3 = 3, /* select data[31:24] */
49 SDWA_WORD_0 = 4, /* select data[15:0] */
50 SDWA_WORD_1 = 5, /* select data[31:16] */
51 SDWA_DWORD = 6 /* select data[31:0] */
52};
53
54// values for format of destination bits for SDWA operations
55enum SDWADstVals : int
56{
57 SDWA_UNUSED_PAD = 0, /* Pad all unused bits with 0 */
58 SDWA_UNUSED_SEXT = 1, /* Sign-extend upper bits; pad lower bits w/ 0 */
59 SDWA_UNUSED_PRESERVE = 2 /* select data[31:0] */
60};
61
62// values for DPP operations
63enum SqDPPVals : int
64{
80 SQ_DPP_ROW_BCAST31 = 0x143
81};
82static const int ROW_SIZE = 16; /* 16 registers per row */
83static const int NUM_BANKS = 4; /* 64 registers, 16/bank */
84
85namespace Gcn3ISA
86{
87 template<typename T>
88 inline T
90 {
91 T wqm = 0;
92 T mask = 0xF;
93
94 for (T bits = val; mask != 0; mask <<= 4)
95 if ((bits & mask) != 0)
96 wqm |= mask;
97
98 return wqm;
99 }
100
101 template<typename T>
102 inline T
104 {
105 T qmsk = 0;
106 T mask = 0xF;
107 T qbit = 0x1;
108
109 for (T bits = val; mask != 0; mask <<= 4, qbit <<= 1) {
110 if (bits & mask) {
111 qmsk |= qbit;
112 }
113 }
114
115 return qmsk;
116 }
117
118 template<typename T>
119 inline ScalarRegI32
121 {
122 ScalarRegI32 num_zeros
123 = std::numeric_limits<T>::digits - popCount(val);
124
125 return num_zeros;
126 }
127
128 template<typename T>
129 inline ScalarRegI32
131 {
132 if (val == ~T(0)) {
133 return -1;
134 }
135
136 return findLsbSet(~val);
137 }
138
139 template<typename T>
140 inline ScalarRegI32
142 {
143 if (!val) {
144 return -1;
145 }
146
147 return findLsbSet(val);
148 }
149
150 template<typename T>
151 inline ScalarRegI32
153 {
154 if (!val) {
155 return -1;
156 }
157
158 return findMsbSet(val);
159 }
160
161 template<typename T>
162 inline ScalarRegI32
164 {
165 if (!val) {
166 return -1;
167 }
168
169 return std::numeric_limits<T>::digits - 1 - findMsbSet(val);
170 }
171
172 inline ScalarRegI32
174 {
175 bool found(false);
176 bool sign_bit = (val & 0x80000000) != 0;
177 ScalarRegU32 tmp_val(0);
178 int count(0);
179
180 if (!val || val == -1) {
181 return -1;
182 }
183
184 for (int i = 0; i < std::numeric_limits<ScalarRegU32>::digits; ++i) {
185 tmp_val = val & (0x80000000 >> i);
186
187 if (!sign_bit) {
188 if (tmp_val) {
189 found = true;
190 break;
191 }
192 } else {
193 if (!tmp_val) {
194 found = true;
195 break;
196 }
197 }
198 ++count;
199 }
200
201 if (found) {
202 return count;
203 } else {
204 return -1;
205 }
206 }
207
208 inline ScalarRegI32
210 {
211 bool found(false);
212 bool sign_bit = (val & 0x8000000000000000ULL) != 0;
213 ScalarRegU64 tmp_val(0);
214 int count(0);
215
216 if (!val || val == -1) {
217 return -1;
218 }
219
220 for (int i = 0; i < std::numeric_limits<ScalarRegU64>::digits; ++i) {
221 tmp_val = val & (0x8000000000000000ULL >> i);
222
223 if (!sign_bit) {
224 if (tmp_val) {
225 found = true;
226 break;
227 }
228 } else {
229 if (!tmp_val) {
230 found = true;
231 break;
232 }
233 }
234 ++count;
235 }
236
237 if (found) {
238 return count;
239 } else {
240 return -1;
241 }
242 }
243
244 template<typename T>
245 inline T
246 median(T val_0, T val_1, T val_2)
247 {
248 if (std::is_floating_point_v<T>) {
249 return std::fmax(std::fmin(val_0, val_1),
250 std::fmin(std::fmax(val_0, val_1), val_2));
251 } else {
252 return std::max(std::min(val_0, val_1),
253 std::min(std::max(val_0, val_1), val_2));
254 }
255 }
256
257 template <typename T>
259 {
260 T int_part = 0;
261 T nearest_round = std::floor(val + 0.5);
262 if ((int)std::floor(val) % 2 == 0
263 && std::modf(std::abs(val), &int_part) == 0.5) {
264 nearest_round = nearest_round - 1;
265 }
266
267 return nearest_round;
268 }
269
270 inline VecElemU32
272 VecElemU64 val_2)
273 {
274 __uint128_t u0 = (__uint128_t)val_0;
275 __uint128_t u1 = (__uint128_t)val_1;
276 __uint128_t u2 = (__uint128_t)val_2;
277 __uint128_t result = u0 * u1 + u2;
278
279 dst = (VecElemU64)result;
280
281 return (VecElemU32)(result >> 64) ? 1 : 0;
282 }
283
284 inline VecElemU32
286 VecElemI64 val_2)
287 {
288 __int128_t u0 = (__int128_t)val_0;
289 __int128_t u1 = (__int128_t)val_1;
290 __int128_t u2 = (__int128_t)val_2;
291 __int128_t result = u0 * u1 + u2;
292
293 dst = (VecElemI64)result;
294
295 return (VecElemU32)(result >> 64) ? 1 : 0;
296 }
297
318 int dppInstImpl(SqDPPVals dppCtrl, int currLane, int rowNum,
319 int rowOffset, bool & outOfBounds)
320 {
321 // local variables
322 // newLane will be the same as the input lane unless swizzling happens
323 int newLane = currLane;
324 // for shift/rotate permutations; positive values are LEFT rotates
325 int count = 1;
326 int localRowOffset = rowOffset;
327 int localRowNum = rowNum;
328
329 if (dppCtrl <= SQ_DPP_QUAD_PERM_MAX) { // DPP_QUAD_PERM{00:FF}
330 int quadBase = (currLane & ~(3));
331 int quadPix = (currLane & 3);
332 quadPix = ((dppCtrl >> (2 * quadPix)) & 3);
333 newLane = (quadBase | quadPix);
334 } else if (dppCtrl == SQ_DPP_RESERVED) {
335 panic("ERROR: instruction using reserved DPP_CTRL value\n");
336 } else if ((dppCtrl >= SQ_DPP_ROW_SL1) &&
337 (dppCtrl <= SQ_DPP_ROW_SL15)) { // DPP_ROW_SL{1:15}
338 count -= (dppCtrl - SQ_DPP_ROW_SL1 + 1);
339 if ((localRowOffset + count >= 0) &&
340 (localRowOffset + count < ROW_SIZE)) {
341 localRowOffset += count;
342 newLane = (rowNum | localRowOffset);
343 } else {
344 outOfBounds = true;
345 }
346 } else if ((dppCtrl >= SQ_DPP_ROW_SR1) &&
347 (dppCtrl <= SQ_DPP_ROW_SR15)) { // DPP_ROW_SR{1:15}
348 count -= (dppCtrl - SQ_DPP_ROW_SR1 + 1);
349 if ((localRowOffset + count >= 0) &&
350 (localRowOffset + count < ROW_SIZE)) {
351 localRowOffset += count;
352 newLane = (rowNum | localRowOffset);
353 } else {
354 outOfBounds = true;
355 }
356 } else if ((dppCtrl >= SQ_DPP_ROW_RR1) &&
357 (dppCtrl <= SQ_DPP_ROW_RR15)) { // DPP_ROW_RR{1:15}
358 count -= (dppCtrl - SQ_DPP_ROW_RR1 + 1);
359 localRowOffset = (localRowOffset + count + ROW_SIZE) % ROW_SIZE;
360 newLane = (rowNum | localRowOffset);
361 } else if (dppCtrl == SQ_DPP_WF_SL1) { // DPP_WF_SL1
362 count = 1;
363 if ((currLane >= 0) && (currLane < NumVecElemPerVecReg)) {
364 newLane += count;
365 } else {
366 outOfBounds = true;
367 }
368 } else if (dppCtrl == SQ_DPP_WF_RL1) { // DPP_WF_RL1
369 count = 1;
370 newLane = (currLane + count + NumVecElemPerVecReg) %
372 } else if (dppCtrl == SQ_DPP_WF_SR1) { // DPP_WF_SR1
373 count = -1;
374 int currVal = (currLane + count);
375 if ((currVal >= 0) && (currVal < NumVecElemPerVecReg)) {
376 newLane += count;
377 } else {
378 outOfBounds = true;
379 }
380 } else if (dppCtrl == SQ_DPP_WF_RR1) { // DPP_WF_RR1
381 count = -1;
382 newLane = (currLane + count + NumVecElemPerVecReg) %
384 } else if (dppCtrl == SQ_DPP_ROW_MIRROR) { // DPP_ROW_MIRROR
385 localRowOffset = (15 - localRowOffset);
386 newLane = (rowNum | localRowOffset);
387 } else if (dppCtrl == SQ_DPP_ROW_HALF_MIRROR) { // DPP_ROW_HALF_MIRROR
388 localRowNum = (currLane & -0x7);
389 localRowOffset = (currLane & 0x7);
390 localRowOffset = (7 - localRowNum);
391 newLane = (localRowNum | localRowOffset);
392 } else if (dppCtrl == SQ_DPP_ROW_BCAST15) { // DPP_ROW_BCAST15
393 count = 15;
394 if (currLane > count) {
395 newLane = (currLane & ~count) - 1;
396 }
397 } else if (dppCtrl == SQ_DPP_ROW_BCAST31) { // DPP_ROW_BCAST31
398 count = 31;
399 if (currLane > count) {
400 newLane = (currLane & ~count) - 1;
401 }
402 } else {
403 panic("Unimplemented DPP control operation: %d\n", dppCtrl);
404 }
405
406 return newLane;
407 }
408
414 template<typename T>
415 void processDPP(GPUDynInstPtr gpuDynInst, InFmt_VOP_DPP dppInst,
416 T & src0)
417 {
418 // local variables
419 SqDPPVals dppCtrl = (SqDPPVals)dppInst.DPP_CTRL;
420 int boundCtrl = dppInst.BOUND_CTRL;
421 int bankMask = dppInst.BANK_MASK;
422 int rowMask = dppInst.ROW_MASK;
423 // row, bank info to be calculated per lane
424 int rowNum = 0, bankNum = 0, rowOffset = 0;
425 // outLane will be the same as the input lane unless swizzling happens
426 int outLane = 0;
427 bool laneDisabled = false;
428 // flags used for determining if a lane should be written to/reset/etc.
429 bool outOfBounds = false, zeroSrc = false;
430 long long threadValid = 0;
431
438 if (dppInst.SRC0_NEG) {
439 src0.negModifier();
440 }
441
442 if (dppInst.SRC0_ABS) {
443 src0.absModifier();
444 }
445
446 // iterate over all register lanes, performing steps 2-4
447 for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
448 threadValid = (0x1LL << lane);
454 rowNum = (lane / ROW_SIZE);
455 rowOffset = (lane % ROW_SIZE);
456 bankNum = (rowOffset / NUM_BANKS);
457
458 if (((rowMask & (0x1 << rowNum)) == 0) /* row mask */ ||
459 ((bankMask & (0x1 << bankNum)) == 0) /* bank mask */) {
460 laneDisabled = true;
461 continue;
462 }
463
480 if (!laneDisabled) {
481 outLane = dppInstImpl(dppCtrl, lane, rowNum, rowOffset,
482 outOfBounds);
483 }
484
490 if (laneDisabled) {
491 threadValid = 0;
492 } else if (outOfBounds) {
493 if (boundCtrl == 1) {
494 zeroSrc = true;
495 } else {
496 threadValid = 0;
497 }
498 } else if (!gpuDynInst->exec_mask[lane]) {
499 if (boundCtrl == 1) {
500 zeroSrc = true;
501 } else {
502 threadValid = 0;
503 }
504 }
505
506 if (threadValid != 0 && !outOfBounds && !zeroSrc) {
507 assert(!laneDisabled);
508 src0[outLane] = src0[lane];
509 } else if (zeroSrc) {
510 src0[lane] = 0;
511 }
512
513 // reset for next iteration
514 laneDisabled = false;
515 }
516 }
517
523 template<typename T>
524 void processDPP(GPUDynInstPtr gpuDynInst, InFmt_VOP_DPP dppInst,
525 T & src0, T & src1)
526 {
533 if (dppInst.SRC1_NEG) {
534 src1.negModifier();
535 }
536
537 if (dppInst.SRC1_ABS) {
538 src1.absModifier();
539 }
540
541 // Since only difference for VOP1 and VOP2/VOPC instructions is SRC1,
542 // which is only used for negation/absolute value, call other version
543 // to do everything else.
544 processDPP(gpuDynInst, dppInst, src0);
545 }
546
553 template<typename T>
554 T sdwaInstSrcImpl_helper(T currOperVal, const T origOperVal,
555 const SDWASelVals sel, const bool signExt)
556 {
557 // local variables
558 int low_bit = 0, high_bit = 0;
559 bool signExt_local = signExt;
560 T retVal = 0;
561
562 // if we're preserving all of the bits, then we can immediately return
563 if (sel == SDWA_DWORD) {
564 return currOperVal;
565 }
566
567 if (sel < SDWA_WORD_0) { // we are selecting 1 byte
568 /*
569 Process byte 0 first. This code eiter selects the original bits
570 of byte 0, or makes the bits of the selected byte be byte 0 (and
571 next either sign extends or zero's out upper bits).
572 */
573 low_bit = (sel * Gcn3ISA::BITS_PER_BYTE);
574 high_bit = low_bit + Gcn3ISA::MSB_PER_BYTE;
575 retVal = bits(currOperVal, high_bit, low_bit);
576
577 // make sure update propagated, since used next
579 bits(origOperVal, high_bit),
580 "ERROR: SDWA byte update not propagated: retVal: %d, "
581 "orig: %d\n", bits(retVal, Gcn3ISA::MSB_PER_BYTE),
582 bits(origOperVal, high_bit));
583 // sign extended value depends on upper-most bit of the new byte 0
584 signExt_local = (signExt &&
585 (bits(retVal, Gcn3ISA::MSB_PER_BYTE, 0) & 0x80));
586
587 // process all other bytes -- if sign extending, make them 1, else
588 // all 0's so leave as is
589 if (signExt_local) {
590 retVal = (uint32_t)sext<Gcn3ISA::MSB_PER_BYTE>(retVal);
591 }
592 } else if (sel < SDWA_DWORD) { // we are selecting 1 word
593 /*
594 Process word 0 first. This code eiter selects the original bits
595 of word 0, or makes the bits of the selected word be word 0 (and
596 next either sign extends or zero's out upper bits).
597 */
598 low_bit = (sel & 1) * Gcn3ISA::BITS_PER_WORD;
599 high_bit = low_bit + Gcn3ISA::MSB_PER_WORD;
600 retVal = bits(currOperVal, high_bit, low_bit);
601
602 // make sure update propagated, since used next
604 bits(origOperVal, high_bit),
605 "ERROR: SDWA word update not propagated: retVal: %d, "
606 "orig: %d\n",
608 bits(origOperVal, high_bit));
609 // sign extended value depends on upper-most bit of the new word 0
610 signExt_local = (signExt &&
611 (bits(retVal, Gcn3ISA::MSB_PER_WORD, 0) &
612 0x8000));
613
614 // process other word -- if sign extending, make them 1, else all
615 // 0's so leave as is
616 if (signExt_local) {
617 retVal = (uint32_t)sext<Gcn3ISA::MSB_PER_WORD>(retVal);
618 }
619 } else {
620 assert(sel != SDWA_DWORD); // should have returned earlier
621 panic("Unimplemented SDWA select operation: %d\n", sel);
622 }
623
624 return retVal;
625 }
626
627
646 template<typename T>
647 void sdwaInstSrcImpl(T & currOper, T & origCurrOper,
648 const SDWASelVals sel, const bool signExt)
649 {
650 // iterate over all lanes, setting appropriate, selected value
651 for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
652 currOper[lane] = sdwaInstSrcImpl_helper(currOper[lane],
653 origCurrOper[lane], sel,
654 signExt);
655 }
656 }
657
658
665 template<typename T>
666 T sdwaInstDstImpl_helper(T currDstVal, const T origDstVal,
667 const bool clamp, const SDWASelVals sel,
668 const SDWADstVals unusedBits_format)
669 {
670 // local variables
671 int low_bit = 0, high_bit = 0;
672 bool signExt = (unusedBits_format == SDWA_UNUSED_SEXT);
673 //bool pad = (unusedBits_format == SDWA_UNUSED_PAD);
674 bool preserve = (unusedBits_format == SDWA_UNUSED_PRESERVE);
675 T retVal = 0, origBits_thisByte = 0, currBits_thisByte = 0,
676 origBits_thisWord = 0, currBits_thisWord = 0, newBits = 0;
677
678 // if we're preserving all of the bits, then we can immediately return
679 if (unusedBits_format == SDWA_UNUSED_PRESERVE) {
680 assert(sel == SDWA_DWORD);
681 return currDstVal;
682 } else if (sel == SDWA_DWORD) {
683 // NOTE: users may set the unused bits variable to anything in this
684 // scenario, because it will be ignored
685 return currDstVal;
686 }
687
688 if (sel < SDWA_WORD_0) { // we are selecting 1 byte
689 // if we sign extended depends on upper-most bit of byte 0
690 signExt = (signExt &&
691 (bits(currDstVal, Gcn3ISA::MSB_PER_WORD, 0) & 0x80));
692
693 for (int byte = 0; byte < 4; ++byte) {
694 low_bit = byte * Gcn3ISA::BITS_PER_BYTE;
695 high_bit = low_bit + Gcn3ISA::MSB_PER_BYTE;
696 /*
697 Options:
698 1. byte == sel: we are keeping all bits in this byte
699 2. preserve is set: keep this byte as is because the
700 output preserve flag is set
701 3. byte > sel && signExt: we're sign extending and
702 this byte is one of the bytes we need to sign extend
703 */
704 origBits_thisByte = bits(origDstVal, high_bit, low_bit);
705 currBits_thisByte = bits(currDstVal, high_bit, low_bit);
706 newBits = ((byte == sel) ? origBits_thisByte :
707 ((preserve) ? currBits_thisByte :
708 (((byte > sel) && signExt) ? 0xff : 0)));
709 retVal = insertBits(retVal, high_bit, low_bit, newBits);
710 }
711 } else if (sel < SDWA_DWORD) { // we are selecting 1 word
712 low_bit = 0;
713 high_bit = low_bit + Gcn3ISA::MSB_PER_WORD;
714 // if we sign extended depends on upper-most bit of word 0
715 signExt = (signExt &&
716 (bits(currDstVal, high_bit, low_bit) & 0x8000));
717
718 for (int word = 0; word < 2; ++word) {
719 low_bit = word * Gcn3ISA::BITS_PER_WORD;
720 high_bit = low_bit + Gcn3ISA::MSB_PER_WORD;
721 /*
722 Options:
723 1. word == sel & 1: we are keeping all bits in this word
724 2. preserve is set: keep this word as is because the
725 output preserve flag is set
726 3. word > (sel & 1) && signExt: we're sign extending and
727 this word is one of the words we need to sign extend
728 */
729 origBits_thisWord = bits(origDstVal, high_bit, low_bit);
730 currBits_thisWord = bits(currDstVal, high_bit, low_bit);
731 newBits = ((word == (sel & 0x1)) ? origBits_thisWord :
732 ((preserve) ? currBits_thisWord :
733 (((word > (sel & 0x1)) && signExt) ? 0xffff : 0)));
734 retVal = insertBits(retVal, high_bit, low_bit, newBits);
735 }
736 } else {
737 assert(sel != SDWA_DWORD); // should have returned earlier
738 panic("Unimplemented SDWA select operation: %d\n", sel);
739 }
740
741 return retVal;
742 }
743
744
766 template<typename T>
767 void sdwaInstDstImpl(T & dstOper, T & origDstOper, const bool clamp,
768 const SDWASelVals sel,
769 const SDWADstVals unusedBits_format)
770 {
771 // iterate over all lanes, setting appropriate, selected value
772 for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) {
773 dstOper[lane] = sdwaInstDstImpl_helper(dstOper[lane],
774 origDstOper[lane], clamp,
775 sel, unusedBits_format);
776 }
777 }
778
779
787 template<typename T>
788 void processSDWA_src_helper(T & currSrc, T & origCurrSrc,
789 const SDWASelVals src_sel,
790 const bool src_signExt, const bool src_abs,
791 const bool src_neg)
792 {
800 if (src_neg) {
801 currSrc.negModifier();
802 }
803
804 if (src_abs) {
805 currSrc.absModifier();
806 }
807
811 sdwaInstSrcImpl(currSrc, origCurrSrc, src_sel, src_signExt);
812 }
813
814
822 template<typename T>
823 void processSDWA_src(InFmt_VOP_SDWA sdwaInst, T & src0, T & origSrc0)
824 {
825 // local variables
826 const SDWASelVals src0_sel = (SDWASelVals)sdwaInst.SRC0_SEL;
827 const bool src0_signExt = sdwaInst.SRC0_SEXT;
828 const bool src0_neg = sdwaInst.SRC0_NEG;
829 const bool src0_abs = sdwaInst.SRC0_ABS;
830
831 // NOTE: difference between VOP1 and VOP2/VOPC is that there is no src1
832 // operand. So ensure that SRC1 fields are not set, then call helper
833 // function only on src0.
834 assert(!sdwaInst.SRC1_SEXT);
835 assert(!sdwaInst.SRC1_NEG);
836 assert(!sdwaInst.SRC1_ABS);
837
838 processSDWA_src_helper(src0, origSrc0, src0_sel, src0_signExt,
839 src0_abs, src0_neg);
840 }
841
842
850 template<typename T>
851 void processSDWA_src(InFmt_VOP_SDWA sdwaInst, T & src0, T & origSrc0,
852 T & src1, T & origSrc1)
853 {
854 // local variables
855 const SDWASelVals src0_sel = (SDWASelVals)sdwaInst.SRC0_SEL;
856 const bool src0_signExt = sdwaInst.SRC0_SEXT;
857 const bool src0_neg = sdwaInst.SRC0_NEG;
858 const bool src0_abs = sdwaInst.SRC0_ABS;
859 const SDWASelVals src1_sel = (SDWASelVals)sdwaInst.SRC1_SEL;
860 const bool src1_signExt = sdwaInst.SRC1_SEXT;
861 const bool src1_neg = sdwaInst.SRC1_NEG;
862 const bool src1_abs = sdwaInst.SRC1_ABS;
863
864 processSDWA_src_helper(src0, origSrc0, src0_sel, src0_signExt,
865 src0_abs, src0_neg);
866 processSDWA_src_helper(src1, origSrc1, src1_sel, src1_signExt,
867 src1_abs, src1_neg);
868 }
869
870
878 template<typename T>
879 void processSDWA_dst(InFmt_VOP_SDWA sdwaInst, T & dst, T & origDst)
880 {
881 // local variables
882 const SDWADstVals dst_unusedBits_format =
883 (SDWADstVals)sdwaInst.DST_UNUSED;
884 const SDWASelVals dst_sel = (SDWASelVals)sdwaInst.DST_SEL;
885 const bool clamp = sdwaInst.CLAMP;
886
891 sdwaInstDstImpl(dst, origDst, clamp, dst_sel, dst_unusedBits_format);
892 }
893} // namespace Gcn3ISA
894} // namespace gem5
895
896#endif // __ARCH_GCN3_INSTS_INST_UTIL_HH__
constexpr int findMsbSet(uint64_t val)
Returns the bit position of the MSB that is set in the input.
Definition bitfield.hh:276
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:76
constexpr int popCount(uint64_t val)
Returns the number of set ones in the provided value.
Definition bitfield.hh:350
constexpr T insertBits(T val, unsigned first, unsigned last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
Definition bitfield.hh:182
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
Definition bitfield.hh:312
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > i
Definition misc_types.hh:67
constexpr unsigned NumVecElemPerVecReg
Definition vec.hh:61
T sdwaInstDstImpl_helper(T currDstVal, const T origDstVal, const bool clamp, const SDWASelVals sel, const SDWADstVals unusedBits_format)
sdwaInstDstImpl_helper contains the per-lane code for selecting the appropriate bytes/words of the la...
Definition inst_util.hh:666
const int BITS_PER_BYTE
const int BITS_PER_WORD
ScalarRegI32 countZeroBits(T val)
Definition inst_util.hh:120
uint64_t VecElemU64
VecElemU32 muladd(VecElemU64 &dst, VecElemU32 val_0, VecElemU32 val_1, VecElemU64 val_2)
Definition inst_util.hh:271
ScalarRegI32 countZeroBitsMsb(T val)
Definition inst_util.hh:163
void processSDWA_src_helper(T &currSrc, T &origCurrSrc, const SDWASelVals src_sel, const bool src_signExt, const bool src_abs, const bool src_neg)
processSDWA_srcHelper is a helper function for implementing sub d-word addressing instructions for th...
Definition inst_util.hh:788
uint32_t ScalarRegU32
T quadMask(T val)
Definition inst_util.hh:103
void sdwaInstSrcImpl(T &currOper, T &origCurrOper, const SDWASelVals sel, const bool signExt)
sdwaInstSrcImpl is a helper function that selects the appropriate bits/bytes for each lane of the inp...
Definition inst_util.hh:647
T median(T val_0, T val_1, T val_2)
Definition inst_util.hh:246
ScalarRegI32 firstOppositeSignBit(ScalarRegI32 val)
Definition inst_util.hh:173
uint64_t ScalarRegU64
T wholeQuadMode(T val)
Definition inst_util.hh:89
T sdwaInstSrcImpl_helper(T currOperVal, const T origOperVal, const SDWASelVals sel, const bool signExt)
sdwaInstSrcImpl_helper contains the per-lane code for selecting the appropriate bytes/words of the la...
Definition inst_util.hh:554
void processSDWA_src(InFmt_VOP_SDWA sdwaInst, T &src0, T &origSrc0)
processSDWA_src is a helper function for implementing sub d-word addressing instructions for the src ...
Definition inst_util.hh:823
void sdwaInstDstImpl(T &dstOper, T &origDstOper, const bool clamp, const SDWASelVals sel, const SDWADstVals unusedBits_format)
sdwaInstDestImpl is a helper function that selects the appropriate bits/bytes for the inputted dest o...
Definition inst_util.hh:767
void processDPP(GPUDynInstPtr gpuDynInst, InFmt_VOP_DPP dppInst, T &src0)
processDPP is a helper function for implementing Data Parallel Primitive instructions.
Definition inst_util.hh:415
int dppInstImpl(SqDPPVals dppCtrl, int currLane, int rowNum, int rowOffset, bool &outOfBounds)
dppInstImpl is a helper function that performs the inputted operation on the inputted vector register...
Definition inst_util.hh:318
uint32_t VecElemU32
ScalarRegI32 findFirstZero(T val)
Definition inst_util.hh:130
const int MSB_PER_WORD
void processSDWA_dst(InFmt_VOP_SDWA sdwaInst, T &dst, T &origDst)
processSDWA_dst is a helper function for implementing sub d-word addressing instructions for the dst ...
Definition inst_util.hh:879
T roundNearestEven(T val)
Definition inst_util.hh:258
const int MSB_PER_BYTE
ScalarRegI32 findFirstOneMsb(T val)
Definition inst_util.hh:152
ScalarRegI32 findFirstOne(T val)
Definition inst_util.hh:141
Bitfield< 63 > val
Definition misc.hh:776
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
static const int NUM_BANKS
Definition inst_util.hh:83
std::shared_ptr< GPUDynInst > GPUDynInstPtr
Definition misc.hh:49
static const int ROW_SIZE
Definition inst_util.hh:82
SDWADstVals
Definition inst_util.hh:56
@ SDWA_UNUSED_PRESERVE
Definition inst_util.hh:59
@ SDWA_UNUSED_PAD
Definition inst_util.hh:57
@ SDWA_UNUSED_SEXT
Definition inst_util.hh:58
SDWASelVals
Definition inst_util.hh:44
@ SDWA_BYTE_1
Definition inst_util.hh:46
@ SDWA_BYTE_3
Definition inst_util.hh:48
@ SDWA_DWORD
Definition inst_util.hh:51
@ SDWA_WORD_1
Definition inst_util.hh:50
@ SDWA_BYTE_2
Definition inst_util.hh:47
@ SDWA_WORD_0
Definition inst_util.hh:49
@ SDWA_BYTE_0
Definition inst_util.hh:45
SqDPPVals
Definition inst_util.hh:64
@ SQ_DPP_WF_RL1
Definition inst_util.hh:74
@ SQ_DPP_ROW_SR1
Definition inst_util.hh:69
@ SQ_DPP_ROW_BCAST31
Definition inst_util.hh:80
@ SQ_DPP_ROW_SL15
Definition inst_util.hh:68
@ SQ_DPP_ROW_HALF_MIRROR
Definition inst_util.hh:78
@ SQ_DPP_QUAD_PERM_MAX
Definition inst_util.hh:65
@ SQ_DPP_ROW_SL1
Definition inst_util.hh:67
@ SQ_DPP_ROW_MIRROR
Definition inst_util.hh:77
@ SQ_DPP_RESERVED
Definition inst_util.hh:66
@ SQ_DPP_ROW_BCAST15
Definition inst_util.hh:79
@ SQ_DPP_ROW_RR1
Definition inst_util.hh:71
@ SQ_DPP_ROW_SR15
Definition inst_util.hh:70
@ SQ_DPP_ROW_RR15
Definition inst_util.hh:72
@ SQ_DPP_WF_RR1
Definition inst_util.hh:76
@ SQ_DPP_WF_SL1
Definition inst_util.hh:73
@ SQ_DPP_WF_SR1
Definition inst_util.hh:75

Generated on Mon Jul 10 2023 15:30:56 for gem5 by doxygen 1.9.7