1//===-- VOP3Instructions.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// Special case for v_div_fmas_{f32|f64}, since it seems to be the
10// only VOP instruction that implicitly reads VCC.
11let Asm64 = " $vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$omod" in {
12def VOP_F32_F32_F32_F32_VCC : VOPProfile<[f32, f32, f32, f32]> {
13  let Outs64 = (outs DstRC.RegClass:$vdst);
14}
15def VOP_F64_F64_F64_F64_VCC : VOPProfile<[f64, f64, f64, f64]> {
16  let Outs64 = (outs DstRC.RegClass:$vdst);
17}
18}
19
20class VOP3b_Profile<ValueType vt> : VOPProfile<[vt, vt, vt, vt]> {
21  let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst);
22  let Asm64 = "$vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$omod";
23  let IsSingle = 1;
24}
25
26def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile<f32>;
27def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile<f64>;
28
29def VOP3b_I64_I1_I32_I32_I64 : VOPProfile<[i64, i32, i32, i64]> {
30  let HasClamp = 1;
31  let IsSingle = 1;
32
33  let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst);
34  let Asm64 = "$vdst, $sdst, $src0, $src1, $src2$clamp";
35}
36
37//===----------------------------------------------------------------------===//
38// VOP3 INTERP
39//===----------------------------------------------------------------------===//
40
41class VOP3Interp<string OpName, VOPProfile P, list<dag> pattern = []> :
42                 VOP3_Pseudo<OpName, P, pattern> {
43  let AsmMatchConverter = "cvtVOP3Interp";
44  let mayRaiseFPException = 0;
45}
46
47def VOP3_INTERP : VOPProfile<[f32, f32, i32, untyped]> {
48  let Ins64 = (ins Src0Mod:$src0_modifiers, VRegSrc_32:$src0,
49                   Attr:$attr, AttrChan:$attrchan,
50                   clampmod0:$clamp, omod0:$omod);
51
52  let Asm64 = "$vdst, $src0_modifiers, $attr$attrchan$clamp$omod";
53}
54
55def VOP3_INTERP_MOV : VOPProfile<[f32, i32, i32, untyped]> {
56  let Ins64 = (ins InterpSlot:$src0,
57                   Attr:$attr, AttrChan:$attrchan,
58                   clampmod0:$clamp, omod0:$omod);
59
60  let Asm64 = "$vdst, $src0, $attr$attrchan$clamp$omod";
61
62  let HasClamp = 1;
63  let HasSrc0Mods = 0;
64}
65
66class getInterp16Asm <bit HasSrc2, bit HasOMod> {
67  string src2 = !if(HasSrc2, ", $src2_modifiers", "");
68  string omod = !if(HasOMod, "$omod", "");
69  string ret =
70    " $vdst, $src0_modifiers, $attr$attrchan"#src2#"$high$clamp"#omod;
71}
72
73class getInterp16Ins <bit HasSrc2, bit HasOMod,
74                      Operand Src0Mod, Operand Src2Mod> {
75  dag ret = !if(HasSrc2,
76                !if(HasOMod,
77                    (ins Src0Mod:$src0_modifiers, VRegSrc_32:$src0,
78                         Attr:$attr, AttrChan:$attrchan,
79                         Src2Mod:$src2_modifiers, VRegSrc_32:$src2,
80                         highmod:$high, clampmod0:$clamp, omod0:$omod),
81                    (ins Src0Mod:$src0_modifiers, VRegSrc_32:$src0,
82                         Attr:$attr, AttrChan:$attrchan,
83                         Src2Mod:$src2_modifiers, VRegSrc_32:$src2,
84                         highmod:$high, clampmod0:$clamp)
85                ),
86                (ins Src0Mod:$src0_modifiers, VRegSrc_32:$src0,
87                     Attr:$attr, AttrChan:$attrchan,
88                     highmod:$high, clampmod0:$clamp, omod0:$omod)
89            );
90}
91
92class VOP3_INTERP16 <list<ValueType> ArgVT> : VOPProfile<ArgVT> {
93
94  let HasOMod = !ne(DstVT.Value, f16.Value);
95  let HasHigh = 1;
96
97  let Outs64 = (outs DstRC.RegClass:$vdst);
98  let Ins64 = getInterp16Ins<HasSrc2, HasOMod, Src0Mod, Src2Mod>.ret;
99  let Asm64 = getInterp16Asm<HasSrc2, HasOMod>.ret;
100}
101
102//===----------------------------------------------------------------------===//
103// VOP3 Instructions
104//===----------------------------------------------------------------------===//
105
106let isCommutable = 1 in {
107
108let isReMaterializable = 1 in {
109let mayRaiseFPException = 0 in {
110let SubtargetPredicate = HasMadMacF32Insts in {
111defm V_MAD_LEGACY_F32 : VOP3Inst <"v_mad_legacy_f32", VOP3_Profile<VOP_F32_F32_F32_F32>>;
112defm V_MAD_F32 : VOP3Inst <"v_mad_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, fmad>;
113} // End SubtargetPredicate = HasMadMacInsts
114
115let SubtargetPredicate = HasFmaLegacy32 in
116defm V_FMA_LEGACY_F32 : VOP3Inst <"v_fma_legacy_f32",
117                                 VOP3_Profile<VOP_F32_F32_F32_F32>,
118                                 int_amdgcn_fma_legacy>;
119}
120
121defm V_MAD_I32_I24 : VOP3Inst <"v_mad_i32_i24", VOP3_Profile<VOP_I32_I32_I32_I32, VOP3_CLAMP>>;
122defm V_MAD_U32_U24 : VOP3Inst <"v_mad_u32_u24", VOP3_Profile<VOP_I32_I32_I32_I32, VOP3_CLAMP>>;
123defm V_FMA_F32 : VOP3Inst <"v_fma_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, any_fma>;
124defm V_LERP_U8 : VOP3Inst <"v_lerp_u8", VOP3_Profile<VOP_I32_I32_I32_I32>, int_amdgcn_lerp>;
125
126let SchedRW = [WriteDoubleAdd] in {
127let FPDPRounding = 1 in {
128defm V_FMA_F64 : VOP3Inst <"v_fma_f64", VOP3_Profile<VOP_F64_F64_F64_F64>, any_fma>;
129defm V_ADD_F64 : VOP3Inst <"v_add_f64", VOP3_Profile<VOP_F64_F64_F64>, any_fadd>;
130defm V_MUL_F64 : VOP3Inst <"v_mul_f64", VOP3_Profile<VOP_F64_F64_F64>, fmul>;
131} // End FPDPRounding = 1
132defm V_MIN_F64 : VOP3Inst <"v_min_f64", VOP3_Profile<VOP_F64_F64_F64>, fminnum_like>;
133defm V_MAX_F64 : VOP3Inst <"v_max_f64", VOP3_Profile<VOP_F64_F64_F64>, fmaxnum_like>;
134} // End SchedRW = [WriteDoubleAdd]
135
136let SchedRW = [WriteIntMul] in {
137defm V_MUL_LO_U32 : VOP3Inst <"v_mul_lo_u32", VOP3_Profile<VOP_I32_I32_I32>, DivergentBinFrag<mul>>;
138defm V_MUL_HI_U32 : VOP3Inst <"v_mul_hi_u32", VOP3_Profile<VOP_I32_I32_I32>, mulhu>;
139defm V_MUL_LO_I32 : VOP3Inst <"v_mul_lo_i32", VOP3_Profile<VOP_I32_I32_I32>>;
140defm V_MUL_HI_I32 : VOP3Inst <"v_mul_hi_i32", VOP3_Profile<VOP_I32_I32_I32>, mulhs>;
141} // End SchedRW = [WriteIntMul]
142} // End isReMaterializable = 1
143
144let Uses = [MODE, VCC, EXEC] in {
145// v_div_fmas_f32:
146//   result = src0 * src1 + src2
147//   if (vcc)
148//     result *= 2^32
149//
150let SchedRW = [WriteFloatFMA] in
151defm V_DIV_FMAS_F32 : VOP3Inst_Pseudo_Wrapper <"v_div_fmas_f32", VOP_F32_F32_F32_F32_VCC, []>;
152// v_div_fmas_f64:
153//   result = src0 * src1 + src2
154//   if (vcc)
155//     result *= 2^64
156//
157let SchedRW = [WriteDouble], FPDPRounding = 1 in
158defm V_DIV_FMAS_F64 : VOP3Inst_Pseudo_Wrapper  <"v_div_fmas_f64", VOP_F64_F64_F64_F64_VCC, []>;
159} // End Uses = [MODE, VCC, EXEC]
160
161} // End isCommutable = 1
162
163let isReMaterializable = 1 in {
164let mayRaiseFPException = 0 in {
165defm V_CUBEID_F32 : VOP3Inst <"v_cubeid_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, int_amdgcn_cubeid>;
166defm V_CUBESC_F32 : VOP3Inst <"v_cubesc_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, int_amdgcn_cubesc>;
167defm V_CUBETC_F32 : VOP3Inst <"v_cubetc_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, int_amdgcn_cubetc>;
168defm V_CUBEMA_F32 : VOP3Inst <"v_cubema_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, int_amdgcn_cubema>;
169} // End mayRaiseFPException
170
171defm V_BFE_U32 : VOP3Inst <"v_bfe_u32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUbfe_u32>;
172defm V_BFE_I32 : VOP3Inst <"v_bfe_i32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUbfe_i32>;
173defm V_BFI_B32 : VOP3Inst <"v_bfi_b32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUbfi>;
174defm V_ALIGNBIT_B32 : VOP3Inst <"v_alignbit_b32", VOP3_Profile<VOP_I32_I32_I32_I32>, fshr>;
175defm V_ALIGNBYTE_B32 : VOP3Inst <"v_alignbyte_b32", VOP3_Profile<VOP_I32_I32_I32_I32>, int_amdgcn_alignbyte>;
176
177// XXX - No FPException seems suspect but manual doesn't say it does
178let mayRaiseFPException = 0 in {
179  let isCommutable = 1 in {
180    defm V_MIN3_I32 : VOP3Inst <"v_min3_i32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUsmin3>;
181    defm V_MIN3_U32 : VOP3Inst <"v_min3_u32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUumin3>;
182    defm V_MAX3_I32 : VOP3Inst <"v_max3_i32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUsmax3>;
183    defm V_MAX3_U32 : VOP3Inst <"v_max3_u32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUumax3>;
184    defm V_MED3_I32 : VOP3Inst <"v_med3_i32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUsmed3>;
185    defm V_MED3_U32 : VOP3Inst <"v_med3_u32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUumed3>;
186  } // End isCommutable = 1
187  defm V_MIN3_F32 : VOP3Inst <"v_min3_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, AMDGPUfmin3>;
188  defm V_MAX3_F32 : VOP3Inst <"v_max3_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, AMDGPUfmax3>;
189  defm V_MED3_F32 : VOP3Inst <"v_med3_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, AMDGPUfmed3>;
190} // End mayRaiseFPException = 0
191
192let isCommutable = 1 in {
193  defm V_SAD_U8 : VOP3Inst <"v_sad_u8", VOP3_Profile<VOP_I32_I32_I32_I32, VOP3_CLAMP>>;
194  defm V_SAD_HI_U8 : VOP3Inst <"v_sad_hi_u8", VOP3_Profile<VOP_I32_I32_I32_I32, VOP3_CLAMP>>;
195  defm V_SAD_U16 : VOP3Inst <"v_sad_u16", VOP3_Profile<VOP_I32_I32_I32_I32, VOP3_CLAMP>>;
196  defm V_SAD_U32 : VOP3Inst <"v_sad_u32", VOP3_Profile<VOP_I32_I32_I32_I32, VOP3_CLAMP>>;
197} // End isCommutable = 1
198defm V_CVT_PK_U8_F32 : VOP3Inst<"v_cvt_pk_u8_f32", VOP3_Profile<VOP_I32_F32_I32_I32>, int_amdgcn_cvt_pk_u8_f32>;
199
200defm V_DIV_FIXUP_F32 : VOP3Inst <"v_div_fixup_f32", VOP3_Profile<VOP_F32_F32_F32_F32>, AMDGPUdiv_fixup>;
201
202let SchedRW = [WriteDoubleAdd], FPDPRounding = 1 in {
203  defm V_DIV_FIXUP_F64 : VOP3Inst <"v_div_fixup_f64", VOP3_Profile<VOP_F64_F64_F64_F64>, AMDGPUdiv_fixup>;
204  defm V_LDEXP_F64 : VOP3Inst <"v_ldexp_f64", VOP3_Profile<VOP_F64_F64_I32>, AMDGPUldexp>;
205} // End SchedRW = [WriteDoubleAdd], FPDPRounding = 1
206} // End isReMaterializable = 1
207
208
209let mayRaiseFPException = 0 in { // Seems suspicious but manual doesn't say it does.
210  let SchedRW = [WriteFloatFMA, WriteSALU] in
211  defm V_DIV_SCALE_F32 : VOP3Inst_Pseudo_Wrapper <"v_div_scale_f32", VOP3b_F32_I1_F32_F32_F32> ;
212
213  // Double precision division pre-scale.
214  let SchedRW = [WriteDouble, WriteSALU], FPDPRounding = 1 in
215  defm V_DIV_SCALE_F64 : VOP3Inst_Pseudo_Wrapper <"v_div_scale_f64", VOP3b_F64_I1_F64_F64_F64>;
216} // End mayRaiseFPException = 0
217
218let isReMaterializable = 1 in
219defm V_MSAD_U8 : VOP3Inst <"v_msad_u8", VOP3_Profile<VOP_I32_I32_I32_I32, VOP3_CLAMP>>;
220
221let Constraints = "@earlyclobber $vdst" in {
222defm V_MQSAD_PK_U16_U8 : VOP3Inst <"v_mqsad_pk_u16_u8", VOP3_Profile<VOP_I64_I64_I32_I64, VOP3_CLAMP>>;
223} // End Constraints = "@earlyclobber $vdst"
224
225
226let isReMaterializable = 1 in {
227let SchedRW = [WriteDouble] in {
228defm V_TRIG_PREOP_F64 : VOP3Inst <"v_trig_preop_f64", VOP3_Profile<VOP_F64_F64_I32>, int_amdgcn_trig_preop>;
229} // End SchedRW = [WriteDouble]
230
231let SchedRW = [Write64Bit] in {
232  let SubtargetPredicate = isGFX6GFX7 in {
233  defm V_LSHL_B64 : VOP3Inst <"v_lshl_b64", VOP3_Profile<VOP_I64_I64_I32>, cshl_64>;
234  defm V_LSHR_B64 : VOP3Inst <"v_lshr_b64", VOP3_Profile<VOP_I64_I64_I32>, csrl_64>;
235  defm V_ASHR_I64 : VOP3Inst <"v_ashr_i64", VOP3_Profile<VOP_I64_I64_I32>, csra_64>;
236  } // End SubtargetPredicate = isGFX6GFX7
237
238  let SubtargetPredicate = isGFX8Plus in {
239  defm V_LSHLREV_B64 : VOP3Inst <"v_lshlrev_b64", VOP3_Profile<VOP_I64_I32_I64>, clshl_rev_64>;
240  defm V_LSHRREV_B64 : VOP3Inst <"v_lshrrev_b64", VOP3_Profile<VOP_I64_I32_I64>, clshr_rev_64>;
241  defm V_ASHRREV_I64 : VOP3Inst <"v_ashrrev_i64", VOP3_Profile<VOP_I64_I32_I64>, cashr_rev_64>;
242  } // End SubtargetPredicate = isGFX8Plus
243} // End SchedRW = [Write64Bit]
244} // End isReMaterializable = 1
245
246def : GCNPat<
247  (i32 (getDivergentFrag<sext>.ret i16:$src)),
248  (i32 (V_BFE_I32_e64 $src, (S_MOV_B32 (i32 0)), (S_MOV_B32 (i32 0x10))))
249>;
250
251let isReMaterializable = 1 in {
252let SubtargetPredicate = isGFX6GFX7GFX10 in {
253defm V_MULLIT_F32 : VOP3Inst <"v_mullit_f32", VOP3_Profile<VOP_F32_F32_F32_F32>>;
254} // End SubtargetPredicate = isGFX6GFX7GFX10
255
256let SchedRW = [Write32Bit] in {
257let SubtargetPredicate = isGFX8Plus in {
258defm V_PERM_B32 : VOP3Inst <"v_perm_b32", VOP3_Profile<VOP_I32_I32_I32_I32>, AMDGPUperm>;
259} // End SubtargetPredicate = isGFX8Plus
260} // End SchedRW = [Write32Bit]
261} // End isReMaterializable = 1
262
263let SubtargetPredicate = isGFX7Plus in {
264
265let Constraints = "@earlyclobber $vdst", SchedRW = [WriteQuarterRate32] in {
266defm V_QSAD_PK_U16_U8 : VOP3Inst <"v_qsad_pk_u16_u8", VOP3_Profile<VOP_I64_I64_I32_I64, VOP3_CLAMP>>;
267defm V_MQSAD_U32_U8 : VOP3Inst <"v_mqsad_u32_u8", VOP3_Profile<VOP_V4I32_I64_I32_V4I32, VOP3_CLAMP>>;
268} // End Constraints = "@earlyclobber $vdst", SchedRW = [WriteQuarterRate32]
269
270let isCommutable = 1 in {
271let SchedRW = [WriteIntMul, WriteSALU] in {
272defm V_MAD_U64_U32 : VOP3Inst <"v_mad_u64_u32", VOP3b_I64_I1_I32_I32_I64>;
273defm V_MAD_I64_I32 : VOP3Inst <"v_mad_i64_i32", VOP3b_I64_I1_I32_I32_I64>;
274} // End SchedRW = [WriteIntMul, WriteSALU]
275} // End isCommutable = 1
276
277} // End SubtargetPredicate = isGFX7Plus
278
279let FPDPRounding = 1 in {
280  let Predicates = [Has16BitInsts, isGFX8Only] in {
281    defm V_DIV_FIXUP_F16 : VOP3Inst <"v_div_fixup_f16", VOP3_Profile<VOP_F16_F16_F16_F16>, AMDGPUdiv_fixup>;
282    defm V_FMA_F16 : VOP3Inst <"v_fma_f16", VOP3_Profile<VOP_F16_F16_F16_F16>, any_fma>;
283  } // End Predicates = [Has16BitInsts, isGFX8Only]
284
285  let renamedInGFX9 = 1, Predicates = [Has16BitInsts, isGFX9Plus] in {
286    defm V_DIV_FIXUP_F16_gfx9 : VOP3Inst <"v_div_fixup_f16_gfx9",
287                                          VOP3_Profile<VOP_F16_F16_F16_F16, VOP3_OPSEL>, AMDGPUdiv_fixup>;
288    defm V_FMA_F16_gfx9 : VOP3Inst <"v_fma_f16_gfx9", VOP3_Profile<VOP_F16_F16_F16_F16, VOP3_OPSEL>, any_fma>;
289  } // End renamedInGFX9 = 1, Predicates = [Has16BitInsts, isGFX9Plus]
290} // End FPDPRounding = 1
291
292let SubtargetPredicate = Has16BitInsts, isCommutable = 1 in {
293
294let renamedInGFX9 = 1 in {
295  defm V_MAD_U16 : VOP3Inst <"v_mad_u16", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_CLAMP>>;
296  defm V_MAD_I16 : VOP3Inst <"v_mad_i16", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_CLAMP>>;
297  let FPDPRounding = 1 in {
298    defm V_MAD_F16 : VOP3Inst <"v_mad_f16", VOP3_Profile<VOP_F16_F16_F16_F16>, fmad>;
299    let Uses = [MODE, M0, EXEC] in {
300    let OtherPredicates = [isNotGFX90APlus] in
301    // For some reason the intrinsic operands are in a different order
302    // from the instruction operands.
303    def V_INTERP_P2_F16 : VOP3Interp <"v_interp_p2_f16", VOP3_INTERP16<[f16, f32, i32, f32]>,
304           [(set f16:$vdst,
305             (int_amdgcn_interp_p2_f16 (VOP3Mods f32:$src2, i32:$src2_modifiers),
306                                       (VOP3Mods f32:$src0, i32:$src0_modifiers),
307                                       (i32 timm:$attrchan),
308                                       (i32 timm:$attr),
309                                       (i1 timm:$high),
310                                       M0))]>;
311    } // End Uses = [M0, MODE, EXEC]
312  } // End FPDPRounding = 1
313} // End renamedInGFX9 = 1
314
315let SubtargetPredicate = isGFX9Only, FPDPRounding = 1 in {
316  defm V_MAD_F16_gfx9   : VOP3Inst <"v_mad_f16_gfx9", VOP3_Profile<VOP_F16_F16_F16_F16, VOP3_OPSEL>> ;
317} // End SubtargetPredicate = isGFX9Only, FPDPRounding = 1
318
319let SubtargetPredicate = isGFX9Plus in {
320defm V_MAD_U16_gfx9   : VOP3Inst <"v_mad_u16_gfx9", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_OPSEL>>;
321defm V_MAD_I16_gfx9   : VOP3Inst <"v_mad_i16_gfx9", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_OPSEL>>;
322let OtherPredicates = [isNotGFX90APlus] in
323def V_INTERP_P2_F16_gfx9 : VOP3Interp <"v_interp_p2_f16_gfx9", VOP3_INTERP16<[f16, f32, i32, f32]>>;
324} // End SubtargetPredicate = isGFX9Plus
325
326// This predicate should only apply to the selection pattern. The
327// instruction still exists and should decode on subtargets with
328// other bank counts.
329let OtherPredicates = [isNotGFX90APlus, has32BankLDS], Uses = [MODE, M0, EXEC], FPDPRounding = 1 in {
330def V_INTERP_P1LL_F16 : VOP3Interp <"v_interp_p1ll_f16", VOP3_INTERP16<[f32, f32, i32, untyped]>,
331       [(set f32:$vdst, (int_amdgcn_interp_p1_f16 (VOP3Mods f32:$src0, i32:$src0_modifiers),
332                                                  (i32 timm:$attrchan),
333                                                  (i32 timm:$attr),
334                                                  (i1 timm:$high), M0))]>;
335} // End OtherPredicates = [isNotGFX90APlus, has32BankLDS], Uses = [MODE, M0, EXEC], FPDPRounding = 1
336
337let OtherPredicates = [isNotGFX90APlus], Uses = [MODE, M0, EXEC], FPDPRounding = 1 in {
338def V_INTERP_P1LV_F16 : VOP3Interp <"v_interp_p1lv_f16", VOP3_INTERP16<[f32, f32, i32, f16]>>;
339} // End OtherPredicates = [isNotGFX90APlus], Uses = [MODE, M0, EXEC], FPDPRounding = 1
340
341} // End SubtargetPredicate = Has16BitInsts, isCommutable = 1
342
343def : GCNPat<
344  (i64 (getDivergentFrag<sext>.ret i16:$src)),
345    (REG_SEQUENCE VReg_64,
346      (i32 (V_BFE_I32_e64 $src, (S_MOV_B32 (i32 0)), (S_MOV_B32 (i32 0x10)))), sub0,
347      (i32 (COPY_TO_REGCLASS
348         (V_ASHRREV_I32_e32 (S_MOV_B32 (i32 0x1f)), (i32 (V_BFE_I32_e64 $src, (S_MOV_B32 (i32 0)), (S_MOV_B32 (i32 0x10))))
349      ), VGPR_32)), sub1)
350>;
351
352let SubtargetPredicate = isGFX8Plus, Uses = [MODE, M0, EXEC], OtherPredicates = [isNotGFX90APlus] in {
353def V_INTERP_P1_F32_e64  : VOP3Interp <"v_interp_p1_f32", VOP3_INTERP>;
354def V_INTERP_P2_F32_e64  : VOP3Interp <"v_interp_p2_f32", VOP3_INTERP>;
355def V_INTERP_MOV_F32_e64 : VOP3Interp <"v_interp_mov_f32", VOP3_INTERP_MOV>;
356} // End SubtargetPredicate = isGFX8Plus, Uses = [MODE, M0, EXEC], OtherPredicates = [isNotGFX90APlus]
357
358let Predicates = [Has16BitInsts, isGFX6GFX7GFX8GFX9] in {
359
360multiclass Ternary_i16_Pats <SDPatternOperator op1, SDPatternOperator op2,
361                             Instruction inst> {
362def : GCNPat <
363  (op2 (op1 i16:$src0, i16:$src1), i16:$src2),
364  (inst i16:$src0, i16:$src1, i16:$src2, (i1 0))
365>;
366
367}
368
369defm: Ternary_i16_Pats<mul, add, V_MAD_U16_e64>;
370defm: Ternary_i16_Pats<mul, add, V_MAD_I16_e64>;
371
372} // End Predicates = [Has16BitInsts, isGFX6GFX7GFX8GFX9]
373
374let Predicates = [Has16BitInsts, isGFX10Plus] in {
375
376multiclass Ternary_i16_Pats_gfx9<SDPatternOperator op1, SDPatternOperator op2,
377                                 Instruction inst> {
378def : GCNPat <
379  (op2 (op1 i16:$src0, i16:$src1), i16:$src2),
380  (inst SRCMODS.NONE, $src0, SRCMODS.NONE, $src1, SRCMODS.NONE, $src2, DSTCLAMP.NONE)
381>;
382
383}
384
385defm: Ternary_i16_Pats_gfx9<mul, add, V_MAD_U16_gfx9_e64>;
386defm: Ternary_i16_Pats_gfx9<mul, add, V_MAD_I16_gfx9_e64>;
387
388} // End Predicates = [Has16BitInsts, isGFX10Plus]
389
390class ThreeOpFrag<SDPatternOperator op1, SDPatternOperator op2> : PatFrag<
391  (ops node:$x, node:$y, node:$z),
392  // When the inner operation is used multiple times, selecting 3-op
393  // instructions may still be beneficial -- if the other users can be
394  // combined similarly. Let's be conservative for now.
395  (op2 (HasOneUseBinOp<op1> node:$x, node:$y), node:$z),
396  [{
397    // Only use VALU ops when the result is divergent.
398    if (!N->isDivergent())
399      return false;
400
401    // Check constant bus limitations.
402    //
403    // Note: Use !isDivergent as a conservative proxy for whether the value
404    //       is in an SGPR (uniform values can end up in VGPRs as well).
405    unsigned ConstantBusUses = 0;
406    for (unsigned i = 0; i < 3; ++i) {
407      if (!Operands[i]->isDivergent() &&
408          !isInlineImmediate(Operands[i].getNode())) {
409        ConstantBusUses++;
410        // This uses AMDGPU::V_ADD3_U32_e64, but all three operand instructions
411        // have the same constant bus limit.
412        if (ConstantBusUses > Subtarget->getConstantBusLimit(AMDGPU::V_ADD3_U32_e64))
413          return false;
414      }
415    }
416
417    return true;
418  }]> {
419  let PredicateCodeUsesOperands = 1;
420
421  // The divergence predicate is irrelevant in GlobalISel, as we have
422  // proper register bank checks. We just need to verify the constant
423  // bus restriction when all the sources are considered.
424  //
425  // FIXME: With unlucky SGPR operands, we could penalize code by
426  // blocking folding SGPR->VGPR copies later.
427  // FIXME: There's no register bank verifier
428  let GISelPredicateCode = [{
429    const int ConstantBusLimit = Subtarget->getConstantBusLimit(AMDGPU::V_ADD3_U32_e64);
430    int ConstantBusUses = 0;
431    for (unsigned i = 0; i < 3; ++i) {
432      const RegisterBank *RegBank = RBI.getRegBank(Operands[i]->getReg(), MRI, TRI);
433      if (RegBank->getID() == AMDGPU::SGPRRegBankID) {
434        if (++ConstantBusUses > ConstantBusLimit)
435          return false;
436      }
437    }
438    return true;
439  }];
440}
441
442def shl_0_to_4 : PatFrag<
443  (ops node:$src0, node:$src1), (shl node:$src0, node:$src1),
444  [{
445     if (auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
446       return C->getZExtValue() <= 4;
447     }
448     return false;
449   }]> {
450  let GISelPredicateCode = [{
451    int64_t Imm = 0;
452    if (!mi_match(MI.getOperand(2).getReg(), MRI, m_ICst(Imm)) &&
453        !mi_match(MI.getOperand(2).getReg(), MRI, m_Copy(m_ICst(Imm))))
454      return false;
455    return (uint64_t)Imm <= 4;
456  }];
457}
458
459let SubtargetPredicate = isGFX9Plus in {
460let isCommutable = 1, isReMaterializable = 1 in {
461  defm V_ADD3_U32 : VOP3Inst <"v_add3_u32", VOP3_Profile<VOP_I32_I32_I32_I32>>;
462  defm V_AND_OR_B32 : VOP3Inst <"v_and_or_b32", VOP3_Profile<VOP_I32_I32_I32_I32>>;
463  defm V_OR3_B32 : VOP3Inst <"v_or3_b32", VOP3_Profile<VOP_I32_I32_I32_I32>>;
464  defm V_XAD_U32 : VOP3Inst <"v_xad_u32", VOP3_Profile<VOP_I32_I32_I32_I32>>;
465  defm V_ADD_I32 : VOP3Inst <"v_add_i32", VOP3_Profile<VOP_I32_I32_I32_ARITH>>;
466  defm V_ADD_LSHL_U32 : VOP3Inst <"v_add_lshl_u32", VOP3_Profile<VOP_I32_I32_I32_I32>>;
467} // End isCommutable = 1, isReMaterializable = 1
468// TODO src0 contains the opsel bit for dst, so if we commute, need to mask and swap this
469// to the new src0.
470defm V_MED3_F16 : VOP3Inst <"v_med3_f16", VOP3_Profile<VOP_F16_F16_F16_F16, VOP3_OPSEL>, AMDGPUfmed3>;
471defm V_MED3_I16 : VOP3Inst <"v_med3_i16", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_OPSEL>, AMDGPUsmed3>;
472defm V_MED3_U16 : VOP3Inst <"v_med3_u16", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_OPSEL>, AMDGPUumed3>;
473
474defm V_MIN3_F16 : VOP3Inst <"v_min3_f16", VOP3_Profile<VOP_F16_F16_F16_F16, VOP3_OPSEL>, AMDGPUfmin3>;
475defm V_MIN3_I16 : VOP3Inst <"v_min3_i16", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_OPSEL>, AMDGPUsmin3>;
476defm V_MIN3_U16 : VOP3Inst <"v_min3_u16", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_OPSEL>, AMDGPUumin3>;
477
478defm V_MAX3_F16 : VOP3Inst <"v_max3_f16", VOP3_Profile<VOP_F16_F16_F16_F16, VOP3_OPSEL>, AMDGPUfmax3>;
479defm V_MAX3_I16 : VOP3Inst <"v_max3_i16", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_OPSEL>, AMDGPUsmax3>;
480defm V_MAX3_U16 : VOP3Inst <"v_max3_u16", VOP3_Profile<VOP_I16_I16_I16_I16, VOP3_OPSEL>, AMDGPUumax3>;
481
482defm V_ADD_I16 : VOP3Inst <"v_add_i16", VOP3_Profile<VOP_I16_I16_I16, VOP3_OPSEL>>;
483defm V_SUB_I16 : VOP3Inst <"v_sub_i16", VOP3_Profile<VOP_I16_I16_I16, VOP3_OPSEL>>;
484
485defm V_MAD_U32_U16 : VOP3Inst <"v_mad_u32_u16", VOP3_Profile<VOP_I32_I16_I16_I32, VOP3_OPSEL>>;
486defm V_MAD_I32_I16 : VOP3Inst <"v_mad_i32_i16", VOP3_Profile<VOP_I32_I16_I16_I32, VOP3_OPSEL>>;
487
488defm V_CVT_PKNORM_I16_F16 : VOP3Inst <"v_cvt_pknorm_i16_f16", VOP3_Profile<VOP_B32_F16_F16, VOP3_OPSEL>>;
489defm V_CVT_PKNORM_U16_F16 : VOP3Inst <"v_cvt_pknorm_u16_f16", VOP3_Profile<VOP_B32_F16_F16, VOP3_OPSEL>>;
490
491defm V_PACK_B32_F16 : VOP3Inst <"v_pack_b32_f16", VOP3_Profile<VOP_B32_F16_F16, VOP3_OPSEL>>;
492
493let isReMaterializable = 1 in {
494defm V_SUB_I32 : VOP3Inst <"v_sub_i32", VOP3_Profile<VOP_I32_I32_I32_ARITH>>;
495defm V_LSHL_ADD_U32 : VOP3Inst <"v_lshl_add_u32", VOP3_Profile<VOP_I32_I32_I32_I32>>;
496defm V_LSHL_OR_B32 : VOP3Inst <"v_lshl_or_b32", VOP3_Profile<VOP_I32_I32_I32_I32>>;
497} // End isReMaterializable = 1
498
499// V_LSHL_ADD_U64: D0.u64 = (S0.u64 << S1.u[2:0]) + S2.u64
500// src0 is shifted left by 0-4 (use “0” to get ADD_U64).
501let SubtargetPredicate = isGFX940Plus in
502defm V_LSHL_ADD_U64 : VOP3Inst <"v_lshl_add_u64", VOP3_Profile<VOP_I64_I64_I32_I64>>;
503
504class ThreeOp_i32_Pats <SDPatternOperator op1, SDPatternOperator op2, Instruction inst> : GCNPat <
505  // This matches (op2 (op1 i32:$src0, i32:$src1), i32:$src2) with conditions.
506  (ThreeOpFrag<op1, op2> i32:$src0, i32:$src1, i32:$src2),
507  (inst VSrc_b32:$src0, VSrc_b32:$src1, VSrc_b32:$src2)
508>;
509
510def : ThreeOp_i32_Pats<cshl_32, add, V_LSHL_ADD_U32_e64>;
511def : ThreeOp_i32_Pats<add, cshl_32, V_ADD_LSHL_U32_e64>;
512def : ThreeOp_i32_Pats<add, add, V_ADD3_U32_e64>;
513def : ThreeOp_i32_Pats<cshl_32, or, V_LSHL_OR_B32_e64>;
514def : ThreeOp_i32_Pats<and, or, V_AND_OR_B32_e64>;
515def : ThreeOp_i32_Pats<or, or, V_OR3_B32_e64>;
516def : ThreeOp_i32_Pats<xor, add, V_XAD_U32_e64>;
517
518let SubtargetPredicate = isGFX940Plus in
519def : GCNPat<
520  (ThreeOpFrag<shl_0_to_4, add> i64:$src0, i32:$src1, i64:$src2),
521  (V_LSHL_ADD_U64_e64 VSrc_b64:$src0, VSrc_b32:$src1, VSrc_b64:$src2)
522>;
523
524def : VOPBinOpClampPat<saddsat, V_ADD_I32_e64, i32>;
525def : VOPBinOpClampPat<ssubsat, V_SUB_I32_e64, i32>;
526
527def : GCNPat<(getDivergentFrag<or>.ret (or_oneuse i64:$src0, i64:$src1), i64:$src2),
528             (REG_SEQUENCE VReg_64,
529               (V_OR3_B32_e64 (i32 (EXTRACT_SUBREG $src0, sub0)),
530                              (i32 (EXTRACT_SUBREG $src1, sub0)),
531                              (i32 (EXTRACT_SUBREG $src2, sub0))), sub0,
532               (V_OR3_B32_e64 (i32 (EXTRACT_SUBREG $src0, sub1)),
533                              (i32 (EXTRACT_SUBREG $src1, sub1)),
534                              (i32 (EXTRACT_SUBREG $src2, sub1))), sub1)>;
535
536// FIXME: Probably should hardcode clamp bit in pseudo and avoid this.
537class OpSelBinOpClampPat<SDPatternOperator node,
538                         Instruction inst> : GCNPat<
539 (node (i16 (VOP3OpSel i16:$src0, i32:$src0_modifiers)),
540       (i16 (VOP3OpSel i16:$src1, i32:$src1_modifiers))),
541  (inst $src0_modifiers, $src0, $src1_modifiers, $src1, DSTCLAMP.ENABLE, 0)
542>;
543
544def : OpSelBinOpClampPat<saddsat, V_ADD_I16_e64>;
545def : OpSelBinOpClampPat<ssubsat, V_SUB_I16_e64>;
546} // End SubtargetPredicate = isGFX9Plus
547
548def VOP3_PERMLANE_Profile : VOP3_Profile<VOPProfile <[i32, i32, i32, i32]>, VOP3_OPSEL> {
549  let Src0RC64 = VRegSrc_32;
550  let Src1RC64 = SCSrc_b32;
551  let Src2RC64 = SCSrc_b32;
552  let InsVOP3OpSel = (ins IntOpSelMods:$src0_modifiers, VRegSrc_32:$src0,
553                          IntOpSelMods:$src1_modifiers, SCSrc_b32:$src1,
554                          IntOpSelMods:$src2_modifiers, SCSrc_b32:$src2,
555                          VGPR_32:$vdst_in, op_sel0:$op_sel);
556  let HasClamp = 0;
557}
558
559class PermlanePat<SDPatternOperator permlane,
560  Instruction inst> : GCNPat<
561  (permlane i32:$vdst_in, i32:$src0, i32:$src1, i32:$src2,
562            timm:$fi, timm:$bc),
563  (inst (as_i1timm $fi), VGPR_32:$src0, (as_i1timm $bc),
564        SCSrc_b32:$src1, 0, SCSrc_b32:$src2, VGPR_32:$vdst_in)
565>;
566
567// Permlane intrinsic that has either fetch invalid or bound control
568// fields enabled.
569class BoundControlOrFetchInvalidPermlane<SDPatternOperator permlane> :
570  PatFrag<(ops node:$vdst_in, node:$src0, node:$src1, node:$src2,
571               node:$fi, node:$bc),
572          (permlane node:$vdst_in, node:$src0, node:
573                    $src1, node:$src2, node:$fi, node:$bc)> {
574  let PredicateCode = [{ return N->getConstantOperandVal(5) != 0 ||
575                                N->getConstantOperandVal(6) != 0; }];
576  let GISelPredicateCode = [{
577    return MI.getOperand(6).getImm() != 0 ||
578           MI.getOperand(7).getImm() != 0;
579  }];
580}
581
582// Drop the input value if it won't be read.
583class PermlaneDiscardVDstIn<SDPatternOperator permlane,
584                            Instruction inst> : GCNPat<
585  (permlane srcvalue, i32:$src0, i32:$src1, i32:$src2,
586            timm:$fi, timm:$bc),
587  (inst (as_i1timm $fi), VGPR_32:$src0, (as_i1timm $bc),
588        SCSrc_b32:$src1, 0, SCSrc_b32:$src2,
589        (IMPLICIT_DEF))
590>;
591
592
593let SubtargetPredicate = isGFX10Plus in {
594  let isCommutable = 1, isReMaterializable = 1 in {
595    defm V_XOR3_B32 : VOP3Inst <"v_xor3_b32", VOP3_Profile<VOP_I32_I32_I32_I32>>;
596  } // End isCommutable = 1, isReMaterializable = 1
597  def : ThreeOp_i32_Pats<xor, xor, V_XOR3_B32_e64>;
598
599  let Constraints = "$vdst = $vdst_in", DisableEncoding="$vdst_in" in {
600    defm V_PERMLANE16_B32 : VOP3Inst<"v_permlane16_b32", VOP3_PERMLANE_Profile>;
601    defm V_PERMLANEX16_B32 : VOP3Inst<"v_permlanex16_b32", VOP3_PERMLANE_Profile>;
602  } // End $vdst = $vdst_in, DisableEncoding $vdst_in
603
604  def : PermlanePat<int_amdgcn_permlane16, V_PERMLANE16_B32_e64>;
605  def : PermlanePat<int_amdgcn_permlanex16, V_PERMLANEX16_B32_e64>;
606
607  def : PermlaneDiscardVDstIn<
608    BoundControlOrFetchInvalidPermlane<int_amdgcn_permlane16>,
609    V_PERMLANE16_B32_e64>;
610  def : PermlaneDiscardVDstIn<
611    BoundControlOrFetchInvalidPermlane<int_amdgcn_permlanex16>,
612    V_PERMLANEX16_B32_e64>;
613
614  defm V_ADD_NC_U16 : VOP3Inst <"v_add_nc_u16", VOP3_Profile<VOP_I16_I16_I16, VOP3_OPSEL>, add>;
615  defm V_SUB_NC_U16 : VOP3Inst <"v_sub_nc_u16", VOP3_Profile<VOP_I16_I16_I16, VOP3_OPSEL>, sub>;
616
617  def : OpSelBinOpClampPat<uaddsat, V_ADD_NC_U16_e64>;
618  def : OpSelBinOpClampPat<usubsat, V_SUB_NC_U16_e64>;
619
620  // Undo sub x, c -> add x, -c canonicalization since c is more likely
621  // an inline immediate than -c.
622  def : GCNPat<
623    (add i16:$src0, (i16 NegSubInlineIntConst16:$src1)),
624    (V_SUB_NC_U16_e64 0, VSrc_b16:$src0, 0, NegSubInlineIntConst16:$src1, 0, 0)
625  >;
626
627} // End SubtargetPredicate = isGFX10Plus
628
629class DivFmasPat<ValueType vt, Instruction inst, Register CondReg> : GCNPat<
630  (AMDGPUdiv_fmas (vt (VOP3Mods vt:$src0, i32:$src0_modifiers)),
631                  (vt (VOP3Mods vt:$src1, i32:$src1_modifiers)),
632                  (vt (VOP3Mods vt:$src2, i32:$src2_modifiers)),
633                  (i1 CondReg)),
634  (inst $src0_modifiers, $src0, $src1_modifiers, $src1, $src2_modifiers, $src2)
635>;
636
637let WaveSizePredicate = isWave64 in {
638def : DivFmasPat<f32, V_DIV_FMAS_F32_e64, VCC>;
639def : DivFmasPat<f64, V_DIV_FMAS_F64_e64, VCC>;
640}
641
642let WaveSizePredicate = isWave32 in {
643def : DivFmasPat<f32, V_DIV_FMAS_F32_e64, VCC_LO>;
644def : DivFmasPat<f64, V_DIV_FMAS_F64_e64, VCC_LO>;
645}
646
647//===----------------------------------------------------------------------===//
648// Integer Clamp Patterns
649//===----------------------------------------------------------------------===//
650
651class getClampPat<VOPProfile P, SDPatternOperator node> {
652  dag ret3 = (P.DstVT (node P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2));
653  dag ret2 = (P.DstVT (node P.Src0VT:$src0, P.Src1VT:$src1));
654  dag ret1 = (P.DstVT (node P.Src0VT:$src0));
655  dag ret = !if(!eq(P.NumSrcArgs, 3), ret3,
656            !if(!eq(P.NumSrcArgs, 2), ret2,
657            ret1));
658}
659
660class getClampRes<VOPProfile P, Instruction inst> {
661  dag ret3 = (inst P.Src0VT:$src0, P.Src1VT:$src1, P.Src2VT:$src2, (i1 0));
662  dag ret2 = (inst P.Src0VT:$src0, P.Src1VT:$src1, (i1 0));
663  dag ret1 = (inst P.Src0VT:$src0, (i1 0));
664  dag ret = !if(!eq(P.NumSrcArgs, 3), ret3,
665            !if(!eq(P.NumSrcArgs, 2), ret2,
666            ret1));
667}
668
669class IntClampPat<VOP3InstBase inst, SDPatternOperator node> : GCNPat<
670  getClampPat<inst.Pfl, node>.ret,
671  getClampRes<inst.Pfl, inst>.ret
672>;
673
674def : IntClampPat<V_MAD_I32_I24_e64, AMDGPUmad_i24>;
675def : IntClampPat<V_MAD_U32_U24_e64, AMDGPUmad_u24>;
676
677def : IntClampPat<V_SAD_U8_e64, int_amdgcn_sad_u8>;
678def : IntClampPat<V_SAD_HI_U8_e64, int_amdgcn_sad_hi_u8>;
679def : IntClampPat<V_SAD_U16_e64, int_amdgcn_sad_u16>;
680
681def : IntClampPat<V_MSAD_U8_e64, int_amdgcn_msad_u8>;
682def : IntClampPat<V_MQSAD_PK_U16_U8_e64, int_amdgcn_mqsad_pk_u16_u8>;
683
684def : IntClampPat<V_QSAD_PK_U16_U8_e64, int_amdgcn_qsad_pk_u16_u8>;
685def : IntClampPat<V_MQSAD_U32_U8_e64, int_amdgcn_mqsad_u32_u8>;
686
687
688//===----------------------------------------------------------------------===//
689// Target-specific instruction encodings.
690//===----------------------------------------------------------------------===//
691
692//===----------------------------------------------------------------------===//
693// GFX10.
694//===----------------------------------------------------------------------===//
695
696let AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10" in {
697  multiclass VOP3_Real_gfx10<bits<10> op> {
698    def _gfx10 :
699      VOP3_Real<!cast<VOP_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX10>,
700      VOP3e_gfx10<op, !cast<VOP_Pseudo>(NAME#"_e64").Pfl>;
701  }
702  multiclass VOP3_Real_No_Suffix_gfx10<bits<10> op> {
703    def _gfx10 :
704      VOP3_Real<!cast<VOP_Pseudo>(NAME), SIEncodingFamily.GFX10>,
705      VOP3e_gfx10<op, !cast<VOP_Pseudo>(NAME).Pfl>;
706  }
707  multiclass VOP3_Real_gfx10_with_name<bits<10> op, string opName,
708                                       string asmName> {
709    def _gfx10 :
710      VOP3_Real<!cast<VOP3_Pseudo>(opName#"_e64"), SIEncodingFamily.GFX10>,
711      VOP3e_gfx10<op, !cast<VOP3_Pseudo>(opName#"_e64").Pfl> {
712        VOP3_Pseudo ps = !cast<VOP3_Pseudo>(opName#"_e64");
713        let AsmString = asmName # ps.AsmOperands;
714        let IsSingle = 1;
715      }
716  }
717  multiclass VOP3be_Real_gfx10<bits<10> op> {
718    def _gfx10 :
719      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX10>,
720      VOP3be_gfx10<op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
721  }
722  multiclass VOP3Interp_Real_gfx10<bits<10> op> {
723    def _gfx10 :
724      VOP3_Real<!cast<VOP3_Pseudo>(NAME), SIEncodingFamily.GFX10>,
725      VOP3Interp_gfx10<op, !cast<VOP3_Pseudo>(NAME).Pfl>;
726  }
727  multiclass VOP3OpSel_Real_gfx10<bits<10> op> {
728    def _gfx10 :
729      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX10>,
730      VOP3OpSel_gfx10<op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
731  }
732  multiclass VOP3OpSel_Real_gfx10_with_name<bits<10> op, string opName,
733                                            string asmName> {
734    def _gfx10 :
735      VOP3_Real<!cast<VOP3_Pseudo>(opName#"_e64"), SIEncodingFamily.GFX10>,
736      VOP3OpSel_gfx10<op, !cast<VOP3_Pseudo>(opName#"_e64").Pfl> {
737        VOP3_Pseudo ps = !cast<VOP3_Pseudo>(opName#"_e64");
738        let AsmString = asmName # ps.AsmOperands;
739      }
740  }
741} // End AssemblerPredicate = isGFX10Only, DecoderNamespace = "GFX10"
742
743defm V_READLANE_B32  : VOP3_Real_No_Suffix_gfx10<0x360>;
744
745let InOperandList = (ins SSrcOrLds_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in) in {
746  defm V_WRITELANE_B32 : VOP3_Real_No_Suffix_gfx10<0x361>;
747} // End InOperandList = (ins SSrcOrLds_b32:$src0, SCSrc_b32:$src1, VGPR_32:$vdst_in)
748
749let SubtargetPredicate = isGFX10Before1030 in {
750  defm V_MUL_LO_I32      : VOP3_Real_gfx10<0x16b>;
751}
752
753defm V_XOR3_B32           : VOP3_Real_gfx10<0x178>;
754defm V_LSHLREV_B64        : VOP3_Real_gfx10<0x2ff>;
755defm V_LSHRREV_B64        : VOP3_Real_gfx10<0x300>;
756defm V_ASHRREV_I64        : VOP3_Real_gfx10<0x301>;
757defm V_PERM_B32           : VOP3_Real_gfx10<0x344>;
758defm V_XAD_U32            : VOP3_Real_gfx10<0x345>;
759defm V_LSHL_ADD_U32       : VOP3_Real_gfx10<0x346>;
760defm V_ADD_LSHL_U32       : VOP3_Real_gfx10<0x347>;
761defm V_ADD3_U32           : VOP3_Real_gfx10<0x36d>;
762defm V_LSHL_OR_B32        : VOP3_Real_gfx10<0x36f>;
763defm V_AND_OR_B32         : VOP3_Real_gfx10<0x371>;
764defm V_OR3_B32            : VOP3_Real_gfx10<0x372>;
765
766// TODO-GFX10: add MC tests for v_add/sub_nc_i16
767defm V_ADD_NC_I16 :
768  VOP3OpSel_Real_gfx10_with_name<0x30d, "V_ADD_I16", "v_add_nc_i16">;
769defm V_SUB_NC_I16 :
770  VOP3OpSel_Real_gfx10_with_name<0x30e, "V_SUB_I16", "v_sub_nc_i16">;
771defm V_SUB_NC_I32 :
772  VOP3_Real_gfx10_with_name<0x376, "V_SUB_I32", "v_sub_nc_i32">;
773defm V_ADD_NC_I32 :
774  VOP3_Real_gfx10_with_name<0x37f, "V_ADD_I32", "v_add_nc_i32">;
775
776defm V_INTERP_P1_F32_e64  : VOP3Interp_Real_gfx10<0x200>;
777defm V_INTERP_P2_F32_e64  : VOP3Interp_Real_gfx10<0x201>;
778defm V_INTERP_MOV_F32_e64 : VOP3Interp_Real_gfx10<0x202>;
779
780defm V_INTERP_P1LL_F16    : VOP3Interp_Real_gfx10<0x342>;
781defm V_INTERP_P1LV_F16    : VOP3Interp_Real_gfx10<0x343>;
782defm V_INTERP_P2_F16      : VOP3Interp_Real_gfx10<0x35a>;
783
784defm V_PACK_B32_F16       : VOP3OpSel_Real_gfx10<0x311>;
785defm V_CVT_PKNORM_I16_F16 : VOP3OpSel_Real_gfx10<0x312>;
786defm V_CVT_PKNORM_U16_F16 : VOP3OpSel_Real_gfx10<0x313>;
787
788defm V_MIN3_F16           : VOP3OpSel_Real_gfx10<0x351>;
789defm V_MIN3_I16           : VOP3OpSel_Real_gfx10<0x352>;
790defm V_MIN3_U16           : VOP3OpSel_Real_gfx10<0x353>;
791defm V_MAX3_F16           : VOP3OpSel_Real_gfx10<0x354>;
792defm V_MAX3_I16           : VOP3OpSel_Real_gfx10<0x355>;
793defm V_MAX3_U16           : VOP3OpSel_Real_gfx10<0x356>;
794defm V_MED3_F16           : VOP3OpSel_Real_gfx10<0x357>;
795defm V_MED3_I16           : VOP3OpSel_Real_gfx10<0x358>;
796defm V_MED3_U16           : VOP3OpSel_Real_gfx10<0x359>;
797defm V_MAD_U32_U16        : VOP3OpSel_Real_gfx10<0x373>;
798defm V_MAD_I32_I16        : VOP3OpSel_Real_gfx10<0x375>;
799
800defm V_MAD_U16 :
801  VOP3OpSel_Real_gfx10_with_name<0x340, "V_MAD_U16_gfx9", "v_mad_u16">;
802defm V_FMA_F16 :
803  VOP3OpSel_Real_gfx10_with_name<0x34b, "V_FMA_F16_gfx9", "v_fma_f16">;
804defm V_MAD_I16 :
805  VOP3OpSel_Real_gfx10_with_name<0x35e, "V_MAD_I16_gfx9", "v_mad_i16">;
806defm V_DIV_FIXUP_F16 :
807  VOP3OpSel_Real_gfx10_with_name<0x35f, "V_DIV_FIXUP_F16_gfx9", "v_div_fixup_f16">;
808
809defm V_ADD_NC_U16      : VOP3OpSel_Real_gfx10<0x303>;
810defm V_SUB_NC_U16      : VOP3OpSel_Real_gfx10<0x304>;
811
812// FIXME-GFX10-OPSEL: Need to add "selective" opsel support to some of these
813// (they do not support SDWA or DPP).
814defm V_MUL_LO_U16      : VOP3_Real_gfx10_with_name<0x305, "V_MUL_LO_U16", "v_mul_lo_u16">;
815defm V_LSHRREV_B16     : VOP3_Real_gfx10_with_name<0x307, "V_LSHRREV_B16", "v_lshrrev_b16">;
816defm V_ASHRREV_I16     : VOP3_Real_gfx10_with_name<0x308, "V_ASHRREV_I16", "v_ashrrev_i16">;
817defm V_MAX_U16         : VOP3_Real_gfx10_with_name<0x309, "V_MAX_U16", "v_max_u16">;
818defm V_MAX_I16         : VOP3_Real_gfx10_with_name<0x30a, "V_MAX_I16", "v_max_i16">;
819defm V_MIN_U16         : VOP3_Real_gfx10_with_name<0x30b, "V_MIN_U16", "v_min_u16">;
820defm V_MIN_I16         : VOP3_Real_gfx10_with_name<0x30c, "V_MIN_I16", "v_min_i16">;
821defm V_LSHLREV_B16     : VOP3_Real_gfx10_with_name<0x314, "V_LSHLREV_B16", "v_lshlrev_b16">;
822defm V_PERMLANE16_B32  : VOP3OpSel_Real_gfx10<0x377>;
823defm V_PERMLANEX16_B32 : VOP3OpSel_Real_gfx10<0x378>;
824
825//===----------------------------------------------------------------------===//
826// GFX7, GFX10.
827//===----------------------------------------------------------------------===//
828
829let AssemblerPredicate = isGFX7Only, DecoderNamespace = "GFX7" in {
830  multiclass VOP3_Real_gfx7<bits<10> op> {
831    def _gfx7 :
832      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.SI>,
833      VOP3e_gfx6_gfx7<op{8-0}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
834  }
835  multiclass VOP3be_Real_gfx7<bits<10> op> {
836    def _gfx7 :
837      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.SI>,
838      VOP3be_gfx6_gfx7<op{8-0}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
839  }
840} // End AssemblerPredicate = isGFX7Only, DecoderNamespace = "GFX7"
841
842multiclass VOP3_Real_gfx7_gfx10<bits<10> op> :
843  VOP3_Real_gfx7<op>, VOP3_Real_gfx10<op>;
844
845multiclass VOP3be_Real_gfx7_gfx10<bits<10> op> :
846  VOP3be_Real_gfx7<op>, VOP3be_Real_gfx10<op>;
847
848defm V_QSAD_PK_U16_U8   : VOP3_Real_gfx7_gfx10<0x172>;
849defm V_MQSAD_U32_U8     : VOP3_Real_gfx7_gfx10<0x175>;
850defm V_MAD_U64_U32      : VOP3be_Real_gfx7_gfx10<0x176>;
851defm V_MAD_I64_I32      : VOP3be_Real_gfx7_gfx10<0x177>;
852
853//===----------------------------------------------------------------------===//
854// GFX6, GFX7, GFX10.
855//===----------------------------------------------------------------------===//
856
857let AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7" in {
858  multiclass VOP3_Real_gfx6_gfx7<bits<10> op> {
859    def _gfx6_gfx7 :
860      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.SI>,
861      VOP3e_gfx6_gfx7<op{8-0}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
862  }
863  multiclass VOP3be_Real_gfx6_gfx7<bits<10> op> {
864    def _gfx6_gfx7 :
865      VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.SI>,
866      VOP3be_gfx6_gfx7<op{8-0}, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
867  }
868} // End AssemblerPredicate = isGFX6GFX7, DecoderNamespace = "GFX6GFX7"
869
870multiclass VOP3_Real_gfx6_gfx7_gfx10<bits<10> op> :
871  VOP3_Real_gfx6_gfx7<op>, VOP3_Real_gfx10<op>;
872
873multiclass VOP3be_Real_gfx6_gfx7_gfx10<bits<10> op> :
874  VOP3be_Real_gfx6_gfx7<op>, VOP3be_Real_gfx10<op>;
875
876defm V_LSHL_B64        : VOP3_Real_gfx6_gfx7<0x161>;
877defm V_LSHR_B64        : VOP3_Real_gfx6_gfx7<0x162>;
878defm V_ASHR_I64        : VOP3_Real_gfx6_gfx7<0x163>;
879defm V_MUL_LO_I32      : VOP3_Real_gfx6_gfx7<0x16b>;
880
881defm V_MAD_LEGACY_F32  : VOP3_Real_gfx6_gfx7_gfx10<0x140>;
882defm V_MAD_F32         : VOP3_Real_gfx6_gfx7_gfx10<0x141>;
883defm V_MAD_I32_I24     : VOP3_Real_gfx6_gfx7_gfx10<0x142>;
884defm V_MAD_U32_U24     : VOP3_Real_gfx6_gfx7_gfx10<0x143>;
885defm V_CUBEID_F32      : VOP3_Real_gfx6_gfx7_gfx10<0x144>;
886defm V_CUBESC_F32      : VOP3_Real_gfx6_gfx7_gfx10<0x145>;
887defm V_CUBETC_F32      : VOP3_Real_gfx6_gfx7_gfx10<0x146>;
888defm V_CUBEMA_F32      : VOP3_Real_gfx6_gfx7_gfx10<0x147>;
889defm V_BFE_U32         : VOP3_Real_gfx6_gfx7_gfx10<0x148>;
890defm V_BFE_I32         : VOP3_Real_gfx6_gfx7_gfx10<0x149>;
891defm V_BFI_B32         : VOP3_Real_gfx6_gfx7_gfx10<0x14a>;
892defm V_FMA_F32         : VOP3_Real_gfx6_gfx7_gfx10<0x14b>;
893defm V_FMA_F64         : VOP3_Real_gfx6_gfx7_gfx10<0x14c>;
894defm V_LERP_U8         : VOP3_Real_gfx6_gfx7_gfx10<0x14d>;
895defm V_ALIGNBIT_B32    : VOP3_Real_gfx6_gfx7_gfx10<0x14e>;
896defm V_ALIGNBYTE_B32   : VOP3_Real_gfx6_gfx7_gfx10<0x14f>;
897defm V_MULLIT_F32      : VOP3_Real_gfx6_gfx7_gfx10<0x150>;
898defm V_MIN3_F32        : VOP3_Real_gfx6_gfx7_gfx10<0x151>;
899defm V_MIN3_I32        : VOP3_Real_gfx6_gfx7_gfx10<0x152>;
900defm V_MIN3_U32        : VOP3_Real_gfx6_gfx7_gfx10<0x153>;
901defm V_MAX3_F32        : VOP3_Real_gfx6_gfx7_gfx10<0x154>;
902defm V_MAX3_I32        : VOP3_Real_gfx6_gfx7_gfx10<0x155>;
903defm V_MAX3_U32        : VOP3_Real_gfx6_gfx7_gfx10<0x156>;
904defm V_MED3_F32        : VOP3_Real_gfx6_gfx7_gfx10<0x157>;
905defm V_MED3_I32        : VOP3_Real_gfx6_gfx7_gfx10<0x158>;
906defm V_MED3_U32        : VOP3_Real_gfx6_gfx7_gfx10<0x159>;
907defm V_SAD_U8          : VOP3_Real_gfx6_gfx7_gfx10<0x15a>;
908defm V_SAD_HI_U8       : VOP3_Real_gfx6_gfx7_gfx10<0x15b>;
909defm V_SAD_U16         : VOP3_Real_gfx6_gfx7_gfx10<0x15c>;
910defm V_SAD_U32         : VOP3_Real_gfx6_gfx7_gfx10<0x15d>;
911defm V_CVT_PK_U8_F32   : VOP3_Real_gfx6_gfx7_gfx10<0x15e>;
912defm V_DIV_FIXUP_F32   : VOP3_Real_gfx6_gfx7_gfx10<0x15f>;
913defm V_DIV_FIXUP_F64   : VOP3_Real_gfx6_gfx7_gfx10<0x160>;
914defm V_ADD_F64         : VOP3_Real_gfx6_gfx7_gfx10<0x164>;
915defm V_MUL_F64         : VOP3_Real_gfx6_gfx7_gfx10<0x165>;
916defm V_MIN_F64         : VOP3_Real_gfx6_gfx7_gfx10<0x166>;
917defm V_MAX_F64         : VOP3_Real_gfx6_gfx7_gfx10<0x167>;
918defm V_LDEXP_F64       : VOP3_Real_gfx6_gfx7_gfx10<0x168>;
919defm V_MUL_LO_U32      : VOP3_Real_gfx6_gfx7_gfx10<0x169>;
920defm V_MUL_HI_U32      : VOP3_Real_gfx6_gfx7_gfx10<0x16a>;
921defm V_MUL_HI_I32      : VOP3_Real_gfx6_gfx7_gfx10<0x16c>;
922defm V_DIV_FMAS_F32    : VOP3_Real_gfx6_gfx7_gfx10<0x16f>;
923defm V_DIV_FMAS_F64    : VOP3_Real_gfx6_gfx7_gfx10<0x170>;
924defm V_MSAD_U8         : VOP3_Real_gfx6_gfx7_gfx10<0x171>;
925defm V_MQSAD_PK_U16_U8 : VOP3_Real_gfx6_gfx7_gfx10<0x173>;
926defm V_TRIG_PREOP_F64  : VOP3_Real_gfx6_gfx7_gfx10<0x174>;
927defm V_DIV_SCALE_F32   : VOP3be_Real_gfx6_gfx7_gfx10<0x16d>;
928defm V_DIV_SCALE_F64   : VOP3be_Real_gfx6_gfx7_gfx10<0x16e>;
929
930// NB: Same opcode as v_mad_legacy_f32
931let DecoderNamespace = "GFX10_B" in
932defm V_FMA_LEGACY_F32  : VOP3_Real_gfx10<0x140>;
933
934//===----------------------------------------------------------------------===//
935// GFX8, GFX9 (VI).
936//===----------------------------------------------------------------------===//
937
938let AssemblerPredicate = isGFX8GFX9, DecoderNamespace = "GFX8" in {
939
940multiclass VOP3_Real_vi<bits<10> op> {
941  def _vi : VOP3_Real<!cast<VOP_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>,
942            VOP3e_vi <op, !cast<VOP_Pseudo>(NAME#"_e64").Pfl>;
943}
944multiclass VOP3_Real_No_Suffix_vi<bits<10> op> {
945  def _vi : VOP3_Real<!cast<VOP_Pseudo>(NAME), SIEncodingFamily.VI>,
946            VOP3e_vi <op, !cast<VOP_Pseudo>(NAME).Pfl>;
947}
948
949multiclass VOP3be_Real_vi<bits<10> op> {
950  def _vi : VOP3_Real<!cast<VOP_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>,
951            VOP3be_vi <op, !cast<VOP_Pseudo>(NAME#"_e64").Pfl>;
952}
953
954multiclass VOP3OpSel_Real_gfx9<bits<10> op> {
955  def _vi : VOP3_Real<!cast<VOP_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>,
956            VOP3OpSel_gfx9 <op, !cast<VOP_Pseudo>(NAME#"_e64").Pfl>;
957}
958
959multiclass VOP3Interp_Real_vi<bits<10> op> {
960  def _vi : VOP3_Real<!cast<VOP_Pseudo>(NAME), SIEncodingFamily.VI>,
961            VOP3Interp_vi <op, !cast<VOP_Pseudo>(NAME).Pfl>;
962}
963
964} // End AssemblerPredicate = isGFX8GFX9, DecoderNamespace = "GFX8"
965
966let AssemblerPredicate = isGFX8Only, DecoderNamespace = "GFX8" in {
967
968multiclass VOP3_F16_Real_vi<bits<10> op> {
969  def _vi : VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.VI>,
970            VOP3e_vi <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl>;
971}
972
973multiclass VOP3Interp_F16_Real_vi<bits<10> op> {
974  def _vi : VOP3_Real<!cast<VOP3_Pseudo>(NAME), SIEncodingFamily.VI>,
975            VOP3Interp_vi <op, !cast<VOP3_Pseudo>(NAME).Pfl>;
976}
977
978} // End AssemblerPredicate = isGFX8Only, DecoderNamespace = "GFX8"
979
980let AssemblerPredicate = isGFX9Only, DecoderNamespace = "GFX9" in {
981
982multiclass VOP3_F16_Real_gfx9<bits<10> op, string OpName, string AsmName> {
983  def _gfx9 : VOP3_Real<!cast<VOP3_Pseudo>(OpName#"_e64"), SIEncodingFamily.GFX9>,
984            VOP3e_vi <op, !cast<VOP3_Pseudo>(OpName#"_e64").Pfl> {
985              VOP3_Pseudo ps = !cast<VOP3_Pseudo>(OpName#"_e64");
986              let AsmString = AsmName # ps.AsmOperands;
987            }
988}
989
990multiclass VOP3OpSel_F16_Real_gfx9<bits<10> op, string AsmName> {
991  def _gfx9 : VOP3_Real<!cast<VOP3_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX9>,
992            VOP3OpSel_gfx9 <op, !cast<VOP3_Pseudo>(NAME#"_e64").Pfl> {
993              VOP3_Pseudo ps = !cast<VOP3_Pseudo>(NAME#"_e64");
994              let AsmString = AsmName # ps.AsmOperands;
995            }
996}
997
998multiclass VOP3Interp_F16_Real_gfx9<bits<10> op, string OpName, string AsmName> {
999  def _gfx9 : VOP3_Real<!cast<VOP3_Pseudo>(OpName), SIEncodingFamily.GFX9>,
1000            VOP3Interp_vi <op, !cast<VOP3_Pseudo>(OpName).Pfl> {
1001              VOP3_Pseudo ps = !cast<VOP3_Pseudo>(OpName);
1002              let AsmString = AsmName # ps.AsmOperands;
1003            }
1004}
1005
1006multiclass VOP3_Real_gfx9<bits<10> op, string AsmName> {
1007  def _gfx9 : VOP3_Real<!cast<VOP_Pseudo>(NAME#"_e64"), SIEncodingFamily.GFX9>,
1008              VOP3e_vi <op, !cast<VOP_Pseudo>(NAME#"_e64").Pfl> {
1009              VOP_Pseudo ps = !cast<VOP_Pseudo>(NAME#"_e64");
1010              let AsmString = AsmName # ps.AsmOperands;
1011            }
1012}
1013
1014} // End AssemblerPredicate = isGFX9Only, DecoderNamespace = "GFX9"
1015
1016defm V_MAD_U64_U32      : VOP3be_Real_vi <0x1E8>;
1017defm V_MAD_I64_I32      : VOP3be_Real_vi <0x1E9>;
1018
1019defm V_MAD_LEGACY_F32   : VOP3_Real_vi <0x1c0>;
1020defm V_MAD_F32          : VOP3_Real_vi <0x1c1>;
1021defm V_MAD_I32_I24      : VOP3_Real_vi <0x1c2>;
1022defm V_MAD_U32_U24      : VOP3_Real_vi <0x1c3>;
1023defm V_CUBEID_F32       : VOP3_Real_vi <0x1c4>;
1024defm V_CUBESC_F32       : VOP3_Real_vi <0x1c5>;
1025defm V_CUBETC_F32       : VOP3_Real_vi <0x1c6>;
1026defm V_CUBEMA_F32       : VOP3_Real_vi <0x1c7>;
1027defm V_BFE_U32          : VOP3_Real_vi <0x1c8>;
1028defm V_BFE_I32          : VOP3_Real_vi <0x1c9>;
1029defm V_BFI_B32          : VOP3_Real_vi <0x1ca>;
1030defm V_FMA_F32          : VOP3_Real_vi <0x1cb>;
1031defm V_FMA_F64          : VOP3_Real_vi <0x1cc>;
1032defm V_LERP_U8          : VOP3_Real_vi <0x1cd>;
1033defm V_ALIGNBIT_B32     : VOP3_Real_vi <0x1ce>;
1034defm V_ALIGNBYTE_B32    : VOP3_Real_vi <0x1cf>;
1035defm V_MIN3_F32         : VOP3_Real_vi <0x1d0>;
1036defm V_MIN3_I32         : VOP3_Real_vi <0x1d1>;
1037defm V_MIN3_U32         : VOP3_Real_vi <0x1d2>;
1038defm V_MAX3_F32         : VOP3_Real_vi <0x1d3>;
1039defm V_MAX3_I32         : VOP3_Real_vi <0x1d4>;
1040defm V_MAX3_U32         : VOP3_Real_vi <0x1d5>;
1041defm V_MED3_F32         : VOP3_Real_vi <0x1d6>;
1042defm V_MED3_I32         : VOP3_Real_vi <0x1d7>;
1043defm V_MED3_U32         : VOP3_Real_vi <0x1d8>;
1044defm V_SAD_U8           : VOP3_Real_vi <0x1d9>;
1045defm V_SAD_HI_U8        : VOP3_Real_vi <0x1da>;
1046defm V_SAD_U16          : VOP3_Real_vi <0x1db>;
1047defm V_SAD_U32          : VOP3_Real_vi <0x1dc>;
1048defm V_CVT_PK_U8_F32    : VOP3_Real_vi <0x1dd>;
1049defm V_DIV_FIXUP_F32    : VOP3_Real_vi <0x1de>;
1050defm V_DIV_FIXUP_F64    : VOP3_Real_vi <0x1df>;
1051defm V_DIV_SCALE_F32    : VOP3be_Real_vi <0x1e0>;
1052defm V_DIV_SCALE_F64    : VOP3be_Real_vi <0x1e1>;
1053defm V_DIV_FMAS_F32     : VOP3_Real_vi <0x1e2>;
1054defm V_DIV_FMAS_F64     : VOP3_Real_vi <0x1e3>;
1055defm V_MSAD_U8          : VOP3_Real_vi <0x1e4>;
1056defm V_QSAD_PK_U16_U8   : VOP3_Real_vi <0x1e5>;
1057defm V_MQSAD_PK_U16_U8  : VOP3_Real_vi <0x1e6>;
1058defm V_MQSAD_U32_U8     : VOP3_Real_vi <0x1e7>;
1059
1060defm V_PERM_B32         : VOP3_Real_vi <0x1ed>;
1061
1062defm V_MAD_F16          : VOP3_F16_Real_vi <0x1ea>;
1063defm V_MAD_U16          : VOP3_F16_Real_vi <0x1eb>;
1064defm V_MAD_I16          : VOP3_F16_Real_vi <0x1ec>;
1065defm V_FMA_F16          : VOP3_F16_Real_vi <0x1ee>;
1066defm V_DIV_FIXUP_F16    : VOP3_F16_Real_vi <0x1ef>;
1067defm V_INTERP_P2_F16    : VOP3Interp_F16_Real_vi <0x276>;
1068
1069let FPDPRounding = 1 in {
1070defm V_MAD_LEGACY_F16       : VOP3_F16_Real_gfx9 <0x1ea, "V_MAD_F16",       "v_mad_legacy_f16">;
1071defm V_FMA_LEGACY_F16       : VOP3_F16_Real_gfx9 <0x1ee, "V_FMA_F16",       "v_fma_legacy_f16">;
1072defm V_DIV_FIXUP_LEGACY_F16 : VOP3_F16_Real_gfx9 <0x1ef, "V_DIV_FIXUP_F16", "v_div_fixup_legacy_f16">;
1073defm V_INTERP_P2_LEGACY_F16 : VOP3Interp_F16_Real_gfx9 <0x276, "V_INTERP_P2_F16", "v_interp_p2_legacy_f16">;
1074} // End FPDPRounding = 1
1075
1076defm V_MAD_LEGACY_U16       : VOP3_F16_Real_gfx9 <0x1eb, "V_MAD_U16",       "v_mad_legacy_u16">;
1077defm V_MAD_LEGACY_I16       : VOP3_F16_Real_gfx9 <0x1ec, "V_MAD_I16",       "v_mad_legacy_i16">;
1078
1079defm V_MAD_F16_gfx9         : VOP3OpSel_F16_Real_gfx9 <0x203, "v_mad_f16">;
1080defm V_MAD_U16_gfx9         : VOP3OpSel_F16_Real_gfx9 <0x204, "v_mad_u16">;
1081defm V_MAD_I16_gfx9         : VOP3OpSel_F16_Real_gfx9 <0x205, "v_mad_i16">;
1082defm V_FMA_F16_gfx9         : VOP3OpSel_F16_Real_gfx9 <0x206, "v_fma_f16">;
1083defm V_DIV_FIXUP_F16_gfx9   : VOP3OpSel_F16_Real_gfx9 <0x207, "v_div_fixup_f16">;
1084defm V_INTERP_P2_F16_gfx9   : VOP3Interp_F16_Real_gfx9 <0x277, "V_INTERP_P2_F16_gfx9", "v_interp_p2_f16">;
1085
1086defm V_ADD_I32         : VOP3_Real_vi <0x29c>;
1087defm V_SUB_I32         : VOP3_Real_vi <0x29d>;
1088
1089defm V_INTERP_P1_F32_e64  : VOP3Interp_Real_vi <0x270>;
1090defm V_INTERP_P2_F32_e64  : VOP3Interp_Real_vi <0x271>;
1091defm V_INTERP_MOV_F32_e64 : VOP3Interp_Real_vi <0x272>;
1092
1093defm V_INTERP_P1LL_F16  : VOP3Interp_Real_vi <0x274>;
1094defm V_INTERP_P1LV_F16  : VOP3Interp_Real_vi <0x275>;
1095defm V_ADD_F64          : VOP3_Real_vi <0x280>;
1096defm V_MUL_F64          : VOP3_Real_vi <0x281>;
1097defm V_MIN_F64          : VOP3_Real_vi <0x282>;
1098defm V_MAX_F64          : VOP3_Real_vi <0x283>;
1099defm V_LDEXP_F64        : VOP3_Real_vi <0x284>;
1100defm V_MUL_LO_U32       : VOP3_Real_vi <0x285>;
1101
1102// removed from VI as identical to V_MUL_LO_U32
1103let isAsmParserOnly = 1 in {
1104defm V_MUL_LO_I32       : VOP3_Real_vi <0x285>;
1105}
1106
1107defm V_MUL_HI_U32       : VOP3_Real_vi <0x286>;
1108defm V_MUL_HI_I32       : VOP3_Real_vi <0x287>;
1109
1110defm V_READLANE_B32     : VOP3_Real_No_Suffix_vi <0x289>;
1111defm V_WRITELANE_B32    : VOP3_Real_No_Suffix_vi <0x28a>;
1112
1113defm V_LSHLREV_B64      : VOP3_Real_vi <0x28f>;
1114defm V_LSHRREV_B64      : VOP3_Real_vi <0x290>;
1115defm V_ASHRREV_I64      : VOP3_Real_vi <0x291>;
1116defm V_TRIG_PREOP_F64   : VOP3_Real_vi <0x292>;
1117
1118defm V_LSHL_ADD_U32 : VOP3_Real_vi <0x1fd>;
1119defm V_ADD_LSHL_U32 : VOP3_Real_vi <0x1fe>;
1120defm V_ADD3_U32 : VOP3_Real_vi <0x1ff>;
1121defm V_LSHL_OR_B32 : VOP3_Real_vi <0x200>;
1122defm V_AND_OR_B32 : VOP3_Real_vi <0x201>;
1123defm V_OR3_B32 : VOP3_Real_vi <0x202>;
1124defm V_PACK_B32_F16 : VOP3OpSel_Real_gfx9 <0x2a0>;
1125
1126defm V_XAD_U32 : VOP3_Real_vi <0x1f3>;
1127
1128defm V_MIN3_F16 : VOP3OpSel_Real_gfx9 <0x1f4>;
1129defm V_MIN3_I16 : VOP3OpSel_Real_gfx9 <0x1f5>;
1130defm V_MIN3_U16 : VOP3OpSel_Real_gfx9 <0x1f6>;
1131
1132defm V_MAX3_F16 : VOP3OpSel_Real_gfx9 <0x1f7>;
1133defm V_MAX3_I16 : VOP3OpSel_Real_gfx9 <0x1f8>;
1134defm V_MAX3_U16 : VOP3OpSel_Real_gfx9 <0x1f9>;
1135
1136defm V_MED3_F16 : VOP3OpSel_Real_gfx9 <0x1fa>;
1137defm V_MED3_I16 : VOP3OpSel_Real_gfx9 <0x1fb>;
1138defm V_MED3_U16 : VOP3OpSel_Real_gfx9 <0x1fc>;
1139
1140defm V_ADD_I16  : VOP3OpSel_Real_gfx9 <0x29e>;
1141defm V_SUB_I16  : VOP3OpSel_Real_gfx9 <0x29f>;
1142
1143defm V_MAD_U32_U16 : VOP3OpSel_Real_gfx9 <0x1f1>;
1144defm V_MAD_I32_I16 : VOP3OpSel_Real_gfx9 <0x1f2>;
1145
1146defm V_CVT_PKNORM_I16_F16 : VOP3OpSel_Real_gfx9 <0x299>;
1147defm V_CVT_PKNORM_U16_F16 : VOP3OpSel_Real_gfx9 <0x29a>;
1148
1149defm V_LSHL_ADD_U64 : VOP3_Real_vi <0x208>;
1150