1//===-- VOP2Instructions.td - Vector Instruction Definitions --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9//===----------------------------------------------------------------------===//
10// VOP2 Classes
11//===----------------------------------------------------------------------===//
12
13class VOP2e <bits<6> op, VOPProfile P> : Enc32 {
14  bits<8> vdst;
15  bits<9> src0;
16  bits<8> src1;
17
18  let Inst{8-0}   = !if(P.HasSrc0, src0, 0);
19  let Inst{16-9}  = !if(P.HasSrc1, src1, 0);
20  let Inst{24-17} = !if(P.EmitDst, vdst, 0);
21  let Inst{30-25} = op;
22  let Inst{31}    = 0x0; //encoding
23}
24
25class VOP2_MADKe <bits<6> op, VOPProfile P> : Enc64 {
26  bits<8>  vdst;
27  bits<9>  src0;
28  bits<8>  src1;
29  bits<32> imm;
30
31  let Inst{8-0}   = !if(P.HasSrc0, src0, 0);
32  let Inst{16-9}  = !if(P.HasSrc1, src1, 0);
33  let Inst{24-17} = !if(P.EmitDst, vdst, 0);
34  let Inst{30-25} = op;
35  let Inst{31}    = 0x0; // encoding
36  let Inst{63-32} = imm;
37}
38
39class VOP2_SDWAe <bits<6> op, VOPProfile P> : VOP_SDWAe <P> {
40  bits<8> vdst;
41  bits<8> src1;
42
43  let Inst{8-0}   = 0xf9; // sdwa
44  let Inst{16-9}  = !if(P.HasSrc1, src1{7-0}, 0);
45  let Inst{24-17} = !if(P.EmitDst, vdst{7-0}, 0);
46  let Inst{30-25} = op;
47  let Inst{31}    = 0x0; // encoding
48}
49
50class VOP2_SDWA9Ae <bits<6> op, VOPProfile P> : VOP_SDWA9Ae <P> {
51  bits<8> vdst;
52  bits<9> src1;
53
54  let Inst{8-0}   = 0xf9; // sdwa
55  let Inst{16-9}  = !if(P.HasSrc1, src1{7-0}, 0);
56  let Inst{24-17} = !if(P.EmitDst, vdst{7-0}, 0);
57  let Inst{30-25} = op;
58  let Inst{31}    = 0x0; // encoding
59  let Inst{63}    = !if(P.HasSrc1, src1{8}, 0); // src1_sgpr
60}
61
62class VOP2_Pseudo <string opName, VOPProfile P, list<dag> pattern=[], string suffix = "_e32"> :
63  VOP_Pseudo <opName, suffix, P, P.Outs32, P.Ins32, "", pattern> {
64
65  let AsmOperands = P.Asm32;
66
67  let Size = 4;
68  let mayLoad = 0;
69  let mayStore = 0;
70  let hasSideEffects = 0;
71
72  let ReadsModeReg = !or(isFloatType<P.DstVT>.ret, isFloatType<P.Src0VT>.ret);
73
74  let mayRaiseFPException = ReadsModeReg;
75
76  let VOP2 = 1;
77  let VALU = 1;
78  let Uses = !if(ReadsModeReg, [MODE, EXEC], [EXEC]);
79
80  let AsmVariantName = AMDGPUAsmVariants.Default;
81}
82
83class VOP2_Real <VOP2_Pseudo ps, int EncodingFamily, string real_name = ps.Mnemonic> :
84  VOP_Real <ps>,
85  InstSI <ps.OutOperandList, ps.InOperandList, real_name # ps.AsmOperands, []>,
86  SIMCInstr <ps.PseudoInstr, EncodingFamily> {
87
88  let VALU = 1;
89  let VOP2 = 1;
90  let isPseudo = 0;
91  let isCodeGenOnly = 0;
92
93  let Constraints     = ps.Constraints;
94  let DisableEncoding = ps.DisableEncoding;
95
96  // copy relevant pseudo op flags
97  let SubtargetPredicate = ps.SubtargetPredicate;
98  let OtherPredicates    = ps.OtherPredicates;
99  let AsmMatchConverter  = ps.AsmMatchConverter;
100  let AsmVariantName     = ps.AsmVariantName;
101  let Constraints        = ps.Constraints;
102  let DisableEncoding    = ps.DisableEncoding;
103  let TSFlags            = ps.TSFlags;
104  let UseNamedOperandTable = ps.UseNamedOperandTable;
105  let Uses                 = ps.Uses;
106  let Defs                 = ps.Defs;
107  let SchedRW              = ps.SchedRW;
108  let mayLoad              = ps.mayLoad;
109  let mayStore             = ps.mayStore;
110}
111
112class VOP2_SDWA_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[]> :
113  VOP_SDWA_Pseudo <OpName, P, pattern> {
114  let AsmMatchConverter = "cvtSdwaVOP2";
115}
116
117class VOP2_DPP_Pseudo <string OpName, VOPProfile P, list<dag> pattern=[]> :
118  VOP_DPP_Pseudo <OpName, P, pattern> {
119}
120
121
122class getVOP2Pat64 <SDPatternOperator node, VOPProfile P> : LetDummies {
123  list<dag> ret = !if(P.HasModifiers,
124    [(set P.DstVT:$vdst,
125      (node (P.Src0VT
126              !if(P.HasOMod,
127                  (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod),
128                  (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp))),
129            (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
130    [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]);
131}
132
133multiclass VOP2Inst_e32<string opName,
134                        VOPProfile P,
135                        SDPatternOperator node = null_frag,
136                        string revOp = opName,
137                        bit GFX9Renamed = 0> {
138  let renamedInGFX9 = GFX9Renamed in {
139    def _e32 : VOP2_Pseudo <opName, P, VOPPatOrNull<node,P>.ret>,
140               Commutable_REV<revOp#"_e32", !eq(revOp, opName)>;
141  } // End renamedInGFX9 = GFX9Renamed
142}
143
144multiclass VOP2Inst_e64<string opName,
145                        VOPProfile P,
146                        SDPatternOperator node = null_frag,
147                        string revOp = opName,
148                        bit GFX9Renamed = 0> {
149  let renamedInGFX9 = GFX9Renamed in {
150    def _e64 : VOP3InstBase <opName, P, node, 1>,
151               Commutable_REV<revOp#"_e64", !eq(revOp, opName)>;
152
153    let SubtargetPredicate = isGFX11Plus in {
154      foreach _ = BoolToList<P.HasExtVOP3DPP>.ret in
155        def _e64_dpp  : VOP3_DPP_Pseudo <opName, P>;
156    } // End SubtargetPredicate = isGFX11Plus
157  } // End renamedInGFX9 = GFX9Renamed
158}
159
160multiclass VOP2Inst_sdwa<string opName,
161                         VOPProfile P,
162                         bit GFX9Renamed = 0> {
163  let renamedInGFX9 = GFX9Renamed in {
164    foreach _ = BoolToList<P.HasExtSDWA>.ret in
165      def _sdwa : VOP2_SDWA_Pseudo <opName, P>;
166  } // End renamedInGFX9 = GFX9Renamed
167}
168
169multiclass VOP2Inst<string opName,
170                    VOPProfile P,
171                    SDPatternOperator node = null_frag,
172                    string revOp = opName,
173                    bit GFX9Renamed = 0> :
174    VOP2Inst_e32<opName, P, node, revOp, GFX9Renamed>,
175    VOP2Inst_e64<opName, P, node, revOp, GFX9Renamed>,
176    VOP2Inst_sdwa<opName, P, GFX9Renamed> {
177  let renamedInGFX9 = GFX9Renamed in {
178    foreach _ = BoolToList<P.HasExtDPP>.ret in
179      def _dpp  : VOP2_DPP_Pseudo <opName, P>;
180  }
181}
182
183multiclass VOP2bInst <string opName,
184                      VOPProfile P,
185                      SDPatternOperator node = null_frag,
186                      string revOp = opName,
187                      bit GFX9Renamed = 0,
188                      bit useSGPRInput = !eq(P.NumSrcArgs, 3)> {
189  let renamedInGFX9 = GFX9Renamed in {
190    let SchedRW = [Write32Bit, WriteSALU] in {
191      let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in {
192        def _e32 : VOP2_Pseudo <opName, P, VOPPatOrNull<node,P>.ret>,
193                   Commutable_REV<revOp#"_e32", !eq(revOp, opName)> {
194          let usesCustomInserter = true;
195        }
196
197        foreach _ = BoolToList<P.HasExtSDWA>.ret in
198          def _sdwa  : VOP2_SDWA_Pseudo <opName, P> {
199            let AsmMatchConverter = "cvtSdwaVOP2b";
200          }
201        foreach _ = BoolToList<P.HasExtDPP>.ret in
202          def _dpp  : VOP2_DPP_Pseudo <opName, P>;
203      } // End Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC]
204
205      def _e64 : VOP3InstBase <opName, P, node, 1>,
206                 Commutable_REV<revOp#"_e64", !eq(revOp, opName)>;
207
208      let SubtargetPredicate = isGFX11Plus in {
209        foreach _ = BoolToList<P.HasExtVOP3DPP>.ret in
210          def _e64_dpp  : VOP3_DPP_Pseudo <opName, P>;
211      } // End SubtargetPredicate = isGFX11Plus
212    }
213  }
214}
215
216class VOP2bInstAlias <VOP2_Pseudo ps, Instruction inst,
217                      string OpName, string opnd> :
218  InstAlias <OpName#" "#!subst("vcc", opnd, ps.Pfl.Asm32),
219             (inst ps.Pfl.DstRC:$vdst, ps.Pfl.Src0RC32:$src0,
220                   ps.Pfl.Src1RC32:$src1)>,
221  PredicateControl {
222}
223
224multiclass VOP2bInstAliases<VOP2_Pseudo ps, VOP2_Real inst, string OpName> {
225  let WaveSizePredicate = isWave32 in {
226    def : VOP2bInstAlias<ps, inst, OpName, "vcc_lo">;
227  }
228  let WaveSizePredicate = isWave64 in {
229    def : VOP2bInstAlias<ps, inst, OpName, "vcc">;
230  }
231}
232
233multiclass VOP2eInst <string opName,
234                      VOPProfile P,
235                      SDPatternOperator node = null_frag,
236                      string revOp = opName,
237                      bit useSGPRInput = !eq(P.NumSrcArgs, 3)> {
238
239  let SchedRW = [Write32Bit] in {
240    let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]) in {
241      def _e32 : VOP2_Pseudo <opName, P>,
242                 Commutable_REV<revOp#"_e32", !eq(revOp, opName)>;
243
244      foreach _ = BoolToList<P.HasExtSDWA>.ret in
245        def _sdwa : VOP2_SDWA_Pseudo <opName, P> {
246          let AsmMatchConverter = "cvtSdwaVOP2e";
247        }
248
249      foreach _ = BoolToList<P.HasExtDPP>.ret in
250        def _dpp  : VOP2_DPP_Pseudo <opName, P>;
251    }
252
253    def _e64 : VOP3InstBase <opName, P, node, 1>,
254               Commutable_REV<revOp#"_e64", !eq(revOp, opName)> {
255      let isReMaterializable = 1;
256    }
257
258    let SubtargetPredicate = isGFX11Plus in {
259      foreach _ = BoolToList<P.HasExtVOP3DPP>.ret in
260        def _e64_dpp  : VOP3_DPP_Pseudo <opName, P>;
261    } // End SubtargetPredicate = isGFX11Plus
262  }
263}
264
265
266class VOP2eInstAlias <VOP2_Pseudo ps, Instruction inst, string opnd = ""> :
267  InstAlias <ps.OpName#" "#ps.Pfl.Asm32#", "#opnd,
268             (inst ps.Pfl.DstRC:$vdst, ps.Pfl.Src0RC32:$src0,
269                   ps.Pfl.Src1RC32:$src1)>, PredicateControl;
270
271class VOP2e64InstAlias <VOP3_Pseudo ps, Instruction inst> :
272  InstAlias <ps.OpName#" "#ps.Pfl.Asm64,
273             (inst ps.Pfl.DstRC:$vdst, VOPDstS64orS32:$sdst,
274                   ps.Pfl.Src0RC32:$src0, ps.Pfl.Src1RC32:$src1, clampmod:$clamp)>,
275  PredicateControl;
276
277multiclass VOP2eInstAliases<VOP2_Pseudo ps, VOP2_Real inst> {
278  let WaveSizePredicate = isWave32 in {
279    def : VOP2eInstAlias<ps, inst, "vcc_lo">;
280  }
281  let WaveSizePredicate = isWave64 in {
282    def : VOP2eInstAlias<ps, inst, "vcc">;
283  }
284}
285
286class VOP_MADAK <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> {
287  field Operand ImmOpType = !if(!eq(vt.Size, 32), f32kimm, f16kimm);
288  field dag Ins32 = !if(!eq(vt.Size, 32),
289                        (ins VSrc_f32_Deferred:$src0, VGPR_32:$src1, ImmOpType:$imm),
290                        (ins VSrc_f16_Deferred:$src0, VGPR_32:$src1, ImmOpType:$imm));
291  field string Asm32 = "$vdst, $src0, $src1, $imm";
292  field bit HasExt = 0;
293  let IsSingle = 1;
294}
295
296def VOP_MADAK_F16 : VOP_MADAK <f16>;
297def VOP_MADAK_F32 : VOP_MADAK <f32>;
298
299class VOP_MADMK <ValueType vt> : VOPProfile <[vt, vt, vt, vt]> {
300  field Operand ImmOpType = !if(!eq(vt.Size, 32), f32kimm, f16kimm);
301  field dag Ins32 = (ins VSrc_f32_Deferred:$src0, ImmOpType:$imm, VGPR_32:$src1);
302  field string Asm32 = "$vdst, $src0, $imm, $src1";
303  field bit HasExt = 0;
304  let IsSingle = 1;
305}
306
307def VOP_MADMK_F16 : VOP_MADMK <f16>;
308def VOP_MADMK_F32 : VOP_MADMK <f32>;
309
310class getRegisterOperandForVT<ValueType VT> {
311  RegisterOperand ret = RegisterOperand<getVregSrcForVT<VT>.ret>;
312}
313
314// FIXME: Remove src2_modifiers. It isn't used, so is wasting memory
315// and processing time but it makes it easier to convert to mad.
316class VOP_MAC <ValueType vt0, ValueType vt1=vt0> : VOPProfile <[vt0, vt1, vt1, vt0]> {
317  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, getVregSrcForVT<Src2VT>.ret:$src2);
318  let Ins64 = getIns64<Src0RC64, Src1RC64, getRegisterOperandForVT<Src2VT>.ret, 3,
319                       0, HasModifiers, HasModifiers, HasOMod,
320                       Src0Mod, Src1Mod, Src2Mod>.ret;
321  let InsDPP = (ins Src0ModDPP:$src0_modifiers, Src0DPP:$src0,
322                    Src1ModDPP:$src1_modifiers, Src1DPP:$src1,
323                    getVregSrcForVT<Src2VT>.ret:$src2, // stub argument
324                    dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
325                    bank_mask:$bank_mask, bound_ctrl:$bound_ctrl);
326  let InsDPP16 = !con(InsDPP, (ins FI:$fi));
327  let InsVOP3Base  = getIns64<Src0VOP3DPP, Src1RC64, RegisterOperand<VGPR_32>, 3,
328                       0, HasModifiers, HasModifiers, HasOMod,
329                       Src0Mod, Src1Mod, Src2Mod>.ret;
330
331  let InsDPP8 = (ins Src0ModDPP:$src0_modifiers, Src0DPP:$src0,
332                     Src1ModDPP:$src1_modifiers, Src1DPP:$src1,
333                     getVregSrcForVT<Src2VT>.ret:$src2, // stub argument
334                     dpp8:$dpp8, FI:$fi);
335  let InsSDWA = (ins Src0ModSDWA:$src0_modifiers, Src0SDWA:$src0,
336                     Src1ModSDWA:$src1_modifiers, Src1SDWA:$src1,
337                     getVregSrcForVT<Src2VT>.ret:$src2, // stub argument
338                     clampmod:$clamp, omod:$omod,
339                     dst_sel:$dst_sel, dst_unused:$dst_unused,
340                     src0_sel:$src0_sel, src1_sel:$src1_sel);
341  let Asm32 = getAsm32<1, 2, vt0>.ret;
342  let Asm64 = getAsm64<1, 2, 0, HasModifiers, HasOMod, vt0>.ret;
343  let AsmDPP = getAsmDPP<1, 2, HasModifiers, vt0>.ret;
344  let AsmDPP16 = getAsmDPP16<1, 2, HasModifiers, vt0>.ret;
345  let AsmDPP8 = getAsmDPP8<1, 2, 0, vt0>.ret;
346  let AsmSDWA = getAsmSDWA<1, 2, vt0>.ret;
347  let AsmSDWA9 = getAsmSDWA9<1, 1, 2, vt0>.ret;
348  let HasSrc2 = 0;
349  let HasSrc2Mods = 0;
350
351  let HasExt = 1;
352  let HasExtDPP = 1;
353  let HasExt32BitDPP = 1;
354  let HasExtSDWA = 1;
355  let HasExtSDWA9 = 0;
356  let TieRegDPP = "$src2";
357}
358
359def VOP_MAC_F16 : VOP_MAC <f16>;
360def VOP_MAC_F32 : VOP_MAC <f32>;
361let HasExtDPP = 0, HasExt32BitDPP = 0 in
362def VOP_MAC_LEGACY_F32 : VOP_MAC <f32>;
363let HasExtSDWA = 0, HasExt32BitDPP = 0, HasExt64BitDPP = 1 in
364def VOP_MAC_F64 : VOP_MAC <f64>;
365
366class VOP_DOT_ACC<ValueType vt0, ValueType vt1> : VOP_MAC<vt0, vt1> {
367  let HasClamp = 0;
368  let HasExtSDWA = 0;
369  let HasOpSel = 0;
370  let IsPacked = 0;
371}
372
373def VOP_DOT_ACC_F32_V2F16 : VOP_DOT_ACC<f32, v2f16> {
374  let Src0ModDPP = FPVRegInputMods;
375  let Src1ModDPP = FPVRegInputMods;
376}
377
378def VOP_DOT_ACC_I32_I32   : VOP_DOT_ACC<i32, i32> {
379  let HasExtVOP3DPP = 0;
380  let HasSrc0Mods = 1;
381  let HasSrc1Mods = 1;
382}
383
384// Write out to vcc or arbitrary SGPR.
385def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped], 0, /*EnableClamp=*/1> {
386  let Asm32 = "$vdst, vcc, $src0, $src1";
387  let Asm64 = "$vdst, $sdst, $src0, $src1$clamp";
388  let AsmSDWA = "$vdst, vcc, $src0_modifiers, $src1_modifiers$clamp $dst_sel $dst_unused $src0_sel $src1_sel";
389  let AsmSDWA9 = "$vdst, vcc, $src0_modifiers, $src1_modifiers$clamp $dst_sel $dst_unused $src0_sel $src1_sel";
390  let AsmDPP = "$vdst, vcc, $src0, $src1 $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
391  let AsmDPP8 = "$vdst, vcc, $src0, $src1 $dpp8$fi";
392  let AsmDPP16 = AsmDPP#"$fi";
393  let AsmVOP3DPPBase = Asm64;
394  let InsDPP = (ins DstRCDPP:$old,
395                    Src0DPP:$src0,
396                    Src1DPP:$src1,
397                    dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
398                    bank_mask:$bank_mask, bound_ctrl:$bound_ctrl);
399  let InsDPP16 = !con(InsDPP, (ins FI:$fi));
400  let InsDPP8 = (ins DstRCDPP:$old,
401                    Src0DPP:$src0,
402                    Src1DPP:$src1,
403                    dpp8:$dpp8, FI:$fi);
404  let Outs32 = (outs DstRC:$vdst);
405  let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst);
406  let OutsVOP3DPP = Outs64;
407  let OutsVOP3DPP8 = Outs64;
408}
409
410// Write out to vcc or arbitrary SGPR and read in from vcc or
411// arbitrary SGPR.
412def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1], 0, /*EnableClamp=*/1> {
413  let HasSrc2Mods = 0;
414  let Asm32 = "$vdst, vcc, $src0, $src1, vcc";
415  let Asm64 = "$vdst, $sdst, $src0, $src1, $src2$clamp";
416  let AsmSDWA = "$vdst, vcc, $src0_modifiers, $src1_modifiers, vcc$clamp $dst_sel $dst_unused $src0_sel $src1_sel";
417  let AsmSDWA9 = "$vdst, vcc, $src0_modifiers, $src1_modifiers, vcc$clamp $dst_sel $dst_unused $src0_sel $src1_sel";
418  let AsmDPP = "$vdst, vcc, $src0, $src1, vcc $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
419  let AsmDPP8 = "$vdst, vcc, $src0, $src1, vcc $dpp8$fi";
420  let AsmDPP16 = AsmDPP#"$fi";
421  let Outs32 = (outs DstRC:$vdst);
422  let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst);
423  let AsmVOP3DPPBase = Asm64;
424  let OutsVOP3DPP = Outs64;
425  let OutsVOP3DPP8 = Outs64;
426
427  // Suppress src2 implied by type since the 32-bit encoding uses an
428  // implicit VCC use.
429  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
430
431  let InsSDWA = (ins Src0ModSDWA:$src0_modifiers, Src0SDWA:$src0,
432                     Src1ModSDWA:$src1_modifiers, Src1SDWA:$src1,
433                     clampmod:$clamp,
434                     dst_sel:$dst_sel, dst_unused:$dst_unused,
435                     src0_sel:$src0_sel, src1_sel:$src1_sel);
436
437  let InsDPP = (ins DstRCDPP:$old,
438                    Src0DPP:$src0,
439                    Src1DPP:$src1,
440                    dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
441                    bank_mask:$bank_mask, bound_ctrl:$bound_ctrl);
442  let InsDPP16 = !con(InsDPP, (ins FI:$fi));
443  let InsDPP8 = (ins DstRCDPP:$old,
444                    Src0DPP:$src0,
445                    Src1DPP:$src1,
446                   dpp8:$dpp8, FI:$fi);
447
448  let HasExt = 1;
449  let HasExtDPP = 1;
450  let HasExt32BitDPP = 1;
451  let HasExtSDWA = 1;
452  let HasExtSDWA9 = 1;
453}
454
455// Read in from vcc or arbitrary SGPR.
456class VOP2e_SGPR<list<ValueType> ArgVT> : VOPProfile<ArgVT, /*EnableF32SrcMods=*/1> {
457  let Asm32 = "$vdst, $src0, $src1";
458  let Asm64 = "$vdst, $src0_modifiers, $src1_modifiers, $src2";
459  let AsmSDWA = "$vdst, $src0_modifiers, $src1_modifiers, vcc$clamp $dst_sel $dst_unused $src0_sel $src1_sel";
460  let AsmSDWA9 = "$vdst, $src0_modifiers, $src1_modifiers, vcc$clamp $dst_sel $dst_unused $src0_sel $src1_sel";
461  let AsmDPP = "$vdst, $src0, $src1, vcc $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
462  let AsmDPP8 = "$vdst, $src0, $src1, vcc $dpp8$fi";
463  let AsmDPP16 = AsmDPP#"$fi";
464  let AsmVOP3DPPBase = Asm64;
465
466  let Outs32 = (outs DstRC:$vdst);
467  let Outs64 = (outs DstRC:$vdst);
468
469  // Suppress src2 implied by type since the 32-bit encoding uses an
470  // implicit VCC use.
471  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
472
473  let InsSDWA = (ins Src0ModSDWA:$src0_modifiers, Src0SDWA:$src0,
474                     Src1ModSDWA:$src1_modifiers, Src1SDWA:$src1,
475                     clampmod:$clamp,
476                     dst_sel:$dst_sel, dst_unused:$dst_unused,
477                     src0_sel:$src0_sel, src1_sel:$src1_sel);
478
479  let InsDPP = (ins DstRCDPP:$old,
480                    Src0ModDPP:$src0_modifiers, Src0DPP:$src0,
481                    Src1ModDPP:$src1_modifiers, Src1DPP:$src1,
482                    dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
483                    bank_mask:$bank_mask, bound_ctrl:$bound_ctrl);
484  let InsDPP16 = !con(InsDPP, (ins FI:$fi));
485  let InsDPP8 = (ins DstRCDPP:$old,
486                     Src0ModDPP:$src0_modifiers, Src0DPP:$src0,
487                     Src1ModDPP:$src1_modifiers, Src1DPP:$src1,
488                     dpp8:$dpp8, FI:$fi);
489
490  let HasExt = 1;
491  let HasExtDPP = 1;
492  let HasExt32BitDPP = 1;
493  let HasExtSDWA = 1;
494  let HasExtSDWA9 = 1;
495}
496
497def VOP2e_I32_I32_I32_I1 : VOP2e_SGPR<[i32, i32, i32, i1]>;
498def VOP2e_I16_I16_I16_I1 : VOP2e_SGPR<[i16, i16, i16, i1]>;
499
500def VOP_READLANE : VOPProfile<[i32, i32, i32, untyped]> {
501  let Outs32 = (outs SReg_32:$vdst);
502  let Outs64 = Outs32;
503  let Ins32 = (ins VRegOrLds_32:$src0, SCSrc_b32:$src1);
504  let Ins64 = Ins32;
505  let Asm32 = " $vdst, $src0, $src1";
506  let Asm64 = Asm32;
507
508  let HasExt = 0;
509  let HasExtDPP = 0;
510  let HasExt32BitDPP = 0;
511  let HasExt64BitDPP = 0;
512  let HasExtSDWA = 0;
513  let HasExtSDWA9 = 0;
514}
515
516def VOP_WRITELANE : VOPProfile<[i32, i32, i32, i32]> {
517  let Outs32 = (outs VGPR_32:$vdst);
518  let Outs64 = Outs32;
519  let Ins32 = (ins SCSrc_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in);
520  let Ins64 = Ins32;
521  let Asm32 = " $vdst, $src0, $src1";
522  let Asm64 = Asm32;
523  let HasSrc2 = 0;
524  let HasSrc2Mods = 0;
525
526  let HasExt = 0;
527  let HasExtDPP = 0;
528  let HasExt32BitDPP = 0;
529  let HasExt64BitDPP = 0;
530  let HasExtSDWA = 0;
531  let HasExtSDWA9 = 0;
532}
533
534//===----------------------------------------------------------------------===//
535// VOP2 Instructions
536//===----------------------------------------------------------------------===//
537
538let SubtargetPredicate = isGFX11Plus in
539defm V_CNDMASK_B16 : VOP2eInst <"v_cndmask_b16", VOP2e_I16_I16_I16_I1>;
540defm V_CNDMASK_B32 : VOP2eInst <"v_cndmask_b32", VOP2e_I32_I32_I32_I1>;
541let SubtargetPredicate = HasMadMacF32Insts, isReMaterializable = 1 in
542def V_MADMK_F32 : VOP2_Pseudo <"v_madmk_f32", VOP_MADMK_F32, []>;
543
544let isCommutable = 1 in {
545let isReMaterializable = 1 in {
546defm V_ADD_F32 : VOP2Inst <"v_add_f32", VOP_F32_F32_F32, any_fadd>;
547defm V_SUB_F32 : VOP2Inst <"v_sub_f32", VOP_F32_F32_F32, any_fsub>;
548defm V_SUBREV_F32 : VOP2Inst <"v_subrev_f32", VOP_F32_F32_F32, null_frag, "v_sub_f32">;
549defm V_MUL_LEGACY_F32 : VOP2Inst <"v_mul_legacy_f32", VOP_F32_F32_F32, AMDGPUfmul_legacy>;
550defm V_MUL_F32 : VOP2Inst <"v_mul_f32", VOP_F32_F32_F32, any_fmul>;
551defm V_MUL_I32_I24 : VOP2Inst <"v_mul_i32_i24", VOP_I32_I32_I32_ARITH, AMDGPUmul_i24>;
552defm V_MUL_HI_I32_I24 : VOP2Inst <"v_mul_hi_i32_i24", VOP_I32_I32_I32, AMDGPUmulhi_i24>;
553defm V_MUL_U32_U24 : VOP2Inst <"v_mul_u32_u24", VOP_I32_I32_I32_ARITH, AMDGPUmul_u24>;
554defm V_MUL_HI_U32_U24 : VOP2Inst <"v_mul_hi_u32_u24", VOP_I32_I32_I32, AMDGPUmulhi_u24>;
555defm V_MIN_F32 : VOP2Inst <"v_min_f32", VOP_F32_F32_F32, fminnum_like>;
556defm V_MAX_F32 : VOP2Inst <"v_max_f32", VOP_F32_F32_F32, fmaxnum_like>;
557defm V_MIN_I32 : VOP2Inst <"v_min_i32", VOP_PAT_GEN<VOP_I32_I32_I32>, smin>;
558defm V_MAX_I32 : VOP2Inst <"v_max_i32", VOP_PAT_GEN<VOP_I32_I32_I32>, smax>;
559defm V_MIN_U32 : VOP2Inst <"v_min_u32", VOP_PAT_GEN<VOP_I32_I32_I32>, umin>;
560defm V_MAX_U32 : VOP2Inst <"v_max_u32", VOP_PAT_GEN<VOP_I32_I32_I32>, umax>;
561defm V_LSHRREV_B32 : VOP2Inst <"v_lshrrev_b32", VOP_I32_I32_I32, clshr_rev_32, "v_lshr_b32">;
562defm V_ASHRREV_I32 : VOP2Inst <"v_ashrrev_i32", VOP_I32_I32_I32, cashr_rev_32, "v_ashr_i32">;
563defm V_LSHLREV_B32 : VOP2Inst <"v_lshlrev_b32", VOP_I32_I32_I32, clshl_rev_32, "v_lshl_b32">;
564defm V_AND_B32 : VOP2Inst <"v_and_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, and>;
565defm V_OR_B32 : VOP2Inst <"v_or_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, or>;
566defm V_XOR_B32 : VOP2Inst <"v_xor_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, xor>;
567} // End isReMaterializable = 1
568
569let mayRaiseFPException = 0 in {
570let OtherPredicates = [HasMadMacF32Insts] in {
571let Constraints = "$vdst = $src2", DisableEncoding="$src2",
572    isConvertibleToThreeAddress = 1 in {
573defm V_MAC_F32 : VOP2Inst <"v_mac_f32", VOP_MAC_F32>;
574
575let SubtargetPredicate = isGFX6GFX7GFX10 in
576defm V_MAC_LEGACY_F32 : VOP2Inst <"v_mac_legacy_f32", VOP_MAC_LEGACY_F32>;
577} // End Constraints = "$vdst = $src2", DisableEncoding="$src2",
578  //     isConvertibleToThreeAddress = 1
579
580let isReMaterializable = 1 in
581def V_MADAK_F32 : VOP2_Pseudo <"v_madak_f32", VOP_MADAK_F32, []>;
582} // End OtherPredicates = [HasMadMacF32Insts]
583} // End mayRaiseFPException = 0
584
585// No patterns so that the scalar instructions are always selected.
586// The scalar versions will be replaced with vector when needed later.
587defm V_ADD_CO_U32 : VOP2bInst <"v_add_co_u32", VOP2b_I32_I1_I32_I32, null_frag, "v_add_co_u32", 1>;
588defm V_SUB_CO_U32 : VOP2bInst <"v_sub_co_u32", VOP2b_I32_I1_I32_I32, null_frag, "v_sub_co_u32", 1>;
589defm V_SUBREV_CO_U32 : VOP2bInst <"v_subrev_co_u32", VOP2b_I32_I1_I32_I32, null_frag, "v_sub_co_u32", 1>;
590defm V_ADDC_U32 : VOP2bInst <"v_addc_u32", VOP2b_I32_I1_I32_I32_I1, null_frag, "v_addc_u32", 1>;
591defm V_SUBB_U32 : VOP2bInst <"v_subb_u32", VOP2b_I32_I1_I32_I32_I1, null_frag, "v_subb_u32", 1>;
592defm V_SUBBREV_U32 : VOP2bInst <"v_subbrev_u32", VOP2b_I32_I1_I32_I32_I1, null_frag, "v_subb_u32", 1>;
593
594
595let SubtargetPredicate = HasAddNoCarryInsts, isReMaterializable = 1 in {
596defm V_ADD_U32 : VOP2Inst <"v_add_u32", VOP_I32_I32_I32_ARITH, null_frag, "v_add_u32", 1>;
597defm V_SUB_U32 : VOP2Inst <"v_sub_u32", VOP_I32_I32_I32_ARITH, null_frag, "v_sub_u32", 1>;
598defm V_SUBREV_U32 : VOP2Inst <"v_subrev_u32", VOP_I32_I32_I32_ARITH, null_frag, "v_sub_u32", 1>;
599}
600
601} // End isCommutable = 1
602
603// These are special and do not read the exec mask.
604let isConvergent = 1, Uses = []<Register> in {
605def V_READLANE_B32 : VOP2_Pseudo<"v_readlane_b32", VOP_READLANE,
606  [(set i32:$vdst, (int_amdgcn_readlane i32:$src0, i32:$src1))]>;
607
608let Constraints = "$vdst = $vdst_in", DisableEncoding="$vdst_in" in {
609def V_WRITELANE_B32 : VOP2_Pseudo<"v_writelane_b32", VOP_WRITELANE,
610  [(set i32:$vdst, (int_amdgcn_writelane i32:$src0, i32:$src1, i32:$vdst_in))]>;
611} // End $vdst = $vdst_in, DisableEncoding $vdst_in
612} // End isConvergent = 1
613
614let isReMaterializable = 1 in {
615defm V_BFM_B32 : VOP2Inst <"v_bfm_b32", VOP_I32_I32_I32>;
616defm V_BCNT_U32_B32 : VOP2Inst <"v_bcnt_u32_b32", VOP_I32_I32_I32, add_ctpop>;
617defm V_MBCNT_LO_U32_B32 : VOP2Inst <"v_mbcnt_lo_u32_b32", VOP_I32_I32_I32, int_amdgcn_mbcnt_lo>;
618defm V_MBCNT_HI_U32_B32 : VOP2Inst <"v_mbcnt_hi_u32_b32", VOP_I32_I32_I32, int_amdgcn_mbcnt_hi>;
619defm V_LDEXP_F32 : VOP2Inst <"v_ldexp_f32", VOP_F32_F32_I32, AMDGPUldexp>;
620
621let ReadsModeReg = 0, mayRaiseFPException = 0 in {
622defm V_CVT_PKNORM_I16_F32 : VOP2Inst <"v_cvt_pknorm_i16_f32", VOP_V2I16_F32_F32, AMDGPUpknorm_i16_f32>;
623defm V_CVT_PKNORM_U16_F32 : VOP2Inst <"v_cvt_pknorm_u16_f32", VOP_V2I16_F32_F32, AMDGPUpknorm_u16_f32>;
624}
625
626defm V_CVT_PKRTZ_F16_F32 : VOP2Inst <"v_cvt_pkrtz_f16_f32", VOP_V2F16_F32_F32, AMDGPUpkrtz_f16_f32>;
627defm V_CVT_PK_U16_U32 : VOP2Inst <"v_cvt_pk_u16_u32", VOP_V2I16_I32_I32, AMDGPUpk_u16_u32>;
628defm V_CVT_PK_I16_I32 : VOP2Inst <"v_cvt_pk_i16_i32", VOP_V2I16_I32_I32, AMDGPUpk_i16_i32>;
629
630
631let SubtargetPredicate = isGFX6GFX7 in {
632defm V_MIN_LEGACY_F32 : VOP2Inst <"v_min_legacy_f32", VOP_F32_F32_F32, AMDGPUfmin_legacy>;
633defm V_MAX_LEGACY_F32 : VOP2Inst <"v_max_legacy_f32", VOP_F32_F32_F32, AMDGPUfmax_legacy>;
634} // End SubtargetPredicate = isGFX6GFX7
635
636let isCommutable = 1 in {
637let SubtargetPredicate = isGFX6GFX7 in {
638defm V_LSHR_B32 : VOP2Inst <"v_lshr_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, csrl_32>;
639defm V_ASHR_I32 : VOP2Inst <"v_ashr_i32", VOP_PAT_GEN<VOP_I32_I32_I32>, csra_32>;
640defm V_LSHL_B32 : VOP2Inst <"v_lshl_b32", VOP_PAT_GEN<VOP_I32_I32_I32>, cshl_32>;
641} // End SubtargetPredicate = isGFX6GFX7
642} // End isCommutable = 1
643} // End isReMaterializable = 1
644
645defm V_CVT_PKACCUM_U8_F32 : VOP2Inst <"v_cvt_pkaccum_u8_f32", VOP_NO_EXT<VOP_I32_F32_I32>>; // TODO: set "Uses = dst"
646
647class DivergentBinOp<SDPatternOperator Op, VOP_Pseudo Inst> :
648  GCNPat<
649      (getDivergentFrag<Op>.ret Inst.Pfl.Src0VT:$src0, Inst.Pfl.Src1VT:$src1),
650      !if(!cast<Commutable_REV>(Inst).IsOrig,
651        (Inst $src0, $src1),
652        (Inst $src1, $src0)
653      )
654  >;
655
656class DivergentClampingBinOp<SDPatternOperator Op, VOP_Pseudo Inst> :
657  GCNPat<
658      (getDivergentFrag<Op>.ret Inst.Pfl.Src0VT:$src0, Inst.Pfl.Src1VT:$src1),
659      !if(!cast<Commutable_REV>(Inst).IsOrig,
660        (Inst $src0, $src1, 0),
661        (Inst $src1, $src0, 0)
662      )
663  >;
664
665def : DivergentBinOp<csrl_32, V_LSHRREV_B32_e64>;
666def : DivergentBinOp<csra_32, V_ASHRREV_I32_e64>;
667def : DivergentBinOp<cshl_32, V_LSHLREV_B32_e64>;
668
669let SubtargetPredicate = HasAddNoCarryInsts in {
670  def : DivergentClampingBinOp<add, V_ADD_U32_e64>;
671  def : DivergentClampingBinOp<sub, V_SUB_U32_e64>;
672}
673
674let SubtargetPredicate = isGFX6GFX7GFX8GFX9, Predicates = [isGFX6GFX7GFX8GFX9] in {
675def : DivergentClampingBinOp<add, V_ADD_CO_U32_e64>;
676def : DivergentClampingBinOp<sub, V_SUB_CO_U32_e64>;
677}
678
679def : DivergentBinOp<adde, V_ADDC_U32_e32>;
680def : DivergentBinOp<sube, V_SUBB_U32_e32>;
681
682class divergent_i64_BinOp <SDPatternOperator Op, Instruction Inst> :
683  GCNPat<
684      (getDivergentFrag<Op>.ret i64:$src0, i64:$src1),
685      (REG_SEQUENCE VReg_64,
686        (Inst
687          (i32 (EXTRACT_SUBREG $src0, sub0)),
688          (i32 (EXTRACT_SUBREG $src1, sub0))
689        ), sub0,
690        (Inst
691          (i32 (EXTRACT_SUBREG $src0, sub1)),
692          (i32 (EXTRACT_SUBREG $src1, sub1))
693        ), sub1
694      )
695  >;
696
697def :  divergent_i64_BinOp <and, V_AND_B32_e64>;
698def :  divergent_i64_BinOp <or,  V_OR_B32_e64>;
699def :  divergent_i64_BinOp <xor, V_XOR_B32_e64>;
700
701
702let SubtargetPredicate = Has16BitInsts in {
703
704let FPDPRounding = 1 in {
705def V_MADMK_F16 : VOP2_Pseudo <"v_madmk_f16", VOP_MADMK_F16, [], "">;
706defm V_LDEXP_F16 : VOP2Inst <"v_ldexp_f16", VOP_F16_F16_I32, AMDGPUldexp>;
707} // End FPDPRounding = 1
708
709defm V_LSHLREV_B16 : VOP2Inst <"v_lshlrev_b16", VOP_I16_I16_I16, clshl_rev_16>;
710defm V_LSHRREV_B16 : VOP2Inst <"v_lshrrev_b16", VOP_I16_I16_I16, clshr_rev_16>;
711defm V_ASHRREV_I16 : VOP2Inst <"v_ashrrev_i16", VOP_I16_I16_I16, cashr_rev_16>;
712
713let isCommutable = 1 in {
714let FPDPRounding = 1 in {
715defm V_ADD_F16 : VOP2Inst <"v_add_f16", VOP_F16_F16_F16, any_fadd>;
716defm V_SUB_F16 : VOP2Inst <"v_sub_f16", VOP_F16_F16_F16, any_fsub>;
717defm V_SUBREV_F16 : VOP2Inst <"v_subrev_f16", VOP_F16_F16_F16, null_frag, "v_sub_f16">;
718defm V_MUL_F16 : VOP2Inst <"v_mul_f16", VOP_F16_F16_F16, any_fmul>;
719
720let mayRaiseFPException = 0 in {
721def V_MADAK_F16 : VOP2_Pseudo <"v_madak_f16", VOP_MADAK_F16, [], "">;
722}
723
724} // End FPDPRounding = 1
725defm V_MUL_LO_U16 : VOP2Inst <"v_mul_lo_u16", VOP_I16_I16_I16, mul>;
726defm V_MAX_F16 : VOP2Inst <"v_max_f16", VOP_F16_F16_F16, fmaxnum_like>;
727defm V_MIN_F16 : VOP2Inst <"v_min_f16", VOP_F16_F16_F16, fminnum_like>;
728defm V_MAX_U16 : VOP2Inst <"v_max_u16", VOP_I16_I16_I16, umax>;
729defm V_MAX_I16 : VOP2Inst <"v_max_i16", VOP_I16_I16_I16, smax>;
730defm V_MIN_U16 : VOP2Inst <"v_min_u16", VOP_I16_I16_I16, umin>;
731defm V_MIN_I16 : VOP2Inst <"v_min_i16", VOP_I16_I16_I16, smin>;
732
733let SubtargetPredicate = isGFX8GFX9 in {
734  defm V_ADD_U16 : VOP2Inst <"v_add_u16", VOP_I16_I16_I16_ARITH, add>;
735  defm V_SUB_U16 : VOP2Inst <"v_sub_u16" , VOP_I16_I16_I16_ARITH, sub>;
736  defm V_SUBREV_U16 : VOP2Inst <"v_subrev_u16", VOP_I16_I16_I16_ARITH, null_frag, "v_sub_u16">;
737}
738
739let Constraints = "$vdst = $src2", DisableEncoding="$src2",
740    isConvertibleToThreeAddress = 1 in {
741defm V_MAC_F16 : VOP2Inst <"v_mac_f16", VOP_MAC_F16>;
742}
743} // End isCommutable = 1
744
745} // End SubtargetPredicate = Has16BitInsts
746
747let SubtargetPredicate = HasDLInsts in {
748
749let isReMaterializable = 1 in
750defm V_XNOR_B32 : VOP2Inst <"v_xnor_b32", VOP_I32_I32_I32, xnor>;
751
752def : GCNPat<
753  (i32 (DivergentUnaryFrag<not> (xor_oneuse i32:$src0, i32:$src1))),
754  (i32 (V_XNOR_B32_e64 $src0, $src1))
755>;
756
757def : GCNPat<
758  (i32 (DivergentBinFrag<xor_oneuse> (not i32:$src0), i32:$src1)),
759  (i32 (V_XNOR_B32_e64 $src0, $src1))
760>;
761
762def : GCNPat<
763  (i64 (DivergentUnaryFrag<not> (xor_oneuse i64:$src0, i64:$src1))),
764  (REG_SEQUENCE VReg_64, (i32 (V_XNOR_B32_e64
765                            (i32 (EXTRACT_SUBREG $src0, sub0)),
766                            (i32 (EXTRACT_SUBREG $src1, sub0)))), sub0,
767                     (i32 (V_XNOR_B32_e64
768                            (i32 (EXTRACT_SUBREG $src0, sub1)),
769                            (i32 (EXTRACT_SUBREG $src1, sub1)))), sub1)
770>;
771
772def : GCNPat<
773  (i64 (DivergentBinFrag<xor_oneuse> (not i64:$src0), i64:$src1)),
774  (REG_SEQUENCE VReg_64, (i32 (V_XNOR_B32_e64
775                            (i32 (EXTRACT_SUBREG $src0, sub0)),
776                            (i32 (EXTRACT_SUBREG $src1, sub0)))), sub0,
777                     (i32 (V_XNOR_B32_e64
778                            (i32 (EXTRACT_SUBREG $src0, sub1)),
779                            (i32 (EXTRACT_SUBREG $src1, sub1)))), sub1)
780>;
781
782let Constraints = "$vdst = $src2",
783    DisableEncoding = "$src2",
784    isConvertibleToThreeAddress = 1,
785    isCommutable = 1 in
786defm V_FMAC_F32 : VOP2Inst <"v_fmac_f32", VOP_MAC_F32>;
787
788} // End SubtargetPredicate = HasDLInsts
789
790let SubtargetPredicate = HasFmaLegacy32 in {
791
792let Constraints = "$vdst = $src2",
793    DisableEncoding = "$src2",
794    isConvertibleToThreeAddress = 1,
795    isCommutable = 1 in
796defm V_FMAC_LEGACY_F32 : VOP2Inst <"v_fmac_legacy_f32", VOP_MAC_LEGACY_F32>;
797
798} // End SubtargetPredicate = HasFmaLegacy32
799
800let SubtargetPredicate = isGFX90APlus,
801    Constraints = "$vdst = $src2",
802    DisableEncoding="$src2",
803    isConvertibleToThreeAddress = 1,
804    isCommutable = 1,
805    SchedRW = [WriteDoubleAdd] in
806defm V_FMAC_F64 : VOP2Inst <"v_fmac_f64", VOP_MAC_F64>;
807
808let Constraints = "$vdst = $src2",
809      DisableEncoding="$src2",
810      isConvertibleToThreeAddress = 1,
811      isCommutable = 1,
812      IsDOT = 1 in {
813  let SubtargetPredicate = HasDot5Insts in
814    defm V_DOT2C_F32_F16 : VOP2Inst<"v_dot2c_f32_f16", VOP_DOT_ACC_F32_V2F16>;
815  let SubtargetPredicate = HasDot6Insts in
816    defm V_DOT4C_I32_I8  : VOP2Inst<"v_dot4c_i32_i8",  VOP_DOT_ACC_I32_I32>;
817
818  let SubtargetPredicate = HasDot4Insts in
819    defm V_DOT2C_I32_I16 : VOP2Inst<"v_dot2c_i32_i16", VOP_DOT_ACC_I32_I32>;
820  let SubtargetPredicate = HasDot3Insts in
821    defm V_DOT8C_I32_I4  : VOP2Inst<"v_dot8c_i32_i4",  VOP_DOT_ACC_I32_I32>;
822}
823
824let AddedComplexity = 30 in {
825  def : GCNPat<
826    (f32 (AMDGPUfdot2 v2f16:$src0, v2f16:$src1, f32:$src2, (i1 DSTCLAMP.NONE))),
827    (f32 (V_DOT2C_F32_F16_e32 $src0, $src1, $src2))
828  > {
829    let SubtargetPredicate = HasDot5Insts;
830  }
831  def : GCNPat<
832    (i32 (int_amdgcn_sdot4 i32:$src0, i32:$src1, i32:$src2, (i1 DSTCLAMP.NONE))),
833    (i32 (V_DOT4C_I32_I8_e32 $src0, $src1, $src2))
834  > {
835    let SubtargetPredicate = HasDot6Insts;
836  }
837  def : GCNPat<
838    (i32 (int_amdgcn_sdot2 v2i16:$src0, v2i16:$src1, i32:$src2, (i1 DSTCLAMP.NONE))),
839    (i32 (V_DOT2C_I32_I16_e32 $src0, $src1, $src2))
840  > {
841    let SubtargetPredicate = HasDot4Insts;
842  }
843  def : GCNPat<
844    (i32 (int_amdgcn_sdot8 i32:$src0, i32:$src1, i32:$src2, (i1 DSTCLAMP.NONE))),
845    (i32 (V_DOT8C_I32_I4_e32 $src0, $src1, $src2))
846  > {
847    let SubtargetPredicate = HasDot3Insts;
848  }
849} // End AddedComplexity = 30
850
851let SubtargetPredicate = HasFmaakFmamkF32Insts, isReMaterializable = 1 in {
852def V_FMAMK_F32 : VOP2_Pseudo<"v_fmamk_f32", VOP_MADMK_F32, [], "">;
853
854let isCommutable = 1 in
855def V_FMAAK_F32 : VOP2_Pseudo<"v_fmaak_f32", VOP_MADAK_F32, [], "">;
856}
857
858let SubtargetPredicate = isGFX10Plus in {
859
860let FPDPRounding = 1 in {
861def V_FMAMK_F16 : VOP2_Pseudo <"v_fmamk_f16", VOP_MADMK_F16, [], "">;
862
863let isCommutable = 1 in
864def V_FMAAK_F16 : VOP2_Pseudo <"v_fmaak_f16", VOP_MADAK_F16, [], "">;
865} // End FPDPRounding  = 1
866
867let Constraints = "$vdst = $src2",
868    DisableEncoding="$src2",
869    isConvertibleToThreeAddress = 1,
870    isCommutable = 1 in {
871defm V_FMAC_F16 : VOP2Inst <"v_fmac_f16", VOP_MAC_F16>;
872}
873
874} // End SubtargetPredicate = isGFX10Plus
875
876let SubtargetPredicate = HasPkFmacF16Inst in {
877defm V_PK_FMAC_F16 : VOP2Inst<"v_pk_fmac_f16", VOP_V2F16_V2F16_V2F16>;
878} // End SubtargetPredicate = HasPkFmacF16Inst
879
880// Note: 16-bit instructions produce a 0 result in the high 16-bits
881// on GFX8 and GFX9 and preserve high 16 bits on GFX10+
882multiclass Arithmetic_i16_0Hi_Pats <SDPatternOperator op, Instruction inst> {
883
884def : GCNPat<
885  (i32 (zext (op i16:$src0, i16:$src1))),
886  (inst VSrc_b16:$src0, VSrc_b16:$src1)
887>;
888
889def : GCNPat<
890  (i64 (zext (op i16:$src0, i16:$src1))),
891   (REG_SEQUENCE VReg_64,
892     (inst $src0, $src1), sub0,
893     (V_MOV_B32_e32 (i32 0)), sub1)
894>;
895}
896
897class ZExt_i16_i1_Pat <SDNode ext> : GCNPat <
898  (i16 (ext i1:$src)),
899  (V_CNDMASK_B32_e64 (i32 0/*src0mod*/), (i32 0/*src0*/),
900                     (i32 0/*src1mod*/), (i32 1/*src1*/),
901                     $src)
902>;
903
904foreach vt = [i16, v2i16] in {
905def : GCNPat <
906  (and vt:$src0, vt:$src1),
907  (V_AND_B32_e64 VSrc_b32:$src0, VSrc_b32:$src1)
908>;
909
910def : GCNPat <
911  (or vt:$src0, vt:$src1),
912  (V_OR_B32_e64 VSrc_b32:$src0, VSrc_b32:$src1)
913>;
914
915def : GCNPat <
916  (xor vt:$src0, vt:$src1),
917  (V_XOR_B32_e64 VSrc_b32:$src0, VSrc_b32:$src1)
918>;
919}
920
921let Predicates = [Has16BitInsts, isGFX8GFX9] in {
922
923// Undo sub x, c -> add x, -c canonicalization since c is more likely
924// an inline immediate than -c.
925// TODO: Also do for 64-bit.
926def : GCNPat<
927  (add i16:$src0, (i16 NegSubInlineIntConst16:$src1)),
928  (V_SUB_U16_e64 VSrc_b16:$src0, NegSubInlineIntConst16:$src1)
929>;
930
931def : GCNPat<
932  (i32 (zext (add i16:$src0, (i16 NegSubInlineIntConst16:$src1)))),
933  (V_SUB_U16_e64 VSrc_b16:$src0, NegSubInlineIntConst16:$src1)
934>;
935
936defm : Arithmetic_i16_0Hi_Pats<add, V_ADD_U16_e64>;
937defm : Arithmetic_i16_0Hi_Pats<mul, V_MUL_LO_U16_e64>;
938defm : Arithmetic_i16_0Hi_Pats<sub, V_SUB_U16_e64>;
939defm : Arithmetic_i16_0Hi_Pats<smin, V_MIN_I16_e64>;
940defm : Arithmetic_i16_0Hi_Pats<smax, V_MAX_I16_e64>;
941defm : Arithmetic_i16_0Hi_Pats<umin, V_MIN_U16_e64>;
942defm : Arithmetic_i16_0Hi_Pats<umax, V_MAX_U16_e64>;
943defm : Arithmetic_i16_0Hi_Pats<clshl_rev_16, V_LSHLREV_B16_e64>;
944defm : Arithmetic_i16_0Hi_Pats<clshr_rev_16, V_LSHRREV_B16_e64>;
945defm : Arithmetic_i16_0Hi_Pats<cashr_rev_16, V_ASHRREV_I16_e64>;
946
947}  // End Predicates = [Has16BitInsts, isGFX8GFX9]
948
949let Predicates = [Has16BitInsts] in {
950
951def : ZExt_i16_i1_Pat<zext>;
952def : ZExt_i16_i1_Pat<anyext>;
953
954def : GCNPat <
955  (i16 (sext i1:$src)),
956  (V_CNDMASK_B32_e64 /*src0mod*/(i32 0), /*src0*/(i32 0),
957                     /*src1mod*/(i32 0), /*src1*/(i32 -1), $src)
958>;
959
960} // End Predicates = [Has16BitInsts]
961
962
963let SubtargetPredicate = HasIntClamp in {
964// Set clamp bit for saturation.
965def : VOPBinOpClampPat<uaddsat, V_ADD_CO_U32_e64, i32>;
966def : VOPBinOpClampPat<usubsat, V_SUB_CO_U32_e64, i32>;
967}
968
969let SubtargetPredicate = HasAddNoCarryInsts, OtherPredicates = [HasIntClamp] in {
970let AddedComplexity = 1 in { // Prefer over form with carry-out.
971def : VOPBinOpClampPat<uaddsat, V_ADD_U32_e64, i32>;
972def : VOPBinOpClampPat<usubsat, V_SUB_U32_e64, i32>;
973}
974}
975
976let SubtargetPredicate = Has16BitInsts, OtherPredicates = [HasIntClamp] in {
977def : VOPBinOpClampPat<uaddsat, V_ADD_U16_e64, i16>;
978def : VOPBinOpClampPat<usubsat, V_SUB_U16_e64, i16>;
979}
980
981let SubtargetPredicate = isGFX11Plus in {
982  let isCommutable = 1 in {
983    defm V_AND_B16 : VOP2Inst <"v_and_b16", VOP_I16_I16_I16, and>;
984    defm V_OR_B16  : VOP2Inst <"v_or_b16", VOP_I16_I16_I16, or>;
985    defm V_XOR_B16 : VOP2Inst <"v_xor_b16", VOP_I16_I16_I16, xor>;
986  } // End isCommutable = 1
987} // End SubtargetPredicate = isGFX11Plus
988
989//===----------------------------------------------------------------------===//
990// DPP Encodings
991//===----------------------------------------------------------------------===//
992
993class VOP2_DPP<bits<6> op, VOP2_DPP_Pseudo ps,
994               string opName = ps.OpName, VOPProfile p = ps.Pfl,
995               bit IsDPP16 = 0> :
996    VOP_DPP<opName, p, IsDPP16> {
997  let hasSideEffects = ps.hasSideEffects;
998  let Defs = ps.Defs;
999  let SchedRW = ps.SchedRW;
1000  let Uses = ps.Uses;
1001
1002  bits<8> vdst;
1003  bits<8> src1;
1004  let Inst{8-0}   = 0xfa;
1005  let Inst{16-9}  = !if(p.HasSrc1, src1{7-0}, 0);
1006  let Inst{24-17} = !if(p.EmitDst, vdst{7-0}, 0);
1007  let Inst{30-25} = op;
1008  let Inst{31}    = 0x0;
1009}
1010
1011class Base_VOP2_DPP16<bits<6> op, VOP2_DPP_Pseudo ps,
1012                 string opName = ps.OpName, VOPProfile p = ps.Pfl> :
1013    VOP2_DPP<op, ps, opName, p, 1> {
1014  let AssemblerPredicate = HasDPP16;
1015  let SubtargetPredicate = HasDPP16;
1016  let OtherPredicates = ps.OtherPredicates;
1017}
1018
1019class VOP2_DPP16<bits<6> op, VOP2_DPP_Pseudo ps, int subtarget,
1020                 string opName = ps.OpName, VOPProfile p = ps.Pfl> :
1021    Base_VOP2_DPP16<op, ps, opName, p>,
1022    SIMCInstr <ps.PseudoInstr, subtarget>;
1023
1024class VOP2_DPP8<bits<6> op, VOP2_Pseudo ps,
1025                VOPProfile p = ps.Pfl> :
1026    VOP_DPP8<ps.OpName, p> {
1027  let hasSideEffects = ps.hasSideEffects;
1028  let Defs = ps.Defs;
1029  let SchedRW = ps.SchedRW;
1030  let Uses = ps.Uses;
1031
1032  bits<8> vdst;
1033  bits<8> src1;
1034
1035  let Inst{8-0}   = fi;
1036  let Inst{16-9}  = !if(p.HasSrc1, src1{7-0}, 0);
1037  let Inst{24-17} = !if(p.EmitDst, vdst{7-0}, 0);
1038  let Inst{30-25} = op;
1039  let Inst{31}    = 0x0;
1040
1041  let OtherPredicates = ps.OtherPredicates;
1042}
1043
1044//===----------------------------------------------------------------------===//
1045// GFX11.
1046//===----------------------------------------------------------------------===//
1047
1048let AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11" in {
1049  //===------------------------------- VOP2 -------------------------------===//
1050  multiclass VOP2Only_Real_MADK_gfx11<bits<6> op> {
1051    def _gfx11 :
1052      VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.GFX11>,
1053      VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>;
1054  }
1055  multiclass VOP2_Real_e32_gfx11<bits<6> op> {
1056    def _e32_gfx11 :
1057      VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.GFX11>,
1058      VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>;
1059  }
1060  multiclass VOP2Only_Real_e32_gfx11<bits<6> op> {
1061    let IsSingle = 1 in
1062      defm NAME: VOP2_Real_e32_gfx11<op>;
1063  }
1064  multiclass VOP2_Real_e64_gfx11<bits<6> op> {
1065    def _e64_gfx11 :
1066      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX11>,
1067      VOP3e_gfx11<{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
1068  }
1069  multiclass VOP2_Real_dpp_gfx11<bits<6> op> {
1070    foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtDPP>.ret in
1071    def _dpp_gfx11 : VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(NAME#"_dpp"), SIEncodingFamily.GFX11> {
1072      let DecoderNamespace = "DPPGFX11";
1073    }
1074  }
1075  multiclass VOP2_Real_dpp8_gfx11<bits<6> op> {
1076    foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtDPP>.ret in
1077    def _dpp8_gfx11 : VOP2_DPP8<op, !cast<VOP2_Pseudo>(NAME#"_e32")> {
1078      let DecoderNamespace = "DPP8GFX11";
1079    }
1080  }
1081
1082  //===------------------------- VOP2 (with name) -------------------------===//
1083  multiclass VOP2_Real_e32_with_name_gfx11<bits<6> op, string opName,
1084                                           string asmName, bit single = 0> {
1085    defvar ps = !cast<VOP2_Pseudo>(opName#"_e32");
1086    def _e32_gfx11 :
1087      VOP2_Real<ps, SIEncodingFamily.GFX11, asmName>,
1088      VOP2e<op{5-0}, ps.Pfl>,
1089      MnemonicAlias<ps.Mnemonic, asmName>, Requires<[isGFX11Plus]> {
1090        let AsmString = asmName # ps.AsmOperands;
1091        let IsSingle = single;
1092      }
1093  }
1094  multiclass VOP2_Real_e64_with_name_gfx11<bits<6> op, string opName,
1095                                           string asmName> {
1096    defvar ps = !cast<VOP3_Pseudo>(opName#"_e64");
1097    def _e64_gfx11 :
1098      VOP3_Real<ps, SIEncodingFamily.GFX11>,
1099      VOP3e_gfx11<{0, 1, 0, 0, op{5-0}}, ps.Pfl>,
1100      MnemonicAlias<ps.Mnemonic, asmName>, Requires<[isGFX11Plus]> {
1101        let AsmString = asmName # ps.AsmOperands;
1102      }
1103  }
1104
1105  multiclass VOP2_Real_dpp_with_name_gfx11<bits<6> op, string opName,
1106                                           string asmName> {
1107    defvar ps = !cast<VOP2_Pseudo>(opName#"_e32");
1108    foreach _ = BoolToList<ps.Pfl.HasExtDPP>.ret in
1109    def _dpp_gfx11 : VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(opName#"_dpp"),
1110        SIEncodingFamily.GFX11> {
1111      let AsmString = asmName # ps.Pfl.AsmDPP16;
1112      let DecoderNamespace = "DPPGFX11";
1113    }
1114  }
1115  multiclass VOP2_Real_dpp8_with_name_gfx11<bits<6> op, string opName,
1116                                            string asmName> {
1117    defvar ps = !cast<VOP2_Pseudo>(opName#"_e32");
1118    foreach _ = BoolToList<ps.Pfl.HasExtDPP>.ret in
1119    def _dpp8_gfx11 : VOP2_DPP8<op, ps> {
1120      let AsmString = asmName # ps.Pfl.AsmDPP8;
1121      let DecoderNamespace = "DPP8GFX11";
1122    }
1123  }
1124
1125  //===------------------------------ VOP2be ------------------------------===//
1126  multiclass VOP2be_Real_e32_gfx11<bits<6> op, string opName, string asmName> {
1127    defvar ps = !cast<VOP2_Pseudo>(opName#"_e32");
1128    def _e32_gfx11 :
1129      VOP2_Real<ps, SIEncodingFamily.GFX11>,
1130      VOP2e<op{5-0}, ps.Pfl> {
1131        let AsmString = asmName # !subst(", vcc", "", ps.AsmOperands);
1132      }
1133  }
1134  multiclass VOP2be_Real_dpp_gfx11<bits<6> op, string opName, string asmName> {
1135    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP>.ret in
1136    def _dpp_gfx11 :
1137      VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(opName#"_dpp"), SIEncodingFamily.GFX11, asmName> {
1138        string AsmDPP = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP16;
1139        let AsmString = asmName # !subst(", vcc", "", AsmDPP);
1140        let DecoderNamespace = "DPPGFX11";
1141      }
1142    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP>.ret in
1143    def _dpp_w32_gfx11 :
1144      Base_VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(opName#"_dpp"), asmName> {
1145        string AsmDPP = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP16;
1146        let AsmString = asmName # !subst("vcc", "vcc_lo", AsmDPP);
1147        let isAsmParserOnly = 1;
1148        let WaveSizePredicate = isWave32;
1149      }
1150    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP>.ret in
1151    def _dpp_w64_gfx11 :
1152      Base_VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(opName#"_dpp"), asmName> {
1153        string AsmDPP = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP16;
1154        let AsmString = asmName # AsmDPP;
1155        let isAsmParserOnly = 1;
1156        let WaveSizePredicate = isWave64;
1157      }
1158  }
1159  multiclass VOP2be_Real_dpp8_gfx11<bits<6> op, string opName, string asmName> {
1160    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP>.ret in
1161    def _dpp8_gfx11 :
1162      VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
1163        string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
1164        let AsmString = asmName # !subst(", vcc", "", AsmDPP8);
1165        let DecoderNamespace = "DPP8GFX11";
1166      }
1167    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP>.ret in
1168    def _dpp8_w32_gfx11 :
1169      VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
1170        string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
1171        let AsmString = asmName # !subst("vcc", "vcc_lo", AsmDPP8);
1172        let isAsmParserOnly = 1;
1173        let WaveSizePredicate = isWave32;
1174      }
1175    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtDPP>.ret in
1176    def _dpp8_w64_gfx11 :
1177      VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
1178        string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
1179        let AsmString = asmName # AsmDPP8;
1180        let isAsmParserOnly = 1;
1181        let WaveSizePredicate = isWave64;
1182      }
1183  }
1184
1185} // End AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11"
1186
1187// We don't want to override separate decoderNamespaces within these
1188multiclass VOP2_Realtriple_e64_gfx11<bits<6> op> {
1189  defm NAME : VOP3_Realtriple_gfx11<{0, 1, 0, 0, op{5-0}}, /*isSingle=*/ 0, NAME> ;
1190}
1191multiclass VOP2_Realtriple_e64_with_name_gfx11<bits<6> op, string opName,
1192                                               string asmName> {
1193  defm NAME : VOP3_Realtriple_with_name_gfx11<{0, 1, 0, 0, op{5-0}}, opName, asmName> ;
1194}
1195
1196multiclass VOP2be_Real_gfx11<bits<6> op, string opName, string asmName> :
1197  VOP2be_Real_e32_gfx11<op, opName, asmName>,
1198  VOP3be_Realtriple_gfx11<{0, 1, 0, 0, op{5-0}}, /*isSingle=*/ 0, opName, asmName>,
1199  VOP2be_Real_dpp_gfx11<op, opName, asmName>,
1200  VOP2be_Real_dpp8_gfx11<op, opName, asmName>;
1201
1202// Only for CNDMASK
1203multiclass VOP2e_Real_gfx11<bits<6> op, string opName, string asmName> :
1204  VOP2_Real_e32_gfx11<op>,
1205  VOP2_Realtriple_e64_gfx11<op>,
1206  VOP2be_Real_dpp_gfx11<op, opName, asmName>,
1207  VOP2be_Real_dpp8_gfx11<op, opName, asmName>;
1208
1209multiclass VOP2Only_Real_gfx11<bits<6> op> :
1210  VOP2Only_Real_e32_gfx11<op>,
1211  VOP2_Real_dpp_gfx11<op>,
1212  VOP2_Real_dpp8_gfx11<op>;
1213
1214multiclass VOP2_Real_NO_VOP3_gfx11<bits<6> op> :
1215  VOP2_Real_e32_gfx11<op>, VOP2_Real_dpp_gfx11<op>, VOP2_Real_dpp8_gfx11<op>;
1216
1217multiclass VOP2_Real_FULL_gfx11<bits<6> op> :
1218  VOP2_Realtriple_e64_gfx11<op>, VOP2_Real_NO_VOP3_gfx11<op>;
1219
1220multiclass VOP2_Real_NO_VOP3_with_name_gfx11<bits<6> op, string opName,
1221                                           string asmName, bit isSingle = 0> :
1222  VOP2_Real_e32_with_name_gfx11<op, opName, asmName, isSingle>,
1223  VOP2_Real_dpp_with_name_gfx11<op, opName, asmName>,
1224  VOP2_Real_dpp8_with_name_gfx11<op, opName, asmName>;
1225
1226multiclass VOP2_Real_FULL_with_name_gfx11<bits<6> op, string opName,
1227                                         string asmName> :
1228  VOP2_Realtriple_e64_with_name_gfx11<op, opName, asmName>,
1229  VOP2_Real_NO_VOP3_with_name_gfx11<op, opName, asmName>;
1230
1231multiclass VOP2_Real_NO_DPP_gfx11<bits<6> op> :
1232  VOP2_Real_e32_gfx11<op>, VOP2_Real_e64_gfx11<op>;
1233
1234multiclass VOP2_Real_NO_DPP_with_name_gfx11<bits<6> op, string opName,
1235                                           string asmName> :
1236  VOP2_Real_e32_with_name_gfx11<op, opName, asmName>,
1237  VOP2_Real_e64_with_name_gfx11<op, opName, asmName>;
1238
1239defm V_CNDMASK_B32 : VOP2e_Real_gfx11<0x001, "V_CNDMASK_B32",
1240  "v_cndmask_b32">;
1241defm V_DOT2ACC_F32_F16 : VOP2_Real_NO_VOP3_with_name_gfx11<0x002,
1242  "V_DOT2C_F32_F16", "v_dot2acc_f32_f16", 1>;
1243defm V_FMAC_DX9_ZERO_F32 : VOP2_Real_NO_DPP_with_name_gfx11<0x006,
1244  "V_FMAC_LEGACY_F32", "v_fmac_dx9_zero_f32">;
1245defm V_MUL_DX9_ZERO_F32 : VOP2_Real_FULL_with_name_gfx11<0x007,
1246  "V_MUL_LEGACY_F32", "v_mul_dx9_zero_f32">;
1247defm V_LSHLREV_B32        : VOP2_Real_FULL_gfx11<0x018>;
1248defm V_LSHRREV_B32        : VOP2_Real_FULL_gfx11<0x019>;
1249defm V_ASHRREV_I32        : VOP2_Real_FULL_gfx11<0x01a>;
1250defm V_ADD_CO_CI_U32 :
1251  VOP2be_Real_gfx11<0x020, "V_ADDC_U32", "v_add_co_ci_u32">;
1252defm V_SUB_CO_CI_U32 :
1253  VOP2be_Real_gfx11<0x021, "V_SUBB_U32", "v_sub_co_ci_u32">;
1254defm V_SUBREV_CO_CI_U32 :
1255  VOP2be_Real_gfx11<0x022, "V_SUBBREV_U32", "v_subrev_co_ci_u32">;
1256
1257defm V_CVT_PK_RTZ_F16_F32  : VOP2_Real_FULL_with_name_gfx11<0x02f,
1258  "V_CVT_PKRTZ_F16_F32", "v_cvt_pk_rtz_f16_f32">;
1259defm V_PK_FMAC_F16     : VOP2Only_Real_gfx11<0x03c>;
1260
1261// VOP3 only.
1262defm V_CNDMASK_B16        : VOP3Only_Realtriple_gfx11<0x25d>;
1263defm V_LDEXP_F32          : VOP3Only_Realtriple_gfx11<0x31c>;
1264defm V_BFM_B32            : VOP3Only_Realtriple_gfx11<0x31d>;
1265defm V_BCNT_U32_B32       : VOP3Only_Realtriple_gfx11<0x31e>;
1266defm V_MBCNT_LO_U32_B32   : VOP3Only_Realtriple_gfx11<0x31f>;
1267defm V_MBCNT_HI_U32_B32   : VOP3Only_Realtriple_gfx11<0x320>;
1268defm V_CVT_PKNORM_I16_F32 : VOP3Only_Realtriple_gfx11<0x321>;
1269defm V_CVT_PKNORM_U16_F32 : VOP3Only_Realtriple_gfx11<0x322>;
1270defm V_CVT_PK_U16_U32     : VOP3Only_Realtriple_gfx11<0x323>;
1271defm V_CVT_PK_I16_I32     : VOP3Only_Realtriple_gfx11<0x324>;
1272defm V_ADD_CO_U32         : VOP3beOnly_Realtriple_gfx11<0x300>;
1273defm V_SUB_CO_U32         : VOP3beOnly_Realtriple_gfx11<0x301>;
1274defm V_SUBREV_CO_U32      : VOP3beOnly_Realtriple_gfx11<0x302>;
1275
1276let SubtargetPredicate = isGFX11Plus in {
1277  defm : VOP2eInstAliases<V_CNDMASK_B32_e32, V_CNDMASK_B32_e32_gfx11>;
1278
1279  defm : VOP2bInstAliases<
1280    V_ADDC_U32_e32, V_ADD_CO_CI_U32_e32_gfx11, "v_add_co_ci_u32">;
1281  defm : VOP2bInstAliases<
1282    V_SUBB_U32_e32, V_SUB_CO_CI_U32_e32_gfx11, "v_sub_co_ci_u32">;
1283  defm : VOP2bInstAliases<
1284    V_SUBBREV_U32_e32, V_SUBREV_CO_CI_U32_e32_gfx11, "v_subrev_co_ci_u32">;
1285} // End SubtargetPredicate = isGFX11Plus
1286
1287//===----------------------------------------------------------------------===//
1288// GFX10.
1289//===----------------------------------------------------------------------===//
1290
1291let AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10" in {
1292  //===------------------------------- VOP2 -------------------------------===//
1293  multiclass VOP2Only_Real_MADK_gfx10<bits<6> op> {
1294    def _gfx10 :
1295      VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.GFX10>,
1296      VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>;
1297  }
1298  multiclass VOP2Only_Real_MADK_gfx10_with_name<bits<6> op, string opName,
1299                                                string asmName> {
1300    def _gfx10 :
1301        VOP2_Real<!cast<VOP2_Pseudo>(opName), SIEncodingFamily.GFX10>,
1302        VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(opName).Pfl> {
1303      VOP2_Pseudo ps = !cast<VOP2_Pseudo>(opName);
1304      let AsmString = asmName # ps.AsmOperands;
1305    }
1306  }
1307  multiclass VOP2_Real_e32_gfx10<bits<6> op> {
1308    def _e32_gfx10 :
1309      VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.GFX10>,
1310      VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>;
1311  }
1312  multiclass VOP2_Real_e64_gfx10<bits<6> op> {
1313    def _e64_gfx10 :
1314      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX10>,
1315      VOP3e_gfx10<{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
1316  }
1317  multiclass VOP2_Real_sdwa_gfx10<bits<6> op> {
1318    foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtSDWA9>.ret in
1319    def _sdwa_gfx10 :
1320      VOP_SDWA10_Real<!cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa")>,
1321      VOP2_SDWA9Ae<op{5-0}, !cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa").Pfl> {
1322      let DecoderNamespace = "SDWA10";
1323    }
1324  }
1325  multiclass VOP2_Real_dpp_gfx10<bits<6> op> {
1326    foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExt32BitDPP>.ret in
1327    def _dpp_gfx10 : VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(NAME#"_dpp"), SIEncodingFamily.GFX10> {
1328      let DecoderNamespace = "SDWA10";
1329    }
1330  }
1331  multiclass VOP2_Real_dpp8_gfx10<bits<6> op> {
1332    foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExt32BitDPP>.ret in
1333    def _dpp8_gfx10 : VOP2_DPP8<op, !cast<VOP2_Pseudo>(NAME#"_e32")> {
1334      let DecoderNamespace = "DPP8";
1335    }
1336  }
1337
1338  //===------------------------- VOP2 (with name) -------------------------===//
1339  multiclass VOP2_Real_e32_gfx10_with_name<bits<6> op, string opName,
1340                                           string asmName> {
1341    def _e32_gfx10 :
1342      VOP2_Real<!cast<VOP2_Pseudo>(opName#"_e32"), SIEncodingFamily.GFX10>,
1343      VOP2e<op{5-0}, !cast<VOP2_Pseudo>(opName#"_e32").Pfl> {
1344        VOP2_Pseudo ps = !cast<VOP2_Pseudo>(opName#"_e32");
1345        let AsmString = asmName # ps.AsmOperands;
1346      }
1347  }
1348  multiclass VOP2_Real_e64_gfx10_with_name<bits<6> op, string opName,
1349                                           string asmName> {
1350    def _e64_gfx10 :
1351      VOP3_Real<!cast<VOP3_Pseudo>(opName#"_e64"), SIEncodingFamily.GFX10>,
1352      VOP3e_gfx10<{0, 1, 0, 0, op{5-0}},
1353                  !cast<VOP3_Pseudo>(opName#"_e64").Pfl> {
1354        VOP3_Pseudo ps = !cast<VOP3_Pseudo>(opName#"_e64");
1355        let AsmString = asmName # ps.AsmOperands;
1356      }
1357  }
1358  let DecoderNamespace = "SDWA10" in {
1359    multiclass VOP2_Real_sdwa_gfx10_with_name<bits<6> op, string opName,
1360                                              string asmName> {
1361      foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtSDWA9>.ret in
1362      def _sdwa_gfx10 :
1363        VOP_SDWA10_Real<!cast<VOP2_SDWA_Pseudo>(opName#"_sdwa")>,
1364        VOP2_SDWA9Ae<op{5-0}, !cast<VOP2_SDWA_Pseudo>(opName#"_sdwa").Pfl> {
1365          VOP2_SDWA_Pseudo ps = !cast<VOP2_SDWA_Pseudo>(opName#"_sdwa");
1366          let AsmString = asmName # ps.AsmOperands;
1367        }
1368    }
1369    multiclass VOP2_Real_dpp_gfx10_with_name<bits<6> op, string opName,
1370                                             string asmName> {
1371      foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExt32BitDPP>.ret in
1372      def _dpp_gfx10 : VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(opName#"_dpp"), SIEncodingFamily.GFX10> {
1373        VOP2_Pseudo ps = !cast<VOP2_Pseudo>(opName#"_e32");
1374        let AsmString = asmName # ps.Pfl.AsmDPP16;
1375      }
1376    }
1377    multiclass VOP2_Real_dpp8_gfx10_with_name<bits<6> op, string opName,
1378                                              string asmName> {
1379      foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExt32BitDPP>.ret in
1380      def _dpp8_gfx10 : VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
1381        VOP2_Pseudo ps = !cast<VOP2_Pseudo>(opName#"_e32");
1382        let AsmString = asmName # ps.Pfl.AsmDPP8;
1383        let DecoderNamespace = "DPP8";
1384      }
1385    }
1386  } // End DecoderNamespace = "SDWA10"
1387
1388  //===------------------------------ VOP2be ------------------------------===//
1389  multiclass VOP2be_Real_e32_gfx10<bits<6> op, string opName, string asmName> {
1390    def _e32_gfx10 :
1391      VOP2_Real<!cast<VOP2_Pseudo>(opName#"_e32"), SIEncodingFamily.GFX10>,
1392      VOP2e<op{5-0}, !cast<VOP2_Pseudo>(opName#"_e32").Pfl> {
1393        VOP2_Pseudo Ps = !cast<VOP2_Pseudo>(opName#"_e32");
1394        let AsmString = asmName # !subst(", vcc", "", Ps.AsmOperands);
1395      }
1396  }
1397  multiclass VOP2be_Real_e64_gfx10<bits<6> op, string opName, string asmName> {
1398    def _e64_gfx10 :
1399      VOP3_Real<!cast<VOP3_Pseudo>(opName#"_e64"), SIEncodingFamily.GFX10>,
1400      VOP3be_gfx10<{0, 1, 0, 0, op{5-0}},
1401                   !cast<VOP3_Pseudo>(opName#"_e64").Pfl> {
1402        VOP3_Pseudo Ps = !cast<VOP3_Pseudo>(opName#"_e64");
1403        let AsmString = asmName # Ps.AsmOperands;
1404      }
1405  }
1406  multiclass VOP2be_Real_sdwa_gfx10<bits<6> op, string opName, string asmName> {
1407    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtSDWA9>.ret in
1408    def _sdwa_gfx10 :
1409      VOP_SDWA10_Real<!cast<VOP2_SDWA_Pseudo>(opName#"_sdwa")>,
1410      VOP2_SDWA9Ae<op{5-0}, !cast<VOP2_SDWA_Pseudo>(opName#"_sdwa").Pfl> {
1411        VOP2_SDWA_Pseudo Ps = !cast<VOP2_SDWA_Pseudo>(opName#"_sdwa");
1412        let AsmString = asmName # !subst(", vcc", "", Ps.AsmOperands);
1413        let DecoderNamespace = "SDWA10";
1414      }
1415    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtSDWA9>.ret in
1416    def _sdwa_w32_gfx10 :
1417      Base_VOP_SDWA10_Real<!cast<VOP2_SDWA_Pseudo>(opName#"_sdwa")>,
1418      VOP2_SDWA9Ae<op{5-0}, !cast<VOP2_SDWA_Pseudo>(opName#"_sdwa").Pfl> {
1419        VOP2_SDWA_Pseudo Ps = !cast<VOP2_SDWA_Pseudo>(opName#"_sdwa");
1420        let AsmString = asmName # !subst("vcc", "vcc_lo", Ps.AsmOperands);
1421        let isAsmParserOnly = 1;
1422        let DecoderNamespace = "SDWA10";
1423        let WaveSizePredicate = isWave32;
1424      }
1425    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExtSDWA9>.ret in
1426    def _sdwa_w64_gfx10 :
1427      Base_VOP_SDWA10_Real<!cast<VOP2_SDWA_Pseudo>(opName#"_sdwa")>,
1428      VOP2_SDWA9Ae<op{5-0}, !cast<VOP2_SDWA_Pseudo>(opName#"_sdwa").Pfl> {
1429        VOP2_SDWA_Pseudo Ps = !cast<VOP2_SDWA_Pseudo>(opName#"_sdwa");
1430        let AsmString = asmName # Ps.AsmOperands;
1431        let isAsmParserOnly = 1;
1432        let DecoderNamespace = "SDWA10";
1433        let WaveSizePredicate = isWave64;
1434      }
1435  }
1436  multiclass VOP2be_Real_dpp_gfx10<bits<6> op, string opName, string asmName> {
1437    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExt32BitDPP>.ret in
1438    def _dpp_gfx10 :
1439      VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(opName#"_dpp"), SIEncodingFamily.GFX10, asmName> {
1440        string AsmDPP = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP16;
1441        let AsmString = asmName # !subst(", vcc", "", AsmDPP);
1442        let DecoderNamespace = "SDWA10";
1443      }
1444    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExt32BitDPP>.ret in
1445    def _dpp_w32_gfx10 :
1446      Base_VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(opName#"_dpp"), asmName> {
1447        string AsmDPP = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP16;
1448        let AsmString = asmName # !subst("vcc", "vcc_lo", AsmDPP);
1449        let isAsmParserOnly = 1;
1450        let WaveSizePredicate = isWave32;
1451      }
1452    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExt32BitDPP>.ret in
1453    def _dpp_w64_gfx10 :
1454      Base_VOP2_DPP16<op, !cast<VOP2_DPP_Pseudo>(opName#"_dpp"), asmName> {
1455        string AsmDPP = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP16;
1456        let AsmString = asmName # AsmDPP;
1457        let isAsmParserOnly = 1;
1458        let WaveSizePredicate = isWave64;
1459      }
1460  }
1461  multiclass VOP2be_Real_dpp8_gfx10<bits<6> op, string opName, string asmName> {
1462    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExt32BitDPP>.ret in
1463    def _dpp8_gfx10 :
1464      VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
1465        string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
1466        let AsmString = asmName # !subst(", vcc", "", AsmDPP8);
1467        let DecoderNamespace = "DPP8";
1468      }
1469    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExt32BitDPP>.ret in
1470    def _dpp8_w32_gfx10 :
1471      VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
1472        string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
1473        let AsmString = asmName # !subst("vcc", "vcc_lo", AsmDPP8);
1474        let isAsmParserOnly = 1;
1475        let WaveSizePredicate = isWave32;
1476      }
1477    foreach _ = BoolToList<!cast<VOP2_Pseudo>(opName#"_e32").Pfl.HasExt32BitDPP>.ret in
1478    def _dpp8_w64_gfx10 :
1479      VOP2_DPP8<op, !cast<VOP2_Pseudo>(opName#"_e32")> {
1480        string AsmDPP8 = !cast<VOP2_Pseudo>(opName#"_e32").Pfl.AsmDPP8;
1481        let AsmString = asmName # AsmDPP8;
1482        let isAsmParserOnly = 1;
1483        let WaveSizePredicate = isWave64;
1484      }
1485  }
1486
1487  //===----------------------------- VOP3Only -----------------------------===//
1488  multiclass VOP3Only_Real_gfx10<bits<10> op> {
1489    def _e64_gfx10 :
1490      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX10>,
1491      VOP3e_gfx10<op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl> {
1492        let IsSingle = 1;
1493      }
1494  }
1495
1496  //===---------------------------- VOP3beOnly ----------------------------===//
1497  multiclass VOP3beOnly_Real_gfx10<bits<10> op> {
1498    def _e64_gfx10 :
1499      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX10>,
1500      VOP3be_gfx10<op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl> {
1501        let IsSingle = 1;
1502      }
1503  }
1504} // End AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10"
1505
1506multiclass VOP2Only_Real_MADK_gfx10_gfx11<bits<6> op> :
1507  VOP2Only_Real_MADK_gfx10<op>, VOP2Only_Real_MADK_gfx11<op>;
1508
1509multiclass VOP2be_Real_gfx10<bits<6> op, string opName, string asmName> :
1510  VOP2be_Real_e32_gfx10<op, opName, asmName>,
1511  VOP2be_Real_e64_gfx10<op, opName, asmName>,
1512  VOP2be_Real_sdwa_gfx10<op, opName, asmName>,
1513  VOP2be_Real_dpp_gfx10<op, opName, asmName>,
1514  VOP2be_Real_dpp8_gfx10<op, opName, asmName>;
1515
1516multiclass VOP2e_Real_gfx10<bits<6> op, string opName, string asmName> :
1517  VOP2_Real_e32_gfx10<op>,
1518  VOP2_Real_e64_gfx10<op>,
1519  VOP2be_Real_sdwa_gfx10<op, opName, asmName>,
1520  VOP2be_Real_dpp_gfx10<op, opName, asmName>,
1521  VOP2be_Real_dpp8_gfx10<op, opName, asmName>;
1522
1523multiclass VOP2_Real_gfx10<bits<6> op> :
1524  VOP2_Real_e32_gfx10<op>, VOP2_Real_e64_gfx10<op>,
1525  VOP2_Real_sdwa_gfx10<op>, VOP2_Real_dpp_gfx10<op>, VOP2_Real_dpp8_gfx10<op>;
1526
1527multiclass VOP2_Real_gfx10_gfx11<bits<6> op> :
1528  VOP2_Real_gfx10<op>, VOP2_Real_FULL_gfx11<op>;
1529
1530multiclass VOP2_Real_with_name_gfx10<bits<6> op, string opName,
1531                                     string asmName> :
1532  VOP2_Real_e32_gfx10_with_name<op, opName, asmName>,
1533  VOP2_Real_e64_gfx10_with_name<op, opName, asmName>,
1534  VOP2_Real_sdwa_gfx10_with_name<op, opName, asmName>,
1535  VOP2_Real_dpp_gfx10_with_name<op, opName, asmName>,
1536  VOP2_Real_dpp8_gfx10_with_name<op, opName, asmName>;
1537
1538multiclass VOP2_Real_with_name_gfx10_gfx11<bits<6> op, string opName,
1539                                     string asmName> :
1540  VOP2_Real_with_name_gfx10<op, opName, asmName>,
1541  VOP2_Real_FULL_with_name_gfx11<op, opName, asmName>;
1542
1543// NB: Same opcode as v_mac_legacy_f32
1544let DecoderNamespace = "GFX10_B" in
1545defm V_FMAC_LEGACY_F32 : VOP2_Real_gfx10<0x006>;
1546
1547defm V_XNOR_B32        : VOP2_Real_gfx10_gfx11<0x01e>;
1548defm V_FMAC_F32        : VOP2_Real_gfx10_gfx11<0x02b>;
1549defm V_FMAMK_F32       : VOP2Only_Real_MADK_gfx10_gfx11<0x02c>;
1550defm V_FMAAK_F32       : VOP2Only_Real_MADK_gfx10_gfx11<0x02d>;
1551defm V_ADD_F16         : VOP2_Real_gfx10_gfx11<0x032>;
1552defm V_SUB_F16         : VOP2_Real_gfx10_gfx11<0x033>;
1553defm V_SUBREV_F16      : VOP2_Real_gfx10_gfx11<0x034>;
1554defm V_MUL_F16         : VOP2_Real_gfx10_gfx11<0x035>;
1555defm V_FMAC_F16        : VOP2_Real_gfx10_gfx11<0x036>;
1556defm V_FMAMK_F16       : VOP2Only_Real_MADK_gfx10_gfx11<0x037>;
1557defm V_FMAAK_F16       : VOP2Only_Real_MADK_gfx10_gfx11<0x038>;
1558defm V_MAX_F16         : VOP2_Real_gfx10_gfx11<0x039>;
1559defm V_MIN_F16         : VOP2_Real_gfx10_gfx11<0x03a>;
1560defm V_LDEXP_F16       : VOP2_Real_gfx10_gfx11<0x03b>;
1561
1562let IsSingle = 1 in {
1563  defm V_PK_FMAC_F16     : VOP2_Real_e32_gfx10<0x03c>;
1564}
1565
1566// VOP2 no carry-in, carry-out.
1567defm V_ADD_NC_U32 :
1568  VOP2_Real_with_name_gfx10_gfx11<0x025, "V_ADD_U32", "v_add_nc_u32">;
1569defm V_SUB_NC_U32 :
1570  VOP2_Real_with_name_gfx10_gfx11<0x026, "V_SUB_U32", "v_sub_nc_u32">;
1571defm V_SUBREV_NC_U32 :
1572  VOP2_Real_with_name_gfx10_gfx11<0x027, "V_SUBREV_U32", "v_subrev_nc_u32">;
1573
1574// VOP2 carry-in, carry-out.
1575defm V_ADD_CO_CI_U32 :
1576  VOP2be_Real_gfx10<0x028, "V_ADDC_U32", "v_add_co_ci_u32">;
1577defm V_SUB_CO_CI_U32 :
1578  VOP2be_Real_gfx10<0x029, "V_SUBB_U32", "v_sub_co_ci_u32">;
1579defm V_SUBREV_CO_CI_U32 :
1580  VOP2be_Real_gfx10<0x02a, "V_SUBBREV_U32", "v_subrev_co_ci_u32">;
1581
1582defm V_CNDMASK_B32 :
1583  VOP2e_Real_gfx10<0x001, "V_CNDMASK_B32", "v_cndmask_b32">;
1584
1585// VOP3 only.
1586defm V_BFM_B32            : VOP3Only_Real_gfx10<0x363>;
1587defm V_BCNT_U32_B32       : VOP3Only_Real_gfx10<0x364>;
1588defm V_MBCNT_LO_U32_B32   : VOP3Only_Real_gfx10<0x365>;
1589defm V_MBCNT_HI_U32_B32   : VOP3Only_Real_gfx10<0x366>;
1590defm V_LDEXP_F32          : VOP3Only_Real_gfx10<0x362>;
1591defm V_CVT_PKNORM_I16_F32 : VOP3Only_Real_gfx10<0x368>;
1592defm V_CVT_PKNORM_U16_F32 : VOP3Only_Real_gfx10<0x369>;
1593defm V_CVT_PK_U16_U32     : VOP3Only_Real_gfx10<0x36a>;
1594defm V_CVT_PK_I16_I32     : VOP3Only_Real_gfx10<0x36b>;
1595
1596// VOP3 carry-out.
1597defm V_ADD_CO_U32 : VOP3beOnly_Real_gfx10<0x30f>;
1598defm V_SUB_CO_U32 : VOP3beOnly_Real_gfx10<0x310>;
1599defm V_SUBREV_CO_U32 : VOP3beOnly_Real_gfx10<0x319>;
1600
1601let SubtargetPredicate = isGFX10Only in {
1602  defm : VOP2eInstAliases<V_CNDMASK_B32_e32, V_CNDMASK_B32_e32_gfx10>;
1603
1604  defm : VOP2bInstAliases<
1605    V_ADDC_U32_e32, V_ADD_CO_CI_U32_e32_gfx10, "v_add_co_ci_u32">;
1606  defm : VOP2bInstAliases<
1607    V_SUBB_U32_e32, V_SUB_CO_CI_U32_e32_gfx10, "v_sub_co_ci_u32">;
1608  defm : VOP2bInstAliases<
1609    V_SUBBREV_U32_e32, V_SUBREV_CO_CI_U32_e32_gfx10, "v_subrev_co_ci_u32">;
1610} // End SubtargetPredicate = isGFX10Only
1611
1612//===----------------------------------------------------------------------===//
1613// GFX6, GFX7, GFX10, GFX11
1614//===----------------------------------------------------------------------===//
1615
1616class VOP2_DPPe <bits<6> op, VOP2_DPP_Pseudo ps, VOPProfile P = ps.Pfl> :
1617  VOP_DPPe <P> {
1618  bits<8> vdst;
1619  bits<8> src1;
1620  let Inst{8-0}   = 0xfa; //dpp
1621  let Inst{16-9}  = !if(P.HasSrc1, src1{7-0}, 0);
1622  let Inst{24-17} = !if(P.EmitDst, vdst{7-0}, 0);
1623  let Inst{30-25} = op;
1624  let Inst{31}    = 0x0; //encoding
1625}
1626
1627let AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" in {
1628  multiclass VOP2_Lane_Real_gfx6_gfx7<bits<6> op> {
1629    def _gfx6_gfx7 :
1630      VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.SI>,
1631      VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>;
1632  }
1633  multiclass VOP2Only_Real_MADK_gfx6_gfx7<bits<6> op> {
1634    def _gfx6_gfx7 :
1635      VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.SI>,
1636      VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>;
1637  }
1638  multiclass VOP2_Real_e32_gfx6_gfx7<bits<6> op, string opName = NAME> {
1639    def _e32_gfx6_gfx7 :
1640      VOP2_Real<!cast<VOP2_Pseudo>(opName#"_e32"), SIEncodingFamily.SI>,
1641      VOP2e<op{5-0}, !cast<VOP2_Pseudo>(opName#"_e32").Pfl>;
1642  }
1643  multiclass VOP2_Real_e64_gfx6_gfx7<bits<6> op, string opName = NAME> {
1644    def _e64_gfx6_gfx7 :
1645      VOP3_Real<!cast<VOP3_Pseudo>(opName#"_e64"), SIEncodingFamily.SI>,
1646      VOP3e_gfx6_gfx7<{1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(opName#"_e64").Pfl>;
1647  }
1648  multiclass VOP2be_Real_e64_gfx6_gfx7<bits<6> op, string opName = NAME> {
1649    def _e64_gfx6_gfx7 :
1650      VOP3_Real<!cast<VOP3_Pseudo>(opName#"_e64"), SIEncodingFamily.SI>,
1651      VOP3be_gfx6_gfx7<{1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(opName#"_e64").Pfl>;
1652  }
1653} // End AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7"
1654
1655multiclass VOP2Only_Real_MADK_gfx6_gfx7_gfx10<bits<6> op> :
1656  VOP2Only_Real_MADK_gfx6_gfx7<op>, VOP2Only_Real_MADK_gfx10<op>;
1657
1658multiclass VOP2_Real_gfx6_gfx7<bits<6> op> :
1659  VOP2_Real_e32_gfx6_gfx7<op>, VOP2_Real_e64_gfx6_gfx7<op>;
1660
1661multiclass VOP2_Real_gfx6_gfx7_gfx10<bits<6> op> :
1662  VOP2_Real_gfx6_gfx7<op>, VOP2_Real_gfx10<op>;
1663
1664multiclass VOP2_Real_gfx6_gfx7_gfx10_gfx11<bits<6> op> :
1665  VOP2_Real_gfx6_gfx7_gfx10<op>, VOP2_Real_FULL_gfx11<op>;
1666
1667multiclass VOP2be_Real_gfx6_gfx7<bits<6> op> :
1668  VOP2_Real_e32_gfx6_gfx7<op>, VOP2be_Real_e64_gfx6_gfx7<op>;
1669
1670multiclass VOP2be_Real_gfx6_gfx7_with_name<bits<6> op,
1671  string opName, string asmName>  {
1672  defvar ps32 = !cast<VOP2_Pseudo>(opName#"_e32");
1673  defvar ps64 = !cast<VOP3_Pseudo>(opName#"_e64");
1674
1675  let AsmString = asmName # ps32.AsmOperands in {
1676    defm "" : VOP2_Real_e32_gfx6_gfx7<op, opName>;
1677  }
1678
1679   let AsmString = asmName # ps64.AsmOperands in {
1680    defm "" : VOP2be_Real_e64_gfx6_gfx7<op, opName>;
1681  }
1682}
1683
1684defm V_CNDMASK_B32        : VOP2_Real_gfx6_gfx7<0x000>;
1685defm V_MIN_LEGACY_F32     : VOP2_Real_gfx6_gfx7<0x00d>;
1686defm V_MAX_LEGACY_F32     : VOP2_Real_gfx6_gfx7<0x00e>;
1687defm V_LSHR_B32           : VOP2_Real_gfx6_gfx7<0x015>;
1688defm V_ASHR_I32           : VOP2_Real_gfx6_gfx7<0x017>;
1689defm V_LSHL_B32           : VOP2_Real_gfx6_gfx7<0x019>;
1690defm V_BFM_B32            : VOP2_Real_gfx6_gfx7<0x01e>;
1691defm V_BCNT_U32_B32       : VOP2_Real_gfx6_gfx7<0x022>;
1692defm V_MBCNT_LO_U32_B32   : VOP2_Real_gfx6_gfx7<0x023>;
1693defm V_MBCNT_HI_U32_B32   : VOP2_Real_gfx6_gfx7<0x024>;
1694defm V_LDEXP_F32          : VOP2_Real_gfx6_gfx7<0x02b>;
1695defm V_CVT_PKACCUM_U8_F32 : VOP2_Real_gfx6_gfx7<0x02c>;
1696defm V_CVT_PKNORM_I16_F32 : VOP2_Real_gfx6_gfx7<0x02d>;
1697defm V_CVT_PKNORM_U16_F32 : VOP2_Real_gfx6_gfx7<0x02e>;
1698defm V_CVT_PK_U16_U32     : VOP2_Real_gfx6_gfx7<0x030>;
1699defm V_CVT_PK_I16_I32     : VOP2_Real_gfx6_gfx7<0x031>;
1700
1701// V_ADD_I32, V_SUB_I32, and V_SUBREV_I32 where renamed to *_U32 in
1702// VI, but the VI instructions behave the same as the SI versions.
1703defm V_ADD_I32            : VOP2be_Real_gfx6_gfx7_with_name<0x025, "V_ADD_CO_U32", "v_add_i32">;
1704defm V_SUB_I32            : VOP2be_Real_gfx6_gfx7_with_name<0x026, "V_SUB_CO_U32", "v_sub_i32">;
1705defm V_SUBREV_I32         : VOP2be_Real_gfx6_gfx7_with_name<0x027, "V_SUBREV_CO_U32", "v_subrev_i32">;
1706defm V_ADDC_U32           : VOP2be_Real_gfx6_gfx7<0x028>;
1707defm V_SUBB_U32           : VOP2be_Real_gfx6_gfx7<0x029>;
1708defm V_SUBBREV_U32        : VOP2be_Real_gfx6_gfx7<0x02a>;
1709
1710defm V_READLANE_B32 : VOP2_Lane_Real_gfx6_gfx7<0x001>;
1711
1712let InOperandList = (ins SSrcOrLds_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in) in {
1713  defm V_WRITELANE_B32 : VOP2_Lane_Real_gfx6_gfx7<0x002>;
1714} // End InOperandList = (ins SSrcOrLds_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in)
1715
1716let SubtargetPredicate = isGFX6GFX7 in {
1717  defm : VOP2eInstAliases<V_CNDMASK_B32_e32, V_CNDMASK_B32_e32_gfx6_gfx7>;
1718  defm : VOP2eInstAliases<V_ADD_CO_U32_e32, V_ADD_I32_e32_gfx6_gfx7>;
1719  defm : VOP2eInstAliases<V_SUB_CO_U32_e32, V_SUB_I32_e32_gfx6_gfx7>;
1720  defm : VOP2eInstAliases<V_SUBREV_CO_U32_e32, V_SUBREV_I32_e32_gfx6_gfx7>;
1721
1722  def : VOP2e64InstAlias<V_ADD_CO_U32_e64, V_ADD_I32_e64_gfx6_gfx7>;
1723  def : VOP2e64InstAlias<V_SUB_CO_U32_e64, V_SUB_I32_e64_gfx6_gfx7>;
1724  def : VOP2e64InstAlias<V_SUBREV_CO_U32_e64, V_SUBREV_I32_e64_gfx6_gfx7>;
1725} // End SubtargetPredicate = isGFX6GFX7
1726
1727defm V_ADD_F32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x003>;
1728defm V_SUB_F32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x004>;
1729defm V_SUBREV_F32         : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x005>;
1730defm V_MAC_LEGACY_F32     : VOP2_Real_gfx6_gfx7_gfx10<0x006>;
1731defm V_MUL_LEGACY_F32     : VOP2_Real_gfx6_gfx7_gfx10<0x007>;
1732defm V_MUL_F32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x008>;
1733defm V_MUL_I32_I24        : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x009>;
1734defm V_MUL_HI_I32_I24     : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x00a>;
1735defm V_MUL_U32_U24        : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x00b>;
1736defm V_MUL_HI_U32_U24     : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x00c>;
1737defm V_MIN_F32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x00f>;
1738defm V_MAX_F32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x010>;
1739defm V_MIN_I32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x011>;
1740defm V_MAX_I32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x012>;
1741defm V_MIN_U32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x013>;
1742defm V_MAX_U32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x014>;
1743defm V_LSHRREV_B32        : VOP2_Real_gfx6_gfx7_gfx10<0x016>;
1744defm V_ASHRREV_I32        : VOP2_Real_gfx6_gfx7_gfx10<0x018>;
1745defm V_LSHLREV_B32        : VOP2_Real_gfx6_gfx7_gfx10<0x01a>;
1746defm V_AND_B32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x01b>;
1747defm V_OR_B32             : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x01c>;
1748defm V_XOR_B32            : VOP2_Real_gfx6_gfx7_gfx10_gfx11<0x01d>;
1749defm V_MAC_F32            : VOP2_Real_gfx6_gfx7_gfx10<0x01f>;
1750defm V_CVT_PKRTZ_F16_F32  : VOP2_Real_gfx6_gfx7_gfx10<0x02f>;
1751defm V_MADMK_F32          : VOP2Only_Real_MADK_gfx6_gfx7_gfx10<0x020>;
1752defm V_MADAK_F32          : VOP2Only_Real_MADK_gfx6_gfx7_gfx10<0x021>;
1753
1754//===----------------------------------------------------------------------===//
1755// GFX8, GFX9 (VI).
1756//===----------------------------------------------------------------------===//
1757
1758let AssemblerPredicate = isGFX8GFX9, DecoderNamespace = "GFX8" in {
1759
1760multiclass VOP2_Real_MADK_vi <bits<6> op> {
1761  def _vi : VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.VI>,
1762            VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl>;
1763}
1764
1765multiclass VOP2_Real_MADK_gfx940 <bits<6> op> {
1766  def _gfx940 : VOP2_Real<!cast<VOP2_Pseudo>(NAME), SIEncodingFamily.GFX940>,
1767                VOP2_MADKe<op{5-0}, !cast<VOP2_Pseudo>(NAME).Pfl> {
1768    let DecoderNamespace = "GFX9";
1769  }
1770}
1771
1772multiclass VOP2_Real_e32_vi <bits<6> op> {
1773  def _e32_vi :
1774    VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.VI>,
1775    VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>;
1776}
1777
1778multiclass VOP2_Real_e64_vi <bits<10> op> {
1779  def _e64_vi :
1780    VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>,
1781    VOP3e_vi <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
1782}
1783
1784multiclass VOP2_Real_e64only_vi <bits<10> op> {
1785  def _e64_vi :
1786    VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>,
1787    VOP3e_vi <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl> {
1788      let IsSingle = 1;
1789    }
1790}
1791
1792multiclass Base_VOP2_Real_e32e64_vi <bits<6> op> :
1793  VOP2_Real_e32_vi<op>,
1794  VOP2_Real_e64_vi<{0, 1, 0, 0, op{5-0}}>;
1795
1796} // End AssemblerPredicate = isGFX8GFX9, DecoderNamespace = "GFX8"
1797
1798multiclass VOP2_SDWA_Real <bits<6> op> {
1799  foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtSDWA>.ret in
1800  def _sdwa_vi :
1801    VOP_SDWA_Real <!cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa")>,
1802    VOP2_SDWAe <op{5-0}, !cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa").Pfl>;
1803}
1804
1805multiclass VOP2_SDWA9_Real <bits<6> op> {
1806  foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtSDWA9>.ret in
1807  def _sdwa_gfx9 :
1808    VOP_SDWA9_Real <!cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa")>,
1809    VOP2_SDWA9Ae <op{5-0}, !cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa").Pfl>;
1810}
1811
1812let AssemblerPredicate = isGFX8Only in {
1813
1814multiclass VOP2be_Real_e32e64_vi_only <bits<6> op, string OpName, string AsmName> {
1815  def _e32_vi :
1816    VOP2_Real<!cast<VOP2_Pseudo>(OpName#"_e32"), SIEncodingFamily.VI>,
1817    VOP2e<op{5-0}, !cast<VOP2_Pseudo>(OpName#"_e32").Pfl> {
1818      VOP2_Pseudo ps = !cast<VOP2_Pseudo>(OpName#"_e32");
1819      let AsmString = AsmName # ps.AsmOperands;
1820      let DecoderNamespace = "GFX8";
1821    }
1822  def _e64_vi :
1823    VOP3_Real<!cast<VOP3_Pseudo>(OpName#"_e64"), SIEncodingFamily.VI>,
1824    VOP3be_vi <{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(OpName#"_e64").Pfl> {
1825      VOP3_Pseudo ps = !cast<VOP3_Pseudo>(OpName#"_e64");
1826      let AsmString = AsmName # ps.AsmOperands;
1827      let DecoderNamespace = "GFX8";
1828    }
1829  foreach _ = BoolToList<!cast<VOP2_Pseudo>(OpName#"_e32").Pfl.HasExtSDWA>.ret in
1830    def _sdwa_vi :
1831      VOP_SDWA_Real <!cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa")>,
1832      VOP2_SDWAe <op{5-0}, !cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa").Pfl> {
1833        VOP2_SDWA_Pseudo ps = !cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa");
1834        let AsmString = AsmName # ps.AsmOperands;
1835      }
1836  foreach _ = BoolToList<!cast<VOP2_Pseudo>(OpName#"_e32").Pfl.HasExtDPP>.ret in
1837    def _dpp_vi :
1838      VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(OpName#"_dpp"), SIEncodingFamily.VI>,
1839      VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(OpName#"_dpp")> {
1840        VOP2_DPP_Pseudo ps = !cast<VOP2_DPP_Pseudo>(OpName#"_dpp");
1841        let AsmString = AsmName # ps.AsmOperands;
1842      }
1843}
1844}
1845
1846let AssemblerPredicate = isGFX9Only in {
1847
1848multiclass VOP2be_Real_e32e64_gfx9 <bits<6> op, string OpName, string AsmName> {
1849  def _e32_gfx9 :
1850    VOP2_Real<!cast<VOP2_Pseudo>(OpName#"_e32"), SIEncodingFamily.GFX9>,
1851    VOP2e<op{5-0}, !cast<VOP2_Pseudo>(OpName#"_e32").Pfl> {
1852      VOP2_Pseudo ps = !cast<VOP2_Pseudo>(OpName#"_e32");
1853      let AsmString = AsmName # ps.AsmOperands;
1854      let DecoderNamespace = "GFX9";
1855    }
1856  def _e64_gfx9 :
1857    VOP3_Real<!cast<VOP3_Pseudo>(OpName#"_e64"), SIEncodingFamily.GFX9>,
1858    VOP3be_vi <{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(OpName#"_e64").Pfl> {
1859      VOP3_Pseudo ps = !cast<VOP3_Pseudo>(OpName#"_e64");
1860      let AsmString = AsmName # ps.AsmOperands;
1861      let DecoderNamespace = "GFX9";
1862    }
1863  foreach _ = BoolToList<!cast<VOP2_Pseudo>(OpName#"_e32").Pfl.HasExtSDWA9>.ret in
1864    def _sdwa_gfx9 :
1865      VOP_SDWA9_Real <!cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa")>,
1866      VOP2_SDWA9Ae <op{5-0}, !cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa").Pfl> {
1867        VOP2_SDWA_Pseudo ps = !cast<VOP2_SDWA_Pseudo>(OpName#"_sdwa");
1868        let AsmString = AsmName # ps.AsmOperands;
1869      }
1870  foreach _ = BoolToList<!cast<VOP2_Pseudo>(OpName#"_e32").Pfl.HasExtDPP>.ret in
1871    def _dpp_gfx9 :
1872      VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(OpName#"_dpp"), SIEncodingFamily.GFX9>,
1873      VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(OpName#"_dpp")> {
1874        VOP2_DPP_Pseudo ps = !cast<VOP2_DPP_Pseudo>(OpName#"_dpp");
1875        let AsmString = AsmName # ps.AsmOperands;
1876        let DecoderNamespace = "SDWA9";
1877      }
1878}
1879
1880multiclass VOP2_Real_e32e64_gfx9 <bits<6> op> {
1881  def _e32_gfx9 :
1882    VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.GFX9>,
1883    VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>{
1884      let DecoderNamespace = "GFX9";
1885    }
1886  def _e64_gfx9 :
1887    VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX9>,
1888    VOP3e_vi <{0, 1, 0, 0, op{5-0}}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl> {
1889      let DecoderNamespace = "GFX9";
1890    }
1891  foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtSDWA9>.ret in
1892    def _sdwa_gfx9 :
1893      VOP_SDWA9_Real <!cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa")>,
1894      VOP2_SDWA9Ae <op{5-0}, !cast<VOP2_SDWA_Pseudo>(NAME#"_sdwa").Pfl> {
1895      }
1896  foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtDPP>.ret in
1897    def _dpp_gfx9 :
1898      VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(NAME#"_dpp"), SIEncodingFamily.GFX9>,
1899      VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(NAME#"_dpp")> {
1900        let DecoderNamespace = "SDWA9";
1901      }
1902}
1903
1904} // AssemblerPredicate = isGFX9Only
1905
1906multiclass VOP2_Real_e32e64_vi <bits<6> op> :
1907  Base_VOP2_Real_e32e64_vi<op>, VOP2_SDWA_Real<op>, VOP2_SDWA9_Real<op> {
1908
1909  foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtDPP>.ret in
1910    def _dpp_vi :
1911      VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(NAME#"_dpp"), SIEncodingFamily.VI>,
1912      VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(NAME#"_dpp")>;
1913}
1914
1915defm V_CNDMASK_B32        : VOP2_Real_e32e64_vi <0x0>;
1916defm V_ADD_F32            : VOP2_Real_e32e64_vi <0x1>;
1917defm V_SUB_F32            : VOP2_Real_e32e64_vi <0x2>;
1918defm V_SUBREV_F32         : VOP2_Real_e32e64_vi <0x3>;
1919let AssemblerPredicate = isGCN3ExcludingGFX90A in
1920defm V_MUL_LEGACY_F32     : VOP2_Real_e32e64_vi <0x4>;
1921defm V_MUL_F32            : VOP2_Real_e32e64_vi <0x5>;
1922defm V_MUL_I32_I24        : VOP2_Real_e32e64_vi <0x6>;
1923defm V_MUL_HI_I32_I24     : VOP2_Real_e32e64_vi <0x7>;
1924defm V_MUL_U32_U24        : VOP2_Real_e32e64_vi <0x8>;
1925defm V_MUL_HI_U32_U24     : VOP2_Real_e32e64_vi <0x9>;
1926defm V_MIN_F32            : VOP2_Real_e32e64_vi <0xa>;
1927defm V_MAX_F32            : VOP2_Real_e32e64_vi <0xb>;
1928defm V_MIN_I32            : VOP2_Real_e32e64_vi <0xc>;
1929defm V_MAX_I32            : VOP2_Real_e32e64_vi <0xd>;
1930defm V_MIN_U32            : VOP2_Real_e32e64_vi <0xe>;
1931defm V_MAX_U32            : VOP2_Real_e32e64_vi <0xf>;
1932defm V_LSHRREV_B32        : VOP2_Real_e32e64_vi <0x10>;
1933defm V_ASHRREV_I32        : VOP2_Real_e32e64_vi <0x11>;
1934defm V_LSHLREV_B32        : VOP2_Real_e32e64_vi <0x12>;
1935defm V_AND_B32            : VOP2_Real_e32e64_vi <0x13>;
1936defm V_OR_B32             : VOP2_Real_e32e64_vi <0x14>;
1937defm V_XOR_B32            : VOP2_Real_e32e64_vi <0x15>;
1938defm V_MAC_F32            : VOP2_Real_e32e64_vi <0x16>;
1939defm V_MADMK_F32          : VOP2_Real_MADK_vi <0x17>;
1940defm V_MADAK_F32          : VOP2_Real_MADK_vi <0x18>;
1941
1942defm V_ADD_U32            : VOP2be_Real_e32e64_vi_only <0x19, "V_ADD_CO_U32",     "v_add_u32">;
1943defm V_SUB_U32            : VOP2be_Real_e32e64_vi_only <0x1a, "V_SUB_CO_U32",     "v_sub_u32">;
1944defm V_SUBREV_U32         : VOP2be_Real_e32e64_vi_only <0x1b, "V_SUBREV_CO_U32",  "v_subrev_u32">;
1945defm V_ADDC_U32           : VOP2be_Real_e32e64_vi_only <0x1c, "V_ADDC_U32",    "v_addc_u32">;
1946defm V_SUBB_U32           : VOP2be_Real_e32e64_vi_only <0x1d, "V_SUBB_U32",    "v_subb_u32">;
1947defm V_SUBBREV_U32        : VOP2be_Real_e32e64_vi_only <0x1e, "V_SUBBREV_U32", "v_subbrev_u32">;
1948
1949defm V_ADD_CO_U32         : VOP2be_Real_e32e64_gfx9 <0x19, "V_ADD_CO_U32",     "v_add_co_u32">;
1950defm V_SUB_CO_U32         : VOP2be_Real_e32e64_gfx9 <0x1a, "V_SUB_CO_U32",     "v_sub_co_u32">;
1951defm V_SUBREV_CO_U32      : VOP2be_Real_e32e64_gfx9 <0x1b, "V_SUBREV_CO_U32",  "v_subrev_co_u32">;
1952defm V_ADDC_CO_U32        : VOP2be_Real_e32e64_gfx9 <0x1c, "V_ADDC_U32",    "v_addc_co_u32">;
1953defm V_SUBB_CO_U32        : VOP2be_Real_e32e64_gfx9 <0x1d, "V_SUBB_U32",    "v_subb_co_u32">;
1954defm V_SUBBREV_CO_U32     : VOP2be_Real_e32e64_gfx9 <0x1e, "V_SUBBREV_U32", "v_subbrev_co_u32">;
1955
1956defm V_ADD_U32            : VOP2_Real_e32e64_gfx9 <0x34>;
1957defm V_SUB_U32            : VOP2_Real_e32e64_gfx9 <0x35>;
1958defm V_SUBREV_U32         : VOP2_Real_e32e64_gfx9 <0x36>;
1959
1960defm V_BFM_B32            : VOP2_Real_e64only_vi <0x293>;
1961defm V_BCNT_U32_B32       : VOP2_Real_e64only_vi <0x28b>;
1962defm V_MBCNT_LO_U32_B32   : VOP2_Real_e64only_vi <0x28c>;
1963defm V_MBCNT_HI_U32_B32   : VOP2_Real_e64only_vi <0x28d>;
1964defm V_LDEXP_F32          : VOP2_Real_e64only_vi <0x288>;
1965defm V_CVT_PKACCUM_U8_F32 : VOP2_Real_e64only_vi <0x1f0>;
1966defm V_CVT_PKNORM_I16_F32 : VOP2_Real_e64only_vi <0x294>;
1967defm V_CVT_PKNORM_U16_F32 : VOP2_Real_e64only_vi <0x295>;
1968defm V_CVT_PKRTZ_F16_F32  : VOP2_Real_e64only_vi <0x296>;
1969defm V_CVT_PK_U16_U32     : VOP2_Real_e64only_vi <0x297>;
1970defm V_CVT_PK_I16_I32     : VOP2_Real_e64only_vi <0x298>;
1971
1972defm V_ADD_F16            : VOP2_Real_e32e64_vi <0x1f>;
1973defm V_SUB_F16            : VOP2_Real_e32e64_vi <0x20>;
1974defm V_SUBREV_F16         : VOP2_Real_e32e64_vi <0x21>;
1975defm V_MUL_F16            : VOP2_Real_e32e64_vi <0x22>;
1976defm V_MAC_F16            : VOP2_Real_e32e64_vi <0x23>;
1977defm V_MADMK_F16          : VOP2_Real_MADK_vi <0x24>;
1978defm V_MADAK_F16          : VOP2_Real_MADK_vi <0x25>;
1979defm V_ADD_U16            : VOP2_Real_e32e64_vi <0x26>;
1980defm V_SUB_U16            : VOP2_Real_e32e64_vi <0x27>;
1981defm V_SUBREV_U16         : VOP2_Real_e32e64_vi <0x28>;
1982defm V_MUL_LO_U16         : VOP2_Real_e32e64_vi <0x29>;
1983defm V_LSHLREV_B16        : VOP2_Real_e32e64_vi <0x2a>;
1984defm V_LSHRREV_B16        : VOP2_Real_e32e64_vi <0x2b>;
1985defm V_ASHRREV_I16        : VOP2_Real_e32e64_vi <0x2c>;
1986defm V_MAX_F16            : VOP2_Real_e32e64_vi <0x2d>;
1987defm V_MIN_F16            : VOP2_Real_e32e64_vi <0x2e>;
1988defm V_MAX_U16            : VOP2_Real_e32e64_vi <0x2f>;
1989defm V_MAX_I16            : VOP2_Real_e32e64_vi <0x30>;
1990defm V_MIN_U16            : VOP2_Real_e32e64_vi <0x31>;
1991defm V_MIN_I16            : VOP2_Real_e32e64_vi <0x32>;
1992defm V_LDEXP_F16          : VOP2_Real_e32e64_vi <0x33>;
1993
1994let SubtargetPredicate = isGFX8GFX9 in {
1995
1996// Aliases to simplify matching of floating-point instructions that
1997// are VOP2 on SI and VOP3 on VI.
1998class SI2_VI3Alias <string name, VOP3_Real inst> : InstAlias <
1999  name#" $dst, $src0, $src1",
2000  !if(inst.Pfl.HasOMod,
2001      (inst VGPR_32:$dst, 0, VCSrc_f32:$src0, 0, VCSrc_f32:$src1, 0, 0),
2002      (inst VGPR_32:$dst, 0, VCSrc_f32:$src0, 0, VCSrc_f32:$src1, 0))
2003>, PredicateControl {
2004  let UseInstAsmMatchConverter = 0;
2005  let AsmVariantName = AMDGPUAsmVariants.VOP3;
2006}
2007
2008def : SI2_VI3Alias <"v_ldexp_f32", V_LDEXP_F32_e64_vi>;
2009def : SI2_VI3Alias <"v_cvt_pkaccum_u8_f32", V_CVT_PKACCUM_U8_F32_e64_vi>;
2010def : SI2_VI3Alias <"v_cvt_pknorm_i16_f32", V_CVT_PKNORM_I16_F32_e64_vi>;
2011def : SI2_VI3Alias <"v_cvt_pknorm_u16_f32", V_CVT_PKNORM_U16_F32_e64_vi>;
2012def : SI2_VI3Alias <"v_cvt_pkrtz_f16_f32", V_CVT_PKRTZ_F16_F32_e64_vi>;
2013
2014defm : VOP2eInstAliases<V_CNDMASK_B32_e32, V_CNDMASK_B32_e32_vi>;
2015
2016} // End SubtargetPredicate = isGFX8GFX9
2017
2018let SubtargetPredicate = isGFX9Only in {
2019
2020defm : VOP2bInstAliases<V_ADD_U32_e32,     V_ADD_CO_U32_e32_gfx9,     "v_add_co_u32">;
2021defm : VOP2bInstAliases<V_ADDC_U32_e32,    V_ADDC_CO_U32_e32_gfx9,    "v_addc_co_u32">;
2022defm : VOP2bInstAliases<V_SUB_U32_e32,     V_SUB_CO_U32_e32_gfx9,     "v_sub_co_u32">;
2023defm : VOP2bInstAliases<V_SUBB_U32_e32,    V_SUBB_CO_U32_e32_gfx9,    "v_subb_co_u32">;
2024defm : VOP2bInstAliases<V_SUBREV_U32_e32,  V_SUBREV_CO_U32_e32_gfx9,  "v_subrev_co_u32">;
2025defm : VOP2bInstAliases<V_SUBBREV_U32_e32, V_SUBBREV_CO_U32_e32_gfx9, "v_subbrev_co_u32">;
2026
2027} // End SubtargetPredicate = isGFX9Only
2028
2029let SubtargetPredicate = HasDLInsts in {
2030
2031defm V_FMAC_F32 : VOP2_Real_e32e64_vi <0x3b>;
2032defm V_XNOR_B32 : VOP2_Real_e32e64_vi <0x3d>;
2033
2034} // End SubtargetPredicate = HasDLInsts
2035
2036let AssemblerPredicate = isGFX90APlus, DecoderNamespace = "GFX90A" in {
2037  multiclass VOP2_Real_e32_gfx90a <bits<6> op> {
2038    def _e32_gfx90a :
2039      VOP2_Real<!cast<VOP2_Pseudo>(NAME#"_e32"), SIEncodingFamily.GFX90A>,
2040      VOP2e<op{5-0}, !cast<VOP2_Pseudo>(NAME#"_e32").Pfl>;
2041  }
2042
2043  multiclass VOP2_Real_e64_gfx90a <bits<10> op> {
2044    def _e64_gfx90a :
2045      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX90A>,
2046      VOP3e_vi <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
2047  }
2048
2049  multiclass Base_VOP2_Real_e32e64_gfx90a <bits<6> op> :
2050    VOP2_Real_e32_gfx90a<op>,
2051    VOP2_Real_e64_gfx90a<{0, 1, 0, 0, op{5-0}}>;
2052
2053  multiclass VOP2_Real_e32e64_gfx90a <bits<6> op> :
2054    Base_VOP2_Real_e32e64_gfx90a<op> {
2055
2056    foreach _ = BoolToList<!cast<VOP2_Pseudo>(NAME#"_e32").Pfl.HasExtDPP>.ret in
2057      def _dpp_gfx90a :
2058        VOP_DPP_Real<!cast<VOP2_DPP_Pseudo>(NAME#"_dpp"), SIEncodingFamily.GFX90A>,
2059        VOP2_DPPe<op, !cast<VOP2_DPP_Pseudo>(NAME#"_dpp")> {
2060          let DecoderNamespace = "SDWA9";
2061        }
2062  }
2063} // End AssemblerPredicate = isGFX90APlus, DecoderNamespace = "GFX90A"
2064
2065let SubtargetPredicate = isGFX90APlus in {
2066  defm V_FMAC_F64       : VOP2_Real_e32e64_gfx90a <0x4>;
2067  let IsSingle = 1 in {
2068    defm V_MUL_LEGACY_F32 : VOP2_Real_e64_gfx90a <0x2a1>;
2069  }
2070} // End SubtargetPredicate = isGFX90APlus
2071
2072let SubtargetPredicate = HasFmaakFmamkF32Insts in {
2073defm V_FMAMK_F32        : VOP2_Real_MADK_gfx940 <0x17>;
2074defm V_FMAAK_F32        : VOP2_Real_MADK_gfx940 <0x18>;
2075}
2076
2077multiclass VOP2_Real_DOT_ACC_gfx9<bits<6> op> : VOP2_Real_e32_vi<op> {
2078  def _dpp_vi : VOP2_DPP<op, !cast<VOP2_DPP_Pseudo>(NAME#"_dpp")>;
2079}
2080
2081multiclass VOP2_Real_DOT_ACC_gfx10<bits<6> op> :
2082  VOP2_Real_e32_gfx10<op>,
2083  VOP2_Real_dpp_gfx10<op>,
2084  VOP2_Real_dpp8_gfx10<op>;
2085
2086let SubtargetPredicate = HasDot5Insts in {
2087  defm V_DOT2C_F32_F16 : VOP2_Real_DOT_ACC_gfx9<0x37>;
2088  // NB: Opcode conflicts with V_DOT8C_I32_I4
2089  // This opcode exists in gfx 10.1* only
2090  defm V_DOT2C_F32_F16 : VOP2_Real_DOT_ACC_gfx10<0x02>;
2091}
2092
2093let SubtargetPredicate = HasDot6Insts in {
2094  defm V_DOT4C_I32_I8  : VOP2_Real_DOT_ACC_gfx9<0x39>;
2095  defm V_DOT4C_I32_I8  : VOP2_Real_DOT_ACC_gfx10<0x0d>;
2096}
2097
2098let SubtargetPredicate = HasDot4Insts in {
2099  defm V_DOT2C_I32_I16 : VOP2_Real_DOT_ACC_gfx9<0x38>;
2100}
2101let SubtargetPredicate = HasDot3Insts in {
2102  defm V_DOT8C_I32_I4  : VOP2_Real_DOT_ACC_gfx9<0x3a>;
2103}
2104
2105let SubtargetPredicate = HasPkFmacF16Inst in {
2106defm V_PK_FMAC_F16 : VOP2_Real_e32_vi<0x3c>;
2107} // End SubtargetPredicate = HasPkFmacF16Inst
2108
2109let SubtargetPredicate = HasDot3Insts in {
2110  // NB: Opcode conflicts with V_DOT2C_F32_F16
2111  let DecoderNamespace = "GFX10_B" in
2112  defm V_DOT8C_I32_I4 : VOP2_Real_DOT_ACC_gfx10<0x02>;
2113}
2114