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<11> vdst; 15 bits<4> src0_modifiers; 16 bits<11> src0; 17 bits<3> src1_modifiers; 18 bits<11> src1; 19 bits<3> src2_modifiers; 20 bits<11> 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{7-0}; 28 let Inst{10-8} = waitexp; 29 // Fields for hi/lo 16-bits of register selection 30 let Inst{11} = !if(P.HasSrc0, src0_modifiers{2}, 0); 31 let Inst{12} = !if(P.HasSrc1, src1_modifiers{2}, 0); 32 let Inst{13} = !if(P.HasSrc2, src2_modifiers{2}, 0); 33 let Inst{14} = !if(P.HasDst, src0_modifiers{3}, 0); 34 let Inst{15} = clamp; 35 let Inst{40-32} = src0{8-0}; 36 let Inst{49-41} = src1{8-0}; 37 let Inst{58-50} = src2{8-0}; 38 let Inst{61} = src0_modifiers{0}; // neg(0) 39 let Inst{62} = src1_modifiers{0}; // neg(1) 40 let Inst{63} = src2_modifiers{0}; // neg(2) 41} 42 43class VINTERPe_gfx11 <bits<7> op, VOPProfile P> : VINTERPe<P> { 44 let Inst{22-16} = op; 45} 46 47class VINTERPe_gfx12 <bits<7> op, VOPProfile P> : VINTERPe<P> { 48 let Inst{20-16} = op{4-0}; 49} 50 51//===----------------------------------------------------------------------===// 52// VOP3 VINTERP 53//===----------------------------------------------------------------------===// 54 55class VINTERP_Pseudo <string OpName, VOPProfile P, list<dag> pattern = []> : 56 VOP3_Pseudo<OpName, P, pattern, 0, 0> { 57 let AsmMatchConverter = "cvtVINTERP"; 58 let mayRaiseFPException = 0; 59 60 let VOP3_OPSEL = 1; 61 let VINTERP = 1; 62} 63 64class VINTERP_Real <VOP_Pseudo ps, int EncodingFamily, string asmName> : 65 VOP3_Real <ps, EncodingFamily, asmName> { 66 let VINTERP = 1; 67 let IsSingle = 1; 68} 69 70def VOP3_VINTERP_F32 : VOPProfile<[f32, f32, f32, f32]> { 71 let HasOpSel = 0; 72 let HasModifiers = 1; 73 74 let Src0Mod = FPVRegInputMods; 75 let Src1Mod = FPVRegInputMods; 76 let Src2Mod = FPVRegInputMods; 77 78 let Outs64 = (outs VGPR_32:$vdst); 79 let Ins64 = (ins Src0Mod:$src0_modifiers, VRegSrc_32:$src0, 80 Src1Mod:$src1_modifiers, VRegSrc_32:$src1, 81 Src2Mod:$src2_modifiers, VRegSrc_32:$src2, 82 Clamp:$clamp, 83 WaitEXP:$waitexp); 84 85 let Asm64 = " $vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$waitexp"; 86} 87 88class VOP3_VINTERP_F16_t16 <list<ValueType> ArgVT> : VOPProfile_True16<VOPProfile<ArgVT>> { 89 let Src0Mod = FPT16VRegInputMods</*Fake16*/0>; 90 let Src1Mod = FPVRegInputMods; 91 let Src2Mod = !if(!eq(ArgVT[3].Size, 16), FPT16VRegInputMods</*Fake16*/0>, 92 FPVRegInputMods); 93 let Ins64 = (ins Src0Mod:$src0_modifiers, VRegSrc_16:$src0, 94 Src1Mod:$src1_modifiers, VRegSrc_32:$src1, 95 Src2Mod:$src2_modifiers, 96 !if(!eq(ArgVT[3].Size, 16), VRegSrc_16, VRegSrc_32):$src2, 97 Clamp:$clamp, op_sel0:$op_sel, 98 WaitEXP:$waitexp); 99 100 let Asm64 = "$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$op_sel$waitexp"; 101} 102 103class VOP3_VINTERP_F16_fake16 <list<ValueType> ArgVT> : VOPProfile_Fake16<VOPProfile<ArgVT>> { 104 let Src0Mod = FPT16VRegInputMods</*Fake16*/1>; 105 let Src1Mod = FPVRegInputMods; 106 let Src2Mod = !if(!eq(ArgVT[3].Size, 16), FPT16VRegInputMods</*Fake16*/1>, 107 FPVRegInputMods); 108 109 let Ins64 = (ins Src0Mod:$src0_modifiers, VRegSrc_fake16:$src0, 110 Src1Mod:$src1_modifiers, VRegSrc_32:$src1, 111 Src2Mod:$src2_modifiers, 112 !if(!eq(ArgVT[3].Size, 16), VRegSrc_fake16, VRegSrc_32):$src2, 113 Clamp:$clamp, op_sel0:$op_sel, 114 WaitEXP:$waitexp); 115 116 let Asm64 = "$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$op_sel$waitexp"; 117} 118 119//===----------------------------------------------------------------------===// 120// VINTERP Pseudo Instructions 121//===----------------------------------------------------------------------===// 122 123let SubtargetPredicate = HasVINTERPEncoding in { 124 125multiclass VINTERP_t16<string OpName, list<ValueType> ArgVT> { 126 let True16Predicate = UseRealTrue16Insts in { 127 def _t16 : VINTERP_Pseudo<OpName#"_t16", VOP3_VINTERP_F16_t16<ArgVT>> ; 128 } 129 let True16Predicate = UseFakeTrue16Insts in { 130 def _fake16 : VINTERP_Pseudo<OpName#"_fake16", VOP3_VINTERP_F16_fake16<ArgVT>> ; 131 } 132} 133 134let Uses = [M0, EXEC, MODE] in { 135def V_INTERP_P10_F32_inreg : VINTERP_Pseudo <"v_interp_p10_f32", VOP3_VINTERP_F32>; 136def V_INTERP_P2_F32_inreg : VINTERP_Pseudo <"v_interp_p2_f32", VOP3_VINTERP_F32>; 137 138defm V_INTERP_P10_F16_F32_inreg : VINTERP_t16<"v_interp_p10_f16_f32", [f32, f16, f32, f16]>; 139defm V_INTERP_P2_F16_F32_inreg : VINTERP_t16<"v_interp_p2_f16_f32", [f16, f16, f32, f32]>; 140} // Uses = [M0, EXEC, MODE] 141 142let Uses = [M0, EXEC] in { 143defm V_INTERP_P10_RTZ_F16_F32_inreg : VINTERP_t16<"v_interp_p10_rtz_f16_f32", [f32, f16, f32, f16]>; 144defm V_INTERP_P2_RTZ_F16_F32_inreg : VINTERP_t16 <"v_interp_p2_rtz_f16_f32", [f16, f16, f32, f32]>; 145} // Uses = [M0, EXEC] 146 147} // SubtargetPredicate = HasVINTERPEncoding. 148 149class VInterpF32Pat <SDPatternOperator op, Instruction inst> : GCNPat < 150 (f32 (op 151 (VINTERPMods f32:$src0, i32:$src0_modifiers), 152 (VINTERPMods f32:$src1, i32:$src1_modifiers), 153 (VINTERPMods f32:$src2, i32:$src2_modifiers))), 154 (inst $src0_modifiers, $src0, 155 $src1_modifiers, $src1, 156 $src2_modifiers, $src2, 157 0, /* clamp */ 158 7) /* wait_exp */ 159>; 160 161class VInterpF16Pat <SDPatternOperator op, Instruction inst, 162 ValueType dst_type, bit high, 163 list<ComplexPattern> pat> : GCNPat < 164 (dst_type (op 165 (pat[0] f32:$src0, i32:$src0_modifiers), 166 (pat[1] f32:$src1, i32:$src1_modifiers), 167 (pat[2] f32:$src2, i32:$src2_modifiers), 168 !if(high, (i1 -1), (i1 0)))), 169 (inst $src0_modifiers, $src0, 170 $src1_modifiers, $src1, 171 $src2_modifiers, $src2, 172 0, /* clamp */ 173 /* op_sel = 0 */ 174 7) /* wait_exp */ 175>; 176 177multiclass VInterpF16Pat <SDPatternOperator op, Instruction inst, 178 ValueType dst_type, list<ComplexPattern> high_pat> { 179 def : VInterpF16Pat<op, inst, dst_type, 0, 180 [VINTERPMods, VINTERPMods, VINTERPMods]>; 181 def : VInterpF16Pat<op, inst, dst_type, 1, high_pat>; 182} 183 184class VInterpF16Pat_t16 <SDPatternOperator op, Instruction inst, 185 ValueType dstVT, bit high, bit isP2> : GCNPat < 186 (dstVT (op 187 (VINTERPMods f32:$src0, i32:$src0_modifiers), 188 (VINTERPMods f32:$src1, i32:$src1_modifiers), 189 (VINTERPMods f32:$src2, i32:$src2_modifiers), 190 !if(high, (i1 -1), (i1 0)))), 191 (inst $src0_modifiers, 192 (f16 (EXTRACT_SUBREG VGPR_32:$src0, !if(high, hi16, lo16))), 193 $src1_modifiers, VGPR_32:$src1, 194 $src2_modifiers, 195 !if(isP2, (f32 VGPR_32:$src2), 196 (f16 (EXTRACT_SUBREG VGPR_32:$src2, !if(high, hi16, lo16)))), 197 0, /* clamp */ 198 7) /* wait_exp */ 199>; 200 201multiclass VInterpF16Pat_t16 <SDPatternOperator op, Instruction inst, 202 ValueType dstVT, bit isP2> { 203 def : VInterpF16Pat_t16<op, inst, dstVT, 0, isP2>; 204 def : VInterpF16Pat_t16<op, inst, dstVT, 1, isP2>; 205} 206 207def : VInterpF32Pat<int_amdgcn_interp_inreg_p10, V_INTERP_P10_F32_inreg>; 208def : VInterpF32Pat<int_amdgcn_interp_inreg_p2, V_INTERP_P2_F32_inreg>; 209 210let True16Predicate = UseRealTrue16Insts in { 211defm : VInterpF16Pat_t16<int_amdgcn_interp_inreg_p10_f16, 212 V_INTERP_P10_F16_F32_inreg_t16, f32, 0>; 213defm : VInterpF16Pat_t16<int_amdgcn_interp_inreg_p2_f16, 214 V_INTERP_P2_F16_F32_inreg_t16, f16, 1>; 215defm : VInterpF16Pat_t16<int_amdgcn_interp_p10_rtz_f16, 216 V_INTERP_P10_RTZ_F16_F32_inreg_t16, f32, 0>; 217defm : VInterpF16Pat_t16<int_amdgcn_interp_p2_rtz_f16, 218 V_INTERP_P2_RTZ_F16_F32_inreg_t16, f16, 1>; 219} 220 221let True16Predicate = UseFakeTrue16Insts in { 222defm : VInterpF16Pat<int_amdgcn_interp_inreg_p10_f16, 223 V_INTERP_P10_F16_F32_inreg_fake16, f32, 224 [VINTERPModsHi, VINTERPMods, VINTERPModsHi]>; 225defm : VInterpF16Pat<int_amdgcn_interp_inreg_p2_f16, 226 V_INTERP_P2_F16_F32_inreg_fake16, f16, 227 [VINTERPModsHi, VINTERPMods, VINTERPMods]>; 228defm : VInterpF16Pat<int_amdgcn_interp_p10_rtz_f16, 229 V_INTERP_P10_RTZ_F16_F32_inreg_fake16, f32, 230 [VINTERPModsHi, VINTERPMods, VINTERPModsHi]>; 231defm : VInterpF16Pat<int_amdgcn_interp_p2_rtz_f16, 232 V_INTERP_P2_RTZ_F16_F32_inreg_fake16, f16, 233 [VINTERPModsHi, VINTERPMods, VINTERPMods]>; 234} 235 236//===----------------------------------------------------------------------===// 237// VINTERP Real Instructions 238//===----------------------------------------------------------------------===// 239 240multiclass VINTERP_Real_gfx11 <bits<7> op, string asmName> { 241 defvar ps = !cast<VOP3_Pseudo>(NAME); 242 let AssemblerPredicate = isGFX11Only, DecoderNamespace = "GFX11" # 243 !if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in { 244 def _gfx11 : 245 VINTERP_Real<ps, SIEncodingFamily.GFX11, asmName>, 246 VINTERPe_gfx11<op, ps.Pfl>; 247 } 248} 249 250multiclass VINTERP_Real_gfx12 <bits<7> op, string asmName> { 251 defvar ps = !cast<VOP3_Pseudo>(NAME); 252 let AssemblerPredicate = isGFX12Only, DecoderNamespace = "GFX12" # 253 !if(ps.Pfl.IsRealTrue16, "", "_FAKE16") in { 254 def _gfx12 : 255 VINTERP_Real<ps, SIEncodingFamily.GFX12, asmName>, 256 VINTERPe_gfx12<op, ps.Pfl>; 257 } 258} 259 260multiclass VINTERP_Real_gfx11_gfx12 <bits<7> op, string asmName = !cast<VOP3_Pseudo>(NAME).Mnemonic> : 261 VINTERP_Real_gfx11<op, asmName>, VINTERP_Real_gfx12<op, asmName>; 262 263multiclass VINTERP_Real_t16_and_fake16_gfx11_gfx12 <bits<7> op, string asmName = !cast<VOP3_Pseudo>(NAME).Mnemonic> { 264 defm _t16: VINTERP_Real_gfx11_gfx12<op, asmName>; 265 defm _fake16: VINTERP_Real_gfx11_gfx12<op, asmName>; 266} 267 268 269defm V_INTERP_P10_F32_inreg : VINTERP_Real_gfx11_gfx12<0x000>; 270defm V_INTERP_P2_F32_inreg : VINTERP_Real_gfx11_gfx12<0x001>; 271defm V_INTERP_P10_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12<0x002, "v_interp_p10_f16_f32">; 272defm V_INTERP_P2_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12<0x003, "v_interp_p2_f16_f32">; 273defm V_INTERP_P10_RTZ_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12<0x004, "v_interp_p10_rtz_f16_f32">; 274defm V_INTERP_P2_RTZ_F16_F32_inreg : VINTERP_Real_t16_and_fake16_gfx11_gfx12<0x005, "v_interp_p2_rtz_f16_f32">; 275 276let AssemblerPredicate = isGFX11Plus in 277def : AMDGPUMnemonicAlias<"v_interp_p2_new_f32", "v_interp_p2_f32">; 278