gem5  v22.0.0.2
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 
39 namespace gem5
40 {
41 
42 // values for SDWA select operations
43 enum 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
55 enum 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
63 enum SqDPPVals : int
64 {
66  SQ_DPP_RESERVED = 0x100,
67  SQ_DPP_ROW_SL1 = 0x101,
68  SQ_DPP_ROW_SL15 = 0x10F,
69  SQ_DPP_ROW_SR1 = 0x111,
70  SQ_DPP_ROW_SR15 = 0x11F,
71  SQ_DPP_ROW_RR1 = 0x121,
72  SQ_DPP_ROW_RR15 = 0x12F,
73  SQ_DPP_WF_SL1 = 0x130,
74  SQ_DPP_WF_RL1 = 0x134,
75  SQ_DPP_WF_SR1 = 0x138,
76  SQ_DPP_WF_RR1 = 0x13C,
81 };
82 static const int ROW_SIZE = 16; /* 16 registers per row */
83 static const int NUM_BANKS = 4; /* 64 registers, 16/bank */
84 
85 namespace 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>
258  inline T roundNearestEven(T val)
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",
607  bits(retVal, Gcn3ISA::MSB_PER_WORD),
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__
gem5::SQ_DPP_WF_RL1
@ SQ_DPP_WF_RL1
Definition: inst_util.hh:74
gem5::SDWADstVals
SDWADstVals
Definition: inst_util.hh:55
gem5::Gcn3ISA::VecElemI32
int32_t VecElemI32
Definition: gpu_registers.hh:166
gem5::NUM_BANKS
static const int NUM_BANKS
Definition: inst_util.hh:83
gem5::Gcn3ISA::roundNearestEven
T roundNearestEven(T val)
Definition: inst_util.hh:258
gem5::Gcn3ISA::median
T median(T val_0, T val_1, T val_2)
Definition: inst_util.hh:246
gem5::Gcn3ISA::InFmt_VOP_SDWA::SRC0_SEXT
unsigned int SRC0_SEXT
Definition: gpu_decoder.hh:1629
sc_dt::word
unsigned int word
Definition: scfx_mant.hh:96
gem5::Gcn3ISA::InFmt_VOP_DPP::DPP_CTRL
unsigned int DPP_CTRL
Definition: gpu_decoder.hh:1610
gem5::Gcn3ISA::sdwaInstDstImpl_helper
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
gem5::Gcn3ISA::InFmt_VOP_SDWA::CLAMP
unsigned int CLAMP
Definition: gpu_decoder.hh:1626
gem5::Gcn3ISA::InFmt_VOP_SDWA::SRC1_SEL
unsigned int SRC1_SEL
Definition: gpu_decoder.hh:1633
gem5::Gcn3ISA::VecElemU32
uint32_t VecElemU32
Definition: gpu_registers.hh:165
gem5::Gcn3ISA::processSDWA_dst
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
gem5::Gcn3ISA::findFirstZero
ScalarRegI32 findFirstZero(T val)
Definition: inst_util.hh:130
gem5::Gcn3ISA::InFmt_VOP_DPP::SRC1_NEG
unsigned int SRC1_NEG
Definition: gpu_decoder.hh:1615
gem5::Gcn3ISA::InFmt_VOP_SDWA::SRC1_SEXT
unsigned int SRC1_SEXT
Definition: gpu_decoder.hh:1634
gem5::Gcn3ISA::processSDWA_src
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
gem5::SQ_DPP_ROW_SL1
@ SQ_DPP_ROW_SL1
Definition: inst_util.hh:67
gpu_registers.hh
gem5::Gcn3ISA::MSB_PER_WORD
const int MSB_PER_WORD
Definition: gpu_registers.hh:146
gem5::Gcn3ISA::findFirstOneMsb
ScalarRegI32 findFirstOneMsb(T val)
Definition: inst_util.hh:152
gem5::Gcn3ISA::processDPP
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
gem5::SQ_DPP_ROW_SR15
@ SQ_DPP_ROW_SR15
Definition: inst_util.hh:70
gem5::X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
gem5::Gcn3ISA::ScalarRegI32
int32_t ScalarRegI32
Definition: gpu_registers.hh:154
gem5::SQ_DPP_ROW_MIRROR
@ SQ_DPP_ROW_MIRROR
Definition: inst_util.hh:77
gem5::Gcn3ISA::muladd
VecElemU32 muladd(VecElemU64 &dst, VecElemU32 val_0, VecElemU32 val_1, VecElemU64 val_2)
Definition: inst_util.hh:271
gem5::Gcn3ISA::countZeroBits
ScalarRegI32 countZeroBits(T val)
Definition: inst_util.hh:120
gem5::Gcn3ISA::BITS_PER_WORD
const int BITS_PER_WORD
Definition: gpu_registers.hh:144
gem5::Gcn3ISA::countZeroBitsMsb
ScalarRegI32 countZeroBitsMsb(T val)
Definition: inst_util.hh:163
gem5::SQ_DPP_QUAD_PERM_MAX
@ SQ_DPP_QUAD_PERM_MAX
Definition: inst_util.hh:65
gem5::SQ_DPP_ROW_BCAST31
@ SQ_DPP_ROW_BCAST31
Definition: inst_util.hh:80
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
gem5::SDWA_DWORD
@ SDWA_DWORD
Definition: inst_util.hh:51
gem5::SDWA_BYTE_1
@ SDWA_BYTE_1
Definition: inst_util.hh:46
gem5::SQ_DPP_ROW_BCAST15
@ SQ_DPP_ROW_BCAST15
Definition: inst_util.hh:79
gem5::Gcn3ISA::InFmt_VOP_DPP
Definition: gpu_decoder.hh:1607
gem5::SQ_DPP_WF_SL1
@ SQ_DPP_WF_SL1
Definition: inst_util.hh:73
gem5::Gcn3ISA::ScalarRegI64
int64_t ScalarRegI64
Definition: gpu_registers.hh:157
gem5::Gcn3ISA::InFmt_VOP_SDWA::SRC0_SEL
unsigned int SRC0_SEL
Definition: gpu_decoder.hh:1628
gem5::mask
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
gem5::SQ_DPP_WF_RR1
@ SQ_DPP_WF_RR1
Definition: inst_util.hh:76
gem5::Gcn3ISA::findFirstOne
ScalarRegI32 findFirstOne(T val)
Definition: inst_util.hh:141
gem5::SQ_DPP_ROW_RR1
@ SQ_DPP_ROW_RR1
Definition: inst_util.hh:71
gem5::SQ_DPP_RESERVED
@ SQ_DPP_RESERVED
Definition: inst_util.hh:66
gem5::findLsbSet
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
Definition: bitfield.hh:296
gem5::Gcn3ISA::wholeQuadMode
T wholeQuadMode(T val)
Definition: inst_util.hh:89
gem5::SQ_DPP_WF_SR1
@ SQ_DPP_WF_SR1
Definition: inst_util.hh:75
gem5::X86ISA::count
count
Definition: misc.hh:703
gem5::popCount
constexpr int popCount(uint64_t val)
Returns the number of set ones in the provided value.
Definition: bitfield.hh:334
gem5::SDWA_BYTE_2
@ SDWA_BYTE_2
Definition: inst_util.hh:47
gem5::Gcn3ISA::NumVecElemPerVecReg
const int NumVecElemPerVecReg(64)
gem5::Gcn3ISA::InFmt_VOP_SDWA::SRC1_ABS
unsigned int SRC1_ABS
Definition: gpu_decoder.hh:1636
gem5::SQ_DPP_ROW_SR1
@ SQ_DPP_ROW_SR1
Definition: inst_util.hh:69
gem5::SQ_DPP_ROW_RR15
@ SQ_DPP_ROW_RR15
Definition: inst_util.hh:72
gem5::Gcn3ISA::sdwaInstDstImpl
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
gem5::insertBits
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:166
gem5::bits
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
gem5::SDWASelVals
SDWASelVals
Definition: inst_util.hh:43
gem5::Gcn3ISA::sdwaInstSrcImpl_helper
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
gem5::Gcn3ISA::sdwaInstSrcImpl
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
gem5::SDWA_BYTE_3
@ SDWA_BYTE_3
Definition: inst_util.hh:48
gem5::Gcn3ISA::InFmt_VOP_DPP::SRC0_ABS
unsigned int SRC0_ABS
Definition: gpu_decoder.hh:1614
gem5::Gcn3ISA::ScalarRegU64
uint64_t ScalarRegU64
Definition: gpu_registers.hh:156
gem5::ROW_SIZE
static const int ROW_SIZE
Definition: inst_util.hh:82
gem5::SQ_DPP_ROW_SL15
@ SQ_DPP_ROW_SL15
Definition: inst_util.hh:68
gem5::Gcn3ISA::InFmt_VOP_DPP::ROW_MASK
unsigned int ROW_MASK
Definition: gpu_decoder.hh:1618
gem5::GPUDynInstPtr
std::shared_ptr< GPUDynInst > GPUDynInstPtr
Definition: misc.hh:49
gem5::SDWA_UNUSED_PAD
@ SDWA_UNUSED_PAD
Definition: inst_util.hh:57
gem5::SDWA_WORD_1
@ SDWA_WORD_1
Definition: inst_util.hh:50
gem5::Gcn3ISA::firstOppositeSignBit
ScalarRegI32 firstOppositeSignBit(ScalarRegI32 val)
Definition: inst_util.hh:173
gem5::Gcn3ISA::InFmt_VOP_SDWA::SRC0_ABS
unsigned int SRC0_ABS
Definition: gpu_decoder.hh:1631
gem5::SDWA_WORD_0
@ SDWA_WORD_0
Definition: inst_util.hh:49
gem5::Gcn3ISA::VecElemI64
int64_t VecElemI64
Definition: gpu_registers.hh:169
gem5::Gcn3ISA::MSB_PER_BYTE
const int MSB_PER_BYTE
Definition: gpu_registers.hh:145
gem5::Gcn3ISA::InFmt_VOP_DPP::BANK_MASK
unsigned int BANK_MASK
Definition: gpu_decoder.hh:1617
gem5::ArmISA::sel
sel
Definition: misc_types.hh:651
gem5::SDWA_UNUSED_PRESERVE
@ SDWA_UNUSED_PRESERVE
Definition: inst_util.hh:59
gem5::Gcn3ISA::BITS_PER_BYTE
const int BITS_PER_BYTE
Definition: gpu_registers.hh:143
gem5::Gcn3ISA::InFmt_VOP_SDWA::SRC0_NEG
unsigned int SRC0_NEG
Definition: gpu_decoder.hh:1630
gem5::Gcn3ISA::quadMask
T quadMask(T val)
Definition: inst_util.hh:103
gem5::findMsbSet
constexpr int findMsbSet(uint64_t val)
Returns the bit position of the MSB that is set in the input.
Definition: bitfield.hh:260
gem5::Gcn3ISA::InFmt_VOP_SDWA
Definition: gpu_decoder.hh:1621
gem5::SQ_DPP_ROW_HALF_MIRROR
@ SQ_DPP_ROW_HALF_MIRROR
Definition: inst_util.hh:78
gem5::Gcn3ISA::dppInstImpl
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
gem5::Gcn3ISA::InFmt_VOP_SDWA::DST_SEL
unsigned int DST_SEL
Definition: gpu_decoder.hh:1624
gem5::Gcn3ISA::InFmt_VOP_DPP::SRC0_NEG
unsigned int SRC0_NEG
Definition: gpu_decoder.hh:1613
gem5::Gcn3ISA::InFmt_VOP_SDWA::SRC1_NEG
unsigned int SRC1_NEG
Definition: gpu_decoder.hh:1635
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::Gcn3ISA::InFmt_VOP_DPP::SRC1_ABS
unsigned int SRC1_ABS
Definition: gpu_decoder.hh:1616
gem5::Gcn3ISA::InFmt_VOP_DPP::BOUND_CTRL
unsigned int BOUND_CTRL
Definition: gpu_decoder.hh:1612
gem5::SDWA_BYTE_0
@ SDWA_BYTE_0
Definition: inst_util.hh:45
gem5::Gcn3ISA::InFmt_VOP_SDWA::DST_UNUSED
unsigned int DST_UNUSED
Definition: gpu_decoder.hh:1625
gem5::Gcn3ISA::processSDWA_src_helper
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
gem5::SDWA_UNUSED_SEXT
@ SDWA_UNUSED_SEXT
Definition: inst_util.hh:58
gem5::Gcn3ISA::ScalarRegU32
uint32_t ScalarRegU32
Definition: gpu_registers.hh:153
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
gem5::SqDPPVals
SqDPPVals
Definition: inst_util.hh:63
gem5::Gcn3ISA::VecElemU64
uint64_t VecElemU64
Definition: gpu_registers.hh:168

Generated on Thu Jul 28 2022 13:32:09 for gem5 by doxygen 1.8.17