192 lines
5.5 KiB
TableGen
192 lines
5.5 KiB
TableGen
//===-- 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 wait_vdst:$waitvdst),
|
|
(ins InterpAttr:$attr, InterpAttrChan:$attrchan, wait_vdst:$waitvdst)
|
|
);
|
|
}
|
|
|
|
class VDSDIR_getIns<bit direct> {
|
|
dag ret = !if(direct,
|
|
(ins wait_va_vdst:$waitvdst, wait_va_vsrc:$waitvsrc),
|
|
(ins InterpAttr:$attr, InterpAttrChan:$attrchan, wait_va_vdst:$waitvdst,
|
|
wait_va_vsrc:$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.Mnemonic, subtarget> {
|
|
let isPseudo = 0;
|
|
let isCodeGenOnly = 0;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 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 = isGFX12Plus 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 = isGFX12Only
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// GFX11
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
multiclass DSDIR_Real_gfx11<bits<2> op,
|
|
DSDIR_Pseudo 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,
|
|
DSDIR_Pseudo 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>;
|