gem5  v20.1.0.0
instructions.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2017 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Authors: Anthony Gutierrez
34  */
35 
37 
38 #include <cmath>
39 
41 #include "debug/GCN3.hh"
42 #include "debug/GPUSync.hh"
43 #include "gpu-compute/shader.hh"
44 
45 namespace Gcn3ISA
46 {
47 
49  : Inst_SOP2(iFmt, "s_add_u32")
50  {
51  setFlag(ALU);
52  } // Inst_SOP2__S_ADD_U32
53 
55  {
56  } // ~Inst_SOP2__S_ADD_U32
57 
58  // D.u = S0.u + S1.u;
59  // SCC = (S0.u + S1.u >= 0x100000000ULL ? 1 : 0) is an unsigned
60  // overflow/carry-out.
61  void
63  {
64  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
65  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
66  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
67  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
68 
69  src0.read();
70  src1.read();
71 
72  sdst = src0.rawData() + src1.rawData();
73  scc = ((ScalarRegU64)src0.rawData() + (ScalarRegU64)src1.rawData())
74  >= 0x100000000ULL ? 1 : 0;
75 
76  sdst.write();
77  scc.write();
78  }
79 
81  : Inst_SOP2(iFmt, "s_sub_u32")
82  {
83  setFlag(ALU);
84  } // Inst_SOP2__S_SUB_U32
85 
87  {
88  } // ~Inst_SOP2__S_SUB_U32
89 
90  // D.u = S0.u - S1.u;
91  // SCC = (S1.u > S0.u ? 1 : 0) is an unsigned overflow or carry-out.
92  void
94  {
95  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
96  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
97  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
98  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
99 
100  src0.read();
101  src1.read();
102 
103  sdst = src0.rawData() - src1.rawData();
104  scc = (src1.rawData() > src0.rawData()) ? 1 : 0;
105 
106  sdst.write();
107  scc.write();
108  }
109 
111  : Inst_SOP2(iFmt, "s_add_i32")
112  {
113  setFlag(ALU);
114  } // Inst_SOP2__S_ADD_I32
115 
117  {
118  } // ~Inst_SOP2__S_ADD_I32
119 
120  // D.i = S0.i + S1.i;
121  // SCC = (S0.u[31] == S1.u[31] && S0.u[31] != D.u[31]) is a signed
122  // overflow.
123  void
125  {
126  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
127  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
128  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
129  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
130 
131  src0.read();
132  src1.read();
133 
134  sdst = src0.rawData() + src1.rawData();
135  scc = (bits(src0.rawData(), 31) == bits(src1.rawData(), 31)
136  && bits(src0.rawData(), 31) != bits(sdst.rawData(), 31))
137  ? 1 : 0;
138 
139  sdst.write();
140  scc.write();
141  }
142 
144  : Inst_SOP2(iFmt, "s_sub_i32")
145  {
146  setFlag(ALU);
147  } // Inst_SOP2__S_SUB_I32
148 
150  {
151  } // ~Inst_SOP2__S_SUB_I32
152 
153  // D.i = S0.i - S1.i;
154  // SCC = (S0.u[31] != S1.u[31] && S0.u[31] != D.u[31]) is a signed
155  // overflow.
156  void
158  {
159  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
160  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
161  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
162  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
163 
164  src0.read();
165  src1.read();
166 
167  sdst = src0.rawData() - src1.rawData();
168  scc = (bits(src0.rawData(), 31) != bits(src1.rawData(), 31)
169  && bits(src0.rawData(), 31) != bits(sdst.rawData(), 31)) ? 1 : 0;
170 
171  sdst.write();
172  scc.write();
173  }
174 
176  : Inst_SOP2(iFmt, "s_addc_u32")
177  {
178  setFlag(ALU);
179  } // Inst_SOP2__S_ADDC_U32
180 
182  {
183  } // ~Inst_SOP2__S_ADDC_U32
184 
185  // D.u = S0.u + S1.u + SCC;
186  // SCC = (S0.u + S1.u + SCC >= 0x100000000ULL ? 1 : 0) is an unsigned
187  // overflow.
188  void
190  {
191  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
192  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
193  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
194  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
195 
196  src0.read();
197  src1.read();
198  scc.read();
199 
200  sdst = src0.rawData() + src1.rawData() + scc.rawData();
201  scc = ((ScalarRegU64)src0.rawData() + (ScalarRegU64)src1.rawData()
202  + (ScalarRegU64)scc.rawData()) >= 0x100000000ULL ? 1 : 0;
203 
204  sdst.write();
205  scc.write();
206  }
207 
209  : Inst_SOP2(iFmt, "s_subb_u32")
210  {
211  setFlag(ALU);
212  } // Inst_SOP2__S_SUBB_U32
213 
215  {
216  } // ~Inst_SOP2__S_SUBB_U32
217 
218  // D.u = S0.u - S1.u - SCC;
219  // SCC = (S1.u + SCC > S0.u ? 1 : 0) is an unsigned overflow.
220  void
222  {
223  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
224  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
225  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
226  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
227 
228  src0.read();
229  src1.read();
230  scc.read();
231 
232  sdst = src0.rawData() - src1.rawData() - scc.rawData();
233  scc = (src1.rawData() + scc.rawData()) > src0.rawData() ? 1 : 0;
234 
235  sdst.write();
236  scc.write();
237  }
238 
240  : Inst_SOP2(iFmt, "s_min_i32")
241  {
242  setFlag(ALU);
243  } // Inst_SOP2__S_MIN_I32
244 
246  {
247  } // ~Inst_SOP2__S_MIN_I32
248 
249  // D.i = (S0.i < S1.i) ? S0.i : S1.i;
250  // SCC = 1 if S0 is chosen as the minimum value.
251  void
253  {
254  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
255  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
256  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
257  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
258 
259  src0.read();
260  src1.read();
261 
262  sdst = std::min(src0.rawData(), src1.rawData());
263  scc = (src0.rawData() < src1.rawData()) ? 1 : 0;
264 
265  sdst.write();
266  scc.write();
267  }
268 
270  : Inst_SOP2(iFmt, "s_min_u32")
271  {
272  setFlag(ALU);
273  } // Inst_SOP2__S_MIN_U32
274 
276  {
277  } // ~Inst_SOP2__S_MIN_U32
278 
279  // D.u = (S0.u < S1.u) ? S0.u : S1.u;
280  // SCC = 1 if S0 is chosen as the minimum value.
281  void
283  {
284  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
285  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
286  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
287  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
288 
289  src0.read();
290  src1.read();
291 
292  sdst = std::min(src0.rawData(), src1.rawData());
293  scc = (src0.rawData() < src1.rawData()) ? 1 : 0;
294 
295  sdst.write();
296  scc.write();
297  }
298 
300  : Inst_SOP2(iFmt, "s_max_i32")
301  {
302  setFlag(ALU);
303  } // Inst_SOP2__S_MAX_I32
304 
306  {
307  } // ~Inst_SOP2__S_MAX_I32
308 
309  // D.i = (S0.i > S1.i) ? S0.i : S1.i;
310  // SCC = 1 if S0 is chosen as the maximum value.
311  void
313  {
314  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
315  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
316  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
317  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
318 
319  src0.read();
320  src1.read();
321 
322  sdst = std::max(src0.rawData(), src1.rawData());
323  scc = (src0.rawData() > src1.rawData()) ? 1 : 0;
324 
325  sdst.write();
326  scc.write();
327  }
328 
330  : Inst_SOP2(iFmt, "s_max_u32")
331  {
332  setFlag(ALU);
333  } // Inst_SOP2__S_MAX_U32
334 
336  {
337  } // ~Inst_SOP2__S_MAX_U32
338 
339  // D.u = (S0.u > S1.u) ? S0.u : S1.u;
340  // SCC = 1 if S0 is chosen as the maximum value.
341  void
343  {
344  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
345  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
346  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
347  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
348 
349  src0.read();
350  src1.read();
351 
352  sdst = std::max(src0.rawData(), src1.rawData());
353  scc = (src0.rawData() > src1.rawData()) ? 1 : 0;
354 
355  sdst.write();
356  scc.write();
357  }
358 
360  : Inst_SOP2(iFmt, "s_cselect_b32")
361  {
362  setFlag(ALU);
363  } // Inst_SOP2__S_CSELECT_B32
364 
366  {
367  } // ~Inst_SOP2__S_CSELECT_B32
368 
369  // D.u = SCC ? S0.u : S1.u (conditional select).
370  void
372  {
373  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
374  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
375  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
376  ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);
377 
378  src0.read();
379  src1.read();
380  scc.read();
381 
382  sdst = scc.rawData() ? src0.rawData() : src1.rawData();
383 
384  sdst.write();
385  }
386 
388  : Inst_SOP2(iFmt, "s_cselect_b64")
389  {
390  setFlag(ALU);
391  } // Inst_SOP2__S_CSELECT_B64
392 
394  {
395  } // ~Inst_SOP2__S_CSELECT_B64
396 
397  // D.u64 = SCC ? S0.u64 : S1.u64 (conditional select).
398  void
400  {
401  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
402  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
403  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
404  ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);
405 
406  src0.read();
407  src1.read();
408  scc.read();
409 
410  sdst = scc.rawData() ? src0.rawData() : src1.rawData();
411 
412  sdst.write();
413  }
414 
416  : Inst_SOP2(iFmt, "s_and_b32")
417  {
418  setFlag(ALU);
419  } // Inst_SOP2__S_AND_B32
420 
422  {
423  } // ~Inst_SOP2__S_AND_B32
424 
425  // D.u = S0.u & S1.u;
426  // SCC = 1 if result is non-zero.
427  void
429  {
430  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
431  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
432  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
433  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
434 
435  src0.read();
436  src1.read();
437 
438  sdst = src0.rawData() & src1.rawData();
439  scc = sdst.rawData() ? 1 : 0;
440 
441  sdst.write();
442  scc.write();
443  }
444 
446  : Inst_SOP2(iFmt, "s_and_b64")
447  {
448  setFlag(ALU);
449  } // Inst_SOP2__S_AND_B64
450 
452  {
453  } // ~Inst_SOP2__S_AND_B64
454 
455  // D.u64 = S0.u64 & S1.u64;
456  // SCC = 1 if result is non-zero.
457  void
459  {
460  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
461  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
462  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
463  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
464 
465  src0.read();
466  src1.read();
467 
468  sdst = src0.rawData() & src1.rawData();
469  scc = sdst.rawData() ? 1 : 0;
470 
471  sdst.write();
472  scc.write();
473  }
474 
476  : Inst_SOP2(iFmt, "s_or_b32")
477  {
478  setFlag(ALU);
479  } // Inst_SOP2__S_OR_B32
480 
482  {
483  } // ~Inst_SOP2__S_OR_B32
484 
485  // D.u = S0.u | S1.u;
486  // SCC = 1 if result is non-zero.
487  void
489  {
490  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
491  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
492  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
493  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
494 
495  src0.read();
496  src1.read();
497 
498  sdst = src0.rawData() | src1.rawData();
499  scc = sdst.rawData() ? 1 : 0;
500 
501  sdst.write();
502  scc.write();
503  }
504 
506  : Inst_SOP2(iFmt, "s_or_b64")
507  {
508  setFlag(ALU);
509  } // Inst_SOP2__S_OR_B64
510 
512  {
513  } // ~Inst_SOP2__S_OR_B64
514 
515  // D.u64 = S0.u64 | S1.u64;
516  // SCC = 1 if result is non-zero.
517  void
519  {
520  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
521  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
522  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
523  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
524 
525  src0.read();
526  src1.read();
527 
528  sdst = src0.rawData() | src1.rawData();
529  scc = sdst.rawData() ? 1 : 0;
530 
531  sdst.write();
532  scc.write();
533  }
534 
536  : Inst_SOP2(iFmt, "s_xor_b32")
537  {
538  setFlag(ALU);
539  } // Inst_SOP2__S_XOR_B32
540 
542  {
543  } // ~Inst_SOP2__S_XOR_B32
544 
545  // D.u = S0.u ^ S1.u;
546  // SCC = 1 if result is non-zero.
547  void
549  {
550  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
551  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
552  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
553  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
554 
555  src0.read();
556  src1.read();
557 
558  sdst = src0.rawData() ^ src1.rawData();
559  scc = sdst.rawData() ? 1 : 0;
560 
561  sdst.write();
562  scc.write();
563  }
564 
566  : Inst_SOP2(iFmt, "s_xor_b64")
567  {
568  setFlag(ALU);
569  } // Inst_SOP2__S_XOR_B64
570 
572  {
573  } // ~Inst_SOP2__S_XOR_B64
574 
575  // D.u64 = S0.u64 ^ S1.u64;
576  // SCC = 1 if result is non-zero.
577  void
579  {
580  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
581  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
582  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
583  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
584 
585  src0.read();
586  src1.read();
587 
588  sdst = src0.rawData() ^ src1.rawData();
589  scc = sdst.rawData() ? 1 : 0;
590 
591  sdst.write();
592  scc.write();
593  }
594 
596  : Inst_SOP2(iFmt, "s_andn2_b32")
597  {
598  setFlag(ALU);
599  } // Inst_SOP2__S_ANDN2_B32
600 
602  {
603  } // ~Inst_SOP2__S_ANDN2_B32
604 
605  // D.u = S0.u & ~S1.u;
606  // SCC = 1 if result is non-zero.
607  void
609  {
610  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
611  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
612  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
613  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
614 
615  src0.read();
616  src1.read();
617 
618  sdst = src0.rawData() &~ src1.rawData();
619  scc = sdst.rawData() ? 1 : 0;
620 
621  sdst.write();
622  scc.write();
623  }
624 
626  : Inst_SOP2(iFmt, "s_andn2_b64")
627  {
628  setFlag(ALU);
629  } // Inst_SOP2__S_ANDN2_B64
630 
632  {
633  } // ~Inst_SOP2__S_ANDN2_B64
634 
635  // D.u64 = S0.u64 & ~S1.u64;
636  // SCC = 1 if result is non-zero.
637  void
639  {
640  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
641  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
642  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
643  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
644 
645  src0.read();
646  src1.read();
647 
648  sdst = src0.rawData() &~ src1.rawData();
649  scc = sdst.rawData() ? 1 : 0;
650 
651  sdst.write();
652  scc.write();
653  }
654 
656  : Inst_SOP2(iFmt, "s_orn2_b32")
657  {
658  setFlag(ALU);
659  } // Inst_SOP2__S_ORN2_B32
660 
662  {
663  } // ~Inst_SOP2__S_ORN2_B32
664 
665  // D.u = S0.u | ~S1.u;
666  // SCC = 1 if result is non-zero.
667  void
669  {
670  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
671  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
672  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
673  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
674 
675  src0.read();
676  src1.read();
677 
678  sdst = src0.rawData() |~ src1.rawData();
679  scc = sdst.rawData() ? 1 : 0;
680 
681  sdst.write();
682  scc.write();
683  }
684 
686  : Inst_SOP2(iFmt, "s_orn2_b64")
687  {
688  setFlag(ALU);
689  } // Inst_SOP2__S_ORN2_B64
690 
692  {
693  } // ~Inst_SOP2__S_ORN2_B64
694 
695  // D.u64 = S0.u64 | ~S1.u64;
696  // SCC = 1 if result is non-zero.
697  void
699  {
700  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
701  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
702  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
703  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
704 
705  src0.read();
706  src1.read();
707 
708  sdst = src0.rawData() |~ src1.rawData();
709  scc = sdst.rawData() ? 1 : 0;
710 
711  sdst.write();
712  scc.write();
713  }
714 
716  : Inst_SOP2(iFmt, "s_nand_b32")
717  {
718  setFlag(ALU);
719  } // Inst_SOP2__S_NAND_B32
720 
722  {
723  } // ~Inst_SOP2__S_NAND_B32
724 
725  // D.u = ~(S0.u & S1.u);
726  // SCC = 1 if result is non-zero.
727  void
729  {
730  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
731  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
732  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
733  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
734 
735  src0.read();
736  src1.read();
737 
738  sdst = ~(src0.rawData() & src1.rawData());
739  scc = sdst.rawData() ? 1 : 0;
740 
741  sdst.write();
742  scc.write();
743  }
744 
746  : Inst_SOP2(iFmt, "s_nand_b64")
747  {
748  setFlag(ALU);
749  } // Inst_SOP2__S_NAND_B64
750 
752  {
753  } // ~Inst_SOP2__S_NAND_B64
754 
755  // D.u64 = ~(S0.u64 & S1.u64);
756  // SCC = 1 if result is non-zero.
757  void
759  {
760  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
761  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
762  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
763  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
764 
765  src0.read();
766  src1.read();
767 
768  sdst = ~(src0.rawData() & src1.rawData());
769  scc = sdst.rawData() ? 1 : 0;
770 
771  sdst.write();
772  scc.write();
773  }
774 
776  : Inst_SOP2(iFmt, "s_nor_b32")
777  {
778  setFlag(ALU);
779  } // Inst_SOP2__S_NOR_B32
780 
782  {
783  } // ~Inst_SOP2__S_NOR_B32
784 
785  // D.u = ~(S0.u | S1.u);
786  // SCC = 1 if result is non-zero.
787  void
789  {
790  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
791  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
792  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
793  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
794 
795  src0.read();
796  src1.read();
797 
798  sdst = ~(src0.rawData() | src1.rawData());
799  scc = sdst.rawData() ? 1 : 0;
800 
801  sdst.write();
802  scc.write();
803  }
804 
806  : Inst_SOP2(iFmt, "s_nor_b64")
807  {
808  setFlag(ALU);
809  } // Inst_SOP2__S_NOR_B64
810 
812  {
813  } // ~Inst_SOP2__S_NOR_B64
814 
815  // D.u64 = ~(S0.u64 | S1.u64);
816  // SCC = 1 if result is non-zero.
817  void
819  {
820  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
821  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
822  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
823  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
824 
825  src0.read();
826  src1.read();
827 
828  sdst = ~(src0.rawData() | src1.rawData());
829  scc = sdst.rawData() ? 1 : 0;
830 
831  sdst.write();
832  scc.write();
833  }
834 
836  : Inst_SOP2(iFmt, "s_xnor_b32")
837  {
838  setFlag(ALU);
839  } // Inst_SOP2__S_XNOR_B32
840 
842  {
843  } // ~Inst_SOP2__S_XNOR_B32
844 
845  // D.u = ~(S0.u ^ S1.u);
846  // SCC = 1 if result is non-zero.
847  void
849  {
850  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
851  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
852  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
853  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
854 
855  src0.read();
856  src1.read();
857 
858  sdst = ~(src0.rawData() ^ src1.rawData());
859  scc = sdst.rawData() ? 1 : 0;
860 
861  sdst.write();
862  scc.write();
863  }
864 
866  : Inst_SOP2(iFmt, "s_xnor_b64")
867  {
868  setFlag(ALU);
869  } // Inst_SOP2__S_XNOR_B64
870 
872  {
873  } // ~Inst_SOP2__S_XNOR_B64
874 
875  // D.u64 = ~(S0.u64 ^ S1.u64);
876  // SCC = 1 if result is non-zero.
877  void
879  {
880  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
881  ConstScalarOperandU64 src1(gpuDynInst, instData.SSRC1);
882  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
883  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
884 
885  src0.read();
886  src1.read();
887 
888  sdst = ~(src0.rawData() ^ src1.rawData());
889  scc = sdst.rawData() ? 1 : 0;
890 
891  sdst.write();
892  scc.write();
893  }
894 
896  : Inst_SOP2(iFmt, "s_lshl_b32")
897  {
898  setFlag(ALU);
899  } // Inst_SOP2__S_LSHL_B32
900 
902  {
903  } // ~Inst_SOP2__S_LSHL_B32
904 
905  // D.u = S0.u << S1.u[4:0];
906  // SCC = 1 if result is non-zero.
907  void
909  {
910  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
911  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
912  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
913  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
914 
915  src0.read();
916  src1.read();
917 
918  sdst = (src0.rawData() << bits(src1.rawData(), 4, 0));
919  scc = sdst.rawData() ? 1 : 0;
920 
921  sdst.write();
922  scc.write();
923  }
924 
926  : Inst_SOP2(iFmt, "s_lshl_b64")
927  {
928  setFlag(ALU);
929  } // Inst_SOP2__S_LSHL_B64
930 
932  {
933  } // ~Inst_SOP2__S_LSHL_B64
934 
935  // D.u64 = S0.u64 << S1.u[5:0];
936  // SCC = 1 if result is non-zero.
937  void
939  {
940  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
941  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
942  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
943  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
944 
945  src0.read();
946  src1.read();
947 
948  sdst = (src0.rawData() << bits(src1.rawData(), 5, 0));
949  scc = sdst.rawData() ? 1 : 0;
950 
951  sdst.write();
952  scc.write();
953  }
954 
956  : Inst_SOP2(iFmt, "s_lshr_b32")
957  {
958  setFlag(ALU);
959  } // Inst_SOP2__S_LSHR_B32
960 
962  {
963  } // ~Inst_SOP2__S_LSHR_B32
964 
965  // D.u = S0.u >> S1.u[4:0];
966  // SCC = 1 if result is non-zero.
967  // The vacated bits are set to zero.
968  void
970  {
971  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
972  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
973  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
974  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
975 
976  src0.read();
977  src1.read();
978 
979  sdst = (src0.rawData() >> bits(src1.rawData(), 4, 0));
980  scc = sdst.rawData() ? 1 : 0;
981 
982  sdst.write();
983  scc.write();
984  }
985 
987  : Inst_SOP2(iFmt, "s_lshr_b64")
988  {
989  setFlag(ALU);
990  } // Inst_SOP2__S_LSHR_B64
991 
993  {
994  } // ~Inst_SOP2__S_LSHR_B64
995 
996  // D.u64 = S0.u64 >> S1.u[5:0];
997  // SCC = 1 if result is non-zero.
998  // The vacated bits are set to zero.
999  void
1001  {
1002  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
1003  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1004  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
1005  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1006 
1007  src0.read();
1008  src1.read();
1009 
1010  sdst = (src0.rawData() >> bits(src1.rawData(), 5, 0));
1011  scc = sdst.rawData() ? 1 : 0;
1012 
1013  sdst.write();
1014  scc.write();
1015  }
1016 
1018  : Inst_SOP2(iFmt, "s_ashr_i32")
1019  {
1020  setFlag(ALU);
1021  } // Inst_SOP2__S_ASHR_I32
1022 
1024  {
1025  } // ~Inst_SOP2__S_ASHR_I32
1026 
1027  // D.i = signext(S0.i) >> S1.u[4:0];
1028  // SCC = 1 if result is non-zero.
1029  // The vacated bits are set to the sign bit of the input value.
1030  void
1032  {
1033  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
1034  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1035  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
1036  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1037 
1038  src0.read();
1039  src1.read();
1040 
1041  sdst = (src0.rawData() >> bits(src1.rawData(), 4, 0));
1042  scc = sdst.rawData() ? 1 : 0;
1043 
1044  sdst.write();
1045  scc.write();
1046  }
1047 
1049  : Inst_SOP2(iFmt, "s_ashr_i64")
1050  {
1051  setFlag(ALU);
1052  } // Inst_SOP2__S_ASHR_I64
1053 
1055  {
1056  } // ~Inst_SOP2__S_ASHR_I64
1057 
1058  // D.i64 = signext(S0.i64) >> S1.u[5:0];
1059  // SCC = 1 if result is non-zero.
1060  // The vacated bits are set to the sign bit of the input value.
1061  void
1063  {
1064  ConstScalarOperandI64 src0(gpuDynInst, instData.SSRC0);
1065  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1066  ScalarOperandI64 sdst(gpuDynInst, instData.SDST);
1067  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1068 
1069  src0.read();
1070  src1.read();
1071 
1072  sdst = (src0.rawData() >> bits(src1.rawData(), 5, 0));
1073  scc = sdst.rawData() ? 1 : 0;
1074 
1075  sdst.write();
1076  scc.write();
1077  }
1078 
1080  : Inst_SOP2(iFmt, "s_bfm_b32")
1081  {
1082  setFlag(ALU);
1083  } // Inst_SOP2__S_BFM_B32
1084 
1086  {
1087  } // ~Inst_SOP2__S_BFM_B32
1088 
1089  // D.u = ((1 << S0.u[4:0]) - 1) << S1.u[4:0] (bitfield mask).
1090  void
1092  {
1093  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
1094  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1095  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
1096 
1097  src0.read();
1098  src1.read();
1099 
1100  sdst = ((1 << bits(src0.rawData(), 4, 0)) - 1)
1101  << bits(src1.rawData(), 4, 0);
1102 
1103  sdst.write();
1104  }
1105 
1107  : Inst_SOP2(iFmt, "s_bfm_b64")
1108  {
1109  setFlag(ALU);
1110  } // Inst_SOP2__S_BFM_B64
1111 
1113  {
1114  } // ~Inst_SOP2__S_BFM_B64
1115 
1116  // D.u64 = ((1ULL << S0.u[5:0]) - 1) << S1.u[5:0] (bitfield mask).
1117  void
1119  {
1120  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
1121  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1122  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
1123 
1124  src0.read();
1125  src1.read();
1126 
1127  sdst = ((1ULL << bits(src0.rawData(), 5, 0)) - 1)
1128  << bits(src1.rawData(), 5, 0);
1129 
1130  sdst.write();
1131  }
1132 
1134  : Inst_SOP2(iFmt, "s_mul_i32")
1135  {
1136  setFlag(ALU);
1137  } // Inst_SOP2__S_MUL_I32
1138 
1140  {
1141  } // ~Inst_SOP2__S_MUL_I32
1142 
1143  // D.i = S0.i * S1.i.
1144  void
1146  {
1147  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
1148  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
1149  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
1150 
1151  src0.read();
1152  src1.read();
1153 
1154  sdst = src0.rawData() * src1.rawData();
1155 
1156  sdst.write();
1157  }
1158 
1160  : Inst_SOP2(iFmt, "s_bfe_u32")
1161  {
1162  setFlag(ALU);
1163  } // Inst_SOP2__S_BFE_U32
1164 
1166  {
1167  } // ~Inst_SOP2__S_BFE_U32
1168 
1169  // Bit field extract. S0 is Data, S1[4:0] is field offset, S1[22:16] is
1170  // field width.
1171  // D.u = (S0.u >> S1.u[4:0]) & ((1 << S1.u[22:16]) - 1);
1172  // SCC = 1 if result is non-zero.
1173  void
1175  {
1176  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
1177  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1178  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
1179  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1180 
1181  src0.read();
1182  src1.read();
1183 
1184  sdst = (src0.rawData() >> bits(src1.rawData(), 4, 0))
1185  & ((1 << bits(src1.rawData(), 22, 16)) - 1);
1186  scc = sdst.rawData() ? 1 : 0;
1187 
1188  sdst.write();
1189  scc.write();
1190  }
1191 
1193  : Inst_SOP2(iFmt, "s_bfe_i32")
1194  {
1195  setFlag(ALU);
1196  } // Inst_SOP2__S_BFE_I32
1197 
1199  {
1200  } // ~Inst_SOP2__S_BFE_I32
1201 
1202  // Bit field extract. S0 is Data, S1[4:0] is field offset, S1[22:16] is
1203  // field width.
1204  // D.i = (S0.i >> S1.u[4:0]) & ((1 << S1.u[22:16]) - 1);
1205  // Sign-extend the result;
1206  // SCC = 1 if result is non-zero.
1207  void
1209  {
1210  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
1211  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1212  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
1213  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1214 
1215  src0.read();
1216  src1.read();
1217 
1218  sdst = (src0.rawData() >> bits(src1.rawData(), 4, 0))
1219  & ((1 << bits(src1.rawData(), 22, 16)) - 1);
1220  scc = sdst.rawData() ? 1 : 0;
1221 
1222  sdst.write();
1223  scc.write();
1224  }
1225 
1227  : Inst_SOP2(iFmt, "s_bfe_u64")
1228  {
1229  setFlag(ALU);
1230  } // Inst_SOP2__S_BFE_U64
1231 
1233  {
1234  } // ~Inst_SOP2__S_BFE_U64
1235 
1236  // Bit field extract. S0 is Data, S1[5:0] is field offset, S1[22:16] is
1237  // field width.
1238  // D.u64 = (S0.u64 >> S1.u[5:0]) & ((1 << S1.u[22:16]) - 1);
1239  // SCC = 1 if result is non-zero.
1240  void
1242  {
1243  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
1244  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1245  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
1246  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1247 
1248  src0.read();
1249  src1.read();
1250 
1251  sdst = (src0.rawData() >> bits(src1.rawData(), 5, 0))
1252  & ((1 << bits(src1.rawData(), 22, 16)) - 1);
1253  scc = sdst.rawData() ? 1 : 0;
1254 
1255  sdst.write();
1256  scc.write();
1257  }
1258 
1260  : Inst_SOP2(iFmt, "s_bfe_i64")
1261  {
1262  setFlag(ALU);
1263  } // Inst_SOP2__S_BFE_I64
1264 
1266  {
1267  } // ~Inst_SOP2__S_BFE_I64
1268 
1269  // Bit field extract. S0 is Data, S1[5:0] is field offset, S1[22:16] is
1270  // field width.
1271  // D.i64 = (S0.i64 >> S1.u[5:0]) & ((1 << S1.u[22:16]) - 1);
1272  // Sign-extend result;
1273  // SCC = 1 if result is non-zero.
1274  void
1276  {
1277  ConstScalarOperandI64 src0(gpuDynInst, instData.SSRC0);
1278  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
1279  ScalarOperandI64 sdst(gpuDynInst, instData.SDST);
1280  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1281 
1282  src0.read();
1283  src1.read();
1284 
1285  sdst = (src0.rawData() >> bits(src1.rawData(), 5, 0))
1286  & ((1 << bits(src1.rawData(), 22, 16)) - 1);
1287  scc = sdst.rawData() ? 1 : 0;
1288 
1289  sdst.write();
1290  scc.write();
1291  }
1292 
1294  : Inst_SOP2(iFmt, "s_cbranch_g_fork")
1295  {
1296  setFlag(Branch);
1297  } // Inst_SOP2__S_CBRANCH_G_FORK
1298 
1300  {
1301  } // ~Inst_SOP2__S_CBRANCH_G_FORK
1302 
1303  // Conditional branch using branch-stack.
1304  // S0 = compare mask(vcc or any sgpr) and
1305  // S1 = 64-bit byte address of target instruction.
1306  void
1308  {
1310  }
1311 
1313  : Inst_SOP2(iFmt, "s_absdiff_i32")
1314  {
1315  setFlag(ALU);
1316  } // Inst_SOP2__S_ABSDIFF_I32
1317 
1319  {
1320  } // ~Inst_SOP2__S_ABSDIFF_I32
1321 
1322  // D.i = S0.i - S1.i;
1323  // if (D.i < 0) then D.i = -D.i;
1324  // SCC = 1 if result is non-zero.
1325  // Compute the absolute value of difference between two values.
1326  void
1328  {
1329  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
1330  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
1331  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
1332  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1333 
1334  sdst = std::abs(src0.rawData() - src1.rawData());
1335  scc = sdst.rawData() ? 1 : 0;
1336 
1337  sdst.write();
1338  scc.write();
1339  }
1340 
1342  InFmt_SOP2 *iFmt)
1343  : Inst_SOP2(iFmt, "s_rfe_restore_b64")
1344  {
1345  } // Inst_SOP2__S_RFE_RESTORE_B64
1346 
1348  {
1349  } // ~Inst_SOP2__S_RFE_RESTORE_B64
1350 
1351  // Return from exception handler and continue.
1352  void
1354  {
1356  }
1357 
1359  : Inst_SOPK(iFmt, "s_movk_i32")
1360  {
1361  setFlag(ALU);
1362  } // Inst_SOPK__S_MOVK_I32
1363 
1365  {
1366  } // ~Inst_SOPK__S_MOVK_I32
1367 
1368  // D.i = signext(SIMM16) (sign extension).
1369  void
1371  {
1373  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
1374 
1375  sdst = simm16;
1376 
1377  sdst.write();
1378  }
1379 
1381  : Inst_SOPK(iFmt, "s_cmovk_i32")
1382  {
1383  setFlag(ALU);
1384  } // Inst_SOPK__S_CMOVK_I32
1385 
1387  {
1388  } // ~Inst_SOPK__S_CMOVK_I32
1389 
1390  // if (SCC) then D.i = signext(SIMM16);
1391  // else NOP.
1392  // Conditional move with sign extension.
1393  void
1395  {
1397  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
1398  ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);
1399 
1400  scc.read();
1401 
1402  if (scc.rawData()) {
1403  sdst = simm16;
1404  sdst.write();
1405  }
1406  }
1407 
1409  : Inst_SOPK(iFmt, "s_cmpk_eq_i32")
1410  {
1411  setFlag(ALU);
1412  } // Inst_SOPK__S_CMPK_EQ_I32
1413 
1415  {
1416  } // ~Inst_SOPK__S_CMPK_EQ_I32
1417 
1418  // SCC = (S0.i == signext(SIMM16)).
1419  void
1421  {
1423  ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
1424  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1425 
1426  src.read();
1427 
1428  scc = (src.rawData() == simm16) ? 1 : 0;
1429 
1430  scc.write();
1431  }
1432 
1434  : Inst_SOPK(iFmt, "s_cmpk_lg_i32")
1435  {
1436  setFlag(ALU);
1437  } // Inst_SOPK__S_CMPK_LG_I32
1438 
1440  {
1441  } // ~Inst_SOPK__S_CMPK_LG_I32
1442 
1443  // SCC = (S0.i != signext(SIMM16)).
1444  void
1446  {
1448  ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
1449  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1450 
1451  src.read();
1452 
1453  scc = (src.rawData() != simm16) ? 1 : 0;
1454 
1455  scc.write();
1456  }
1457 
1459  : Inst_SOPK(iFmt, "s_cmpk_gt_i32")
1460  {
1461  setFlag(ALU);
1462  } // Inst_SOPK__S_CMPK_GT_I32
1463 
1465  {
1466  } // ~Inst_SOPK__S_CMPK_GT_I32
1467 
1468  // SCC = (S0.i > signext(SIMM16)).
1469  void
1471  {
1473  ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
1474  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1475 
1476  src.read();
1477 
1478  scc = (src.rawData() > simm16) ? 1 : 0;
1479 
1480  scc.write();
1481  }
1482 
1484  : Inst_SOPK(iFmt, "s_cmpk_ge_i32")
1485  {
1486  setFlag(ALU);
1487  } // Inst_SOPK__S_CMPK_GE_I32
1488 
1490  {
1491  } // ~Inst_SOPK__S_CMPK_GE_I32
1492 
1493  // SCC = (S0.i >= signext(SIMM16)).
1494  void
1496  {
1498  ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
1499  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1500 
1501  src.read();
1502 
1503  scc = (src.rawData() >= simm16) ? 1 : 0;
1504 
1505  scc.write();
1506  }
1507 
1509  : Inst_SOPK(iFmt, "s_cmpk_lt_i32")
1510  {
1511  setFlag(ALU);
1512  } // Inst_SOPK__S_CMPK_LT_I32
1513 
1515  {
1516  } // ~Inst_SOPK__S_CMPK_LT_I32
1517 
1518  // SCC = (S0.i < signext(SIMM16)).
1519  void
1521  {
1523  ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
1524  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1525 
1526  src.read();
1527 
1528  scc = (src.rawData() < simm16) ? 1 : 0;
1529 
1530  scc.write();
1531  }
1532 
1534  : Inst_SOPK(iFmt, "s_cmpk_le_i32")
1535  {
1536  setFlag(ALU);
1537  } // Inst_SOPK__S_CMPK_LE_I32
1538 
1540  {
1541  } // ~Inst_SOPK__S_CMPK_LE_I32
1542 
1543  // SCC = (S0.i <= signext(SIMM16)).
1544  void
1546  {
1548  ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
1549  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1550 
1551  src.read();
1552 
1553  scc = (src.rawData() <= simm16) ? 1 : 0;
1554 
1555  scc.write();
1556  }
1557 
1559  : Inst_SOPK(iFmt, "s_cmpk_eq_u32")
1560  {
1561  setFlag(ALU);
1562  } // Inst_SOPK__S_CMPK_EQ_U32
1563 
1565  {
1566  } // ~Inst_SOPK__S_CMPK_EQ_U32
1567 
1568  // SCC = (S0.u == SIMM16).
1569  void
1571  {
1573  ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
1574  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1575 
1576  src.read();
1577 
1578  scc = (src.rawData() == simm16) ? 1 : 0;
1579 
1580  scc.write();
1581  }
1582 
1584  : Inst_SOPK(iFmt, "s_cmpk_lg_u32")
1585  {
1586  setFlag(ALU);
1587  } // Inst_SOPK__S_CMPK_LG_U32
1588 
1590  {
1591  } // ~Inst_SOPK__S_CMPK_LG_U32
1592 
1593  // SCC = (S0.u != SIMM16).
1594  void
1596  {
1598  ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
1599  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1600 
1601  src.read();
1602 
1603  scc = (src.rawData() != simm16) ? 1 : 0;
1604 
1605  scc.write();
1606  }
1607 
1609  : Inst_SOPK(iFmt, "s_cmpk_gt_u32")
1610  {
1611  setFlag(ALU);
1612  } // Inst_SOPK__S_CMPK_GT_U32
1613 
1615  {
1616  } // ~Inst_SOPK__S_CMPK_GT_U32
1617 
1618  // SCC = (S0.u > SIMM16).
1619  void
1621  {
1623  ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
1624  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1625 
1626  src.read();
1627 
1628  scc = (src.rawData() > simm16) ? 1 : 0;
1629 
1630  scc.write();
1631  }
1632 
1634  : Inst_SOPK(iFmt, "s_cmpk_ge_u32")
1635  {
1636  setFlag(ALU);
1637  } // Inst_SOPK__S_CMPK_GE_U32
1638 
1640  {
1641  } // ~Inst_SOPK__S_CMPK_GE_U32
1642 
1643  // SCC = (S0.u >= SIMM16).
1644  void
1646  {
1648  ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
1649  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1650 
1651  src.read();
1652 
1653  scc = (src.rawData() >= simm16) ? 1 : 0;
1654 
1655  scc.write();
1656  }
1657 
1659  : Inst_SOPK(iFmt, "s_cmpk_lt_u32")
1660  {
1661  setFlag(ALU);
1662  } // Inst_SOPK__S_CMPK_LT_U32
1663 
1665  {
1666  } // ~Inst_SOPK__S_CMPK_LT_U32
1667 
1668  // SCC = (S0.u < SIMM16).
1669  void
1671  {
1673  ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
1674  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1675 
1676  src.read();
1677 
1678  scc = (src.rawData() < simm16) ? 1 : 0;
1679 
1680  scc.write();
1681  }
1682 
1684  : Inst_SOPK(iFmt, "s_cmpk_le_u32")
1685  {
1686  setFlag(ALU);
1687  } // Inst_SOPK__S_CMPK_LE_U32
1688 
1690  {
1691  } // ~Inst_SOPK__S_CMPK_LE_U32
1692 
1693  // SCC = (S0.u <= SIMM16).
1694  void
1696  {
1698  ConstScalarOperandU32 src(gpuDynInst, instData.SDST);
1699  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1700 
1701  src.read();
1702 
1703  scc = (src.rawData() <= simm16) ? 1 : 0;
1704 
1705  scc.write();
1706  }
1707 
1709  : Inst_SOPK(iFmt, "s_addk_i32")
1710  {
1711  setFlag(ALU);
1712  } // Inst_SOPK__S_ADDK_I32
1713 
1715  {
1716  } // ~Inst_SOPK__S_ADDK_I32
1717 
1718  // D.i = D.i + signext(SIMM16);
1719  // SCC = overflow.
1720  void
1722  {
1723  ScalarRegI16 simm16 = instData.SIMM16;
1724  ConstScalarOperandI32 src(gpuDynInst, instData.SDST);
1725  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
1726  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1727 
1728  src.read();
1729 
1730  sdst = src.rawData() + (ScalarRegI32)simm16;
1731  scc = (bits(src.rawData(), 31) == bits(simm16, 15)
1732  && bits(src.rawData(), 31) != bits(sdst.rawData(), 31)) ? 1 : 0;
1733 
1734  sdst.write();
1735  scc.write();
1736  }
1737 
1739  : Inst_SOPK(iFmt, "s_mulk_i32")
1740  {
1741  setFlag(ALU);
1742  } // Inst_SOPK__S_MULK_I32
1743 
1745  {
1746  } // ~Inst_SOPK__S_MULK_I32
1747 
1748  // D.i = D.i * signext(SIMM16).
1749  void
1751  {
1752  ScalarRegI16 simm16 = instData.SIMM16;
1753  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
1754 
1755  sdst.read();
1756 
1757  sdst = sdst.rawData() * (ScalarRegI32)simm16;
1758 
1759  sdst.write();
1760  }
1761 
1763  : Inst_SOPK(iFmt, "s_cbranch_i_fork")
1764  {
1765  setFlag(Branch);
1766  } // Inst_SOPK__S_CBRANCH_I_FORK
1767 
1769  {
1770  } // ~Inst_SOPK__S_CBRANCH_I_FORK
1771 
1772  // Conditional branch using branch-stack.
1773  // S0 = compare mask(vcc or any sgpr), and
1774  // SIMM16 = signed DWORD branch offset relative to next instruction.
1775  void
1777  {
1779  }
1780 
1782  : Inst_SOPK(iFmt, "s_getreg_b32")
1783  {
1784  } // Inst_SOPK__S_GETREG_B32
1785 
1787  {
1788  } // ~Inst_SOPK__S_GETREG_B32
1789 
1790  // D.u = hardware-reg. Read some or all of a hardware register into the
1791  // LSBs of D.
1792  // SIMM16 = {size[4:0], offset[4:0], hwRegId[5:0]}; offset is 0..31, size
1793  // is 1..32.
1794  void
1796  {
1798  }
1799 
1801  : Inst_SOPK(iFmt, "s_setreg_b32")
1802  {
1803  setFlag(ALU);
1804  } // Inst_SOPK__S_SETREG_B32
1805 
1807  {
1808  } // ~Inst_SOPK__S_SETREG_B32
1809 
1810  // hardware-reg = S0.u. Write some or all of the LSBs of D into a hardware
1811  // register.
1812  // SIMM16 = {size[4:0], offset[4:0], hwRegId[5:0]}; offset is 0..31, size
1813  // is 1..32.
1814  void
1816  {
1817  ScalarRegI16 simm16 = instData.SIMM16;
1818  ScalarRegU32 hwregId = simm16 & 0x3f;
1819  ScalarRegU32 offset = (simm16 >> 6) & 31;
1820  ScalarRegU32 size = ((simm16 >> 11) & 31) + 1;
1821 
1822  ScalarOperandU32 hwreg(gpuDynInst, hwregId);
1823  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
1824  hwreg.read();
1825  sdst.read();
1826 
1827  // Store value from SDST to part of the hardware register.
1828  ScalarRegU32 mask = (((1U << size) - 1U) << offset);
1829  hwreg = ((hwreg.rawData() & ~mask)
1830  | ((sdst.rawData() << offset) & mask));
1831  hwreg.write();
1832 
1833  // set MODE register to control the behavior of single precision
1834  // floating-point numbers: denormal mode or round mode
1835  if (hwregId==1 && size==2
1836  && (offset==4 || offset==0)) {
1837  warn_once("Be cautious that s_setreg_b32 has no real effect "
1838  "on FP modes: %s\n", gpuDynInst->disassemble());
1839  return;
1840  }
1841 
1842  // panic if not changing MODE of floating-point numbers
1844  }
1845 
1847  InFmt_SOPK *iFmt)
1848  : Inst_SOPK(iFmt, "s_setreg_imm32_b32")
1849  {
1850  } // Inst_SOPK__S_SETREG_IMM32_B32
1851 
1853  {
1854  } // ~Inst_SOPK__S_SETREG_IMM32_B32
1855 
1856  // Write some or all of the LSBs of IMM32 into a hardware register; this
1857  // instruction requires a 32-bit literal constant.
1858  // SIMM16 = {size[4:0], offset[4:0], hwRegId[5:0]}; offset is 0..31, size
1859  // is 1..32.
1860  void
1862  {
1864  }
1865 
1867  : Inst_SOP1(iFmt, "s_mov_b32")
1868  {
1869  setFlag(ALU);
1870  } // Inst_SOP1__S_MOV_B32
1871 
1873  {
1874  } // ~Inst_SOP1__S_MOV_B32
1875 
1876  // D.u = S0.u.
1877  void
1879  {
1880  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
1881  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
1882 
1883  src.read();
1884 
1885  sdst = src.rawData();
1886 
1887  sdst.write();
1888  }
1889 
1891  : Inst_SOP1(iFmt, "s_mov_b64")
1892  {
1893  setFlag(ALU);
1894  } // Inst_SOP1__S_MOV_B64
1895 
1897  {
1898  } // ~Inst_SOP1__S_MOV_B64
1899 
1900  // D.u64 = S0.u64.
1901  void
1903  {
1904  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
1905  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
1906 
1907  src.read();
1908 
1909  sdst = src.rawData();
1910 
1911  sdst.write();
1912  }
1913 
1915  : Inst_SOP1(iFmt, "s_cmov_b32")
1916  {
1917  setFlag(ALU);
1918  } // Inst_SOP1__S_CMOV_B32
1919 
1921  {
1922  } // ~Inst_SOP1__S_CMOV_B32
1923 
1924  // if (SCC) then D.u = S0.u;
1925  // else NOP.
1926  // Conditional move.
1927  void
1929  {
1930  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
1931  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
1932  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1933 
1934  src.read();
1935  scc.read();
1936 
1937  if (scc.rawData()) {
1938  sdst = src.rawData();
1939  sdst.write();
1940  }
1941  }
1942 
1944  : Inst_SOP1(iFmt, "s_cmov_b64")
1945  {
1946  setFlag(ALU);
1947  } // Inst_SOP1__S_CMOV_B64
1948 
1950  {
1951  } // ~Inst_SOP1__S_CMOV_B64
1952 
1953  // if (SCC) then D.u64 = S0.u64;
1954  // else NOP.
1955  // Conditional move.
1956  void
1958  {
1959  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
1960  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
1961  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1962 
1963  src.read();
1964  scc.read();
1965 
1966  if (scc.rawData()) {
1967  sdst = src.rawData();
1968  sdst.write();
1969  }
1970  }
1971 
1973  : Inst_SOP1(iFmt, "s_not_b32")
1974  {
1975  setFlag(ALU);
1976  } // Inst_SOP1__S_NOT_B32
1977 
1979  {
1980  } // ~Inst_SOP1__S_NOT_B32
1981 
1982  // D.u = ~S0.u;
1983  // SCC = 1 if result is non-zero.
1984  // Bitwise negation.
1985  void
1987  {
1988  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
1989  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
1990  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
1991 
1992  src.read();
1993 
1994  sdst = ~src.rawData();
1995 
1996  scc = sdst.rawData() ? 1 : 0;
1997 
1998  sdst.write();
1999  scc.write();
2000  }
2001 
2003  : Inst_SOP1(iFmt, "s_not_b64")
2004  {
2005  setFlag(ALU);
2006  } // Inst_SOP1__S_NOT_B64
2007 
2009  {
2010  } // ~Inst_SOP1__S_NOT_B64
2011 
2012  // D.u64 = ~S0.u64;
2013  // SCC = 1 if result is non-zero.
2014  // Bitwise negation.
2015  void
2017  {
2018  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2019  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2020  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2021 
2022  src.read();
2023 
2024  sdst = ~src.rawData();
2025  scc = sdst.rawData() ? 1 : 0;
2026 
2027  sdst.write();
2028  scc.write();
2029  }
2030 
2032  : Inst_SOP1(iFmt, "s_wqm_b32")
2033  {
2034  setFlag(ALU);
2035  } // Inst_SOP1__S_WQM_B32
2036 
2038  {
2039  } // ~Inst_SOP1__S_WQM_B32
2040 
2041  // Computes whole quad mode for an active/valid mask.
2042  // SCC = 1 if result is non-zero.
2043  void
2045  {
2046  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2047  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
2048  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2049 
2050  src.read();
2051 
2052  sdst = wholeQuadMode(src.rawData());
2053  scc = sdst.rawData() ? 1 : 0;
2054 
2055  sdst.write();
2056  scc.write();
2057  }
2058 
2060  : Inst_SOP1(iFmt, "s_wqm_b64")
2061  {
2062  setFlag(ALU);
2063  } // Inst_SOP1__S_WQM_B64
2064 
2066  {
2067  } // ~Inst_SOP1__S_WQM_B64
2068 
2069  // Computes whole quad mode for an active/valid mask.
2070  // SCC = 1 if result is non-zero.
2071  void
2073  {
2074  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2075  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2076  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2077 
2078  src.read();
2079 
2080  sdst = wholeQuadMode(src.rawData());
2081  scc = sdst.rawData() ? 1 : 0;
2082 
2083  sdst.write();
2084  scc.write();
2085  }
2086 
2088  : Inst_SOP1(iFmt, "s_brev_b32")
2089  {
2090  setFlag(ALU);
2091  } // Inst_SOP1__S_BREV_B32
2092 
2094  {
2095  } // ~Inst_SOP1__S_BREV_B32
2096 
2097  // D.u[31:0] = S0.u[0:31] (reverse bits).
2098  void
2100  {
2101  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2102  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
2103 
2104  src.read();
2105 
2106  sdst = reverseBits(src.rawData());
2107 
2108  sdst.write();
2109  }
2110 
2112  : Inst_SOP1(iFmt, "s_brev_b64")
2113  {
2114  setFlag(ALU);
2115  } // Inst_SOP1__S_BREV_B64
2116 
2118  {
2119  } // ~Inst_SOP1__S_BREV_B64
2120 
2121  // D.u64[63:0] = S0.u64[0:63] (reverse bits).
2122  void
2124  {
2125  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2126  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2127 
2128  src.read();
2129 
2130  sdst = reverseBits(src.rawData());
2131 
2132  sdst.write();
2133  }
2134 
2136  : Inst_SOP1(iFmt, "s_bcnt0_i32_b32")
2137  {
2138  setFlag(ALU);
2139  } // Inst_SOP1__S_BCNT0_I32_B32
2140 
2142  {
2143  } // ~Inst_SOP1__S_BCNT0_I32_B32
2144 
2145  // D.i = CountZeroBits(S0.u);
2146  // SCC = 1 if result is non-zero.
2147  void
2149  {
2150  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2151  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2152  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2153 
2154  src.read();
2155 
2156  sdst = countZeroBits(src.rawData());
2157  scc = sdst.rawData() ? 1 : 0;
2158 
2159  sdst.write();
2160  scc.write();
2161  }
2162 
2164  : Inst_SOP1(iFmt, "s_bcnt0_i32_b64")
2165  {
2166  setFlag(ALU);
2167  } // Inst_SOP1__S_BCNT0_I32_B64
2168 
2170  {
2171  } // ~Inst_SOP1__S_BCNT0_I32_B64
2172 
2173  // D.i = CountZeroBits(S0.u64);
2174  // SCC = 1 if result is non-zero.
2175  void
2177  {
2178  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2179  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2180  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2181 
2182  src.read();
2183 
2184  sdst = countZeroBits(src.rawData());
2185  scc = sdst.rawData() ? 1 : 0;
2186 
2187  sdst.write();
2188  scc.write();
2189  }
2190 
2192  : Inst_SOP1(iFmt, "s_bcnt1_i32_b32")
2193  {
2194  setFlag(ALU);
2195  } // Inst_SOP1__S_BCNT1_I32_B32
2196 
2198  {
2199  } // ~Inst_SOP1__S_BCNT1_I32_B32
2200 
2201  // D.i = CountOneBits(S0.u);
2202  // SCC = 1 if result is non-zero.
2203  void
2205  {
2206  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2207  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2208  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2209 
2210  src.read();
2211 
2212  sdst = popCount(src.rawData());
2213  scc = sdst.rawData() ? 1 : 0;
2214 
2215  sdst.write();
2216  scc.write();
2217  }
2218 
2220  : Inst_SOP1(iFmt, "s_bcnt1_i32_b64")
2221  {
2222  setFlag(ALU);
2223  } // Inst_SOP1__S_BCNT1_I32_B64
2224 
2226  {
2227  } // ~Inst_SOP1__S_BCNT1_I32_B64
2228 
2229  // D.i = CountOneBits(S0.u64);
2230  // SCC = 1 if result is non-zero.
2231  void
2233  {
2234  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2235  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2236  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2237 
2238  src.read();
2239 
2240  sdst = popCount(src.rawData());
2241  scc = sdst.rawData() ? 1 : 0;
2242 
2243  sdst.write();
2244  scc.write();
2245  }
2246 
2248  : Inst_SOP1(iFmt, "s_ff0_i32_b32")
2249  {
2250  setFlag(ALU);
2251  } // Inst_SOP1__S_FF0_I32_B32
2252 
2254  {
2255  } // ~Inst_SOP1__S_FF0_I32_B32
2256 
2257  // D.i = FindFirstZero(S0.u);
2258  // If no zeros are found, return -1.
2259  // Returns the bit position of the first zero from the LSB.
2260  void
2262  {
2263  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2264  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2265 
2266  src.read();
2267 
2268  sdst = findFirstZero(src.rawData());
2269 
2270  sdst.write();
2271  }
2272 
2274  : Inst_SOP1(iFmt, "s_ff0_i32_b64")
2275  {
2276  setFlag(ALU);
2277  } // Inst_SOP1__S_FF0_I32_B64
2278 
2280  {
2281  } // ~Inst_SOP1__S_FF0_I32_B64
2282 
2283  // D.i = FindFirstZero(S0.u64);
2284  // If no zeros are found, return -1.
2285  // Returns the bit position of the first zero from the LSB.
2286  void
2288  {
2289  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2290  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2291 
2292  src.read();
2293 
2294  sdst = findFirstZero(src.rawData());
2295 
2296  sdst.write();
2297  }
2298 
2300  : Inst_SOP1(iFmt, "s_ff1_i32_b32")
2301  {
2302  setFlag(ALU);
2303  } // Inst_SOP1__S_FF1_I32_B32
2304 
2306  {
2307  } // ~Inst_SOP1__S_FF1_I32_B32
2308 
2309  // D.i = FindFirstOne(S0.u);
2310  // If no ones are found, return -1.
2311  // Returns the bit position of the first one from the LSB.
2312  void
2314  {
2315  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2316  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2317 
2318  src.read();
2319 
2320  sdst = findFirstOne(src.rawData());
2321 
2322  sdst.write();
2323  }
2324 
2326  : Inst_SOP1(iFmt, "s_ff1_i32_b64")
2327  {
2328  setFlag(ALU);
2329  } // Inst_SOP1__S_FF1_I32_B64
2330 
2332  {
2333  } // ~Inst_SOP1__S_FF1_I32_B64
2334 
2335  // D.i = FindFirstOne(S0.u64);
2336  // If no ones are found, return -1.
2337  // Returns the bit position of the first one from the LSB.
2338  void
2340  {
2341  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2342  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2343 
2344  src.read();
2345 
2346  sdst = findFirstOne(src.rawData());
2347 
2348  sdst.write();
2349  }
2350 
2352  : Inst_SOP1(iFmt, "s_flbit_i32_b32")
2353  {
2354  setFlag(ALU);
2355  } // Inst_SOP1__S_FLBIT_I32_B32
2356 
2358  {
2359  } // ~Inst_SOP1__S_FLBIT_I32_B32
2360 
2361  // D.i = FindFirstOne(S0.u);
2362  // If no ones are found, return -1.
2363  // Counts how many zeros before the first one starting from the MSB.
2364  void
2366  {
2367  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2368  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2369 
2370  src.read();
2371 
2372  sdst = countZeroBitsMsb(src.rawData());
2373 
2374  sdst.write();
2375  }
2376 
2378  : Inst_SOP1(iFmt, "s_flbit_i32_b64")
2379  {
2380  setFlag(ALU);
2381  } // Inst_SOP1__S_FLBIT_I32_B64
2382 
2384  {
2385  } // ~Inst_SOP1__S_FLBIT_I32_B64
2386 
2387  // D.i = FindFirstOne(S0.u64);
2388  // If no ones are found, return -1.
2389  // Counts how many zeros before the first one starting from the MSB.
2390  void
2392  {
2393  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2394  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2395 
2396  src.read();
2397 
2398  sdst = countZeroBitsMsb(src.rawData());
2399 
2400  sdst.write();
2401  }
2402 
2404  : Inst_SOP1(iFmt, "s_flbit_i32")
2405  {
2406  setFlag(ALU);
2407  } // Inst_SOP1__S_FLBIT_I32
2408 
2410  {
2411  } // ~Inst_SOP1__S_FLBIT_I32
2412 
2413  // D.i = FirstOppositeSignBit(S0.i);
2414  // If S0.i == 0 or S0.i == -1 (all bits are the same), return -1.
2415  // Counts how many bits in a row (from MSB to LSB) are the same as the
2416  // sign bit.
2417  void
2419  {
2420  ConstScalarOperandI32 src(gpuDynInst, instData.SSRC0);
2421  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2422 
2423  src.read();
2424 
2425  sdst = firstOppositeSignBit(src.rawData());
2426 
2427  sdst.write();
2428  }
2429 
2431  : Inst_SOP1(iFmt, "s_flbit_i32_i64")
2432  {
2433  setFlag(ALU);
2434  } // Inst_SOP1__S_FLBIT_I32_I64
2435 
2437  {
2438  } // ~Inst_SOP1__S_FLBIT_I32_I64
2439 
2440  // D.i = FirstOppositeSignBit(S0.i64);
2441  // If S0.i == 0 or S0.i == -1 (all bits are the same), return -1.
2442  // Counts how many bits in a row (from MSB to LSB) are the same as the
2443  // sign bit.
2444  void
2446  {
2447  ConstScalarOperandI64 src(gpuDynInst, instData.SSRC0);
2448  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2449 
2450  src.read();
2451 
2452  sdst = firstOppositeSignBit(src.rawData());
2453 
2454  sdst.write();
2455  }
2456 
2458  : Inst_SOP1(iFmt, "s_sext_i32_i8")
2459  {
2460  setFlag(ALU);
2461  } // Inst_SOP1__S_SEXT_I32_I8
2462 
2464  {
2465  } // ~Inst_SOP1__S_SEXT_I32_I8
2466 
2467  // D.i = signext(S0.i[7:0]) (sign extension).
2468  void
2470  {
2471  ConstScalarOperandI32 src(gpuDynInst, instData.SSRC0);
2472  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2473 
2474  src.read();
2475 
2476  sdst = sext<std::numeric_limits<ScalarRegI8>::digits>(
2477  bits(src.rawData(), 7, 0));
2478 
2479  sdst.write();
2480  }
2481 
2483  : Inst_SOP1(iFmt, "s_sext_i32_i16")
2484  {
2485  setFlag(ALU);
2486  } // Inst_SOP1__S_SEXT_I32_I16
2487 
2489  {
2490  } // ~Inst_SOP1__S_SEXT_I32_I16
2491 
2492  // D.i = signext(S0.i[15:0]) (sign extension).
2493  void
2495  {
2496  ConstScalarOperandI32 src(gpuDynInst, instData.SSRC0);
2497  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
2498 
2499  src.read();
2500 
2501  sdst = sext<std::numeric_limits<ScalarRegI16>::digits>(
2502  bits(src.rawData(), 15, 0));
2503 
2504  sdst.write();
2505  }
2506 
2508  : Inst_SOP1(iFmt, "s_bitset0_b32")
2509  {
2510  setFlag(ALU);
2511  } // Inst_SOP1__S_BITSET0_B32
2512 
2514  {
2515  } // ~Inst_SOP1__S_BITSET0_B32
2516 
2517  // D.u[S0.u[4:0]] = 0.
2518  void
2520  {
2521  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2522  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
2523 
2524  src.read();
2525 
2526  sdst.setBit(bits(src.rawData(), 4, 0), 0);
2527 
2528  sdst.write();
2529  }
2530 
2532  : Inst_SOP1(iFmt, "s_bitset0_b64")
2533  {
2534  setFlag(ALU);
2535  } // Inst_SOP1__S_BITSET0_B64
2536 
2538  {
2539  } // ~Inst_SOP1__S_BITSET0_B64
2540 
2541  // D.u64[S0.u[5:0]] = 0.
2542  void
2544  {
2545  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2546  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2547 
2548  src.read();
2549 
2550  sdst.setBit(bits(src.rawData(), 5, 0), 0);
2551 
2552  sdst.write();
2553  }
2554 
2556  : Inst_SOP1(iFmt, "s_bitset1_b32")
2557  {
2558  setFlag(ALU);
2559  } // Inst_SOP1__S_BITSET1_B32
2560 
2562  {
2563  } // ~Inst_SOP1__S_BITSET1_B32
2564 
2565  // D.u[S0.u[4:0]] = 1.
2566  void
2568  {
2569  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2570  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
2571 
2572  src.read();
2573 
2574  sdst.setBit(bits(src.rawData(), 4, 0), 1);
2575 
2576  sdst.write();
2577  }
2578 
2580  : Inst_SOP1(iFmt, "s_bitset1_b64")
2581  {
2582  setFlag(ALU);
2583  } // Inst_SOP1__S_BITSET1_B64
2584 
2586  {
2587  } // ~Inst_SOP1__S_BITSET1_B64
2588 
2589  // D.u64[S0.u[5:0]] = 1.
2590  void
2592  {
2593  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2594  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2595 
2596  src.read();
2597 
2598  sdst.setBit(bits(src.rawData(), 5, 0), 1);
2599 
2600  sdst.write();
2601  }
2602 
2604  : Inst_SOP1(iFmt, "s_getpc_b64")
2605  {
2606  setFlag(ALU);
2607  } // Inst_SOP1__S_GETPC_B64
2608 
2610  {
2611  } // ~Inst_SOP1__S_GETPC_B64
2612 
2613  // D.u64 = PC + 4.
2614  // Destination receives the byte address of the next instruction.
2615  void
2617  {
2618  Wavefront *wf = gpuDynInst->wavefront();
2619  Addr pc = wf->pc();
2620  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2621 
2622  sdst = pc + 4;
2623 
2624  sdst.write();
2625  }
2626 
2628  : Inst_SOP1(iFmt, "s_setpc_b64")
2629  {
2630  setFlag(ALU);
2631  } // Inst_SOP1__S_SETPC_B64
2632 
2634  {
2635  } // ~Inst_SOP1__S_SETPC_B64
2636 
2637  // PC = S0.u64.
2638  // S0.u64 is a byte address of the instruction to jump to.
2639  void
2641  {
2642  Wavefront *wf = gpuDynInst->wavefront();
2643  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2644 
2645  src.read();
2646 
2647  wf->pc(src.rawData());
2648  }
2649 
2651  : Inst_SOP1(iFmt, "s_swappc_b64")
2652  {
2653  setFlag(ALU);
2654  } // Inst_SOP1__S_SWAPPC_B64
2655 
2657  {
2658  } // ~Inst_SOP1__S_SWAPPC_B64
2659 
2660  // D.u64 = PC + 4; PC = S0.u64.
2661  // S0.u64 is a byte address of the instruction to jump to.
2662  void
2664  {
2665  Wavefront *wf = gpuDynInst->wavefront();
2666  Addr pc = wf->pc();
2667  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2668  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2669 
2670  src.read();
2671 
2672  sdst = pc + 4;
2673 
2674  wf->pc(src.rawData());
2675  sdst.write();
2676  }
2677 
2679  : Inst_SOP1(iFmt, "s_rfe_b64")
2680  {
2681  } // Inst_SOP1__S_RFE_B64
2682 
2684  {
2685  } // ~Inst_SOP1__S_RFE_B64
2686 
2687  // Return from exception handler and continue.
2688  void
2690  {
2692  }
2693 
2695  InFmt_SOP1 *iFmt)
2696  : Inst_SOP1(iFmt, "s_and_saveexec_b64")
2697  {
2698  setFlag(ALU);
2699  } // Inst_SOP1__S_AND_SAVEEXEC_B64
2700 
2702  {
2703  } // ~Inst_SOP1__S_AND_SAVEEXEC_B64
2704 
2705  // D.u64 = EXEC;
2706  // EXEC = S0.u64 & EXEC;
2707  // SCC = 1 if the new value of EXEC is non-zero.
2708  void
2710  {
2711  Wavefront *wf = gpuDynInst->wavefront();
2712  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2713  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2714  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2715 
2716  src.read();
2717 
2718  sdst = wf->execMask().to_ullong();
2719  wf->execMask() = src.rawData() & wf->execMask().to_ullong();
2720  scc = wf->execMask().any() ? 1 : 0;
2721 
2722  sdst.write();
2723  scc.write();
2724  }
2725 
2727  InFmt_SOP1 *iFmt)
2728  : Inst_SOP1(iFmt, "s_or_saveexec_b64")
2729  {
2730  setFlag(ALU);
2731  } // Inst_SOP1__S_OR_SAVEEXEC_B64
2732 
2734  {
2735  } // ~Inst_SOP1__S_OR_SAVEEXEC_B64
2736 
2737  // D.u64 = EXEC;
2738  // EXEC = S0.u64 | EXEC;
2739  // SCC = 1 if the new value of EXEC is non-zero.
2740  void
2742  {
2743  Wavefront *wf = gpuDynInst->wavefront();
2744  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2745  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2746  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2747 
2748  src.read();
2749 
2750  sdst = wf->execMask().to_ullong();
2751  wf->execMask() = src.rawData() | wf->execMask().to_ullong();
2752  scc = wf->execMask().any() ? 1 : 0;
2753 
2754  sdst.write();
2755  scc.write();
2756  }
2757 
2759  InFmt_SOP1 *iFmt)
2760  : Inst_SOP1(iFmt, "s_xor_saveexec_b64")
2761  {
2762  setFlag(ALU);
2763  } // Inst_SOP1__S_XOR_SAVEEXEC_B64
2764 
2766  {
2767  } // ~Inst_SOP1__S_XOR_SAVEEXEC_B64
2768 
2769  // D.u64 = EXEC;
2770  // EXEC = S0.u64 ^ EXEC;
2771  // SCC = 1 if the new value of EXEC is non-zero.
2772  void
2774  {
2775  Wavefront *wf = gpuDynInst->wavefront();
2776  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2777  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2778  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2779 
2780  src.read();
2781 
2782  sdst = wf->execMask().to_ullong();
2783  wf->execMask() = src.rawData() ^ wf->execMask().to_ullong();
2784  scc = wf->execMask().any() ? 1 : 0;
2785 
2786  sdst.write();
2787  scc.write();
2788  }
2789 
2791  InFmt_SOP1 *iFmt)
2792  : Inst_SOP1(iFmt, "s_andn2_saveexec_b64")
2793  {
2794  setFlag(ALU);
2795  } // Inst_SOP1__S_ANDN2_SAVEEXEC_B64
2796 
2798  {
2799  } // ~Inst_SOP1__S_ANDN2_SAVEEXEC_B64
2800 
2801  // D.u64 = EXEC;
2802  // EXEC = S0.u64 & ~EXEC;
2803  // SCC = 1 if the new value of EXEC is non-zero.
2804  void
2806  {
2807  Wavefront *wf = gpuDynInst->wavefront();
2808  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2809  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2810  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2811 
2812  src.read();
2813 
2814  sdst = wf->execMask().to_ullong();
2815  wf->execMask() = src.rawData() &~ wf->execMask().to_ullong();
2816  scc = wf->execMask().any() ? 1 : 0;
2817 
2818  sdst.write();
2819  scc.write();
2820  }
2821 
2823  InFmt_SOP1 *iFmt)
2824  : Inst_SOP1(iFmt, "s_orn2_saveexec_b64")
2825  {
2826  setFlag(ALU);
2827  } // Inst_SOP1__S_ORN2_SAVEEXEC_B64
2828 
2830  {
2831  } // ~Inst_SOP1__S_ORN2_SAVEEXEC_B64
2832 
2833  // D.u64 = EXEC;
2834  // EXEC = S0.u64 | ~EXEC;
2835  // SCC = 1 if the new value of EXEC is non-zero.
2836  void
2838  {
2839  Wavefront *wf = gpuDynInst->wavefront();
2840  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2841  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2842  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2843 
2844  src.read();
2845 
2846  sdst = wf->execMask().to_ullong();
2847  wf->execMask() = src.rawData() |~ wf->execMask().to_ullong();
2848  scc = wf->execMask().any() ? 1 : 0;
2849 
2850  sdst.write();
2851  scc.write();
2852  }
2853 
2855  InFmt_SOP1 *iFmt)
2856  : Inst_SOP1(iFmt, "s_nand_saveexec_b64")
2857  {
2858  setFlag(ALU);
2859  } // Inst_SOP1__S_NAND_SAVEEXEC_B64
2860 
2862  {
2863  } // ~Inst_SOP1__S_NAND_SAVEEXEC_B64
2864 
2865  // D.u64 = EXEC;
2866  // EXEC = ~(S0.u64 & EXEC);
2867  // SCC = 1 if the new value of EXEC is non-zero.
2868  void
2870  {
2871  Wavefront *wf = gpuDynInst->wavefront();
2872  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2873  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2874  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2875 
2876  src.read();
2877 
2878  sdst = wf->execMask().to_ullong();
2879  wf->execMask() = ~(src.rawData() & wf->execMask().to_ullong());
2880  scc = wf->execMask().any() ? 1 : 0;
2881 
2882  sdst.write();
2883  scc.write();
2884  }
2885 
2887  InFmt_SOP1 *iFmt)
2888  : Inst_SOP1(iFmt, "s_nor_saveexec_b64")
2889  {
2890  setFlag(ALU);
2891  } // Inst_SOP1__S_NOR_SAVEEXEC_B64
2892 
2894  {
2895  } // ~Inst_SOP1__S_NOR_SAVEEXEC_B64
2896 
2897  // D.u64 = EXEC;
2898  // EXEC = ~(S0.u64 | EXEC);
2899  // SCC = 1 if the new value of EXEC is non-zero.
2900  void
2902  {
2903  Wavefront *wf = gpuDynInst->wavefront();
2904  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2905  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2906  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2907 
2908  src.read();
2909 
2910  sdst = wf->execMask().to_ullong();
2911  wf->execMask() = ~(src.rawData() | wf->execMask().to_ullong());
2912  scc = wf->execMask().any() ? 1 : 0;
2913 
2914  sdst.write();
2915  scc.write();
2916  }
2917 
2919  InFmt_SOP1 *iFmt)
2920  : Inst_SOP1(iFmt, "s_xnor_saveexec_b64")
2921  {
2922  setFlag(ALU);
2923  } // Inst_SOP1__S_XNOR_SAVEEXEC_B64
2924 
2926  {
2927  } // ~Inst_SOP1__S_XNOR_SAVEEXEC_B64
2928 
2929  // D.u64 = EXEC;
2930  // EXEC = ~(S0.u64 ^ EXEC);
2931  // SCC = 1 if the new value of EXEC is non-zero.
2932  void
2934  {
2935  Wavefront *wf = gpuDynInst->wavefront();
2936  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2937  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2938  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2939 
2940  src.read();
2941 
2942  sdst = wf->execMask().to_ullong();
2943  wf->execMask() = ~(src.rawData() ^ wf->execMask().to_ullong());
2944  scc = wf->execMask().any() ? 1 : 0;
2945 
2946  sdst.write();
2947  scc.write();
2948  }
2949 
2951  : Inst_SOP1(iFmt, "s_quadmask_b32")
2952  {
2953  setFlag(ALU);
2954  } // Inst_SOP1__S_QUADMASK_B32
2955 
2957  {
2958  } // ~Inst_SOP1__S_QUADMASK_B32
2959 
2960  // D.u = QuadMask(S0.u):
2961  // D[0] = OR(S0[3:0]), D[1] = OR(S0[7:4]) ... D[31:8] = 0;
2962  // SCC = 1 if result is non-zero.
2963  void
2965  {
2966  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
2967  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
2968  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2969 
2970  src.read();
2971 
2972  sdst = quadMask(src.rawData());
2973  scc = sdst.rawData() ? 1 : 0;
2974 
2975  sdst.write();
2976  scc.write();
2977  }
2978 
2980  : Inst_SOP1(iFmt, "s_quadmask_b64")
2981  {
2982  setFlag(ALU);
2983  } // Inst_SOP1__S_QUADMASK_B64
2984 
2986  {
2987  } // ~Inst_SOP1__S_QUADMASK_B64
2988 
2989  // D.u64 = QuadMask(S0.u64):
2990  // D[0] = OR(S0[3:0]), D[1] = OR(S0[7:4]) ... D[63:16] = 0;
2991  // SCC = 1 if result is non-zero.
2992  void
2994  {
2995  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
2996  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
2997  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
2998 
2999  src.read();
3000 
3001  sdst = quadMask(src.rawData());
3002  scc = sdst.rawData() ? 1 : 0;
3003 
3004  sdst.write();
3005  scc.write();
3006  }
3007 
3009  : Inst_SOP1(iFmt, "s_movrels_b32")
3010  {
3011  setFlag(ALU);
3012  } // Inst_SOP1__S_MOVRELS_B32
3013 
3015  {
3016  } // ~Inst_SOP1__S_MOVRELS_B32
3017 
3018  // D.u = SGPR[S0.u + M0.u].u (move from relative source).
3019  void
3021  {
3022  ConstScalarOperandU32 m0(gpuDynInst, REG_M0);
3023  m0.read();
3024  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0 + m0.rawData());
3025  ScalarOperandU32 sdst(gpuDynInst, instData.SDST);
3026 
3027  src.read();
3028 
3029  sdst = src.rawData();
3030 
3031  sdst.write();
3032  }
3033 
3035  : Inst_SOP1(iFmt, "s_movrels_b64")
3036  {
3037  setFlag(ALU);
3038  } // Inst_SOP1__S_MOVRELS_B64
3039 
3041  {
3042  } // ~Inst_SOP1__S_MOVRELS_B64
3043 
3044  // D.u64 = SGPR[S0.u + M0.u].u64 (move from relative source).
3045  // The index in M0.u must be even for this operation.
3046  void
3048  {
3049  ConstScalarOperandU32 m0(gpuDynInst, REG_M0);
3050  m0.read();
3051  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0 + m0.rawData());
3052  ScalarOperandU64 sdst(gpuDynInst, instData.SDST);
3053 
3054  src.read();
3055 
3056  sdst = src.rawData();
3057 
3058  sdst.write();
3059  }
3060 
3062  : Inst_SOP1(iFmt, "s_movreld_b32")
3063  {
3064  setFlag(ALU);
3065  } // Inst_SOP1__S_MOVRELD_B32
3066 
3068  {
3069  } // ~Inst_SOP1__S_MOVRELD_B32
3070 
3071  // SGPR[D.u + M0.u].u = S0.u (move to relative destination).
3072  void
3074  {
3075  ConstScalarOperandU32 m0(gpuDynInst, REG_M0);
3076  m0.read();
3077  ConstScalarOperandU32 src(gpuDynInst, instData.SSRC0);
3078  ScalarOperandU32 sdst(gpuDynInst, instData.SDST + m0.rawData());
3079 
3080  src.read();
3081 
3082  sdst = src.rawData();
3083 
3084  sdst.write();
3085  }
3086 
3088  : Inst_SOP1(iFmt, "s_movreld_b64")
3089  {
3090  setFlag(ALU);
3091  } // Inst_SOP1__S_MOVRELD_B64
3092 
3094  {
3095  } // ~Inst_SOP1__S_MOVRELD_B64
3096 
3097  // SGPR[D.u + M0.u].u64 = S0.u64 (move to relative destination).
3098  // The index in M0.u must be even for this operation.
3099  void
3101  {
3102  ConstScalarOperandU32 m0(gpuDynInst, REG_M0);
3103  m0.read();
3104  ConstScalarOperandU64 src(gpuDynInst, instData.SSRC0);
3105  ScalarOperandU64 sdst(gpuDynInst, instData.SDST + m0.rawData());
3106 
3107  src.read();
3108 
3109  sdst = src.rawData();
3110 
3111  sdst.write();
3112  }
3113 
3115  : Inst_SOP1(iFmt, "s_cbranch_join")
3116  {
3117  setFlag(Branch);
3118  } // Inst_SOP1__S_CBRANCH_JOIN
3119 
3121  {
3122  } // ~Inst_SOP1__S_CBRANCH_JOIN
3123 
3124  // Conditional branch join point (end of conditional branch block).
3125  void
3127  {
3129  }
3130 
3132  : Inst_SOP1(iFmt, "s_abs_i32")
3133  {
3134  setFlag(ALU);
3135  } // Inst_SOP1__S_ABS_I32
3136 
3138  {
3139  } // ~Inst_SOP1__S_ABS_I32
3140 
3141  // if (S.i < 0) then D.i = -S.i;
3142  // else D.i = S.i;
3143  // SCC = 1 if result is non-zero.
3144  // Integer absolute value.
3145  void
3147  {
3148  ConstScalarOperandI32 src(gpuDynInst, instData.SSRC0);
3149  ScalarOperandI32 sdst(gpuDynInst, instData.SDST);
3150  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3151 
3152  src.read();
3153 
3154  sdst = std::abs(src.rawData());
3155 
3156  scc = sdst.rawData() ? 1 : 0;
3157 
3158  sdst.write();
3159  scc.write();
3160  }
3161 
3163  : Inst_SOP1(iFmt, "s_mov_fed_b32")
3164  {
3165  setFlag(ALU);
3166  } // Inst_SOP1__S_MOV_FED_B32
3167 
3169  {
3170  } // ~Inst_SOP1__S_MOV_FED_B32
3171 
3172  // D.u = S0.u.
3173  void
3175  {
3177  }
3178 
3180  InFmt_SOP1 *iFmt)
3181  : Inst_SOP1(iFmt, "s_set_gpr_idx_idx")
3182  {
3183  } // Inst_SOP1__S_SET_GPR_IDX_IDX
3184 
3186  {
3187  } // ~Inst_SOP1__S_SET_GPR_IDX_IDX
3188 
3189  // M0[7:0] = S0.u[7:0].
3190  // Modify the index used in vector GPR indexing.
3191  void
3193  {
3195  }
3196 
3198  : Inst_SOPC(iFmt, "s_cmp_eq_i32")
3199  {
3200  setFlag(ALU);
3201  } // Inst_SOPC__S_CMP_EQ_I32
3202 
3204  {
3205  } // ~Inst_SOPC__S_CMP_EQ_I32
3206 
3207  // SCC = (S0.i == S1.i).
3208  void
3210  {
3211  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
3212  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
3213  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3214 
3215  src0.read();
3216  src1.read();
3217 
3218  scc = (src0.rawData() == src1.rawData()) ? 1 : 0;
3219 
3220  scc.write();
3221  }
3222 
3224  : Inst_SOPC(iFmt, "s_cmp_lg_i32")
3225  {
3226  setFlag(ALU);
3227  } // Inst_SOPC__S_CMP_LG_I32
3228 
3230  {
3231  } // ~Inst_SOPC__S_CMP_LG_I32
3232 
3233  // SCC = (S0.i != S1.i).
3234  void
3236  {
3237  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
3238  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
3239  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3240 
3241  src0.read();
3242  src1.read();
3243 
3244  scc = (src0.rawData() != src1.rawData()) ? 1 : 0;
3245 
3246  scc.write();
3247  }
3248 
3250  : Inst_SOPC(iFmt, "s_cmp_gt_i32")
3251  {
3252  setFlag(ALU);
3253  } // Inst_SOPC__S_CMP_GT_I32
3254 
3256  {
3257  } // ~Inst_SOPC__S_CMP_GT_I32
3258 
3259  // SCC = (S0.i > S1.i).
3260  void
3262  {
3263  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
3264  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
3265  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3266 
3267  src0.read();
3268  src1.read();
3269 
3270  scc = (src0.rawData() > src1.rawData()) ? 1 : 0;
3271 
3272  scc.write();
3273  }
3274 
3276  : Inst_SOPC(iFmt, "s_cmp_ge_i32")
3277  {
3278  setFlag(ALU);
3279  } // Inst_SOPC__S_CMP_GE_I32
3280 
3282  {
3283  } // ~Inst_SOPC__S_CMP_GE_I32
3284 
3285  // SCC = (S0.i >= S1.i).
3286  void
3288  {
3289  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
3290  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
3291  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3292 
3293  src0.read();
3294  src1.read();
3295 
3296  scc = (src0.rawData() >= src1.rawData()) ? 1 : 0;
3297 
3298  scc.write();
3299  }
3300 
3302  : Inst_SOPC(iFmt, "s_cmp_lt_i32")
3303  {
3304  setFlag(ALU);
3305  } // Inst_SOPC__S_CMP_LT_I32
3306 
3308  {
3309  } // ~Inst_SOPC__S_CMP_LT_I32
3310 
3311  // SCC = (S0.i < S1.i).
3312  void
3314  {
3315  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
3316  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
3317  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3318 
3319  src0.read();
3320  src1.read();
3321 
3322  scc = (src0.rawData() < src1.rawData()) ? 1 : 0;
3323 
3324  scc.write();
3325  }
3326 
3328  : Inst_SOPC(iFmt, "s_cmp_le_i32")
3329  {
3330  setFlag(ALU);
3331  } // Inst_SOPC__S_CMP_LE_I32
3332 
3334  {
3335  } // ~Inst_SOPC__S_CMP_LE_I32
3336 
3337  // SCC = (S0.i <= S1.i).
3338  void
3340  {
3341  ConstScalarOperandI32 src0(gpuDynInst, instData.SSRC0);
3342  ConstScalarOperandI32 src1(gpuDynInst, instData.SSRC1);
3343  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3344 
3345  src0.read();
3346  src1.read();
3347 
3348  scc = (src0.rawData() <= src1.rawData()) ? 1 : 0;
3349 
3350  scc.write();
3351  }
3352 
3354  : Inst_SOPC(iFmt, "s_cmp_eq_u32")
3355  {
3356  setFlag(ALU);
3357  } // Inst_SOPC__S_CMP_EQ_U32
3358 
3360  {
3361  } // ~Inst_SOPC__S_CMP_EQ_U32
3362 
3363  // SCC = (S0.u == S1.u).
3364  void
3366  {
3367  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
3368  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3369  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3370 
3371  src0.read();
3372  src1.read();
3373 
3374  scc = (src0.rawData() == src1.rawData()) ? 1 : 0;
3375 
3376  scc.write();
3377  }
3378 
3380  : Inst_SOPC(iFmt, "s_cmp_lg_u32")
3381  {
3382  setFlag(ALU);
3383  } // Inst_SOPC__S_CMP_LG_U32
3384 
3386  {
3387  } // ~Inst_SOPC__S_CMP_LG_U32
3388 
3389  // SCC = (S0.u != S1.u).
3390  void
3392  {
3393  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
3394  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3395  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3396 
3397  src0.read();
3398  src1.read();
3399 
3400  scc = (src0.rawData() != src1.rawData()) ? 1 : 0;
3401 
3402  scc.write();
3403  }
3404 
3406  : Inst_SOPC(iFmt, "s_cmp_gt_u32")
3407  {
3408  setFlag(ALU);
3409  } // Inst_SOPC__S_CMP_GT_U32
3410 
3412  {
3413  } // ~Inst_SOPC__S_CMP_GT_U32
3414 
3415  // SCC = (S0.u > S1.u).
3416  void
3418  {
3419  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
3420  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3421  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3422 
3423  src0.read();
3424  src1.read();
3425 
3426  scc = (src0.rawData() > src1.rawData()) ? 1 : 0;
3427 
3428  scc.write();
3429  }
3430 
3432  : Inst_SOPC(iFmt, "s_cmp_ge_u32")
3433  {
3434  setFlag(ALU);
3435  } // Inst_SOPC__S_CMP_GE_U32
3436 
3438  {
3439  } // ~Inst_SOPC__S_CMP_GE_U32
3440 
3441  // SCC = (S0.u >= S1.u).
3442  void
3444  {
3445  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
3446  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3447  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3448 
3449  src0.read();
3450  src1.read();
3451 
3452  scc = (src0.rawData() >= src1.rawData()) ? 1 : 0;
3453 
3454  scc.write();
3455  }
3456 
3458  : Inst_SOPC(iFmt, "s_cmp_lt_u32")
3459  {
3460  setFlag(ALU);
3461  } // Inst_SOPC__S_CMP_LT_U32
3462 
3464  {
3465  } // ~Inst_SOPC__S_CMP_LT_U32
3466 
3467  // SCC = (S0.u < S1.u).
3468  void
3470  {
3471  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
3472  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3473  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3474 
3475  src0.read();
3476  src1.read();
3477 
3478  scc = (src0.rawData() <= src1.rawData()) ? 1 : 0;
3479 
3480  scc.write();
3481  }
3482 
3484  : Inst_SOPC(iFmt, "s_cmp_le_u32")
3485  {
3486  setFlag(ALU);
3487  } // Inst_SOPC__S_CMP_LE_U32
3488 
3490  {
3491  } // ~Inst_SOPC__S_CMP_LE_U32
3492 
3493  // SCC = (S0.u <= S1.u).
3494  void
3496  {
3497  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
3498  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3499  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3500 
3501  src0.read();
3502  src1.read();
3503 
3504  scc = (src0.rawData() <= src1.rawData()) ? 1 : 0;
3505 
3506  scc.write();
3507  }
3508 
3510  : Inst_SOPC(iFmt, "s_bitcmp0_b32")
3511  {
3512  setFlag(ALU);
3513  } // Inst_SOPC__S_BITCMP0_B32
3514 
3516  {
3517  } // ~Inst_SOPC__S_BITCMP0_B32
3518 
3519  // SCC = (S0.u[S1.u[4:0]] == 0).
3520  void
3522  {
3523  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
3524  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3525  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3526 
3527  src0.read();
3528  src1.read();
3529 
3530  scc = !bits(src0.rawData(), bits(src1.rawData(), 4, 0)) ? 1 : 0;
3531 
3532  scc.write();
3533  }
3534 
3536  : Inst_SOPC(iFmt, "s_bitcmp1_b32")
3537  {
3538  setFlag(ALU);
3539  } // Inst_SOPC__S_BITCMP1_B32
3540 
3542  {
3543  } // ~Inst_SOPC__S_BITCMP1_B32
3544 
3545  // SCC = (S0.u[S1.u[4:0]] == 1).
3546  void
3548  {
3549  ConstScalarOperandU32 src0(gpuDynInst, instData.SSRC0);
3550  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3551  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3552 
3553  src0.read();
3554  src1.read();
3555 
3556  scc = bits(src0.rawData(), bits(src1.rawData(), 4, 0)) ? 1 : 0;
3557 
3558  scc.write();
3559  }
3560 
3562  : Inst_SOPC(iFmt, "s_bitcmp0_b64")
3563  {
3564  setFlag(ALU);
3565  } // Inst_SOPC__S_BITCMP0_B64
3566 
3568  {
3569  } // ~Inst_SOPC__S_BITCMP0_B64
3570 
3571  // SCC = (S0.u64[S1.u[5:0]] == 0).
3572  void
3574  {
3575  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
3576  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3577  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3578 
3579  src0.read();
3580  src1.read();
3581 
3582  scc = !bits(src0.rawData(), bits(src1.rawData(), 5, 0)) ? 1 : 0;
3583 
3584  scc.write();
3585  }
3586 
3588  : Inst_SOPC(iFmt, "s_bitcmp1_b64")
3589  {
3590  setFlag(ALU);
3591  } // Inst_SOPC__S_BITCMP1_B64
3592 
3594  {
3595  } // ~Inst_SOPC__S_BITCMP1_B64
3596 
3597  // SCC = (S0.u64[S1.u[5:0]] == 1).
3598  void
3600  {
3601  ConstScalarOperandU64 src0(gpuDynInst, instData.SSRC0);
3602  ConstScalarOperandU32 src1(gpuDynInst, instData.SSRC1);
3603  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3604 
3605  src0.read();
3606  src1.read();
3607 
3608  scc = bits(src0.rawData(), bits(src1.rawData(), 5, 0)) ? 1 : 0;
3609 
3610  scc.write();
3611  }
3612 
3614  : Inst_SOPC(iFmt, "s_setvskip")
3615  {
3616  setFlag(UnconditionalJump);
3617  } // Inst_SOPC__S_SETVSKIP
3618 
3620  {
3621  } // ~Inst_SOPC__S_SETVSKIP
3622 
3623  // VSKIP = S0.u[S1.u[4:0]].
3624  // Enables and disables VSKIP mode.
3625  // When VSKIP is enabled, no VOP*/M*BUF/MIMG/DS/FLAT/EXP instuctions are
3626  // issued.
3627  void
3629  {
3631  }
3632 
3634  : Inst_SOPC(iFmt, "s_set_gpr_idx_on")
3635  {
3636  } // Inst_SOPC__S_SET_GPR_IDX_ON
3637 
3639  {
3640  } // ~Inst_SOPC__S_SET_GPR_IDX_ON
3641 
3642  // MODE.gpr_idx_en = 1;
3643  // M0[7:0] = S0.u[7:0];
3644  // M0[15:12] = SIMM4 (direct contents of S1 field);
3645  // Remaining bits of M0 are unmodified.
3646  // Enable GPR indexing mode. Vector operations after this will perform
3647  // relative GPR addressing based on the contents of M0.
3648  // The raw contents of the S1 field are read and used to set the enable
3649  // bits. S1[0] = VSRC0_REL, S1[1] = VSRC1_REL, S1[2] = VSRC2_REL and
3650  // S1[3] = VDST_REL.
3651  void
3653  {
3655  }
3656 
3658  : Inst_SOPC(iFmt, "s_cmp_eq_u64")
3659  {
3660  setFlag(ALU);
3661  } // Inst_SOPC__S_CMP_EQ_U64
3662 
3664  {
3665  } // ~Inst_SOPC__S_CMP_EQ_U64
3666 
3667  // SCC = (S0.i64 == S1.i64).
3668  void
3670  {
3671  ConstScalarOperandI64 src0(gpuDynInst, instData.SSRC0);
3672  ConstScalarOperandI64 src1(gpuDynInst, instData.SSRC1);
3673  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3674 
3675  src0.read();
3676  src1.read();
3677 
3678  scc = (src0.rawData() == src1.rawData()) ? 1 : 0;
3679 
3680  scc.write();
3681  }
3682 
3684  : Inst_SOPC(iFmt, "s_cmp_lg_u64")
3685  {
3686  setFlag(ALU);
3687  } // Inst_SOPC__S_CMP_LG_U64
3688 
3690  {
3691  } // ~Inst_SOPC__S_CMP_LG_U64
3692 
3693  // SCC = (S0.i64 != S1.i64).
3694  void
3696  {
3697  ConstScalarOperandI64 src0(gpuDynInst, instData.SSRC0);
3698  ConstScalarOperandI64 src1(gpuDynInst, instData.SSRC1);
3699  ScalarOperandU32 scc(gpuDynInst, REG_SCC);
3700 
3701  src0.read();
3702  src1.read();
3703 
3704  scc = (src0.rawData() != src1.rawData()) ? 1 : 0;
3705 
3706  scc.write();
3707  }
3708 
3710  : Inst_SOPP(iFmt, "s_nop")
3711  {
3712  setFlag(Nop);
3713  } // Inst_SOPP__S_NOP
3714 
3716  {
3717  } // ~Inst_SOPP__S_NOP
3718 
3719  // Do nothing.
3720  void
3722  {
3723  }
3724 
3726  : Inst_SOPP(iFmt, "s_endpgm")
3727  {
3728  setFlag(EndOfKernel);
3729  } // Inst_SOPP__S_ENDPGM
3730 
3732  {
3733  } // ~Inst_SOPP__S_ENDPGM
3734 
3735  // End of program; terminate wavefront.
3736  void
3738  {
3739  Wavefront *wf = gpuDynInst->wavefront();
3740  ComputeUnit *cu = gpuDynInst->computeUnit();
3741 
3742  // delete extra instructions fetched for completed work-items
3743  wf->instructionBuffer.erase(wf->instructionBuffer.begin() + 1,
3744  wf->instructionBuffer.end());
3745 
3746  if (wf->pendingFetch) {
3747  wf->dropFetch = true;
3748  }
3749 
3751  .flushBuf(wf->wfSlotId);
3753 
3754  int refCount = wf->computeUnit->getLds()
3755  .decreaseRefCounter(wf->dispatchId, wf->wgId);
3756 
3762  int bar_id = WFBarrier::InvalidID;
3763  if (wf->hasBarrier()) {
3764  assert(wf->getStatus() != Wavefront::S_BARRIER);
3765  bar_id = wf->barrierId();
3766  assert(bar_id != WFBarrier::InvalidID);
3767  wf->releaseBarrier();
3768  cu->decMaxBarrierCnt(bar_id);
3769  DPRINTF(GPUSync, "CU[%d] WF[%d][%d] Wave[%d] - Exiting the "
3770  "program and decrementing max barrier count for "
3771  "barrier Id%d. New max count: %d.\n", cu->cu_id,
3772  wf->simdId, wf->wfSlotId, wf->wfDynId, bar_id,
3773  cu->maxBarrierCnt(bar_id));
3774  }
3775 
3776  DPRINTF(GPUExec, "CU%d: decrease ref ctr WG[%d] to [%d]\n",
3777  wf->computeUnit->cu_id, wf->wgId, refCount);
3778 
3780  wf->computeUnit->completedWfs++;
3781  wf->computeUnit->activeWaves--;
3782 
3783  panic_if(wf->computeUnit->activeWaves < 0, "CU[%d] Active waves less "
3784  "than zero\n", wf->computeUnit->cu_id);
3785 
3786  DPRINTF(GPUExec, "Doing return for CU%d: WF[%d][%d][%d]\n",
3787  wf->computeUnit->cu_id, wf->simdId, wf->wfSlotId, wf->wfDynId);
3788 
3789  for (int i = 0; i < wf->vecReads.size(); i++) {
3790  if (wf->rawDist.find(i) != wf->rawDist.end()) {
3791  wf->readsPerWrite.sample(wf->vecReads.at(i));
3792  }
3793  }
3794  wf->vecReads.clear();
3795  wf->rawDist.clear();
3796  wf->lastInstExec = 0;
3797 
3798  if (!refCount) {
3805  if (bar_id != WFBarrier::InvalidID) {
3806  DPRINTF(GPUSync, "CU[%d] WF[%d][%d] Wave[%d] - All waves are "
3807  "now complete. Releasing barrier Id%d.\n", cu->cu_id,
3808  wf->simdId, wf->wfSlotId, wf->wfDynId,
3809  wf->barrierId());
3810  cu->releaseBarrier(bar_id);
3811  }
3812 
3820  // check whether the workgroup is indicating the kernel end (i.e.,
3821  // the last workgroup in the kernel).
3822  bool kernelEnd =
3824  // further check whether 'release @ kernel end' is needed
3825  bool relNeeded =
3827 
3828  // if not a kernel end or no release needed, retire the workgroup
3829  // directly
3830  if (!kernelEnd || !relNeeded) {
3833  wf->computeUnit->completedWGs++;
3834 
3835  return;
3836  }
3837 
3842  setFlag(MemSync);
3843  setFlag(GlobalSegment);
3844  // Notify Memory System of Kernel Completion
3846  gpuDynInst->simdId = wf->simdId;
3847  gpuDynInst->wfSlotId = wf->wfSlotId;
3848  gpuDynInst->wfDynId = wf->wfDynId;
3849 
3850  DPRINTF(GPUExec, "inject global memory fence for CU%d: "
3851  "WF[%d][%d][%d]\n", wf->computeUnit->cu_id,
3852  wf->simdId, wf->wfSlotId, wf->wfDynId);
3853 
3854  // call shader to prepare the flush operations
3855  wf->computeUnit->shader->prepareFlush(gpuDynInst);
3856 
3857  wf->computeUnit->completedWGs++;
3858  } else {
3860  }
3861  }
3862 
3863 
3865  : Inst_SOPP(iFmt, "s_branch")
3866  {
3867  setFlag(Branch);
3868  } // Inst_SOPP__S_BRANCH
3869 
3871  {
3872  } // ~Inst_SOPP__S_BRANCH
3873 
3874  // PC = PC + signext(SIMM16 * 4) + 4 (short jump).
3875  void
3877  {
3878  Wavefront *wf = gpuDynInst->wavefront();
3879  Addr pc = wf->pc();
3880  ScalarRegI16 simm16 = instData.SIMM16;
3881 
3882  pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
3883 
3884  wf->pc(pc);
3885  }
3886 
3888  : Inst_SOPP(iFmt, "s_wakeup")
3889  {
3890  } // Inst_SOPP__S_WAKEUP
3891 
3893  {
3894  } // ~Inst_SOPP__S_WAKEUP
3895 
3896  // Allow a wave to wakeup all the other waves in its workgroup to force
3897  // them to wake up immediately from an S_SLEEP instruction. The wakeup is
3898  // ignored if the waves are not sleeping.
3899  void
3901  {
3903  }
3904 
3906  : Inst_SOPP(iFmt, "s_cbranch_scc0")
3907  {
3908  setFlag(Branch);
3909  } // Inst_SOPP__S_CBRANCH_SCC0
3910 
3912  {
3913  } // ~Inst_SOPP__S_CBRANCH_SCC0
3914 
3915  // if (SCC == 0) then PC = PC + signext(SIMM16 * 4) + 4;
3916  // else NOP.
3917  void
3919  {
3920  Wavefront *wf = gpuDynInst->wavefront();
3921  Addr pc = wf->pc();
3922  ScalarRegI16 simm16 = instData.SIMM16;
3923  ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);
3924 
3925  scc.read();
3926 
3927  if (!scc.rawData()) {
3928  pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
3929  }
3930 
3931  wf->pc(pc);
3932  }
3933 
3935  : Inst_SOPP(iFmt, "s_cbranch_scc1")
3936  {
3937  setFlag(Branch);
3938  } // Inst_SOPP__S_CBRANCH_SCC1
3939 
3941  {
3942  } // ~Inst_SOPP__S_CBRANCH_SCC1
3943 
3944  // if (SCC == 1) then PC = PC + signext(SIMM16 * 4) + 4;
3945  // else NOP.
3946  void
3948  {
3949  Wavefront *wf = gpuDynInst->wavefront();
3950  Addr pc = wf->pc();
3951  ScalarRegI16 simm16 = instData.SIMM16;
3952  ConstScalarOperandU32 scc(gpuDynInst, REG_SCC);
3953 
3954  scc.read();
3955 
3956  if (scc.rawData()) {
3957  pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
3958  }
3959 
3960  wf->pc(pc);
3961  }
3962 
3964  : Inst_SOPP(iFmt, "s_cbranch_vccz")
3965  {
3966  setFlag(Branch);
3967  setFlag(ReadsVCC);
3968  } // Inst_SOPP__S_CBRANCH_VCCZ
3969 
3971  {
3972  } // ~Inst_SOPP__S_CBRANCH_VCCZ
3973 
3974  // if (VCC == 0) then PC = PC + signext(SIMM16 * 4) + 4;
3975  // else NOP.
3976  void
3978  {
3979  Wavefront *wf = gpuDynInst->wavefront();
3980  ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);
3981  Addr pc = wf->pc();
3982  ScalarRegI16 simm16 = instData.SIMM16;
3983 
3984  vcc.read();
3985 
3986  if (!vcc.rawData()) {
3987  pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
3988  }
3989 
3990  wf->pc(pc);
3991  }
3992 
3994  : Inst_SOPP(iFmt, "s_cbranch_vccnz")
3995  {
3996  setFlag(Branch);
3997  setFlag(ReadsVCC);
3998  } // Inst_SOPP__S_CBRANCH_VCCNZ
3999 
4001  {
4002  } // ~Inst_SOPP__S_CBRANCH_VCCNZ
4003 
4004  // if (VCC != 0) then PC = PC + signext(SIMM16 * 4) + 4;
4005  // else NOP.
4006  void
4008  {
4009  Wavefront *wf = gpuDynInst->wavefront();
4010  ConstScalarOperandU64 vcc(gpuDynInst, REG_VCC_LO);
4011 
4012  vcc.read();
4013 
4014  if (vcc.rawData()) {
4015  Addr pc = wf->pc();
4016  ScalarRegI16 simm16 = instData.SIMM16;
4017  pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
4018  wf->pc(pc);
4019  }
4020  }
4021 
4023  : Inst_SOPP(iFmt, "s_cbranch_execz")
4024  {
4025  setFlag(Branch);
4026  } // Inst_SOPP__S_CBRANCH_EXECZ
4027 
4029  {
4030  } // ~Inst_SOPP__S_CBRANCH_EXECZ
4031 
4032  // if (EXEC == 0) then PC = PC + signext(SIMM16 * 4) + 4;
4033  // else NOP.
4034  void
4036  {
4037  Wavefront *wf = gpuDynInst->wavefront();
4038 
4039  if (wf->execMask().none()) {
4040  Addr pc = wf->pc();
4041  ScalarRegI16 simm16 = instData.SIMM16;
4042  pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
4043  wf->pc(pc);
4044  }
4045  }
4046 
4048  : Inst_SOPP(iFmt, "s_cbranch_execnz")
4049  {
4050  setFlag(Branch);
4051  } // Inst_SOPP__S_CBRANCH_EXECNZ
4052 
4054  {
4055  } // ~Inst_SOPP__S_CBRANCH_EXECNZ
4056 
4057  // if (EXEC != 0) then PC = PC + signext(SIMM16 * 4) + 4;
4058  // else NOP.
4059  void
4061  {
4062  Wavefront *wf = gpuDynInst->wavefront();
4063 
4064  if (wf->execMask().any()) {
4065  Addr pc = wf->pc();
4066  ScalarRegI16 simm16 = instData.SIMM16;
4067  pc = pc + ((ScalarRegI64)simm16 * 4LL) + 4LL;
4068  wf->pc(pc);
4069  }
4070  }
4071 
4073  : Inst_SOPP(iFmt, "s_barrier")
4074  {
4075  setFlag(MemBarrier);
4076  } // Inst_SOPP__S_BARRIER
4077 
4079  {
4080  } // ~Inst_SOPP__S_BARRIER
4081 
4088  void
4090  {
4091  Wavefront *wf = gpuDynInst->wavefront();
4092  ComputeUnit *cu = gpuDynInst->computeUnit();
4093 
4094  if (wf->hasBarrier()) {
4095  int bar_id = wf->barrierId();
4096  assert(wf->getStatus() != Wavefront::S_BARRIER);
4098  cu->incNumAtBarrier(bar_id);
4099  DPRINTF(GPUSync, "CU[%d] WF[%d][%d] Wave[%d] - Stalling at "
4100  "barrier Id%d. %d waves now at barrier, %d waves "
4101  "remain.\n", cu->cu_id, wf->simdId, wf->wfSlotId,
4102  wf->wfDynId, bar_id, cu->numAtBarrier(bar_id),
4103  cu->numYetToReachBarrier(bar_id));
4104  }
4105  } // execute
4106  // --- Inst_SOPP__S_SETKILL class methods ---
4107 
4109  : Inst_SOPP(iFmt, "s_setkill")
4110  {
4111  } // Inst_SOPP__S_SETKILL
4112 
4114  {
4115  } // ~Inst_SOPP__S_SETKILL
4116 
4117  void
4119  {
4121  }
4122 
4124  : Inst_SOPP(iFmt, "s_waitcnt")
4125  {
4126  setFlag(ALU);
4127  setFlag(Waitcnt);
4128  } // Inst_SOPP__S_WAITCNT
4129 
4131  {
4132  } // ~Inst_SOPP__S_WAITCNT
4133 
4134  // Wait for the counts of outstanding lds, vector-memory and
4135  // export/vmem-write-data to be at or below the specified levels.
4136  // SIMM16[3:0] = vmcount (vector memory operations),
4137  // SIMM16[6:4] = export/mem-write-data count,
4138  // SIMM16[12:8] = LGKM_cnt (scalar-mem/GDS/LDS count).
4139  void
4141  {
4142  ScalarRegI32 vm_cnt = 0;
4143  ScalarRegI32 exp_cnt = 0;
4144  ScalarRegI32 lgkm_cnt = 0;
4145  vm_cnt = bits<ScalarRegI16>(instData.SIMM16, 3, 0);
4146  exp_cnt = bits<ScalarRegI16>(instData.SIMM16, 6, 4);
4147  lgkm_cnt = bits<ScalarRegI16>(instData.SIMM16, 12, 8);
4148  gpuDynInst->wavefront()->setWaitCnts(vm_cnt, exp_cnt, lgkm_cnt);
4149  }
4150 
4152  : Inst_SOPP(iFmt, "s_sethalt")
4153  {
4154  } // Inst_SOPP__S_SETHALT
4155 
4157  {
4158  } // ~Inst_SOPP__S_SETHALT
4159 
4160  void
4162  {
4164  }
4165 
4167  : Inst_SOPP(iFmt, "s_sleep")
4168  {
4169  } // Inst_SOPP__S_SLEEP
4170 
4172  {
4173  } // ~Inst_SOPP__S_SLEEP
4174 
4175  // Cause a wave to sleep for (64 * SIMM16[2:0] + 1..64) clocks.
4176  void
4178  {
4180  }
4181 
4183  : Inst_SOPP(iFmt, "s_setprio")
4184  {
4185  } // Inst_SOPP__S_SETPRIO
4186 
4188  {
4189  } // ~Inst_SOPP__S_SETPRIO
4190 
4191  // User settable wave priority is set to SIMM16[1:0]. 0 = lowest,
4192  // 3 = highest.
4193  void
4195  {
4197  }
4198 
4200  : Inst_SOPP(iFmt, "s_sendmsg")
4201  {
4202  } // Inst_SOPP__S_SENDMSG
4203 
4205  {
4206  } // ~Inst_SOPP__S_SENDMSG
4207 
4208  void
4210  {
4212  }
4213 
4215  : Inst_SOPP(iFmt, "s_sendmsghalt")
4216  {
4217  } // Inst_SOPP__S_SENDMSGHALT
4218 
4220  {
4221  } // ~Inst_SOPP__S_SENDMSGHALT
4222 
4223  void
4225  {
4227  }
4228 
4230  : Inst_SOPP(iFmt, "s_trap")
4231  {
4232  } // Inst_SOPP__S_TRAP
4233 
4235  {
4236  } // ~Inst_SOPP__S_TRAP
4237 
4238  // Enter the trap handler.
4239  void
4241  {
4243  }
4244 
4246  : Inst_SOPP(iFmt, "s_icache_inv")
4247  {
4248  } // Inst_SOPP__S_ICACHE_INV
4249 
4251  {
4252  } // ~Inst_SOPP__S_ICACHE_INV
4253 
4254  // Invalidate entire L1 instruction cache.
4255  void
4257  {
4259  }
4260 
4262  : Inst_SOPP(iFmt, "s_incperflevel")
4263  {
4264  } // Inst_SOPP__S_INCPERFLEVEL
4265 
4267  {
4268  } // ~Inst_SOPP__S_INCPERFLEVEL
4269 
4270  void
4272  {
4274  }
4275 
4277  : Inst_SOPP(iFmt, "s_decperflevel")
4278  {
4279  } // Inst_SOPP__S_DECPERFLEVEL
4280 
4282  {
4283  } // ~Inst_SOPP__S_DECPERFLEVEL
4284 
4285  void
4287  {
4289  }
4290 
4292  : Inst_SOPP(iFmt, "s_ttracedata")
4293  {
4294  } // Inst_SOPP__S_TTRACEDATA
4295 
4297  {
4298  } // ~Inst_SOPP__S_TTRACEDATA
4299 
4300  void
4302  {
4304  }
4305 
4307  InFmt_SOPP *iFmt)
4308  : Inst_SOPP(iFmt, "s_cbranch_cdbgsys")
4309  {
4310  setFlag(Branch);
4311  } // Inst_SOPP__S_CBRANCH_CDBGSYS
4312 
4314  {
4315  } // ~Inst_SOPP__S_CBRANCH_CDBGSYS
4316 
4317  void
4319  {
4321  }
4322 
4324  InFmt_SOPP *iFmt)
4325  : Inst_SOPP(iFmt, "s_cbranch_cdbguser")
4326  {
4327  setFlag(Branch);
4328  } // Inst_SOPP__S_CBRANCH_CDBGUSER
4329 
4331  {
4332  } // ~Inst_SOPP__S_CBRANCH_CDBGUSER
4333 
4334  void
4336  {
4338  }
4339 
4341  InFmt_SOPP *iFmt)
4342  : Inst_SOPP(iFmt, "s_cbranch_cdbgsys_or_user")
4343  {
4344  setFlag(Branch);
4345  } // Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER
4346 
4349  {
4350  } // ~Inst_SOPP__S_CBRANCH_CDBGSYS_OR_USER
4351 
4352  void
4354  {
4356  }
4357 
4360  : Inst_SOPP(iFmt, "s_cbranch_cdbgsys_and_user")
4361  {
4362  setFlag(Branch);
4363  } // Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER
4364 
4367  {
4368  } // ~Inst_SOPP__S_CBRANCH_CDBGSYS_AND_USER
4369 
4370  void
4372  {
4374  }
4375 
4377  : Inst_SOPP(iFmt, "s_endpgm_saved")
4378  {
4379  } // Inst_SOPP__S_ENDPGM_SAVED
4380 
4382  {
4383  } // ~Inst_SOPP__S_ENDPGM_SAVED
4384 
4385  // End of program.
4386  void
4388  {
4390  }
4391 
4393  InFmt_SOPP *iFmt)
4394  : Inst_SOPP(iFmt, "s_set_gpr_idx_off")
4395  {
4396  } // Inst_SOPP__S_SET_GPR_IDX_OFF
4397 
4399  {
4400  } // ~Inst_SOPP__S_SET_GPR_IDX_OFF
4401 
4402  // MODE.gpr_idx_en = 0.
4403  // Clear GPR indexing mode. Vector operations after this will not perform
4404  // relative GPR addressing regardless of the contents of M0.
4405  void
4407  {
4409  }
4410 
4412  InFmt_SOPP *iFmt)
4413  : Inst_SOPP(iFmt, "s_set_gpr_idx_mode")
4414  {
4415  } // Inst_SOPP__S_SET_GPR_IDX_MODE
4416 
4418  {
4419  } // ~Inst_SOPP__S_SET_GPR_IDX_MODE
4420 
4421  // M0[15:12] = SIMM4.
4422  // Modify the mode used for vector GPR indexing.
4423  // The raw contents of the source field are read and used to set the enable
4424  // bits. SIMM4[0] = VSRC0_REL, SIMM4[1] = VSRC1_REL, SIMM4[2] = VSRC2_REL
4425  // and SIMM4[3] = VDST_REL.
4426  void
4428  {
4430  }
4431 
4433  : Inst_SMEM(iFmt, "s_load_dword")
4434  {
4435  setFlag(MemoryRef);
4436  setFlag(Load);
4437  } // Inst_SMEM__S_LOAD_DWORD
4438 
4440  {
4441  } // ~Inst_SMEM__S_LOAD_DWORD
4442 
4449  void
4451  {
4452  Wavefront *wf = gpuDynInst->wavefront();
4453  gpuDynInst->execUnitId = wf->execUnitId;
4454  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4455  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4456  ScalarRegU32 offset(0);
4457  ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
4458 
4459  addr.read();
4460 
4461  if (instData.IMM) {
4462  offset = extData.OFFSET;
4463  } else {
4464  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4465  off_sgpr.read();
4466  offset = off_sgpr.rawData();
4467  }
4468 
4469  calcAddr(gpuDynInst, addr, offset);
4470 
4471  gpuDynInst->computeUnit()->scalarMemoryPipe
4472  .getGMReqFIFO().push(gpuDynInst);
4473 
4474  wf->scalarRdGmReqsInPipe--;
4476  gpuDynInst->wavefront()->outstandingReqs++;
4477  gpuDynInst->wavefront()->validateRequestCounters();
4478  }
4479 
4480  void
4482  {
4483  initMemRead<1>(gpuDynInst);
4484  } // initiateAcc
4485 
4486  void
4488  {
4489  ScalarOperandU32 sdst(gpuDynInst, instData.SDATA);
4490  sdst.write();
4491  } // completeAcc
4492 
4494  : Inst_SMEM(iFmt, "s_load_dwordx2")
4495  {
4496  setFlag(MemoryRef);
4497  setFlag(Load);
4498  } // Inst_SMEM__S_LOAD_DWORDX2
4499 
4501  {
4502  } // ~Inst_SMEM__S_LOAD_DWORDX2
4503 
4508  void
4510  {
4511  Wavefront *wf = gpuDynInst->wavefront();
4512  gpuDynInst->execUnitId = wf->execUnitId;
4513  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4514  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4515  ScalarRegU32 offset(0);
4516  ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
4517 
4518  addr.read();
4519 
4520  if (instData.IMM) {
4521  offset = extData.OFFSET;
4522  } else {
4523  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4524  off_sgpr.read();
4525  offset = off_sgpr.rawData();
4526  }
4527 
4528  calcAddr(gpuDynInst, addr, offset);
4529 
4530  gpuDynInst->computeUnit()->scalarMemoryPipe.
4531  getGMReqFIFO().push(gpuDynInst);
4532 
4533  wf->scalarRdGmReqsInPipe--;
4535  gpuDynInst->wavefront()->outstandingReqs++;
4536  gpuDynInst->wavefront()->validateRequestCounters();
4537  }
4538 
4539  void
4541  {
4542  initMemRead<2>(gpuDynInst);
4543  } // initiateAcc
4544 
4545  void
4547  {
4548  ScalarOperandU64 sdst(gpuDynInst, instData.SDATA);
4549  sdst.write();
4550  } // completeAcc
4551 
4553  : Inst_SMEM(iFmt, "s_load_dwordx4")
4554  {
4555  setFlag(MemoryRef);
4556  setFlag(Load);
4557  } // Inst_SMEM__S_LOAD_DWORDX4
4558 
4560  {
4561  } // ~Inst_SMEM__S_LOAD_DWORDX4
4562 
4563  // Read 4 dwords from scalar data cache. See S_LOAD_DWORD for details on
4564  // the offset input.
4565  void
4567  {
4568  Wavefront *wf = gpuDynInst->wavefront();
4569  gpuDynInst->execUnitId = wf->execUnitId;
4570  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4571  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4572  ScalarRegU32 offset(0);
4573  ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
4574 
4575  addr.read();
4576 
4577  if (instData.IMM) {
4578  offset = extData.OFFSET;
4579  } else {
4580  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4581  off_sgpr.read();
4582  offset = off_sgpr.rawData();
4583  }
4584 
4585  calcAddr(gpuDynInst, addr, offset);
4586 
4587  gpuDynInst->computeUnit()->scalarMemoryPipe.
4588  getGMReqFIFO().push(gpuDynInst);
4589 
4590  wf->scalarRdGmReqsInPipe--;
4592  gpuDynInst->wavefront()->outstandingReqs++;
4593  gpuDynInst->wavefront()->validateRequestCounters();
4594  }
4595 
4596  void
4598  {
4599  initMemRead<4>(gpuDynInst);
4600  } // initiateAcc
4601 
4602  void
4604  {
4605  ScalarOperandU128 sdst(gpuDynInst, instData.SDATA);
4606  sdst.write();
4607  } // completeAcc
4608 
4610  : Inst_SMEM(iFmt, "s_load_dwordx8")
4611  {
4612  setFlag(MemoryRef);
4613  setFlag(Load);
4614  } // Inst_SMEM__S_LOAD_DWORDX8
4615 
4617  {
4618  } // ~Inst_SMEM__S_LOAD_DWORDX8
4619 
4620  // Read 8 dwords from scalar data cache. See S_LOAD_DWORD for details on
4621  // the offset input.
4622  void
4624  {
4625  Wavefront *wf = gpuDynInst->wavefront();
4626  gpuDynInst->execUnitId = wf->execUnitId;
4627  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4628  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4629  ScalarRegU32 offset(0);
4630  ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
4631 
4632  addr.read();
4633 
4634  if (instData.IMM) {
4635  offset = extData.OFFSET;
4636  } else {
4637  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4638  off_sgpr.read();
4639  offset = off_sgpr.rawData();
4640  }
4641 
4642  calcAddr(gpuDynInst, addr, offset);
4643 
4644  gpuDynInst->computeUnit()->scalarMemoryPipe.
4645  getGMReqFIFO().push(gpuDynInst);
4646 
4647  wf->scalarRdGmReqsInPipe--;
4649  gpuDynInst->wavefront()->outstandingReqs++;
4650  gpuDynInst->wavefront()->validateRequestCounters();
4651  }
4652 
4653  void
4655  {
4656  initMemRead<8>(gpuDynInst);
4657  } // initiateAcc
4658 
4659  void
4661  {
4662  ScalarOperandU256 sdst(gpuDynInst, instData.SDATA);
4663  sdst.write();
4664  } // completeAcc
4665 
4667  : Inst_SMEM(iFmt, "s_load_dwordx16")
4668  {
4669  setFlag(MemoryRef);
4670  setFlag(Load);
4671  } // Inst_SMEM__S_LOAD_DWORDX16
4672 
4674  {
4675  } // ~Inst_SMEM__S_LOAD_DWORDX16
4676 
4677  // Read 16 dwords from scalar data cache. See S_LOAD_DWORD for details on
4678  // the offset input.
4679  void
4681  {
4682  Wavefront *wf = gpuDynInst->wavefront();
4683  gpuDynInst->execUnitId = wf->execUnitId;
4684  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4685  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4686  ScalarRegU32 offset(0);
4687  ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
4688 
4689  addr.read();
4690 
4691  if (instData.IMM) {
4692  offset = extData.OFFSET;
4693  } else {
4694  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4695  off_sgpr.read();
4696  offset = off_sgpr.rawData();
4697  }
4698 
4699  calcAddr(gpuDynInst, addr, offset);
4700 
4701  gpuDynInst->computeUnit()->scalarMemoryPipe.
4702  getGMReqFIFO().push(gpuDynInst);
4703 
4704  wf->scalarRdGmReqsInPipe--;
4706  gpuDynInst->wavefront()->outstandingReqs++;
4707  gpuDynInst->wavefront()->validateRequestCounters();
4708  }
4709 
4710  void
4712  {
4713  initMemRead<16>(gpuDynInst);
4714  } // initiateAcc
4715 
4716  void
4718  {
4719  ScalarOperandU512 sdst(gpuDynInst, instData.SDATA);
4720  sdst.write();
4721  } // completeAcc
4722 
4724  InFmt_SMEM *iFmt)
4725  : Inst_SMEM(iFmt, "s_buffer_load_dword")
4726  {
4727  setFlag(MemoryRef);
4728  setFlag(Load);
4729  } // Inst_SMEM__S_BUFFER_LOAD_DWORD
4730 
4732  {
4733  } // ~Inst_SMEM__S_BUFFER_LOAD_DWORD
4734 
4735  // Read 1 dword from scalar data cache. See S_LOAD_DWORD for details on the
4736  // offset input.
4737  void
4739  {
4740  Wavefront *wf = gpuDynInst->wavefront();
4741  gpuDynInst->execUnitId = wf->execUnitId;
4742  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4743  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4744  ScalarRegU32 offset(0);
4745  ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);
4746 
4747  rsrcDesc.read();
4748 
4749  if (instData.IMM) {
4750  offset = extData.OFFSET;
4751  } else {
4752  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4753  off_sgpr.read();
4754  offset = off_sgpr.rawData();
4755  }
4756 
4757  calcAddr(gpuDynInst, rsrcDesc, offset);
4758 
4759  gpuDynInst->computeUnit()->scalarMemoryPipe
4760  .getGMReqFIFO().push(gpuDynInst);
4761 
4762  wf->scalarRdGmReqsInPipe--;
4764  gpuDynInst->wavefront()->outstandingReqs++;
4765  gpuDynInst->wavefront()->validateRequestCounters();
4766  } // execute
4767 
4768  void
4770  {
4771  initMemRead<1>(gpuDynInst);
4772  } // initiateAcc
4773 
4774  void
4776  {
4777  // 1 request, size 32
4778  ScalarOperandU32 sdst(gpuDynInst, instData.SDATA);
4779  sdst.write();
4780  } // completeAcc
4781 
4783  InFmt_SMEM *iFmt)
4784  : Inst_SMEM(iFmt, "s_buffer_load_dwordx2")
4785  {
4786  setFlag(MemoryRef);
4787  setFlag(Load);
4788  } // Inst_SMEM__S_BUFFER_LOAD_DWORDX2
4789 
4791  {
4792  } // ~Inst_SMEM__S_BUFFER_LOAD_DWORDX2
4793 
4794  // Read 2 dwords from scalar data cache. See S_LOAD_DWORD for details on
4795  // the offset input.
4796  void
4798  {
4799  Wavefront *wf = gpuDynInst->wavefront();
4800  gpuDynInst->execUnitId = wf->execUnitId;
4801  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4802  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4803  ScalarRegU32 offset(0);
4804  ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);
4805 
4806  rsrcDesc.read();
4807 
4808  if (instData.IMM) {
4809  offset = extData.OFFSET;
4810  } else {
4811  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4812  off_sgpr.read();
4813  offset = off_sgpr.rawData();
4814  }
4815 
4816  calcAddr(gpuDynInst, rsrcDesc, offset);
4817 
4818  gpuDynInst->computeUnit()->scalarMemoryPipe
4819  .getGMReqFIFO().push(gpuDynInst);
4820 
4821  wf->scalarRdGmReqsInPipe--;
4823  gpuDynInst->wavefront()->outstandingReqs++;
4824  gpuDynInst->wavefront()->validateRequestCounters();
4825  } // execute
4826 
4827  void
4829  {
4830  initMemRead<2>(gpuDynInst);
4831  } // initiateAcc
4832 
4833  void
4835  {
4836  // use U64 because 2 requests, each size 32
4837  ScalarOperandU64 sdst(gpuDynInst, instData.SDATA);
4838  sdst.write();
4839  } // completeAcc
4840 
4842  InFmt_SMEM *iFmt)
4843  : Inst_SMEM(iFmt, "s_buffer_load_dwordx4")
4844  {
4845  setFlag(MemoryRef);
4846  setFlag(Load);
4847  } // Inst_SMEM__S_BUFFER_LOAD_DWORDX4
4848 
4850  {
4851  } // ~Inst_SMEM__S_BUFFER_LOAD_DWORDX4
4852 
4853  // Read 4 dwords from scalar data cache. See S_LOAD_DWORD for details on
4854  // the offset input.
4855  void
4857  {
4858  Wavefront *wf = gpuDynInst->wavefront();
4859  gpuDynInst->execUnitId = wf->execUnitId;
4860  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4861  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4862  ScalarRegU32 offset(0);
4863  ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);
4864 
4865  rsrcDesc.read();
4866 
4867  if (instData.IMM) {
4868  offset = extData.OFFSET;
4869  } else {
4870  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4871  off_sgpr.read();
4872  offset = off_sgpr.rawData();
4873  }
4874 
4875  calcAddr(gpuDynInst, rsrcDesc, offset);
4876 
4877  gpuDynInst->computeUnit()->scalarMemoryPipe
4878  .getGMReqFIFO().push(gpuDynInst);
4879 
4880  wf->scalarRdGmReqsInPipe--;
4882  gpuDynInst->wavefront()->outstandingReqs++;
4883  gpuDynInst->wavefront()->validateRequestCounters();
4884  } // execute
4885 
4886  void
4888  {
4889  initMemRead<4>(gpuDynInst);
4890  } // initiateAcc
4891 
4892  void
4894  {
4895  // 4 requests, each size 32
4896  ScalarOperandU128 sdst(gpuDynInst, instData.SDATA);
4897  sdst.write();
4898  } // completeAcc
4899 
4901  InFmt_SMEM *iFmt)
4902  : Inst_SMEM(iFmt, "s_buffer_load_dwordx8")
4903  {
4904  setFlag(MemoryRef);
4905  setFlag(Load);
4906  } // Inst_SMEM__S_BUFFER_LOAD_DWORDX8
4907 
4909  {
4910  } // ~Inst_SMEM__S_BUFFER_LOAD_DWORDX8
4911 
4912  // Read 8 dwords from scalar data cache. See S_LOAD_DWORD for details on
4913  // the offset input.
4914  void
4916  {
4917  Wavefront *wf = gpuDynInst->wavefront();
4918  gpuDynInst->execUnitId = wf->execUnitId;
4919  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4920  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4921  ScalarRegU32 offset(0);
4922  ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);
4923 
4924  rsrcDesc.read();
4925 
4926  if (instData.IMM) {
4927  offset = extData.OFFSET;
4928  } else {
4929  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4930  off_sgpr.read();
4931  offset = off_sgpr.rawData();
4932  }
4933 
4934  calcAddr(gpuDynInst, rsrcDesc, offset);
4935 
4936  gpuDynInst->computeUnit()->scalarMemoryPipe
4937  .getGMReqFIFO().push(gpuDynInst);
4938 
4939  wf->scalarRdGmReqsInPipe--;
4941  gpuDynInst->wavefront()->outstandingReqs++;
4942  gpuDynInst->wavefront()->validateRequestCounters();
4943  } // execute
4944 
4945  void
4947  {
4948  initMemRead<8>(gpuDynInst);
4949  } // initiateAcc
4950 
4951  void
4953  {
4954  // 8 requests, each size 32
4955  ScalarOperandU256 sdst(gpuDynInst, instData.SDATA);
4956  sdst.write();
4957  } // completeAcc
4958 
4960  InFmt_SMEM *iFmt)
4961  : Inst_SMEM(iFmt, "s_buffer_load_dwordx16")
4962  {
4963  setFlag(MemoryRef);
4964  setFlag(Load);
4965  } // Inst_SMEM__S_BUFFER_LOAD_DWORDX16
4966 
4968  {
4969  } // ~Inst_SMEM__S_BUFFER_LOAD_DWORDX16
4970 
4971  // Read 16 dwords from scalar data cache. See S_LOAD_DWORD for details on
4972  // the offset input.
4973  void
4975  {
4976  Wavefront *wf = gpuDynInst->wavefront();
4977  gpuDynInst->execUnitId = wf->execUnitId;
4978  gpuDynInst->latency.init(gpuDynInst->computeUnit());
4979  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
4980  ScalarRegU32 offset(0);
4981  ConstScalarOperandU128 rsrcDesc(gpuDynInst, instData.SBASE);
4982 
4983  rsrcDesc.read();
4984 
4985  if (instData.IMM) {
4986  offset = extData.OFFSET;
4987  } else {
4988  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
4989  off_sgpr.read();
4990  offset = off_sgpr.rawData();
4991  }
4992 
4993  calcAddr(gpuDynInst, rsrcDesc, offset);
4994 
4995  gpuDynInst->computeUnit()->scalarMemoryPipe
4996  .getGMReqFIFO().push(gpuDynInst);
4997 
4998  wf->scalarRdGmReqsInPipe--;
5000  gpuDynInst->wavefront()->outstandingReqs++;
5001  gpuDynInst->wavefront()->validateRequestCounters();
5002  } // execute
5003 
5004  void
5006  {
5007  initMemRead<16>(gpuDynInst);
5008  } // initiateAcc
5009 
5010  void
5012  {
5013  // 16 requests, each size 32
5014  ScalarOperandU512 sdst(gpuDynInst, instData.SDATA);
5015  sdst.write();
5016  } // completeAcc
5017 
5019  : Inst_SMEM(iFmt, "s_store_dword")
5020  {
5021  setFlag(MemoryRef);
5022  setFlag(Store);
5023  } // Inst_SMEM__S_STORE_DWORD
5024 
5026  {
5027  } // ~Inst_SMEM__S_STORE_DWORD
5028 
5029  // Write 1 dword to scalar data cache.
5030  // If the offset is specified as an SGPR, the SGPR contains an unsigned
5031  // BYTE offset (the 2 LSBs are ignored).
5032  // If the offset is specified as an immediate 20-bit constant, the
5033  // constant is an unsigned BYTE offset.
5034  void
5036  {
5037  Wavefront *wf = gpuDynInst->wavefront();
5038  gpuDynInst->execUnitId = wf->execUnitId;
5039  gpuDynInst->latency.init(gpuDynInst->computeUnit());
5040  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
5041  ScalarRegU32 offset(0);
5042  ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
5043 
5044  addr.read();
5045 
5046  if (instData.IMM) {
5047  offset = extData.OFFSET;
5048  } else {
5049  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
5050  off_sgpr.read();
5051  offset = off_sgpr.rawData();
5052  }
5053 
5054  calcAddr(gpuDynInst, addr, offset);
5055 
5056  gpuDynInst->computeUnit()->scalarMemoryPipe.
5057  getGMReqFIFO().push(gpuDynInst);
5058 
5059  wf->scalarWrGmReqsInPipe--;
5061  gpuDynInst->wavefront()->outstandingReqs++;
5062  gpuDynInst->wavefront()->validateRequestCounters();
5063  }
5064 
5065  void
5067  {
5068  ConstScalarOperandU32 sdata(gpuDynInst, instData.SDATA);
5069  sdata.read();
5070  std::memcpy((void*)gpuDynInst->scalar_data, sdata.rawDataPtr(),
5071  sizeof(ScalarRegU32));
5072  initMemWrite<1>(gpuDynInst);
5073  } // initiateAcc
5074 
5075  void
5077  {
5078  } // completeAcc
5079 
5081  : Inst_SMEM(iFmt, "s_store_dwordx2")
5082  {
5083  setFlag(MemoryRef);
5084  setFlag(Store);
5085  } // Inst_SMEM__S_STORE_DWORDX2
5086 
5088  {
5089  } // ~Inst_SMEM__S_STORE_DWORDX2
5090 
5091  // Write 2 dwords to scalar data cache. See S_STORE_DWORD for details on
5092  // the offset input.
5093  void
5095  {
5096  Wavefront *wf = gpuDynInst->wavefront();
5097  gpuDynInst->execUnitId = wf->execUnitId;
5098  gpuDynInst->latency.init(gpuDynInst->computeUnit());
5099  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
5100  ScalarRegU32 offset(0);
5101  ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
5102 
5103  addr.read();
5104 
5105  if (instData.IMM) {
5106  offset = extData.OFFSET;
5107  } else {
5108  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
5109  off_sgpr.read();
5110  offset = off_sgpr.rawData();
5111  }
5112 
5113  calcAddr(gpuDynInst, addr, offset);
5114 
5115  gpuDynInst->computeUnit()->scalarMemoryPipe.
5116  getGMReqFIFO().push(gpuDynInst);
5117 
5118  wf->scalarWrGmReqsInPipe--;
5120  gpuDynInst->wavefront()->outstandingReqs++;
5121  gpuDynInst->wavefront()->validateRequestCounters();
5122  }
5123 
5124  void
5126  {
5127  ConstScalarOperandU64 sdata(gpuDynInst, instData.SDATA);
5128  sdata.read();
5129  std::memcpy((void*)gpuDynInst->scalar_data, sdata.rawDataPtr(),
5130  sizeof(ScalarRegU64));
5131  initMemWrite<2>(gpuDynInst);
5132  } // initiateAcc
5133 
5134  void
5136  {
5137  } // completeAcc
5138 
5140  : Inst_SMEM(iFmt, "s_store_dwordx4")
5141  {
5142  setFlag(MemoryRef);
5143  setFlag(Store);
5144  } // Inst_SMEM__S_STORE_DWORDX4
5145 
5147  {
5148  } // ~Inst_SMEM__S_STORE_DWORDX4
5149 
5150  // Write 4 dwords to scalar data cache. See S_STORE_DWORD for details on
5151  // the offset input.
5152  void
5154  {
5155  Wavefront *wf = gpuDynInst->wavefront();
5156  gpuDynInst->execUnitId = wf->execUnitId;
5157  gpuDynInst->latency.init(gpuDynInst->computeUnit());
5158  gpuDynInst->latency.set(gpuDynInst->computeUnit()->clockPeriod());
5159  ScalarRegU32 offset(0);
5160  ConstScalarOperandU64 addr(gpuDynInst, instData.SBASE << 1);
5161 
5162  addr.read();
5163 
5164  if (instData.IMM) {
5165  offset = extData.OFFSET;
5166  } else {
5167  ConstScalarOperandU32 off_sgpr(gpuDynInst, extData.OFFSET);
5168  off_sgpr.read();
5169  offset = off_sgpr.rawData();
5170  }
5171 
5172  calcAddr(gpuDynInst, addr, offset);
5173 
5174  gpuDynInst->computeUnit()->scalarMemoryPipe.
5175  getGMReqFIFO().push(gpuDynInst);
5176 
5177  wf->scalarWrGmReqsInPipe--;
5179  gpuDynInst->wavefront()->outstandingReqs++;
5180  gpuDynInst->wavefront()->validateRequestCounters();
5181  }
5182 
5183  void
5185  {
5186  ConstScalarOperandU128 sdata(gpuDynInst, instData.SDATA);
5187  sdata.read();
5188  std::memcpy((void*)gpuDynInst->scalar_data, sdata.rawDataPtr(),
5189  4 * sizeof(ScalarRegU32));
5190  initMemWrite<4>(gpuDynInst);
5191  } // initiateAcc
5192 
5193  void
5195  {
5196  } // completeAcc
5197 
5199  InFmt_SMEM *iFmt)
5200  : Inst_SMEM(iFmt, "s_buffer_store_dword")
5201  {
5202  setFlag(MemoryRef);
5203  setFlag(Store);
5204  } // Inst_SMEM__S_BUFFER_STORE_DWORD
5205 
5207  {
5208  } // ~Inst_SMEM__S_BUFFER_STORE_DWORD
5209 
5210  // Write 1 dword to scalar data cache. See S_STORE_DWORD for details on the
5211  // offset input.
5212  void
5214  {
5216  }
5217 
5218  void
5220  {
5221  } // initiateAcc
5222 
5223  void
5225  {
5226  } // completeAcc
5227 
5229  InFmt_SMEM *iFmt)
5230  : Inst_SMEM(iFmt, "s_buffer_store_dwordx2")
5231  {
5232  setFlag(MemoryRef);
5233  setFlag(Store);
5234  } // Inst_SMEM__S_BUFFER_STORE_DWORDX2
5235 
5237  {
5238  } // ~Inst_SMEM__S_BUFFER_STORE_DWORDX2
5239 
5240  // Write 2 dwords to scalar data cache. See S_STORE_DWORD for details on
5241  // the offset input.
5242  void
5244  {
5246  }
5247 
5248  void
5250  {
5251  } // initiateAcc
5252 
5253  void
5255  {
5256  } // completeAcc
5257 
5259  InFmt_SMEM *iFmt)
5260  : Inst_SMEM(iFmt, "s_buffer_store_dwordx4")
5261  {
5262  setFlag(MemoryRef);
5263  setFlag(Store);
5264  } // Inst_SMEM__S_BUFFER_STORE_DWORDX4
5265 
5267  {
5268  } // ~Inst_SMEM__S_BUFFER_STORE_DWORDX4
5269 
5270  // Write 4 dwords to scalar data cache. See S_STORE_DWORD for details on
5271  // the offset input.
5272  void
5274  {
5276  }
5277 
5278  void
5280  {
5281  } // initiateAcc
5282 
5283  void
5285  {
5286  } // completeAcc
5287 
5289  : Inst_SMEM(iFmt, "s_dcache_inv")
5290  {
5291  } // Inst_SMEM__S_DCACHE_INV
5292 
5294  {
5295  } // ~Inst_SMEM__S_DCACHE_INV
5296 
5297  // Invalidate the scalar data cache.
5298  void
5300  {
5302  }
5303 
5305  : Inst_SMEM(iFmt, "s_dcache_wb")
5306  {
5307  } // Inst_SMEM__S_DCACHE_WB
5308 
5310  {
5311  } // ~Inst_SMEM__S_DCACHE_WB
5312 
5313  // Write back dirty data in the scalar data cache.
5314  void
5316  {
5318  }
5319 
5321  : Inst_SMEM(iFmt, "s_dcache_inv_vol")
5322  {
5323  } // Inst_SMEM__S_DCACHE_INV_VOL
5324 
5326  {
5327  } // ~Inst_SMEM__S_DCACHE_INV_VOL
5328 
5329  // Invalidate the scalar data cache volatile lines.
5330  void
5332  {
5334  }