1//===-- VINTERPInstructions.td - VINTERP 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// VINTERP encoding
11//===----------------------------------------------------------------------===//
12
13class VINTERPe <VOPProfile P> : Enc64 {
14  bits<8> vdst;
15  bits<4> src0_modifiers;
16  bits<9> src0;
17  bits<3> src1_modifiers;
18  bits<9> src1;
19  bits<3> src2_modifiers;
20  bits<9> src2;
21  bits<1> clamp;
22  bits<3> waitexp;
23
24  let Inst{31-26} = 0x33; // VOP3P encoding
25  let Inst{25-24} = 0x1; // VINTERP sub-encoding
26
27  let Inst{7-0}   = vdst;
28  let Inst{10-8}  = waitexp;
29  let Inst{11}    = !if(P.HasOpSel, src0_modifiers{2}, 0); // op_sel(0)
30  let Inst{12}    = !if(P.HasOpSel, src1_modifiers{2}, 0); // op_sel(1)
31  let Inst{13}    = !if(P.HasOpSel, src2_modifiers{2}, 0); // op_sel(2)
32  let Inst{14}    = !if(P.HasOpSel, src0_modifiers{3}, 0); // op_sel(3)
33  let Inst{15}    = clamp;
34  let Inst{40-32} = src0;
35  let Inst{49-41} = src1;
36  let Inst{58-50} = src2;
37  let Inst{61}    = src0_modifiers{0}; // neg(0)
38  let Inst{62}    = src1_modifiers{0}; // neg(1)
39  let Inst{63}    = src2_modifiers{0}; // neg(2)
40}
41
42class VINTERPe_gfx11 <bits<7> op, VOPProfile P> : VINTERPe<P> {
43  let Inst{22-16} = op;
44}
45
46class VINTERPe_gfx12 <bits<7> op, VOPProfile P> : VINTERPe<P> {
47  let Inst{20-16} = op{4-0};
48}
49
50//===----------------------------------------------------------------------===//
51// VOP3 VINTERP
52//===----------------------------------------------------------------------===//
53
54class VINTERP_Pseudo <string OpName, VOPProfile P, list<dag> pattern = []> :
55  VOP3_Pseudo<OpName, P, pattern, 0, 0> {
56  let AsmMatchConverter = "cvtVINTERP";
57  let mayRaiseFPException = 0;
58
59  let VOP3_OPSEL = 1;
60  let VINTERP = 1;
61}
62
63class VINTERP_Real <VOP_Pseudo ps, int EncodingFamily> :
64  VOP3_Real <ps, EncodingFamily> {
65  let VINTERP = 1;
66}
67
68def VOP3_VINTERP_F32 : VOPProfile<[f32, f32, f32, f32]> {
69  let HasOpSel = 0;
70  let HasModifiers = 1;
71
72  let Src0Mod = FPVRegInputMods;
73  let Src1Mod = FPVRegInputMods;
74  let Src2Mod = FPVRegInputMods;
75
76  let Outs64 = (outs VGPR_32:$vdst);
77  let Ins64 = (ins Src0Mod:$src0_modifiers, VRegSrc_32:$src0,
78                   Src1Mod:$src1_modifiers, VRegSrc_32:$src1,
79                   Src2Mod:$src2_modifiers, VRegSrc_32:$src2,
80                   clampmod:$clamp,
81                   wait_exp:$waitexp);
82
83  let Asm64 = " $vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$waitexp";
84}
85
86class VOP3_VINTERP_F16 <list<ValueType> ArgVT> : VOPProfile<ArgVT> {
87  let HasOpSel = 1;
88  let HasModifiers = 1;
89
90  let Src0Mod = FPVRegInputMods;
91  let Src1Mod = FPVRegInputMods;
92  let Src2Mod = FPVRegInputMods;
93
94  let Outs64 = (outs VGPR_32:$vdst);
95  let Ins64 = (ins Src0Mod:$src0_modifiers, VRegSrc_32:$src0,
96                   Src1Mod:$src1_modifiers, VRegSrc_32:$src1,
97                   Src2Mod:$src2_modifiers, VRegSrc_32:$src2,
98                   clampmod:$clamp, op_sel0:$op_sel,
99                   wait_exp:$waitexp);
100
101  let Asm64 = " $vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$op_sel$waitexp";
102}
103
104//===----------------------------------------------------------------------===//
105// VINTERP Pseudo Instructions
106//===----------------------------------------------------------------------===//
107
108let SubtargetPredicate = isGFX11Plus in {
109
110let Uses = [M0, EXEC, MODE] in {
111def V_INTERP_P10_F32_inreg : VINTERP_Pseudo <"v_interp_p10_f32", VOP3_VINTERP_F32>;
112def V_INTERP_P2_F32_inreg : VINTERP_Pseudo <"v_interp_p2_f32", VOP3_VINTERP_F32>;
113def V_INTERP_P10_F16_F32_inreg :
114  VINTERP_Pseudo <"v_interp_p10_f16_f32", VOP3_VINTERP_F16<[f32, f32, f32, f32]>>;
115def V_INTERP_P2_F16_F32_inreg :
116  VINTERP_Pseudo <"v_interp_p2_f16_f32", VOP3_VINTERP_F16<[f16, f32, f32, f32]>>;
117} // Uses = [M0, EXEC, MODE]
118
119let Uses = [M0, EXEC] in {
120def V_INTERP_P10_RTZ_F16_F32_inreg :
121  VINTERP_Pseudo <"v_interp_p10_rtz_f16_f32", VOP3_VINTERP_F16<[f32, f32, f32, f32]>>;
122def V_INTERP_P2_RTZ_F16_F32_inreg :
123  VINTERP_Pseudo <"v_interp_p2_rtz_f16_f32", VOP3_VINTERP_F16<[f16, f32, f32, f32]>>;
124} // Uses = [M0, EXEC]
125
126} // SubtargetPredicate = isGFX11Plus
127
128class VInterpF32Pat <SDPatternOperator op, Instruction inst> : GCNPat <
129   (f32 (op
130      (VINTERPMods f32:$src0, i32:$src0_modifiers),
131      (VINTERPMods f32:$src1, i32:$src1_modifiers),
132      (VINTERPMods f32:$src2, i32:$src2_modifiers))),
133    (inst $src0_modifiers, $src0,
134          $src1_modifiers, $src1,
135          $src2_modifiers, $src2,
136          0, /* clamp */
137          7) /* wait_exp */
138>;
139
140def VINTERP_OPSEL {
141  int LOW = 0;
142  int HIGH = 0xa;
143}
144
145class VInterpF16Pat <SDPatternOperator op, Instruction inst,
146                     ValueType dst_type, bit high,
147                     list<ComplexPattern> pat> : GCNPat <
148   (dst_type (op
149      (pat[0] f32:$src0, i32:$src0_modifiers),
150      (pat[1] f32:$src1, i32:$src1_modifiers),
151      (pat[2] f32:$src2, i32:$src2_modifiers),
152      !if(high, (i1 -1), (i1 0)))),
153    (inst $src0_modifiers, $src0,
154          $src1_modifiers, $src1,
155          $src2_modifiers, $src2,
156          0, /* clamp */
157          /* op_sel = 0 */
158          7) /* wait_exp */
159>;
160
161multiclass VInterpF16Pat <SDPatternOperator op, Instruction inst,
162                          ValueType dst_type, list<ComplexPattern> high_pat> {
163  def : VInterpF16Pat<op, inst, dst_type, 0,
164                      [VINTERPMods, VINTERPMods, VINTERPMods]>;
165  def : VInterpF16Pat<op, inst, dst_type, 1, high_pat>;
166}
167
168def : VInterpF32Pat<int_amdgcn_interp_inreg_p10, V_INTERP_P10_F32_inreg>;
169def : VInterpF32Pat<int_amdgcn_interp_inreg_p2, V_INTERP_P2_F32_inreg>;
170defm : VInterpF16Pat<int_amdgcn_interp_inreg_p10_f16,
171                     V_INTERP_P10_F16_F32_inreg, f32,
172                     [VINTERPModsHi, VINTERPMods, VINTERPModsHi]>;
173defm : VInterpF16Pat<int_amdgcn_interp_inreg_p2_f16,
174                     V_INTERP_P2_F16_F32_inreg, f16,
175                     [VINTERPModsHi, VINTERPMods, VINTERPMods]>;
176
177//===----------------------------------------------------------------------===//
178// VINTERP Real Instructions
179//===----------------------------------------------------------------------===//
180
181multiclass VINTERP_Real_gfx11 <bits<7> op> {
182  let AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11" in {
183    def _gfx11 :
184      VINTERP_Real<!cast<VOP3_Pseudo>(NAME), SIEncodingFamily.GFX11>,
185      VINTERPe_gfx11<op, !cast<VOP3_Pseudo>(NAME).Pfl>;
186  }
187}
188
189multiclass VINTERP_Real_gfx12 <bits<7> op> {
190  let AssemblerPredicate = isGFX12Only, DecoderNamespace = "GFX12" in {
191    def _gfx12 :
192      VINTERP_Real<!cast<VOP3_Pseudo>(NAME), SIEncodingFamily.GFX12>,
193      VINTERPe_gfx12<op, !cast<VOP3_Pseudo>(NAME).Pfl>;
194  }
195}
196
197multiclass VINTERP_Real_gfx11_gfx12 <bits<7> op> :
198  VINTERP_Real_gfx11<op>, VINTERP_Real_gfx12<op>;
199
200defm V_INTERP_P10_F32_inreg : VINTERP_Real_gfx11_gfx12<0x000>;
201defm V_INTERP_P2_F32_inreg : VINTERP_Real_gfx11_gfx12<0x001>;
202defm V_INTERP_P10_F16_F32_inreg : VINTERP_Real_gfx11_gfx12<0x002>;
203defm V_INTERP_P2_F16_F32_inreg : VINTERP_Real_gfx11_gfx12<0x003>;
204defm V_INTERP_P10_RTZ_F16_F32_inreg : VINTERP_Real_gfx11_gfx12<0x004>;
205defm V_INTERP_P2_RTZ_F16_F32_inreg : VINTERP_Real_gfx11_gfx12<0x005>;
206