X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FAMDGPU%2FSIInstrInfo.td;h=d6c8a3d295137042917cd6653fd91c46af20a30e;hb=2320de6adb4f38633ae1698ac522def2bf0aacc5;hp=b39a78714640e1e2da184c19bfbdc30f61e54c45;hpb=f5be357d37b40602ad91fd6d77c855df8bb029fd;p=oota-llvm.git diff --git a/lib/Target/AMDGPU/SIInstrInfo.td b/lib/Target/AMDGPU/SIInstrInfo.td index b39a7871464..d6c8a3d2951 100644 --- a/lib/Target/AMDGPU/SIInstrInfo.td +++ b/lib/Target/AMDGPU/SIInstrInfo.td @@ -8,6 +8,9 @@ //===----------------------------------------------------------------------===// def isCI : Predicate<"Subtarget->getGeneration() " ">= AMDGPUSubtarget::SEA_ISLANDS">; +def isCIOnly : Predicate<"Subtarget->getGeneration() ==" + "AMDGPUSubtarget::SEA_ISLANDS">, + AssemblerPredicate <"FeatureSeaIslands">; def isVI : Predicate < "Subtarget->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS">, AssemblerPredicate<"FeatureGCN3Encoding">; @@ -69,6 +72,15 @@ class sopk si, bits<5> vi = si> { field bits<5> VI = vi; } +// Specify an SMRD opcode for SI and SMEM opcode for VI + +// FIXME: This should really be bits<5> si, Tablegen crashes if +// parameter default value is other parameter with different bit size +class smrd si, bits<8> vi = si> { + field bits<5> SI = si{4-0}; + field bits<8> VI = vi; +} + // Execpt for the NONE field, this must be kept in sync with the SISubtarget enum // in AMDGPUInstrInfo.cpp def SISubtarget { @@ -328,9 +340,9 @@ class SGPRImm : PatLeaf(Subtarget->getRegisterInfo()); for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end(); U != E; ++U) { - if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) { + const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo()); + if (RC && SIRI->isSGPRClass(RC)) return true; - } } return false; }]>; @@ -393,7 +405,7 @@ def GDS01MatchClass : GDSBaseMatchClass <"parseDSOff01OptionalOps">; class GLCBaseMatchClass : AsmOperandClass { let Name = "GLC"#parser; let PredicateMethod = "isImm"; - let ParserMethod = parser; + let ParserMethod = parser; let RenderMethod = "addImmOperands"; } @@ -436,6 +448,17 @@ def ClampMatchClass : AsmOperandClass { let RenderMethod = "addImmOperands"; } +class SMRDOffsetBaseMatchClass : AsmOperandClass { + let Name = "SMRDOffset"#predicate; + let PredicateMethod = predicate; + let RenderMethod = "addImmOperands"; +} + +def SMRDOffsetMatchClass : SMRDOffsetBaseMatchClass <"isSMRDOffset">; +def SMRDLiteralOffsetMatchClass : SMRDOffsetBaseMatchClass < + "isSMRDLiteralOffset" +>; + let OperandType = "OPERAND_IMMEDIATE" in { def offen : Operand { @@ -510,6 +533,16 @@ def ClampMod : Operand { let ParserMatchClass = ClampMatchClass; } +def smrd_offset : Operand { + let PrintMethod = "printU32ImmOperand"; + let ParserMatchClass = SMRDOffsetMatchClass; +} + +def smrd_literal_offset : Operand { + let PrintMethod = "printU32ImmOperand"; + let ParserMatchClass = SMRDLiteralOffsetMatchClass; +} + } // End OperandType = "OPERAND_IMMEDIATE" def VOPDstS64 : VOPDstOperand ; @@ -528,6 +561,13 @@ def MUBUFScratch : ComplexPattern; def MUBUFOffset : ComplexPattern; def MUBUFOffsetAtomic : ComplexPattern; +def SMRDImm : ComplexPattern; +def SMRDImm32 : ComplexPattern; +def SMRDSgpr : ComplexPattern; +def SMRDBufferImm : ComplexPattern; +def SMRDBufferImm32 : ComplexPattern; +def SMRDBufferSgpr : ComplexPattern; + def VOP3Mods0 : ComplexPattern; def VOP3NoMods0 : ComplexPattern; def VOP3Mods0Clamp : ComplexPattern; @@ -717,19 +757,6 @@ class SOP2_Real_vi : let AssemblerPredicates = [isVI]; } -multiclass SOP2_SELECT_32 pattern> { - def "" : SOP2_Pseudo ; - - def _si : SOP2_Real_si ; - - def _vi : SOP2_Real_vi ; -} - multiclass SOP2_m pattern> { @@ -758,8 +785,10 @@ multiclass SOP2_64_32 pattern> : SOP2_m < class SOPC_Helper op, RegisterOperand rc, ValueType vt, string opName, PatLeaf cond> : SOPC < - op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1), - opName#" $src0, $src1", []>; + op, (outs), (ins rc:$src0, rc:$src1), + opName#" $src0, $src1", []> { + let Defs = [SCC]; +} class SOPC_32 op, string opName, PatLeaf cond = COND_NULL> : SOPC_Helper; @@ -812,15 +841,20 @@ multiclass SOPK_32 pattern> { } multiclass SOPK_SCC pattern> { - def "" : SOPK_Pseudo ; + def "" : SOPK_Pseudo { + let Defs = [SCC]; + } - let DisableEncoding = "$dst" in { - def _si : SOPK_Real_si ; - def _vi : SOPK_Real_vi ; + def _si : SOPK_Real_si { + let Defs = [SCC]; + } + + def _vi : SOPK_Real_vi { + let Defs = [SCC]; } } @@ -868,35 +902,68 @@ class SMRD_Real_si op, string opName, bit imm, dag outs, dag ins, } class SMRD_Real_vi op, string opName, bit imm, dag outs, dag ins, - string asm> : - SMRD , + string asm, list pattern = []> : + SMRD , SMEMe_vi , SIMCInstr { let AssemblerPredicates = [isVI]; } -multiclass SMRD_m op, string opName, bit imm, dag outs, dag ins, +multiclass SMRD_m pattern> { def "" : SMRD_Pseudo ; - def _si : SMRD_Real_si ; + def _si : SMRD_Real_si ; // glc is only applicable to scalar stores, which are not yet // implemented. let glc = 0 in { - def _vi : SMRD_Real_vi <{0, 0, 0, op}, opName, imm, outs, ins, asm>; + def _vi : SMRD_Real_vi ; } } -multiclass SMRD_Helper op, string opName, RegisterClass baseClass, +multiclass SMRD_Inval { + let hasSideEffects = 1, mayStore = 1 in { + def "" : SMRD_Pseudo ; + + let sbase = 0, offset = 0 in { + let sdst = 0 in { + def _si : SMRD_Real_si ; + } + + let glc = 0, sdata = 0 in { + def _vi : SMRD_Real_vi ; + } + } + } +} + +class SMEM_Inval op, string opName, SDPatternOperator node> : + SMRD_Real_vi { + let hasSideEffects = 1; + let mayStore = 1; + let sbase = 0; + let sdata = 0; + let glc = 0; + let offset = 0; +} + +multiclass SMRD_Helper { defm _IMM : SMRD_m < op, opName#"_IMM", 1, (outs dstClass:$dst), - (ins baseClass:$sbase, u32imm:$offset), + (ins baseClass:$sbase, smrd_offset:$offset), opName#" $dst, $sbase, $offset", [] >; + def _IMM_ci : SMRD < + (outs dstClass:$dst), (ins baseClass:$sbase, smrd_literal_offset:$offset), + opName#" $dst, $sbase, $offset", []>, SMRD_IMMe_ci { + let AssemblerPredicates = [isCIOnly]; + } + defm _SGPR : SMRD_m < op, opName#"_SGPR", 0, (outs dstClass:$dst), (ins baseClass:$sbase, SReg_32:$soff), @@ -922,11 +989,12 @@ def InputModsNoDefault : Operand { let ParserMatchClass = InputModsMatchClass; } -class getNumSrcArgs { +class getNumSrcArgs { int ret = - !if (!eq(Src1.Value, untyped.Value), 1, // VOP1 + !if (!eq(Src0.Value, untyped.Value), 0, + !if (!eq(Src1.Value, untyped.Value), 1, // VOP1 !if (!eq(Src2.Value, untyped.Value), 2, // VOP2 - 3)); // VOP3 + 3))); // VOP3 } // Returns the register class to use for the destination of VOP[123C] @@ -934,28 +1002,37 @@ class getNumSrcArgs { class getVALUDstForVT { RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand, !if(!eq(VT.Size, 64), VOPDstOperand, - VOPDstOperand)); // else VT == i1 + !if(!eq(VT.Size, 16), VOPDstOperand, + VOPDstOperand))); // else VT == i1 } // Returns the register class to use for source 0 of VOP[12C] // instructions for the given VT. class getVOPSrc0ForVT { - RegisterOperand ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64); + RegisterOperand ret = !if(!eq(VT.Size, 64), VSrc_64, VSrc_32); } // Returns the register class to use for source 1 of VOP[12C] for the // given VT. class getVOPSrc1ForVT { - RegisterClass ret = !if(!eq(VT.Size, 32), VGPR_32, VReg_64); + RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32); } // Returns the register class to use for sources of VOP3 instructions for the // given VT. class getVOP3SrcForVT { - RegisterOperand ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64); + RegisterOperand ret = + !if(!eq(VT.Size, 64), + VCSrc_64, + !if(!eq(VT.Value, i1.Value), + SCSrc_64, + VCSrc_32 + ) + ); } // Returns 1 if the source arguments have modifiers, 0 if they do not. +// XXX - do f16 instructions? class hasModifiers { bit ret = !if(!eq(SrcVT.Value, f32.Value), 1, !if(!eq(SrcVT.Value, f64.Value), 1, 0)); @@ -1009,17 +1086,20 @@ class getIns64 { +class getAsm32 { + string dst = "$dst"; + string src0 = ", $src0"; string src1 = ", $src1"; string src2 = ", $src2"; - string ret = "$dst, $src0"# - !if(!eq(NumSrcArgs, 1), "", src1)# - !if(!eq(NumSrcArgs, 3), src2, ""); + string ret = !if(HasDst, dst, "") # + !if(!eq(NumSrcArgs, 1), src0, "") # + !if(!eq(NumSrcArgs, 2), src0#src1, "") # + !if(!eq(NumSrcArgs, 3), src0#src1#src2, ""); } // Returns the assembly string for the inputs and outputs of a VOP3 // instruction. -class getAsm64 { +class getAsm64 { string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,"); string src1 = !if(!eq(NumSrcArgs, 1), "", !if(!eq(NumSrcArgs, 2), " $src1_modifiers", @@ -1027,11 +1107,10 @@ class getAsm64 { string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", ""); string ret = !if(!eq(HasModifiers, 0), - getAsm32.ret, + getAsm32.ret, "$dst, "#src0#src1#src2#"$clamp"#"$omod"); } - class VOPProfile _ArgVT> { field list ArgVT = _ArgVT; @@ -1047,29 +1126,38 @@ class VOPProfile _ArgVT> { field RegisterOperand Src1RC64 = getVOP3SrcForVT.ret; field RegisterOperand Src2RC64 = getVOP3SrcForVT.ret; - field int NumSrcArgs = getNumSrcArgs.ret; + field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1); + field bit HasDst32 = HasDst; + field int NumSrcArgs = getNumSrcArgs.ret; field bit HasModifiers = hasModifiers.ret; - field dag Outs = (outs DstRC:$dst); + field dag Outs = !if(HasDst,(outs DstRC:$dst),(outs)); + + // VOP3b instructions are a special case with a second explicit + // output. This is manually overridden for them. + field dag Outs32 = Outs; + field dag Outs64 = Outs; field dag Ins32 = getIns32.ret; field dag Ins64 = getIns64.ret; - field string Asm32 = getAsm32.ret; - field string Asm64 = getAsm64.ret; + field string Asm32 = getAsm32.ret; + field string Asm64 = getAsm64.ret; } // FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order // for the instruction patterns to work. -def VOP_F16_F16 : VOPProfile <[f32, f32, untyped, untyped]>; -def VOP_F16_I16 : VOPProfile <[f32, i32, untyped, untyped]>; -def VOP_I16_F16 : VOPProfile <[i32, f32, untyped, untyped]>; +def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>; +def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>; +def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>; -def VOP_F16_F16_F16 : VOPProfile <[f32, f32, f32, untyped]>; -def VOP_F16_F16_I16 : VOPProfile <[f32, f32, i32, untyped]>; +def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>; +def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>; def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>; +def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>; + def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>; def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>; def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>; @@ -1087,25 +1175,76 @@ def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>; def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>; def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>; def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>; -def VOP_I32_I32_I32_VCC : VOPProfile <[i32, i32, i32, untyped]> { + +// Write out to vcc or arbitrary SGPR. +def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> { + let Asm32 = "$dst, vcc, $src0, $src1"; + let Asm64 = "$dst, $sdst, $src0, $src1"; + let Outs32 = (outs DstRC:$dst); + let Outs64 = (outs DstRC:$dst, SReg_64:$sdst); +} + +// Write out to vcc or arbitrary SGPR and read in from vcc or +// arbitrary SGPR. +def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> { + // We use VCSrc_32 to exclude literal constants, even though the + // encoding normally allows them since the implicit VCC use means + // using one would always violate the constant bus + // restriction. SGPRs are still allowed because it should + // technically be possible to use VCC again as src0. let Src0RC32 = VCSrc_32; + let Asm32 = "$dst, vcc, $src0, $src1, vcc"; + let Asm64 = "$dst, $sdst, $src0, $src1, $src2"; + let Outs32 = (outs DstRC:$dst); + let Outs64 = (outs DstRC:$dst, SReg_64:$sdst); + + // Suppress src2 implied by type since the 32-bit encoding uses an + // implicit VCC use. + let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); } -def VOP_I1_F32_I32 : VOPProfile <[i1, f32, i32, untyped]> { - let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1); - let Asm64 = "$dst, $src0_modifiers, $src1"; +class VOP3b_Profile : VOPProfile<[vt, vt, vt, vt]> { + let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst); + let Asm64 = "$vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod"; +} + +def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile { + // FIXME: Hack to stop printing _e64 + let DstRC = RegisterOperand; } -def VOP_I1_F64_I32 : VOPProfile <[i1, f64, i32, untyped]> { +def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile { + // FIXME: Hack to stop printing _e64 + let DstRC = RegisterOperand; +} + +// VOPC instructions are a special case because for the 32-bit +// encoding, we want to display the implicit vcc write as if it were +// an explicit $dst. +class VOPC_Profile : VOPProfile <[i1, vt0, vt1, untyped]> { + let Asm32 = "vcc, $src0, $src1"; + // The destination for 32-bit encoding is implicit. + let HasDst32 = 0; +} + +class VOPC_Class_Profile : VOPC_Profile { let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1); let Asm64 = "$dst, $src0_modifiers, $src1"; } +def VOPC_I1_F32_F32 : VOPC_Profile; +def VOPC_I1_F64_F64 : VOPC_Profile; +def VOPC_I1_I32_I32 : VOPC_Profile; +def VOPC_I1_I64_I64 : VOPC_Profile; + +def VOPC_I1_F32_I32 : VOPC_Class_Profile; +def VOPC_I1_F64_I32 : VOPC_Class_Profile; + def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>; def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>; def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>; def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> { - let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VCCReg:$src2); + let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1); let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2); let Asm64 = "$dst, $src0, $src1, $src2"; } @@ -1119,13 +1258,60 @@ def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> { let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2); let Ins64 = getIns64, 3, HasModifiers>.ret; - let Asm32 = getAsm32<2>.ret; - let Asm64 = getAsm64<2, HasModifiers>.ret; + let Asm32 = getAsm32<1, 2>.ret; + let Asm64 = getAsm64<1, 2, HasModifiers>.ret; } def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>; def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>; def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>; +class SIInstAlias : + InstAlias , PredicateControl { + + field bit isCompare; + field bit isCommutable; + + let ResultInst = + !if (p.HasDst32, + !if (!eq(p.NumSrcArgs, 0), + // 1 dst, 0 src + (inst p.DstRC:$dst), + !if (!eq(p.NumSrcArgs, 1), + // 1 dst, 1 src + (inst p.DstRC:$dst, p.Src0RC32:$src0), + !if (!eq(p.NumSrcArgs, 2), + // 1 dst, 2 src + (inst p.DstRC:$dst, p.Src0RC32:$src0, p.Src1RC32:$src1), + // else - unreachable + (inst)))), + // else + !if (!eq(p.NumSrcArgs, 2), + // 0 dst, 2 src + (inst p.Src0RC32:$src0, p.Src1RC32:$src1), + !if (!eq(p.NumSrcArgs, 1), + // 0 dst, 1 src + (inst p.Src0RC32:$src1), + // else + // 0 dst, 0 src + (inst)))); +} + +class SIInstAliasSI : + SIInstAlias (op_name#"_e32_si"), p> { + let AssemblerPredicate = SIAssemblerPredicate; +} + +class SIInstAliasVI : + SIInstAlias (op_name#"_e32_vi"), p> { + let AssemblerPredicates = [isVI]; +} + +multiclass SIInstAliasBuilder { + + def : SIInstAliasSI ; + + def : SIInstAliasVI ; +} class VOP { string OpName = opName; @@ -1165,20 +1351,22 @@ class VOP1_Real_vi : let AssemblerPredicates = [isVI]; } -multiclass VOP1_m pattern, - string opName> { - def "" : VOP1_Pseudo ; +multiclass VOP1_m pattern, + string asm = opName#p.Asm32> { + def "" : VOP1_Pseudo ; - def _si : VOP1_Real_si ; + def _si : VOP1_Real_si ; + + def _vi : VOP1_Real_vi ; - def _vi : VOP1_Real_vi ; } -multiclass VOP1SI_m pattern, - string opName> { - def "" : VOP1_Pseudo ; +multiclass VOP1SI_m pattern, + string asm = opName#p.Asm32> { + + def "" : VOP1_Pseudo ; - def _si : VOP1_Real_si ; + def _si : VOP1_Real_si ; } class VOP2_Pseudo pattern, string opName> : @@ -1202,22 +1390,24 @@ class VOP2_Real_vi : let AssemblerPredicates = [isVI]; } -multiclass VOP2SI_m pattern, - string opName, string revOp> { - def "" : VOP2_Pseudo , +multiclass VOP2SI_m pattern, + string revOp> { + + def "" : VOP2_Pseudo , VOP2_REV; - def _si : VOP2_Real_si ; + def _si : VOP2_Real_si ; } -multiclass VOP2_m pattern, - string opName, string revOp> { - def "" : VOP2_Pseudo , +multiclass VOP2_m pattern, + string revOp> { + + def "" : VOP2_Pseudo , VOP2_REV; - def _si : VOP2_Real_si ; + def _si : VOP2_Real_si ; - def _vi : VOP2_Real_vi ; + def _vi : VOP2_Real_vi ; } @@ -1250,6 +1440,9 @@ class VOP3_Pseudo pattern, string opName> : MnemonicAlias { let isPseudo = 1; let isCodeGenOnly = 1; + + field bit vdst; + field bit src0; } class VOP3_Real_si op, dag outs, dag ins, string asm, string opName> : @@ -1295,22 +1488,6 @@ multiclass VOP3_m pattern, HasMods>; } -// VOP3_m without source modifiers -multiclass VOP3_m_nomods pattern, - string opName, int NumSrcArgs, bit HasMods = 1> { - - def "" : VOP3_Pseudo ; - - let src0_modifiers = 0, - src1_modifiers = 0, - src2_modifiers = 0, - clamp = 0, - omod = 0 in { - def _si : VOP3_Real_si ; - def _vi : VOP3_Real_vi ; - } -} - multiclass VOP3_1_m pattern, string opName, bit HasMods = 1> { @@ -1335,7 +1512,7 @@ multiclass VOP3SI_1_m pattern, string opName, string revOp, - bit HasMods = 1, bit UseFullOp = 0> { + bit HasMods = 1> { def "" : VOP3_Pseudo , VOP2_REV; @@ -1349,7 +1526,7 @@ multiclass VOP3_2_m pattern, string opName, string revOp, - bit HasMods = 1, bit UseFullOp = 0> { + bit HasMods = 1> { def "" : VOP3_Pseudo , VOP2_REV; @@ -1360,54 +1537,41 @@ multiclass VOP3SI_2_m pattern, string opName, string revOp, - bit HasMods = 1, bit UseFullOp = 0> { - def "" : VOP3_Pseudo , - VOP2_REV; - - // The VOP2 variant puts the carry out into VCC, the VOP3 variant - // can write it into any SGPR. We currently don't use the carry out, - // so for now hardcode it to VCC as well. - let sdst = SIOperand.VCC, Defs = [VCC] in { - def _si : VOP3b_Real_si , - VOP3DisableFields<1, 0, HasMods>; - - def _vi : VOP3b_Real_vi , - VOP3DisableFields<1, 0, HasMods>; - } // End sdst = SIOperand.VCC, Defs = [VCC] -} - -multiclass VOP3b_3_m pattern, string opName, string revOp, - bit HasMods = 1, bit UseFullOp = 0> { +// Two operand VOP3b instruction that may have a 3rd SGPR bool operand +// instead of an implicit VCC as in the VOP2b format. +multiclass VOP3b_2_3_m pattern, string opName, string revOp, + bit HasMods = 1, bit useSrc2Input = 0> { def "" : VOP3_Pseudo ; - def _si : VOP3b_Real_si , - VOP3DisableFields<1, 1, HasMods>; + VOP3DisableFields<1, useSrc2Input, HasMods>; def _vi : VOP3b_Real_vi , - VOP3DisableFields<1, 1, HasMods>; + VOP3DisableFields<1, useSrc2Input, HasMods>; } multiclass VOP3_C_m pattern, string opName, - bit HasMods, bit defExec, string revOp> { + bit HasMods, bit defExec, + string revOp, list sched> { def "" : VOP3_Pseudo , - VOP2_REV; + VOP2_REV { + let Defs = !if(defExec, [EXEC], []); + let SchedRW = sched; + } def _si : VOP3_Real_si , VOP3DisableFields<1, 0, HasMods> { let Defs = !if(defExec, [EXEC], []); + let SchedRW = sched; } def _vi : VOP3_Real_vi , VOP3DisableFields<1, 0, HasMods> { let Defs = !if(defExec, [EXEC], []); + let SchedRW = sched; } } @@ -1432,32 +1596,28 @@ multiclass VOP2SI_3VI_m pat32, - dag ins64, string asm64, list pat64, - bit HasMods> { +multiclass VOP1_Helper pat32, + list pat64> { - defm _e32 : VOP1_m ; + defm _e32 : VOP1_m ; - defm _e64 : VOP3_1_m ; + defm _e64 : VOP3_1_m ; } multiclass VOP1Inst : VOP1_Helper < - op, opName, P.Outs, - P.Ins32, P.Asm32, [], - P.Ins64, P.Asm64, + op, opName, P, [], !if(P.HasModifiers, [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod))))], - [(set P.DstVT:$dst, (node P.Src0VT:$src0))]), - P.HasModifiers + [(set P.DstVT:$dst, (node P.Src0VT:$src0))]) >; multiclass VOP1InstSI { - defm _e32 : VOP1SI_m ; + defm _e32 : VOP1SI_m ; defm _e64 : VOP3SI_1_m ; } -multiclass VOP2_Helper pat32, - dag ins64, string asm64, list pat64, - string revOp, bit HasMods> { - defm _e32 : VOP2_m ; +multiclass VOP2_Helper pat32, + list pat64, string revOp> { - defm _e64 : VOP3_2_m ; + defm _e32 : VOP2_m ; + + defm _e64 : VOP3_2_m ; } multiclass VOP2Inst : VOP2_Helper < - op, opName, P.Outs, - P.Ins32, P.Asm32, [], - P.Ins64, P.Asm64, + op, opName, P, [], !if(P.HasModifiers, [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), - revOp, P.HasModifiers + revOp >; multiclass VOP2InstSI { - defm _e32 : VOP2SI_m ; + + defm _e32 : VOP2SI_m ; defm _e64 : VOP3SI_2_m ; } -multiclass VOP2b_Helper pat32, - dag ins64, string asm64, list pat64, - string revOp, bit HasMods> { +multiclass VOP2b_Helper pat32, list pat64, + string revOp, bit useSGPRInput> { - defm _e32 : VOP2_m ; + let SchedRW = [Write32Bit, WriteSALU] in { + let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in { + defm _e32 : VOP2_m ; + } - defm _e64 : VOP3b_2_m ; + defm _e64 : VOP3b_2_3_m ; + } } multiclass VOP2bInst : VOP2b_Helper < - op, opName, P.Outs, - P.Ins32, P.Asm32, [], - P.Ins64, P.Asm64, + op, opName, P, [], !if(P.HasModifiers, [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), - revOp, P.HasModifiers + revOp, !eq(P.NumSrcArgs, 3) >; // A VOP2 instruction that is VOP3-only on VI. -multiclass VOP2_VI3_Helper pat32, - dag ins64, string asm64, list pat64, - string revOp, bit HasMods> { - defm _e32 : VOP2SI_m ; +multiclass VOP2_VI3_Helper pat32, list pat64, string revOp> { + + defm _e32 : VOP2SI_m ; - defm _e64 : VOP3_2_m ; + defm _e64 : VOP3_2_m ; } multiclass VOP2_VI3_Inst : VOP2_VI3_Helper < - op, opName, P.Outs, - P.Ins32, P.Asm32, [], - P.Ins64, P.Asm64, + op, opName, P, [], !if(P.HasModifiers, [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))], [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]), - revOp, P.HasModifiers + revOp >; multiclass VOP2MADK pattern = []> { @@ -1583,62 +1737,75 @@ let isCodeGenOnly = 0 in { } // End isCodeGenOnly = 0 } -class VOPC_Pseudo pattern, string opName> : +class VOPC_Pseudo pattern, string opName> : VOPCCommon , VOP , - SIMCInstr, - MnemonicAlias { + SIMCInstr { let isPseudo = 1; let isCodeGenOnly = 1; } -multiclass VOPC_m pattern, - string opName, bit DefExec, string revOpName = ""> { - def "" : VOPC_Pseudo ; - - def _si : VOPC, - SIMCInstr { - let Defs = !if(DefExec, [EXEC], []); - let hasSideEffects = DefExec; +multiclass VOPC_m pattern, + string opName, bit DefExec, VOPProfile p, + list sched, + string revOpName = "", string asm = opName#"_e32 "#op_asm, + string alias_asm = opName#" "#op_asm> { + def "" : VOPC_Pseudo { + let Defs = !if(DefExec, [VCC, EXEC], [VCC]); + let SchedRW = sched; } - def _vi : VOPC, - SIMCInstr { - let Defs = !if(DefExec, [EXEC], []); - let hasSideEffects = DefExec; - } + let AssemblerPredicates = [isSICI] in { + def _si : VOPC, + SIMCInstr { + let Defs = !if(DefExec, [VCC, EXEC], [VCC]); + let hasSideEffects = DefExec; + let SchedRW = sched; + } + + } // End AssemblerPredicates = [isSICI] + + let AssemblerPredicates = [isVI] in { + def _vi : VOPC, + SIMCInstr { + let Defs = !if(DefExec, [VCC, EXEC], [VCC]); + let hasSideEffects = DefExec; + let SchedRW = sched; + } + + } // End AssemblerPredicates = [isVI] + + defm : SIInstAliasBuilder; } -multiclass VOPC_Helper pat32, - dag out64, dag ins64, string asm64, list pat64, - bit HasMods, bit DefExec, string revOp> { - defm _e32 : VOPC_m ; +multiclass VOPC_Helper pat32, + list pat64, bit DefExec, string revOp, + VOPProfile p, list sched> { + defm _e32 : VOPC_m ; - defm _e64 : VOP3_C_m ; + defm _e64 : VOP3_C_m ; } // Special case for class instructions which only have modifiers on // the 1st source operand. -multiclass VOPC_Class_Helper pat32, - dag out64, dag ins64, string asm64, list pat64, - bit HasMods, bit DefExec, string revOp> { - defm _e32 : VOPC_m ; - - defm _e64 : VOP3_C_m , +multiclass VOPC_Class_Helper pat32, + list pat64, bit DefExec, string revOp, + VOPProfile p, list sched> { + defm _e32 : VOPC_m ; + + defm _e64 : VOP3_C_m , VOP3DisableModFields<1, 0, 0>; } multiclass VOPCInst : VOPC_Helper < - op, opName, - P.Ins32, P.Asm32, [], - (outs VOPDstS64:$dst), P.Ins64, P.Asm64, + bit DefExec = 0, + list sched = [Write32Bit]> : + VOPC_Helper < + op, opName, [], !if(P.HasModifiers, [(set i1:$dst, (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, @@ -1646,51 +1813,51 @@ multiclass VOPCInst ; multiclass VOPCClassInst : VOPC_Class_Helper < - op, opName, - P.Ins32, P.Asm32, [], - (outs VOPDstS64:$dst), P.Ins64, P.Asm64, + bit DefExec = 0, + list sched> : VOPC_Class_Helper < + op, opName, [], !if(P.HasModifiers, [(set i1:$dst, (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))], [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]), - P.HasModifiers, DefExec, opName + DefExec, opName, P, sched >; multiclass VOPC_F32 : - VOPCInst ; + VOPCInst ; multiclass VOPC_F64 : - VOPCInst ; + VOPCInst ; multiclass VOPC_I32 : - VOPCInst ; + VOPCInst ; multiclass VOPC_I64 : - VOPCInst ; + VOPCInst ; multiclass VOPCX sched, string revOp = ""> - : VOPCInst ; + : VOPCInst ; multiclass VOPCX_F32 : - VOPCX ; + VOPCX ; multiclass VOPCX_F64 : - VOPCX ; + VOPCX ; multiclass VOPCX_I32 : - VOPCX ; + VOPCX ; multiclass VOPCX_I64 : - VOPCX ; + VOPCX ; multiclass VOP3_Helper pat, int NumSrcArgs, bit HasMods> : VOP3_m < @@ -1698,16 +1865,16 @@ multiclass VOP3_Helper ; multiclass VOPC_CLASS_F32 : - VOPCClassInst ; + VOPCClassInst ; multiclass VOPCX_CLASS_F32 : - VOPCClassInst ; + VOPCClassInst ; multiclass VOPC_CLASS_F64 : - VOPCClassInst ; + VOPCClassInst ; multiclass VOPCX_CLASS_F64 : - VOPCClassInst ; + VOPCClassInst ; multiclass VOP3Inst : VOP3_Helper < @@ -1759,25 +1926,13 @@ multiclass VOP3_VCC_Inst ; -multiclass VOP3b_Helper pattern> : - VOP3b_3_m < - op, (outs vrc:$vdst, SReg_64:$sdst), - (ins InputModsNoDefault:$src0_modifiers, arc:$src0, - InputModsNoDefault:$src1_modifiers, arc:$src1, - InputModsNoDefault:$src2_modifiers, arc:$src2, - ClampMod:$clamp, omod:$omod), - opName#" $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern, - opName, opName, 1, 1 +multiclass VOP3bInst pattern = []> : + VOP3b_2_3_m < + op, P.Outs64, P.Ins64, + opName#" "#P.Asm64, pattern, + opName, "", 1, 1 >; -multiclass VOP3b_64 pattern> : - VOP3b_Helper ; - -multiclass VOP3b_32 pattern> : - VOP3b_Helper ; - - class Vop3ModPat : Pat< (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)), (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), @@ -1923,12 +2078,14 @@ multiclass DS_1A1D_RET op, string opName, RegisterClass rc, dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds), string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> { - def "" : DS_Pseudo , - AtomicNoRet; + let hasPostISelHook = 1 in { + def "" : DS_Pseudo , + AtomicNoRet; - let data1 = 0 in { - def _si : DS_Off16_Real_si ; - def _vi : DS_Off16_Real_vi ; + let data1 = 0 in { + def _si : DS_Off16_Real_si ; + def _vi : DS_Off16_Real_vi ; + } } } @@ -1937,11 +2094,13 @@ multiclass DS_1A2D_RET_m op, string opName, RegisterClass rc, dag outs = (outs rc:$vdst), string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> { - def "" : DS_Pseudo , - AtomicNoRet; + let hasPostISelHook = 1 in { + def "" : DS_Pseudo , + AtomicNoRet; - def _si : DS_Off16_Real_si ; - def _vi : DS_Off16_Real_vi ; + def _si : DS_Off16_Real_si ; + def _vi : DS_Off16_Real_vi ; + } } multiclass DS_1A2D_RET op, string asm, RegisterClass rc, @@ -2212,7 +2371,7 @@ multiclass MUBUF_Atomic ; @@ -2231,7 +2390,7 @@ multiclass MUBUF_Atomic { @@ -2366,6 +2527,23 @@ multiclass MUBUF_Store_Helper { + let hasSideEffects = 1, mayStore = 1, AsmMatchConverter = "" in { + def "" : MUBUF_Pseudo ; + + // Set everything to 0. + let offset = 0, offen = 0, idxen = 0, glc = 0, vaddr = 0, + vdata = 0, srsrc = 0, slc = 0, tfe = 0, soffset = 0 in { + let addr64 = 0 in { + def _si : MUBUF_Real_si ; + } + + def _vi : MUBUF_Real_vi ; + } + } // End hasSideEffects = 1, mayStore = 1, AsmMatchConverter = "" +} + class FLAT_Load_Helper op, string asm, RegisterClass regClass> : FLAT op, string name, RegisterClass vdst_rc, name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>, AtomicNoRet { let glc = 1; + let hasPostISelHook = 1; } } }