| //===-- DSDIRInstructions.td - LDS/VDS Direct Instruction Definitions -----===// | 
 | // | 
 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
 | // See https://llvm.org/LICENSE.txt for license information. | 
 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // LDSDIR/VDSDIR encoding (LDSDIR is gfx11, VDSDIR is gfx12+) | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | class LDSDIRe<bits<2> op, bit is_direct> : Enc32 { | 
 |   // encoding fields | 
 |   bits<2> attrchan; | 
 |   bits<6> attr; | 
 |   bits<4> waitvdst; | 
 |   bits<8> vdst; | 
 |  | 
 |   // encoding | 
 |   let Inst{31-24} = 0xce; // encoding | 
 |   let Inst{23-22} = 0x0; // reserved | 
 |   let Inst{21-20} = op; | 
 |   let Inst{19-16} = waitvdst; | 
 |   let Inst{15-10} = !if(is_direct, ?, attr); | 
 |   let Inst{9-8} = !if(is_direct, ?, attrchan); | 
 |   let Inst{7-0} = vdst; | 
 | } | 
 |  | 
 | class VDSDIRe<bits<2> op, bit is_direct> : Enc32 { | 
 |   // encoding fields | 
 |   bits<2> attrchan; | 
 |   bits<6> attr; | 
 |   bits<4> waitvdst; | 
 |   bits<8> vdst; | 
 |   bits<1> waitvsrc; | 
 |  | 
 |   // encoding | 
 |   let Inst{31-24} = 0xce; // encoding | 
 |   let Inst{23} = waitvsrc; | 
 |   let Inst{22} = 0x0; // reserved | 
 |   let Inst{21-20} = op; | 
 |   let Inst{19-16} = waitvdst; | 
 |   let Inst{15-10} = !if(is_direct, ?, attr); | 
 |   let Inst{9-8} = !if(is_direct, ?, attrchan); | 
 |   let Inst{7-0} = vdst; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // LDSDIR/VDSDIR Classes | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | class LDSDIR_getIns<bit direct> { | 
 |   dag ret = !if(direct, | 
 |     (ins WaitVDST:$waitvdst), | 
 |     (ins InterpAttr:$attr, InterpAttrChan:$attrchan, WaitVDST:$waitvdst) | 
 |   ); | 
 | } | 
 |  | 
 | class VDSDIR_getIns<bit direct> { | 
 |   dag ret = !if(direct, | 
 |     (ins WaitVAVDst:$waitvdst, WaitVMVSrc:$waitvsrc), | 
 |     (ins InterpAttr:$attr, InterpAttrChan:$attrchan, WaitVAVDst:$waitvdst, | 
 |          WaitVMVSrc:$waitvsrc) | 
 |   ); | 
 | } | 
 |  | 
 | class DSDIR_Common<string opName, string asm = "", dag ins, bit direct> : | 
 |   InstSI<(outs VGPR_32:$vdst), ins, asm> { | 
 |   let LDSDIR = 1; | 
 |   let EXP_CNT = 1; | 
 |  | 
 |   let hasSideEffects = 0; | 
 |   let mayLoad = 1; | 
 |   let mayStore = 0; | 
 |   let maybeAtomic = 0; | 
 |  | 
 |   string Mnemonic = opName; | 
 |   let UseNamedOperandTable = 1; | 
 |  | 
 |   let Uses = [M0, EXEC]; | 
 |   let DisableWQM = 0; | 
 |   let SchedRW = [WriteLDS]; | 
 |  | 
 |   bit is_direct; | 
 |   let is_direct = direct; | 
 | } | 
 |  | 
 | class DSDIR_Pseudo<string opName, dag ins, bit direct> : | 
 |   DSDIR_Common<opName, "", ins, direct>, | 
 |   SIMCInstr<opName, SIEncodingFamily.NONE> { | 
 |   let isPseudo = 1; | 
 |   let isCodeGenOnly = 1; | 
 | } | 
 |  | 
 | class LDSDIR_getAsm<bit direct> { | 
 |   string ret = !if(direct, | 
 |     " $vdst$waitvdst", | 
 |     " $vdst, $attr$attrchan$waitvdst" | 
 |   ); | 
 | } | 
 |  | 
 | class VDSDIR_getAsm<bit direct> { | 
 |   string ret = !if(direct, | 
 |     " $vdst$waitvdst$waitvsrc", | 
 |     " $vdst, $attr$attrchan$waitvdst$waitvsrc" | 
 |   ); | 
 | } | 
 |  | 
 | class DSDIR_Real<DSDIR_Pseudo lds, dag ins, string asm, int subtarget> : | 
 |   DSDIR_Common<lds.Mnemonic, | 
 |                lds.Mnemonic # asm, | 
 |                ins, | 
 |                lds.is_direct>, | 
 |   SIMCInstr <lds.PseudoInstr, subtarget> { | 
 |   let isPseudo = 0; | 
 |   let isCodeGenOnly = 0; | 
 |  | 
 |   // copy SubtargetPredicate from pseudo. | 
 |   let SubtargetPredicate = lds.SubtargetPredicate; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // LDS/VDS Direct Instructions | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | let SubtargetPredicate = isGFX11Only in { | 
 |  | 
 | def LDS_DIRECT_LOAD : DSDIR_Pseudo<"lds_direct_load", LDSDIR_getIns<1>.ret, 1>; | 
 | def LDS_PARAM_LOAD : DSDIR_Pseudo<"lds_param_load", LDSDIR_getIns<0>.ret, 0>; | 
 |  | 
 | def : GCNPat < | 
 |   (f32 (int_amdgcn_lds_direct_load M0)), | 
 |   (LDS_DIRECT_LOAD 0) | 
 | >; | 
 |  | 
 | def : GCNPat < | 
 |   (f32 (int_amdgcn_lds_param_load timm:$attrchan, timm:$attr, M0)), | 
 |   (LDS_PARAM_LOAD timm:$attr, timm:$attrchan, 0) | 
 | >; | 
 |  | 
 | } // End SubtargetPredicate = isGFX11Only | 
 |  | 
 | let SubtargetPredicate = isGFX12PlusNot12_50 in { | 
 |  | 
 | def DS_DIRECT_LOAD : DSDIR_Pseudo<"ds_direct_load", VDSDIR_getIns<1>.ret, 1>; | 
 | def DS_PARAM_LOAD : DSDIR_Pseudo<"ds_param_load", VDSDIR_getIns<0>.ret, 0>; | 
 |  | 
 | def : GCNPat < | 
 |   (f32 (int_amdgcn_lds_direct_load M0)), | 
 |   (DS_DIRECT_LOAD 0, 1) | 
 | >; | 
 |  | 
 | def : GCNPat < | 
 |   (f32 (int_amdgcn_lds_param_load timm:$attrchan, timm:$attr, M0)), | 
 |   (DS_PARAM_LOAD timm:$attr, timm:$attrchan, 0, 1) | 
 | >; | 
 |  | 
 | } // End SubtargetPredicate = isGFX12PlusNot12_50. | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // GFX11 | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | multiclass DSDIR_Real_gfx11<bits<2> op> { | 
 |   defvar lds = !cast<DSDIR_Pseudo>(NAME); | 
 |   def _gfx11 : DSDIR_Real<lds, lds.InOperandList, | 
 |                           LDSDIR_getAsm<lds.is_direct>.ret, | 
 |                           SIEncodingFamily.GFX11>, | 
 |                LDSDIRe<op, lds.is_direct> { | 
 |     let AssemblerPredicate = isGFX11Only; | 
 |     let DecoderNamespace = "GFX11"; | 
 |   } | 
 | } | 
 |  | 
 | defm LDS_PARAM_LOAD : DSDIR_Real_gfx11<0x0>; | 
 | defm LDS_DIRECT_LOAD : DSDIR_Real_gfx11<0x1>; | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // GFX12+ | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | multiclass DSDIR_Real_gfx12<bits<2> op> { | 
 |   defvar lds = !cast<DSDIR_Pseudo>(NAME); | 
 |   def _gfx12 : DSDIR_Real<lds, lds.InOperandList, | 
 |                           VDSDIR_getAsm<lds.is_direct>.ret, | 
 |                           SIEncodingFamily.GFX12>, | 
 |                VDSDIRe<op, lds.is_direct> { | 
 |     let AssemblerPredicate = isGFX12Plus; | 
 |     let DecoderNamespace = "GFX12"; | 
 |   } | 
 | } | 
 |  | 
 | defm DS_PARAM_LOAD : DSDIR_Real_gfx12<0x0>; | 
 | defm DS_DIRECT_LOAD : DSDIR_Real_gfx12<0x1>; | 
 |  | 
 | let SubtargetPredicate = isGFX12Plus in { | 
 |   def : AMDGPUMnemonicAlias<"lds_param_load", "ds_param_load">; | 
 |   def : AMDGPUMnemonicAlias<"lds_direct_load", "ds_direct_load">; | 
 | } |