llvm.org GIT mirror llvm / 93211d9
[AMDGPU] Assembler: match e32 VOP instructions before e64. Summary: Split assembler match table in 4 tables with assembler variants: Default - all instructions except VOP3, SDWA and DPP - VOP3 - SDWA - DPP First match Default table then VOP3, SDWA and DPP. Reviewers: tstellarAMD, artem.tamazov, vpykhtin Subscribers: arsenm, wdng, nhaehnle, AMDGPU Differential Revision: https://reviews.llvm.org/D24252 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281023 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Kolton 4 years ago
7 changed file(s) with 134 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
348348 let ShouldEmitMatchRegisterName = 0;
349349 }
350350
351 def AMDGPUAsmVariants {
352 string Default = "Default";
353 int Default_ID = 0;
354 string VOP3 = "VOP3";
355 int VOP3_ID = 1;
356 string SDWA = "SDWA";
357 int SDWA_ID = 2;
358 string DPP = "DPP";
359 int DPP_ID = 3;
360 }
361
362 def DefaultAMDGPUAsmParserVariant : AsmParserVariant {
363 let Variant = AMDGPUAsmVariants.Default_ID;
364 let Name = AMDGPUAsmVariants.Default;
365 }
366
367 def VOP3AsmParserVariant : AsmParserVariant {
368 let Variant = AMDGPUAsmVariants.VOP3_ID;
369 let Name = AMDGPUAsmVariants.VOP3;
370 }
371
372 def SDWAAsmParserVariant : AsmParserVariant {
373 let Variant = AMDGPUAsmVariants.SDWA_ID;
374 let Name = AMDGPUAsmVariants.SDWA;
375 }
376
377 def DPPAsmParserVariant : AsmParserVariant {
378 let Variant = AMDGPUAsmVariants.DPP_ID;
379 let Name = AMDGPUAsmVariants.DPP;
380 }
381
351382 def AMDGPU : Target {
352383 // Pull in Instruction Info:
353384 let InstructionSet = AMDGPUInstrInfo;
354385 let AssemblyParsers = [AMDGPUAsmParser];
386 let AssemblyParserVariants = [DefaultAMDGPUAsmParserVariant,
387 VOP3AsmParserVariant,
388 SDWAAsmParserVariant,
389 DPPAsmParserVariant];
355390 }
356391
357392 // Dummy Instruction itineraries for pseudo instructions
11461146 MCStreamer &Out,
11471147 uint64_t &ErrorInfo,
11481148 bool MatchingInlineAsm) {
1149 // What asm variants we should check
1150 std::vector MatchedVariants;
1151 if (getForcedEncodingSize() == 32) {
1152 MatchedVariants = {AMDGPUAsmVariants::DEFAULT};
1153 } else if (isForcedVOP3()) {
1154 MatchedVariants = {AMDGPUAsmVariants::VOP3};
1155 } else if (isForcedSDWA()) {
1156 MatchedVariants = {AMDGPUAsmVariants::SDWA};
1157 } else if (isForcedDPP()) {
1158 MatchedVariants = {AMDGPUAsmVariants::DPP};
1159 } else {
1160 MatchedVariants = {AMDGPUAsmVariants::DEFAULT,
1161 AMDGPUAsmVariants::VOP3,
1162 AMDGPUAsmVariants::SDWA,
1163 AMDGPUAsmVariants::DPP};
1164 }
1165
11491166 MCInst Inst;
1150
1151 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
1152 default: break;
1153 case Match_Success:
1154 Inst.setLoc(IDLoc);
1155 Out.EmitInstruction(Inst, getSTI());
1156 return false;
1157 case Match_MissingFeature:
1158 return Error(IDLoc, "instruction not supported on this GPU");
1159
1160 case Match_MnemonicFail:
1161 return Error(IDLoc, "unrecognized instruction mnemonic");
1162
1163 case Match_InvalidOperand: {
1164 SMLoc ErrorLoc = IDLoc;
1165 if (ErrorInfo != ~0ULL) {
1166 if (ErrorInfo >= Operands.size()) {
1167 return Error(IDLoc, "too few operands for instruction");
1168 }
1169 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
1170 if (ErrorLoc == SMLoc())
1171 ErrorLoc = IDLoc;
1167 unsigned Result = Match_Success;
1168 for (auto Variant : MatchedVariants) {
1169 uint64_t EI;
1170 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
1171 Variant);
1172 // We order match statuses from least to most specific. We use most specific
1173 // status as resulting
1174 // Match_MnemonicFail < Match_InvalidOperand < Match_MissingFeature < Match_PreferE32
1175 if ((R == Match_Success) ||
1176 (R == Match_PreferE32) ||
1177 (R == Match_MissingFeature && Result != Match_PreferE32) ||
1178 (R == Match_InvalidOperand && Result != Match_MissingFeature
1179 && Result != Match_PreferE32) ||
1180 (R == Match_MnemonicFail && Result != Match_InvalidOperand
1181 && Result != Match_MissingFeature
1182 && Result != Match_PreferE32)) {
1183 Result = R;
1184 ErrorInfo = EI;
1185 }
1186 if (R == Match_Success)
1187 break;
1188 }
1189
1190 switch (Result) {
1191 default: break;
1192 case Match_Success:
1193 Inst.setLoc(IDLoc);
1194 Out.EmitInstruction(Inst, getSTI());
1195 return false;
1196
1197 case Match_MissingFeature:
1198 return Error(IDLoc, "instruction not supported on this GPU");
1199
1200 case Match_MnemonicFail:
1201 return Error(IDLoc, "unrecognized instruction mnemonic");
1202
1203 case Match_InvalidOperand: {
1204 SMLoc ErrorLoc = IDLoc;
1205 if (ErrorInfo != ~0ULL) {
1206 if (ErrorInfo >= Operands.size()) {
1207 return Error(IDLoc, "too few operands for instruction");
11721208 }
1173 return Error(ErrorLoc, "invalid operand for instruction");
1174 }
1175 case Match_PreferE32:
1176 return Error(IDLoc, "internal error: instruction without _e64 suffix "
1177 "should be encoded as e32");
1209 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
1210 if (ErrorLoc == SMLoc())
1211 ErrorLoc = IDLoc;
1212 }
1213 return Error(ErrorLoc, "invalid operand for instruction");
1214 }
1215
1216 case Match_PreferE32:
1217 return Error(IDLoc, "internal error: instruction without _e64 suffix "
1218 "should be encoded as e32");
11781219 }
11791220 llvm_unreachable("Implement any new match types added!");
11801221 }
101101 MUL2 = 1,
102102 MUL4 = 2,
103103 DIV2 = 3
104 };
105 }
106
107 namespace AMDGPUAsmVariants {
108 enum {
109 DEFAULT = 0,
110 VOP3 = 1,
111 SDWA = 2,
112 DPP = 3
104113 };
105114 }
106115
9494 field bits<1> DisableDecoder = 0;
9595
9696 let isAsmParserOnly = !if(!eq(DisableDecoder{0}, {0}), 0, 1);
97 let AsmVariantName = AMDGPUAsmVariants.Default;
9798 }
9899
99100 class PseudoInstSI pattern = []>
185186 !if(!eq(VOP3Only,1),
186187 "cvtVOP3",
187188 !if(!eq(HasMods,1), "cvtVOP3_2_mod", ""));
189
190 let AsmVariantName = AMDGPUAsmVariants.VOP3;
188191
189192 let isCodeGenOnly = 0;
190193
11091109 def VOP_I64_I64_I32_I64 : VOPProfile <[i64, i64, i32, i64]>;
11101110
11111111 // This class is used only with VOPC instructions. Use $sdst for out operand
1112 class SIInstAlias > :
1112 class SIInstAlias ,
1113 string VariantName = ""> :
11131114 InstAlias , PredicateControl {
11141115
11151116 field bit isCompare;
11381139 // else
11391140 // 0 dst, 0 src
11401141 (inst))));
1141 }
1142
1143 class SIInstAliasSI :
1144 SIInstAlias (op_name#"_e32_si"), p> {
1142
1143 let AsmVariantName = VariantName;
1144 }
1145
1146 class SIInstAliasSI :
1147 SIInstAlias (op_name#"_e32_si"), p, VariantName> {
11451148 let AssemblerPredicate = SIAssemblerPredicate;
11461149 }
11471150
1148 class SIInstAliasVI :
1149 SIInstAlias (op_name#"_e32_vi"), p> {
1151 class SIInstAliasVI :
1152 SIInstAlias (op_name#"_e32_vi"), p, VariantName> {
11501153 let AssemblerPredicates = [isVI];
11511154 }
11521155
1153 multiclass SIInstAliasBuilder {
1154
1155 def : SIInstAliasSI ;
1156
1157 def : SIInstAliasVI ;
1156 multiclass SIInstAliasBuilder {
1157
1158 def : SIInstAliasSI ;
1159
1160 def : SIInstAliasVI ;
11581161 }
11591162
11601163 class VOP {
18171820
18181821 } // End AssemblerPredicates = [isVI]
18191822
1820 defm : SIInstAliasBuilder>;
1823 defm : SIInstAliasBuilder, AMDGPUAsmVariants.Default>;
18211824 }
18221825
18231826 multiclass VOPC_Helper pat32,
139139 let Size = 8;
140140
141141 let AsmMatchConverter = !if(!eq(HasMods,1), "cvtDPP", "");
142 let AsmVariantName = AMDGPUAsmVariants.DPP;
142143 }
143144
144145 class VOP_DPPe : Enc64 {
185186 VOPAnyCommon {
186187 let SDWA = 1;
187188 let Size = 8;
189 let AsmVariantName = AMDGPUAsmVariants.SDWA;
188190 }
189191
190192 class VOP_SDWAe : Enc64 {
9292 (inst VGPR_32:$dst, 0, VCSrc_32:$src0, 0, VCSrc_32:$src1, 0, 0)
9393 >, PredicateControl {
9494 let UseInstAsmMatchConverter = 0;
95 let AsmVariantName = AMDGPUAsmVariants.VOP3;
9596 }
9697
9798 def : SI2_VI3Alias <"v_ldexp_f32", V_LDEXP_F32_e64_vi>;