diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SOPInstructions.td')
-rw-r--r-- | llvm/lib/Target/AMDGPU/SOPInstructions.td | 161 |
1 files changed, 86 insertions, 75 deletions
diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td index 37d20045adb5..ad9af662307f 100644 --- a/llvm/lib/Target/AMDGPU/SOPInstructions.td +++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td @@ -39,7 +39,7 @@ class SOP_Pseudo<string opName, dag outs, dag ins, string asmOps, class SOP1_Pseudo <string opName, dag outs, dag ins, string asmOps, list<dag> pattern=[]> : - SOP_Pseudo<opName, outs, ins, asmOps, pattern> { + SOP_Pseudo<opName, outs, ins, " " # asmOps, pattern> { let mayLoad = 0; let mayStore = 0; @@ -51,12 +51,12 @@ class SOP1_Pseudo <string opName, dag outs, dag ins, let UseNamedOperandTable = 1; bits<1> has_src0 = 1; - bits<1> has_sdst = 1; + let has_sdst = 1; } class SOP1_Real<bits<8> op, SOP1_Pseudo ps, string real_name = ps.Mnemonic> : InstSI <ps.OutOperandList, ps.InOperandList, - real_name # " " # ps.AsmOperands, []>, + real_name # ps.AsmOperands>, Enc32 { let SALU = 1; @@ -157,6 +157,7 @@ class SOP1_1 <string opName, list<dag> pattern=[]> : SOP1_Pseudo < let has_sdst = 0; } + class UniformUnaryFrag<SDPatternOperator Op> : PatFrag < (ops node:$src0), (Op $src0), @@ -181,6 +182,18 @@ class UniformBinFrag<SDPatternOperator Op> : PatFrag < let GISelPredicateCode = [{return true;}]; } +class UniformTernaryFrag<SDPatternOperator Op> : PatFrag < + (ops node:$src0, node:$src1, node:$src2), + (Op $src0, $src1, $src2), + [{ return !N->isDivergent(); }]> { + // This check is unnecessary as it's captured by the result register + // bank constraint. + // + // FIXME: Should add a way for the emitter to recognize this is a + // trivially true predicate to eliminate the check. + let GISelPredicateCode = [{return true;}]; +} + class DivergentBinFrag<SDPatternOperator Op> : PatFrag < (ops node:$src0, node:$src1), (Op $src0, $src1), @@ -405,7 +418,7 @@ let SubtargetPredicate = isGFX11Plus in { class SOP2_Pseudo<string opName, dag outs, dag ins, string asmOps, list<dag> pattern=[]> : - SOP_Pseudo<opName, outs, ins, asmOps, pattern> { + SOP_Pseudo<opName, outs, ins, " " # asmOps, pattern> { let mayLoad = 0; let mayStore = 0; @@ -427,7 +440,7 @@ class SOP2_Pseudo<string opName, dag outs, dag ins, class SOP2_Real<bits<7> op, SOP_Pseudo ps, string real_name = ps.Mnemonic> : InstSI <ps.OutOperandList, ps.InOperandList, - real_name # " " # ps.AsmOperands, []>, + real_name # ps.AsmOperands>, Enc32 { let SALU = 1; let SOP2 = 1; @@ -516,21 +529,16 @@ def S_MAX_U32 : SOP2_32 <"s_max_u32", } // End isCommutable = 1 } // End Defs = [SCC] -// This pattern is restricted to certain subtargets (practically GFX8Plus) -// because isel sometimes produces an sreg_64 copy to SCC as a by-product -// of this pattern, and only for subtargets with hasScalarCompareEq64 -// is it possible to map such copy to a single instruction (S_CMP_LG_U64). -class SelectPat<SDPatternOperator select> : PatFrag < +def SelectPat : PatFrag < (ops node:$src1, node:$src2), (select SCC, $src1, $src2), - [{ return Subtarget->hasScalarCompareEq64() && - N->getOperand(0)->hasOneUse() && !N->isDivergent(); }] + [{ return !N->isDivergent(); }] >; let Uses = [SCC] in { let AddedComplexity = 20 in { def S_CSELECT_B32 : SOP2_32 <"s_cselect_b32", - [(set i32:$sdst, (SelectPat<select> i32:$src0, i32:$src1))] + [(set i32:$sdst, (SelectPat i32:$src0, i32:$src1))] >; } @@ -714,30 +722,27 @@ let SubtargetPredicate = isGFX11Plus in { class SOPK_Pseudo <string opName, dag outs, dag ins, string asmOps, list<dag> pattern=[]> : - InstSI <outs, ins, "", pattern>, - SIMCInstr<opName, SIEncodingFamily.NONE> { - let isPseudo = 1; - let isCodeGenOnly = 1; + SOP_Pseudo<opName, outs, ins, " " # asmOps, pattern> { let mayLoad = 0; let mayStore = 0; let hasSideEffects = 0; let SALU = 1; let SOPK = 1; + let FixedSize = 1; let SchedRW = [WriteSALU]; let UseNamedOperandTable = 1; - string Mnemonic = opName; - string AsmOperands = asmOps; - bits<1> has_sdst = 1; + let has_sdst = 1; } class SOPK_Real<SOPK_Pseudo ps> : InstSI <ps.OutOperandList, ps.InOperandList, - ps.Mnemonic # " " # ps.AsmOperands, []> { + ps.Mnemonic # ps.AsmOperands> { let SALU = 1; let SOPK = 1; let isPseudo = 0; let isCodeGenOnly = 0; + let UseNamedOperandTable = 1; // copy relevant pseudo op flags let SubtargetPredicate = ps.SubtargetPredicate; @@ -806,7 +811,7 @@ class SOPK_SCC <string opName, string base_op, bit isSignExt> : SOPK_Pseudo < !if(isSignExt, (ins SReg_32:$sdst, s16imm:$simm16), (ins SReg_32:$sdst, u16imm:$simm16)), - "$sdst, $simm16", []>, + "$sdst, $simm16">, SOPKInstTable<1, base_op>{ let Defs = [SCC]; } @@ -860,9 +865,10 @@ def S_CMPK_LE_U32 : SOPK_SCC <"s_cmpk_le_u32", "s_cmp_le_u32", 0>; } // End SOPKZext = 1 } // End isCompare = 1 -let Defs = [SCC], isCommutable = 1, DisableEncoding = "$src0", +let isCommutable = 1, DisableEncoding = "$src0", Constraints = "$sdst = $src0" in { - def S_ADDK_I32 : SOPK_32TIE <"s_addk_i32">; + let Defs = [SCC] in + def S_ADDK_I32 : SOPK_32TIE <"s_addk_i32">; def S_MULK_I32 : SOPK_32TIE <"s_mulk_i32">; } @@ -977,7 +983,7 @@ let SubtargetPredicate = isGFX10Plus in { class SOPC_Pseudo<string opName, dag outs, dag ins, string asmOps, list<dag> pattern=[]> : - SOP_Pseudo<opName, outs, ins, asmOps, pattern> { + SOP_Pseudo<opName, outs, ins, " " # asmOps, pattern> { let mayLoad = 0; let mayStore = 0; let hasSideEffects = 0; @@ -988,9 +994,9 @@ class SOPC_Pseudo<string opName, dag outs, dag ins, let UseNamedOperandTable = 1; } -class SOPC_Real<bits<7> op, SOPC_Pseudo ps, string real_name = ps.Mnemonic> : +class SOPC_Real<bits<7> op, SOPC_Pseudo ps> : InstSI <ps.OutOperandList, ps.InOperandList, - real_name # " " # ps.AsmOperands, []>, + ps.Mnemonic # ps.AsmOperands>, Enc32 { let SALU = 1; let SOPC = 1; @@ -1026,7 +1032,7 @@ class SOPC_Base <RegisterOperand rc0, RegisterOperand rc1, class SOPC_Helper <RegisterOperand rc, ValueType vt, string opName, SDPatternOperator cond> : SOPC_Base < rc, rc, opName, - [(set SCC, (si_setcc_uniform vt:$src0, vt:$src1, cond))] > { + [(set SCC, (UniformTernaryFrag<setcc> vt:$src0, vt:$src1, cond))] > { } class SOPC_CMP_32<string opName, @@ -1099,10 +1105,10 @@ def S_SET_GPR_IDX_ON : SOPC_Pseudo < //===----------------------------------------------------------------------===// class SOPP_Pseudo<string opName, dag ins, - string asmOps = "", list<dag> pattern=[], string keyName = opName> : - SOP_Pseudo<opName, (outs), ins, asmOps, pattern> { - let isPseudo = 1; - let isCodeGenOnly = 1; + string asmOps = "", list<dag> pattern=[], + string sep = !if(!empty(asmOps), "", " "), + string keyName = opName> : + SOP_Pseudo<opName, (outs), ins, sep # asmOps, pattern> { let mayLoad = 0; let mayStore = 0; let hasSideEffects = 0; @@ -1121,10 +1127,9 @@ class SOPPRelaxTable <bit isRelaxed, string keyName, string gfxip> { string KeyName = keyName # gfxip; } -//spaces inserted in realname on instantiation of this record to allow s_endpgm to omit whitespace class SOPP_Real<SOPP_Pseudo ps, string real_name = ps.Mnemonic> : InstSI <ps.OutOperandList, ps.InOperandList, - real_name # ps.AsmOperands, []> { + real_name # ps.AsmOperands> { let SALU = 1; let SOPP = 1; let isPseudo = 0; @@ -1164,13 +1169,13 @@ Enc64 { multiclass SOPP_With_Relaxation <string opName, dag ins, string asmOps, list<dag> pattern=[]> { def "" : SOPP_Pseudo <opName, ins, asmOps, pattern>; - def _pad_s_nop : SOPP_Pseudo <opName # "_pad_s_nop", ins, asmOps, pattern, opName>; + def _pad_s_nop : SOPP_Pseudo <opName # "_pad_s_nop", ins, asmOps, pattern, " ", opName>; } def S_NOP : SOPP_Pseudo<"s_nop" , (ins i16imm:$simm16), "$simm16">; let isTerminator = 1 in { -def S_ENDPGM : SOPP_Pseudo<"s_endpgm", (ins EndpgmImm:$simm16), "$simm16"> { +def S_ENDPGM : SOPP_Pseudo<"s_endpgm", (ins EndpgmImm:$simm16), "$simm16", [], ""> { let isBarrier = 1; let isReturn = 1; let hasSideEffects = 1; @@ -1357,7 +1362,7 @@ let SubtargetPredicate = isGFX10Plus in { def S_CLAUSE : SOPP_Pseudo<"s_clause", (ins s16imm:$simm16), "$simm16">; def S_WAIT_IDLE : - SOPP_Pseudo <"s_wait_idle", (ins), ""> { + SOPP_Pseudo <"s_wait_idle", (ins)> { let simm16 = 0; let fixed_imm = 1; } @@ -1378,7 +1383,9 @@ let SubtargetPredicate = isGFX10Plus in { let SubtargetPredicate = isGFX11Plus in { def S_WAIT_EVENT : SOPP_Pseudo<"s_wait_event", (ins s16imm:$simm16), - "$simm16">; + "$simm16"> { + let hasSideEffects = 1; + } def S_DELAY_ALU : SOPP_Pseudo<"s_delay_alu", (ins DELAY_FLAG:$simm16), "$simm16">; } // End SubtargetPredicate = isGFX11Plus @@ -1420,6 +1427,10 @@ def : GCNPat< (S_SEXT_I32_I16 $src) >; +def : GCNPat < + (int_amdgcn_s_wait_event_export_ready), + (S_WAIT_EVENT (i16 0)) +>; //===----------------------------------------------------------------------===// // SOP2 Patterns @@ -1923,20 +1934,20 @@ defm S_SETREG_IMM32_B32 : SOPK_Real64_gfx6_gfx7_gfx10<0x015>; // SOPP - GFX11 //===----------------------------------------------------------------------===// -multiclass SOPP_Real_32_gfx11<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> { - def _gfx11 : SOPP_Real_32<op, !cast<SOPP_Pseudo>(NAME), real_name>, +multiclass SOPP_Real_32_gfx11<bits<7> op> { + def _gfx11 : SOPP_Real_32<op, !cast<SOPP_Pseudo>(NAME), !cast<SOPP_Pseudo>(NAME).Mnemonic>, Select_gfx11<!cast<SOPP_Pseudo>(NAME).Mnemonic>, SOPPRelaxTable<0, !cast<SOPP_Pseudo>(NAME).KeyName, "_gfx11">; } -multiclass SOPP_Real_64_gfx11<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> { - def _gfx11 : SOPP_Real_64<op, !cast<SOPP_Pseudo>(NAME), real_name>, +multiclass SOPP_Real_64_gfx11<bits<7> op> { + def _gfx11 : SOPP_Real_64<op, !cast<SOPP_Pseudo>(NAME), !cast<SOPP_Pseudo>(NAME).Mnemonic>, Select_gfx11<!cast<SOPP_Pseudo>(NAME).Mnemonic>, SOPPRelaxTable<1, !cast<SOPP_Pseudo>(NAME).KeyName, "_gfx11">; } multiclass SOPP_Real_32_Renamed_gfx11<bits<7> op, SOPP_Pseudo backing_pseudo, string real_name> { - def _gfx11 : SOPP_Real_32<op, backing_pseudo, real_name # " ">, + def _gfx11 : SOPP_Real_32<op, backing_pseudo, real_name>, Select_gfx11<backing_pseudo.Mnemonic>, MnemonicAlias<backing_pseudo.Mnemonic, real_name>, Requires<[isGFX11Plus]>; } @@ -1970,7 +1981,7 @@ defm S_CBRANCH_CDBGSYS : SOPP_Real_With_Relaxation_gfx11<0x027>; defm S_CBRANCH_CDBGUSER : SOPP_Real_With_Relaxation_gfx11<0x028>; defm S_CBRANCH_CDBGSYS_OR_USER : SOPP_Real_With_Relaxation_gfx11<0x029>; defm S_CBRANCH_CDBGSYS_AND_USER : SOPP_Real_With_Relaxation_gfx11<0x02a>; -defm S_ENDPGM : SOPP_Real_32_gfx11<0x030, "s_endpgm">; +defm S_ENDPGM : SOPP_Real_32_gfx11<0x030>; defm S_ENDPGM_SAVED : SOPP_Real_32_gfx11<0x031>; defm S_WAKEUP : SOPP_Real_32_gfx11<0x034>; defm S_SETPRIO : SOPP_Real_32_gfx11<0x035>; @@ -1987,75 +1998,75 @@ defm S_BARRIER : SOPP_Real_32_gfx11<0x03d>; // SOPP - GFX6, GFX7, GFX8, GFX9, GFX10 //===----------------------------------------------------------------------===// -multiclass SOPP_Real_32_gfx6_gfx7<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic> { +multiclass SOPP_Real_32_gfx6_gfx7<bits<7> op> { defvar ps = !cast<SOPP_Pseudo>(NAME); - def _gfx6_gfx7 : SOPP_Real_32<op, ps, real_name>, + def _gfx6_gfx7 : SOPP_Real_32<op, ps, !cast<SOPP_Pseudo>(NAME).Mnemonic>, Select_gfx6_gfx7<ps.Mnemonic>, SOPPRelaxTable<0, ps.KeyName, "_gfx6_gfx7">; } -multiclass SOPP_Real_32_gfx8_gfx9<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> { +multiclass SOPP_Real_32_gfx8_gfx9<bits<7> op> { defvar ps = !cast<SOPP_Pseudo>(NAME); - def _vi : SOPP_Real_32<op, ps, real_name>, + def _vi : SOPP_Real_32<op, ps>, Select_vi<ps.Mnemonic>, SOPPRelaxTable<0, ps.KeyName, "_vi">; } -multiclass SOPP_Real_32_gfx10<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> { +multiclass SOPP_Real_32_gfx10<bits<7> op> { defvar ps = !cast<SOPP_Pseudo>(NAME); - def _gfx10 : SOPP_Real_32<op, ps, real_name>, + def _gfx10 : SOPP_Real_32<op, ps>, Select_gfx10<ps.Mnemonic>, SOPPRelaxTable<0, ps.KeyName, "_gfx10">; } -multiclass SOPP_Real_32_gfx8_gfx9_gfx10<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_32_gfx8_gfx9<op, real_name>, SOPP_Real_32_gfx10<op, real_name>; +multiclass SOPP_Real_32_gfx8_gfx9_gfx10<bits<7> op> : + SOPP_Real_32_gfx8_gfx9<op>, SOPP_Real_32_gfx10<op>; -multiclass SOPP_Real_32_gfx6_gfx7_gfx8_gfx9<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_32_gfx6_gfx7<op, real_name>, SOPP_Real_32_gfx8_gfx9<op, real_name>; +multiclass SOPP_Real_32_gfx6_gfx7_gfx8_gfx9<bits<7> op> : + SOPP_Real_32_gfx6_gfx7<op>, SOPP_Real_32_gfx8_gfx9<op>; -multiclass SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_32_gfx6_gfx7_gfx8_gfx9<op, real_name>, SOPP_Real_32_gfx10<op, real_name>; +multiclass SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10<bits<7> op> : + SOPP_Real_32_gfx6_gfx7_gfx8_gfx9<op>, SOPP_Real_32_gfx10<op>; -multiclass SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10_gfx11<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10<op, real_name>, SOPP_Real_32_gfx11<op, real_name>; +multiclass SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10_gfx11<bits<7> op> : + SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10<op>, SOPP_Real_32_gfx11<op>; -multiclass SOPP_Real_32_gfx10_gfx11<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_32_gfx10<op, real_name>, SOPP_Real_32_gfx11<op, real_name>; +multiclass SOPP_Real_32_gfx10_gfx11<bits<7> op> : + SOPP_Real_32_gfx10<op>, SOPP_Real_32_gfx11<op>; //64 bit encodings, for Relaxation -multiclass SOPP_Real_64_gfx6_gfx7<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> { +multiclass SOPP_Real_64_gfx6_gfx7<bits<7> op> { defvar ps = !cast<SOPP_Pseudo>(NAME); - def _gfx6_gfx7 : SOPP_Real_64<op, ps, real_name>, + def _gfx6_gfx7 : SOPP_Real_64<op, ps>, Select_gfx6_gfx7<ps.Mnemonic>, SOPPRelaxTable<1, ps.KeyName, "_gfx6_gfx7">; } -multiclass SOPP_Real_64_gfx8_gfx9<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> { +multiclass SOPP_Real_64_gfx8_gfx9<bits<7> op> { defvar ps = !cast<SOPP_Pseudo>(NAME); - def _vi : SOPP_Real_64<op, ps, real_name>, + def _vi : SOPP_Real_64<op, ps>, Select_vi<ps.Mnemonic>, SOPPRelaxTable<1, ps.KeyName, "_vi">; } -multiclass SOPP_Real_64_gfx10<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> { +multiclass SOPP_Real_64_gfx10<bits<7> op> { defvar ps = !cast<SOPP_Pseudo>(NAME); - def _gfx10 : SOPP_Real_64<op, ps, real_name>, + def _gfx10 : SOPP_Real_64<op, ps>, Select_gfx10<ps.Mnemonic>, SOPPRelaxTable<1, ps.KeyName, "_gfx10">; } -multiclass SOPP_Real_64_gfx8_gfx9_gfx10<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_64_gfx8_gfx9<op, real_name>, SOPP_Real_64_gfx10<op, real_name>; +multiclass SOPP_Real_64_gfx8_gfx9_gfx10<bits<7> op> : + SOPP_Real_64_gfx8_gfx9<op>, SOPP_Real_64_gfx10<op>; -multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_64_gfx6_gfx7<op, real_name>, SOPP_Real_64_gfx8_gfx9<op, real_name>; +multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9<bits<7> op> : + SOPP_Real_64_gfx6_gfx7<op>, SOPP_Real_64_gfx8_gfx9<op>; -multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_64_gfx6_gfx7_gfx8_gfx9<op, real_name>, SOPP_Real_64_gfx10<op, real_name>; +multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10<bits<7> op> : + SOPP_Real_64_gfx6_gfx7_gfx8_gfx9<op>, SOPP_Real_64_gfx10<op>; -multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10_gfx11<bits<7> op, string real_name = !cast<SOPP_Pseudo>(NAME).Mnemonic # " "> : - SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10<op, real_name>, SOPP_Real_64_gfx11<op, real_name>; +multiclass SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10_gfx11<bits<7> op> : + SOPP_Real_64_gfx6_gfx7_gfx8_gfx9_gfx10<op>, SOPP_Real_64_gfx11<op>; //relaxation for insts with no operands not implemented multiclass SOPP_Real_With_Relaxation_gfx6_gfx7_gfx8_gfx9_gfx10<bits<7> op> { @@ -2064,7 +2075,7 @@ multiclass SOPP_Real_With_Relaxation_gfx6_gfx7_gfx8_gfx9_gfx10<bits<7> op> { } defm S_NOP : SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10_gfx11<0x000>; -defm S_ENDPGM : SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10<0x001, "s_endpgm">; +defm S_ENDPGM : SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10<0x001>; defm S_WAKEUP : SOPP_Real_32_gfx8_gfx9_gfx10<0x003>; defm S_BARRIER : SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10<0x00a>; defm S_WAITCNT : SOPP_Real_32_gfx6_gfx7_gfx8_gfx9_gfx10<0x00c>; |