llvm.org GIT mirror llvm / 5d5019b
Use bitset for assembler predicates AMDGPU target run out of Subtarget feature flags hitting the limit of 64. AssemblerPredicates uses at most uint64_t for their representation. At the same time CodeGen has exhausted this a long time ago and switched to a FeatureBitset with the current limit of 192 bits. This patch completes transition to the bitset for feature bits extending it to asm matcher and MC code emitter. Differential Revision: https://reviews.llvm.org/D59002 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355839 91177308-0d34-0410-b5e6-96231b3b80d8 Stanislav Mekhanoshin 1 year, 4 months ago
23 changed file(s) with 412 addition(s) and 246 deletion(s). Raw diff Collapse all Expand all
1515 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
1616 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
1717 #include "llvm/MC/MCTargetOptions.h"
18 #include "llvm/MC/SubtargetFeature.h"
1819 #include "llvm/Support/SMLoc.h"
1920 #include
2021 #include
201202 // The instruction encoding is not valid because it requires some target
202203 // features that are not currently enabled. MissingFeatures has a bit set for
203204 // each feature that the encoding needs but which is not enabled.
204 static NearMissInfo getMissedFeature(uint64_t MissingFeatures) {
205 static NearMissInfo getMissedFeature(const FeatureBitset &MissingFeatures) {
205206 NearMissInfo Result;
206207 Result.Kind = NearMissFeature;
207208 Result.Features = MissingFeatures;
253254
254255 // Feature flags required by the instruction, that the current target does
255256 // not have.
256 uint64_t getFeatures() const {
257 const FeatureBitset& getFeatures() const {
257258 assert(Kind == NearMissFeature);
258259 return Features;
259260 }
303304 };
304305
305306 union {
306 uint64_t Features;
307 FeatureBitset Features;
307308 unsigned PredicateError;
308309 MissedOpInfo MissedOperand;
309310 TooFewOperandsInfo TooFewOperands;
333334 MCSubtargetInfo ©STI();
334335
335336 /// AvailableFeatures - The current set of available features.
336 uint64_t AvailableFeatures = 0;
337 FeatureBitset AvailableFeatures;
337338
338339 /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
339340 bool ParsingInlineAsm = false;
358359
359360 const MCSubtargetInfo &getSTI() const;
360361
361 uint64_t getAvailableFeatures() const { return AvailableFeatures; }
362 void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
362 const FeatureBitset& getAvailableFeatures() const {
363 return AvailableFeatures;
364 }
365 void setAvailableFeatures(const FeatureBitset& Value) {
366 AvailableFeatures = Value;
367 }
363368
364369 bool isParsingInlineAsm () { return ParsingInlineAsm; }
365370 void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
4444 FeatureBitset(std::initializer_list Init) {
4545 for (auto I : Init)
4646 set(I);
47 }
48
49 bool operator < (const FeatureBitset &Other) const {
50 for (unsigned I = 0, E = size(); I != E; ++I) {
51 bool LHS = test(I), RHS = Other.test(I);
52 if (LHS != RHS)
53 return LHS < RHS;
54 }
55 return false;
4756 }
4857 };
4958
41654165 }
41664166 }
41674167
4168 static std::string AArch64MnemonicSpellCheck(StringRef S, uint64_t FBS,
4168 static std::string AArch64MnemonicSpellCheck(StringRef S,
4169 const FeatureBitset &FBS,
41694170 unsigned VariantID = 0);
41704171
41714172 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
47754776 }
47764777
47774778 MCInst Inst;
4779 FeatureBitset MissingFeatures;
47784780 // First try to match against the secondary set of tables containing the
47794781 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
47804782 unsigned MatchResult =
4781 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
4783 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
4784 MatchingInlineAsm, 1);
47824785
47834786 // If that fails, try against the alternate table containing long-form NEON:
47844787 // "fadd v0.2s, v1.2s, v2.2s"
47874790 // long-form match also fails.
47884791 auto ShortFormNEONErrorInfo = ErrorInfo;
47894792 auto ShortFormNEONMatchResult = MatchResult;
4793 auto ShortFormNEONMissingFeatures = MissingFeatures;
47904794
47914795 MatchResult =
4792 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
4796 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
4797 MatchingInlineAsm, 0);
47934798
47944799 // Now, both matches failed, and the long-form match failed on the mnemonic
47954800 // suffix token operand. The short-form match failure is probably more
47994804 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
48004805 MatchResult = ShortFormNEONMatchResult;
48014806 ErrorInfo = ShortFormNEONErrorInfo;
4807 MissingFeatures = ShortFormNEONMissingFeatures;
48024808 }
48034809 }
48044810
48174823 return false;
48184824 }
48194825 case Match_MissingFeature: {
4820 assert(ErrorInfo && "Unknown missing feature!");
4826 assert(MissingFeatures.any() && "Unknown missing feature!");
48214827 // Special case the error message for the very common case where only
48224828 // a single subtarget feature is missing (neon, e.g.).
48234829 std::string Msg = "instruction requires:";
4824 uint64_t Mask = 1;
4825 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
4826 if (ErrorInfo & Mask) {
4830 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
4831 if (MissingFeatures[i]) {
48274832 Msg += " ";
4828 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
4833 Msg += getSubtargetFeatureName(i);
48294834 }
4830 Mask <<= 1;
48314835 }
48324836 return Error(IDLoc, Msg);
48334837 }
51465150 FeatureBitset ToggleFeatures = EnableFeature
51475151 ? (~Features & Extension.Features)
51485152 : ( Features & Extension.Features);
5149 uint64_t Features =
5153 FeatureBitset Features =
51505154 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
51515155 setAvailableFeatures(Features);
51525156 break;
51905194 FeatureBitset ToggleFeatures = EnableFeature
51915195 ? (~Features & Extension.Features)
51925196 : (Features & Extension.Features);
5193 uint64_t Features =
5197 FeatureBitset Features =
51945198 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
51955199 setAvailableFeatures(Features);
51965200 return false;
52555259 FeatureBitset ToggleFeatures = EnableFeature
52565260 ? (~Features & Extension.Features)
52575261 : ( Features & Extension.Features);
5258 uint64_t Features =
5262 FeatureBitset Features =
52595263 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
52605264 setAvailableFeatures(Features);
52615265 FoundExtension = true;
186186 const MCSubtargetInfo &STI) const;
187187
188188 private:
189 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
190 void verifyInstructionPredicates(const MCInst &MI,
191 uint64_t AvailableFeatures) const;
189 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
190 void
191 verifyInstructionPredicates(const MCInst &MI,
192 const FeatureBitset &AvailableFeatures) const;
192193 };
193194
194195 } // end anonymous namespace
26702670 return true;
26712671 }
26722672
2673 static std::string AMDGPUMnemonicSpellCheck(StringRef S, uint64_t FBS,
2673 static std::string AMDGPUMnemonicSpellCheck(StringRef S,
2674 const FeatureBitset &FBS,
26742675 unsigned VariantID = 0);
26752676
26762677 bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
27162717 return Error(IDLoc, "instruction not supported on this GPU");
27172718
27182719 case Match_MnemonicFail: {
2719 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
2720 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
27202721 std::string Suggestion = AMDGPUMnemonicSpellCheck(
27212722 ((AMDGPUOperand &)*Operands[0]).getToken(), FBS);
27222723 return Error(IDLoc, "invalid instruction" + Suggestion,
6363 }
6464
6565 protected:
66 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
67 void verifyInstructionPredicates(const MCInst &MI,
68 uint64_t AvailableFeatures) const;
66 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
67 void
68 verifyInstructionPredicates(const MCInst &MI,
69 const FeatureBitset &AvailableFeatures) const;
6970 };
7071
7172 } // End namespace llvm
6363 uint64_t getBinaryCodeForInstr(const MCInst &MI,
6464 SmallVectorImpl &Fixups,
6565 const MCSubtargetInfo &STI) const;
66 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
67 void verifyInstructionPredicates(const MCInst &MI,
68 uint64_t AvailableFeatures) const;
66 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
67 void
68 verifyInstructionPredicates(const MCInst &MI,
69 const FeatureBitset &AvailableFeatures) const;
6970
7071 };
7172
503503
504504 void SwitchMode() {
505505 MCSubtargetInfo &STI = copySTI();
506 uint64_t FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
506 auto FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
507507 setAvailableFeatures(FB);
508508 }
509509
60086008 return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
60096009 }
60106010
6011 static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
6011 static void applyMnemonicAliases(StringRef &Mnemonic,
6012 const FeatureBitset &Features,
60126013 unsigned VariantID);
60136014
60146015 // The GNU assembler has aliases of ldrd and strd with the second register
60666067 // The generic tblgen'erated code does this later, at the start of
60676068 // MatchInstructionImpl(), but that's too late for aliases that include
60686069 // any sort of suffix.
6069 uint64_t AvailableFeatures = getAvailableFeatures();
6070 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
60706071 unsigned AssemblerDialect = getParser().getAssemblerDialect();
60716072 applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect);
60726073
92789279 return PlainMatchResult;
92799280 }
92809281
9281 static std::string ARMMnemonicSpellCheck(StringRef S, uint64_t FBS,
9282 static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
92829283 unsigned VariantID = 0);
92839284
92849285 static const char *getSubtargetFeatureName(uint64_t Val);
93519352 ReportNearMisses(NearMisses, IDLoc, Operands);
93529353 return true;
93539354 case Match_MnemonicFail: {
9354 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
9355 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
93559356 std::string Suggestion = ARMMnemonicSpellCheck(
93569357 ((ARMOperand &)*Operands[0]).getToken(), FBS);
93579358 return Error(IDLoc, "invalid instruction" + Suggestion,
1042610427 // variants of an instruction that take 8- and 16-bit immediates, we want
1042710428 // to only report the widest one.
1042810429 std::multimap OperandMissesSeen;
10429 SmallSet<uint64_t, 4> FeatureMissesSeen;
10430 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1043010431 bool ReportedTooFewOperands = false;
1043110432
1043210433 // Process the near-misses in reverse order, so that we see more general ones
1047710478 break;
1047810479 }
1047910480 case NearMissInfo::NearMissFeature: {
10480 uint64_t MissingFeatures = I.getFeatures();
10481 const FeatureBitset &MissingFeatures = I.getFeatures();
1048110482 // Don't report the same set of features twice.
1048210483 if (FeatureMissesSeen.count(MissingFeatures))
1048310484 break;
1048510486
1048610487 // Special case: don't report a feature set which includes arm-mode for
1048710488 // targets that don't have ARM mode.
10488 if ((MissingFeatures & Feature_IsARM) && !hasARM())
10489 if (MissingFeatures.test(Feature_IsARMBit) && !hasARM())
1048910490 break;
1049010491 // Don't report any near-misses that both require switching instruction
1049110492 // set, and adding other subtarget features.
10492 if (isThumb() && (MissingFeatures & Feature_IsARM) &&
10493 (MissingFeatures & ~Feature_IsARM))
10493 if (isThumb() && MissingFeatures.test(Feature_IsARMBit) &&
10494 MissingFeatures.count() > 1)
1049410495 break;
10495 if (!isThumb() && (MissingFeatures & Feature_IsThumb) &&
10496 (MissingFeatures & ~Feature_IsThumb))
10496 if (!isThumb() && MissingFeatures.test(Feature_IsThumbBit) &&
10497 MissingFeatures.count() > 1)
1049710498 break;
10498 if (!isThumb() && (MissingFeatures & Feature_IsThumb2) &&
10499 (MissingFeatures & ~(Feature_IsThumb2 | Feature_IsThumb)))
10499 if (!isThumb() && MissingFeatures.test(Feature_IsThumb2Bit) &&
10500 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
10501 Feature_IsThumbBit})).any())
1050010502 break;
10501 if (isMClass() && (MissingFeatures & Feature_HasNEON))
10503 if (isMClass() && MissingFeatures.test(Feature_HasNEONBit))
1050210504 break;
1050310505
1050410506 NearMissMessage Message;
1050610508 raw_svector_ostream OS(Message.Message);
1050710509
1050810510 OS << "instruction requires:";
10509 uint64_t Mask = 1;
10510 for (unsigned MaskPos = 0; MaskPos < (sizeof(MissingFeatures) * 8 - 1);
10511 ++MaskPos) {
10512 if (MissingFeatures & Mask) {
10513 OS << " " << getSubtargetFeatureName(MissingFeatures & Mask);
10514 }
10515 Mask <<= 1;
10516 }
10511 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)
10512 if (MissingFeatures.test(i))
10513 OS << ' ' << getSubtargetFeatureName(i);
10514
1051710515 NearMissesOut.emplace_back(Message);
1051810516
1051910517 break;
1058910587 }
1059010588 }
1059110589
10592 // FIXME: This structure should be moved inside ARMTargetParser
10593 // when we start to table-generate them, and we can use the ARM
10594 // flags below, that were generated by table-gen.
10595 static const struct {
10596 const unsigned Kind;
10597 const uint64_t ArchCheck;
10598 const FeatureBitset Features;
10599 } Extensions[] = {
10600 { ARM::AEK_CRC, Feature_HasV8, {ARM::FeatureCRC} },
10601 { ARM::AEK_CRYPTO, Feature_HasV8,
10602 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10603 { ARM::AEK_FP, Feature_HasV8, {ARM::FeatureFPARMv8} },
10604 { (ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM), Feature_HasV7 | Feature_IsNotMClass,
10605 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM} },
10606 { ARM::AEK_MP, Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
10607 { ARM::AEK_SIMD, Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10608 { ARM::AEK_SEC, Feature_HasV6K, {ARM::FeatureTrustZone} },
10609 // FIXME: Only available in A-class, isel not predicated
10610 { ARM::AEK_VIRT, Feature_HasV7, {ARM::FeatureVirtualization} },
10611 { ARM::AEK_FP16, Feature_HasV8_2a, {ARM::FeatureFPARMv8, ARM::FeatureFullFP16} },
10612 { ARM::AEK_RAS, Feature_HasV8, {ARM::FeatureRAS} },
10613 // FIXME: Unsupported extensions.
10614 { ARM::AEK_OS, Feature_None, {} },
10615 { ARM::AEK_IWMMXT, Feature_None, {} },
10616 { ARM::AEK_IWMMXT2, Feature_None, {} },
10617 { ARM::AEK_MAVERICK, Feature_None, {} },
10618 { ARM::AEK_XSCALE, Feature_None, {} },
10619 };
10620
1062110590 /// parseDirectiveArchExtension
1062210591 /// ::= .arch_extension [no]feature
1062310592 bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
10593 // FIXME: This structure should be moved inside ARMTargetParser
10594 // when we start to table-generate them, and we can use the ARM
10595 // flags below, that were generated by table-gen.
10596 static const struct {
10597 const unsigned Kind;
10598 const FeatureBitset ArchCheck;
10599 const FeatureBitset Features;
10600 } Extensions[] = {
10601 { ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC} },
10602 { ARM::AEK_CRYPTO, {Feature_HasV8Bit},
10603 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10604 { ARM::AEK_FP, {Feature_HasV8Bit}, {ARM::FeatureFPARMv8} },
10605 { (ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM),
10606 {Feature_HasV7Bit, Feature_IsNotMClassBit},
10607 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM} },
10608 { ARM::AEK_MP, {Feature_HasV7Bit, Feature_IsNotMClassBit},
10609 {ARM::FeatureMP} },
10610 { ARM::AEK_SIMD, {Feature_HasV8Bit},
10611 {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10612 { ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone} },
10613 // FIXME: Only available in A-class, isel not predicated
10614 { ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization} },
10615 { ARM::AEK_FP16, {Feature_HasV8_2aBit},
10616 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16} },
10617 { ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS} },
10618 // FIXME: Unsupported extensions.
10619 { ARM::AEK_OS, {}, {} },
10620 { ARM::AEK_IWMMXT, {}, {} },
10621 { ARM::AEK_IWMMXT2, {}, {} },
10622 { ARM::AEK_MAVERICK, {}, {} },
10623 { ARM::AEK_XSCALE, {}, {} },
10624 };
10625
1062410626 MCAsmParser &Parser = getParser();
1062510627
1062610628 if (getLexer().isNot(AsmToken::Identifier))
1066010662 ? (~STI.getFeatureBits() & Extension.Features)
1066110663 : ( STI.getFeatureBits() & Extension.Features);
1066210664
10663 uint64_t Features =
10665 FeatureBitset Features =
1066410666 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
1066510667 setAvailableFeatures(Features);
1066610668 return false;
6262 const MCSubtargetInfo &STI) const override;
6363
6464 private:
65 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
66 void verifyInstructionPredicates(const MCInst &MI,
67 uint64_t AvailableFeatures) const;
65 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
66 void
67 verifyInstructionPredicates(const MCInst &MI,
68 const FeatureBitset &AvailableFeatures) const;
6869 };
6970
7071 } // end anonymous namespace
376376 State.Bundle = &MI;
377377 State.Index = 0;
378378 size_t Last = HexagonMCInstrInfo::bundleSize(HMB) - 1;
379 uint64_t Features = computeAvailableFeatures(STI.getFeatureBits());
379 FeatureBitset Features = computeAvailableFeatures(STI.getFeatureBits());
380380
381381 for (auto &I : HexagonMCInstrInfo::bundleInstructions(HMB)) {
382382 MCInst &HMI = const_cast(*I.getInst());
8181 // Return parse bits for instruction `MCI' inside bundle `MCB'
8282 uint32_t parseBits(size_t Last, MCInst const &MCB, MCInst const &MCI) const;
8383
84 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
85 void verifyInstructionPredicates(const MCInst &MI,
86 uint64_t AvailableFeatures) const;
84 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
85 void
86 verifyInstructionPredicates(const MCInst &MI,
87 const FeatureBitset &AvailableFeatures) const;
8788 };
8889
8990 } // end namespace llvm
63206320 return false;
63216321 }
63226322
6323 static std::string MipsMnemonicSpellCheck(StringRef S, uint64_t FBS,
6323 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
63246324 unsigned VariantID = 0);
63256325
63266326 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
63336333
63346334 // Check if we have valid mnemonic
63356335 if (!mnemonicIsValid(Name, 0)) {
6336 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6336 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
63376337 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
63386338 return Error(NameLoc, "unknown instruction" + Suggestion);
63396339 }
11271127 }
11281128 }
11291129
1130 static std::string PPCMnemonicSpellCheck(StringRef S, uint64_t FBS,
1130 static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
11311131 unsigned VariantID = 0);
11321132
11331133 bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
11461146 case Match_MissingFeature:
11471147 return Error(IDLoc, "instruction use requires an option to be enabled");
11481148 case Match_MnemonicFail: {
1149 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1149 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11501150 std::string Suggestion = PPCMnemonicSpellCheck(
11511151 ((PPCOperand &)*Operands[0]).getToken(), FBS);
11521152 return Error(IDLoc, "invalid instruction" + Suggestion,
9797 unsigned getInstSizeInBytes(const MCInst &MI) const;
9898
9999 private:
100 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
101 void verifyInstructionPredicates(const MCInst &MI,
102 uint64_t AvailableFeatures) const;
100 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
101 void
102 verifyInstructionPredicates(const MCInst &MI,
103 const FeatureBitset &AvailableFeatures) const;
103104 };
104105
105106 } // namespace llvm
644644 return Error(StartLoc, "invalid register name");
645645 }
646646
647 static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
647 static void applyMnemonicAliases(StringRef &Mnemonic,
648 const FeatureBitset &Features,
648649 unsigned VariantID);
649650
650651 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
8282 const MCSubtargetInfo &STI) const;
8383
8484 private:
85 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
86 void verifyInstructionPredicates(const MCInst &MI,
87 uint64_t AvailableFeatures) const;
85 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
86 void
87 verifyInstructionPredicates(const MCInst &MI,
88 const FeatureBitset &AvailableFeatures) const;
8889 };
8990
9091 } // end anonymous namespace
11791179 // features to be available during the operand check, or else we will fail to
11801180 // find the custom parser, and then we will later get an InvalidOperand error
11811181 // instead of a MissingFeature errror.
1182 uint64_t AvailableFeatures = getAvailableFeatures();
1183 setAvailableFeatures(~(uint64_t)0);
1182 FeatureBitset AvailableFeatures = getAvailableFeatures();
1183 FeatureBitset All;
1184 All.set();
1185 setAvailableFeatures(All);
11841186 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
11851187 setAvailableFeatures(AvailableFeatures);
11861188 if (ResTy == MatchOperand_Success)
12311233 return false;
12321234 }
12331235
1234 static std::string SystemZMnemonicSpellCheck(StringRef S, uint64_t FBS,
1236 static std::string SystemZMnemonicSpellCheck(StringRef S,
1237 const FeatureBitset &FBS,
12351238 unsigned VariantID = 0);
12361239
12371240 bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
12421245 MCInst Inst;
12431246 unsigned MatchResult;
12441247
1248 FeatureBitset MissingFeatures;
12451249 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
1246 MatchingInlineAsm);
1250 MissingFeatures, MatchingInlineAsm);
12471251 switch (MatchResult) {
12481252 case Match_Success:
12491253 Inst.setLoc(IDLoc);
12511255 return false;
12521256
12531257 case Match_MissingFeature: {
1254 assert(ErrorInfo && "Unknown missing feature!");
1258 assert(MissingFeatures.any() && "Unknown missing feature!");
12551259 // Special case the error message for the very common case where only
12561260 // a single subtarget feature is missing
12571261 std::string Msg = "instruction requires:";
1258 uint64_t Mask = 1;
1259 for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
1260 if (ErrorInfo & Mask) {
1262 for (unsigned I = 0, E = MissingFeatures.size(); I != E; ++I) {
1263 if (MissingFeatures[I]) {
12611264 Msg += " ";
1262 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
1265 Msg += getSubtargetFeatureName(I);
12631266 }
1264 Mask <<= 1;
12651267 }
12661268 return Error(IDLoc, Msg);
12671269 }
12801282 }
12811283
12821284 case Match_MnemonicFail: {
1283 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1285 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
12841286 std::string Suggestion = SystemZMnemonicSpellCheck(
12851287 ((SystemZOperand &)*Operands[0]).getToken(), FBS);
12861288 return Error(IDLoc, "invalid instruction" + Suggestion,
142142 }
143143
144144 private:
145 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
146 void verifyInstructionPredicates(const MCInst &MI,
147 uint64_t AvailableFeatures) const;
145 FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
146 void
147 verifyInstructionPredicates(const MCInst &MI,
148 const FeatureBitset &AvailableFeatures) const;
148149 };
149150
150151 } // end anonymous namespace
8888 }
8989
9090 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
91 uint64_t &ErrorInfo, bool matchingInlineAsm,
92 unsigned VariantID = 0) {
91 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
92 bool matchingInlineAsm, unsigned VariantID = 0) {
9393 // In Code16GCC mode, match as 32-bit.
9494 if (Code16GCC)
9595 SwitchMode(X86::Mode32Bit);
9696 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
97 matchingInlineAsm, VariantID);
97 MissingFeatures, matchingInlineAsm,
98 VariantID);
9899 if (Code16GCC)
99100 SwitchMode(X86::Mode16Bit);
100101 return rv;
873874 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
874875 MCStreamer &Out, bool MatchingInlineAsm);
875876
876 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
877 bool ErrorMissingFeature(SMLoc IDLoc, const FeatureBitset &MissingFeatures,
877878 bool MatchingInlineAsm);
878879
879880 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
912913 MCSubtargetInfo &STI = copySTI();
913914 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit});
914915 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
915 uint64_t FB = ComputeAvailableFeatures(
916 FeatureBitset FB = ComputeAvailableFeatures(
916917 STI.ToggleFeature(OldMode.flip(mode)));
917918 setAvailableFeatures(FB);
918919
29052906 }
29062907 }
29072908
2908 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo,
2909 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
2910 const FeatureBitset &MissingFeatures,
29092911 bool MatchingInlineAsm) {
2910 assert(ErrorInfo && "Unknown missing feature!");
2912 assert(MissingFeatures.any() && "Unknown missing feature!");
29112913 SmallString<126> Msg;
29122914 raw_svector_ostream OS(Msg);
29132915 OS << "instruction requires:";
2914 uint64_t Mask = 1;
2915 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
2916 if (ErrorInfo & Mask)
2917 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask);
2918 Mask <<= 1;
2916 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
2917 if (MissingFeatures[i])
2918 OS << ' ' << getSubtargetFeatureName(i);
29192919 }
29202920 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
29212921 }
29522952 Inst.setFlags(Prefixes);
29532953
29542954 // First, try a direct match.
2955 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2956 isParsingIntelSyntax())) {
2955 FeatureBitset MissingFeatures;
2956 switch (MatchInstruction(Operands, Inst, ErrorInfo, MissingFeatures,
2957 MatchingInlineAsm, isParsingIntelSyntax())) {
29572958 default: llvm_unreachable("Unexpected match result!");
29582959 case Match_Success:
29592960 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
29712972 Opcode = Inst.getOpcode();
29722973 return false;
29732974 case Match_MissingFeature:
2974 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm);
2975 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
29752976 case Match_InvalidOperand:
29762977 WasOriginallyInvalidOperand = true;
29772978 break;
30013002
30023003 // Check for the various suffix matches.
30033004 uint64_t ErrorInfoIgnore;
3004 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
3005 FeatureBitset ErrorInfoMissingFeatures; // Init suppresses compiler warnings.
30053006 unsigned Match[4];
30063007
30073008 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
30083009 Tmp.back() = Suffixes[I];
30093010 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3010 MatchingInlineAsm, isParsingIntelSyntax());
3011 MissingFeatures, MatchingInlineAsm,
3012 isParsingIntelSyntax());
30113013 // If this returned as a missing feature failure, remember that.
30123014 if (Match[I] == Match_MissingFeature)
3013 ErrorInfoMissingFeature = ErrorInfoIgnore;
3015 ErrorInfoMissingFeatures = MissingFeatures;
30143016 }
30153017
30163018 // Restore the old token.
30873089 // missing feature.
30883090 if (std::count(std::begin(Match), std::end(Match),
30893091 Match_MissingFeature) == 1) {
3090 ErrorInfo = ErrorInfoMissingFeature;
3091 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3092 ErrorInfo = Match_MissingFeature;
3093 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
30923094 MatchingInlineAsm);
30933095 }
30943096
31523154 }
31533155
31543156 SmallVector Match;
3155 uint64_t ErrorInfoMissingFeature = 0;
3157 FeatureBitset ErrorInfoMissingFeatures;
3158 FeatureBitset MissingFeatures;
31563159
31573160 // If unsized push has immediate operand we should default the default pointer
31583161 // size for the size.
31723175 Op.setTokenValue(Tmp);
31733176 // Do match in ATT mode to allow explicit suffix usage.
31743177 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
3175 MatchingInlineAsm,
3178 MissingFeatures, MatchingInlineAsm,
31763179 false /*isParsingIntelSyntax()*/));
31773180 Op.setTokenValue(Base);
31783181 }
31893192 uint64_t ErrorInfoIgnore;
31903193 unsigned LastOpcode = Inst.getOpcode();
31913194 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
3192 MatchingInlineAsm, isParsingIntelSyntax());
3195 MissingFeatures, MatchingInlineAsm,
3196 isParsingIntelSyntax());
31933197 if (Match.empty() || LastOpcode != Inst.getOpcode())
31943198 Match.push_back(M);
31953199
31963200 // If this returned as a missing feature failure, remember that.
31973201 if (Match.back() == Match_MissingFeature)
3198 ErrorInfoMissingFeature = ErrorInfoIgnore;
3202 ErrorInfoMissingFeatures = MissingFeatures;
31993203 }
32003204
32013205 // Restore the size of the unsized memory operand if we modified it.
32073211 // matching with the unsized operand.
32083212 if (Match.empty()) {
32093213 Match.push_back(MatchInstruction(
3210 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
3214 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
3215 isParsingIntelSyntax()));
32113216 // If this returned as a missing feature failure, remember that.
32123217 if (Match.back() == Match_MissingFeature)
3213 ErrorInfoMissingFeature = ErrorInfo;
3218 ErrorInfoMissingFeatures = MissingFeatures;
32143219 }
32153220
32163221 // Restore the size of the unsized memory operand if we modified it.
32323237 UnsizedMemOp->getMemFrontendSize()) {
32333238 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
32343239 unsigned M = MatchInstruction(
3235 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax());
3240 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
3241 isParsingIntelSyntax());
32363242 if (M == Match_Success)
32373243 NumSuccessfulMatches = 1;
32383244
32723278 // missing feature.
32733279 if (std::count(std::begin(Match), std::end(Match),
32743280 Match_MissingFeature) == 1) {
3275 ErrorInfo = ErrorInfoMissingFeature;
3276 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature,
3281 ErrorInfo = Match_MissingFeature;
3282 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
32773283 MatchingInlineAsm);
32783284 }
32793285
14721472 for (const auto &Pair : SubtargetFeatures)
14731473 LLVM_DEBUG(Pair.second.dump());
14741474 #endif // NDEBUG
1475 assert(SubtargetFeatures.size() <= 64 && "Too many subtarget features!");
14761475
14771476 bool HasMnemonicFirst = AsmParser->getValueAsBit("HasMnemonicFirst");
14781477 bool ReportMultipleNearMisses =
26742673 for (const auto &SF : Info.SubtargetFeatures) {
26752674 const SubtargetFeatureInfo &SFI = SF.second;
26762675 // FIXME: Totally just a placeholder name to get the algorithm working.
2677 OS << " case " << SFI.getEnumName() << ": return \""
2676 OS << " case " << SFI.getEnumBitName() << ": return \""
26782677 << SFI.TheDef->getValueAsString("PredicateName") << "\";\n";
26792678 }
26802679 OS << " default: return \"(unknown)\";\n";
26902689 const AsmMatcherInfo &Info) {
26912690 std::vector ReqFeatures = R->getValueAsListOfDefs("Predicates");
26922691 std::string Result;
2693 unsigned NumFeatures = 0;
2692
2693 if (ReqFeatures.empty())
2694 return Result;
2695
26942696 for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) {
26952697 const SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]);
26962698
26982700 PrintFatalError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() +
26992701 "' is not marked as an AssemblerPredicate!");
27002702
2701 if (NumFeatures)
2702 Result += '|';
2703
2704 Result += F->getEnumName();
2705 ++NumFeatures;
2706 }
2707
2708 if (NumFeatures > 1)
2709 Result = '(' + Result + ')';
2703 if (i)
2704 Result += " && ";
2705
2706 Result += "Features.test(" + F->getEnumBitName() + ')';
2707 }
2708
27102709 return Result;
27112710 }
27122711
27622761
27632762 if (!MatchCode.empty())
27642763 MatchCode += "else ";
2765 MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n";
2764 MatchCode += "if (" + FeatureMask + ")\n";
27662765 MatchCode += " Mnemonic = \"";
27672766 MatchCode += R->getValueAsString("ToMnemonic");
27682767 MatchCode += "\";\n";
27972796 if (Aliases.empty()) return false;
27982797
27992798 OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
2800 "uint64_t Features, unsigned VariantID) {\n";
2799 "const FeatureBitset &Features, unsigned VariantID) {\n";
28012800 OS << " switch (VariantID) {\n";
28022801 unsigned VariantCount = Target.getAsmParserVariantCount();
28032802 for (unsigned VC = 0; VC != VariantCount; ++VC) {
28222821 static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target,
28232822 const AsmMatcherInfo &Info, StringRef ClassName,
28242823 StringToOffsetTable &StringTable,
2825 unsigned MaxMnemonicIndex, bool HasMnemonicFirst) {
2824 unsigned MaxMnemonicIndex,
2825 unsigned MaxFeaturesIndex,
2826 bool HasMnemonicFirst) {
28262827 unsigned MaxMask = 0;
28272828 for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) {
28282829 MaxMask |= OMI.OperandMask;
28312832 // Emit the static custom operand parsing table;
28322833 OS << "namespace {\n";
28332834 OS << " struct OperandMatchEntry {\n";
2834 OS << " " << getMinimalTypeForEnumBitfield(Info.SubtargetFeatures.size())
2835 << " RequiredFeatures;\n";
28362835 OS << " " << getMinimalTypeForRange(MaxMnemonicIndex)
28372836 << " Mnemonic;\n";
2837 OS << " " << getMinimalTypeForRange(MaxMask)
2838 << " OperandMask;\n";
28382839 OS << " " << getMinimalTypeForRange(std::distance(
28392840 Info.Classes.begin(), Info.Classes.end())) << " Class;\n";
2840 OS << " " << getMinimalTypeForRange(MaxMask)
2841 << " OperandMask;\n\n";
2841 OS << " " << getMinimalTypeForRange(MaxFeaturesIndex)
2842 << " RequiredFeaturesIdx;\n\n";
28422843 OS << " StringRef getMnemonic() const {\n";
28432844 OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n";
28442845 OS << " MnemonicTable[Mnemonic]);\n";
28642865 OS << "static const OperandMatchEntry OperandMatchTable["
28652866 << Info.OperandMatchInfo.size() << "] = {\n";
28662867
2867 OS << " /* Operand List Mask, Mnemonic, Operand Class, Features */\n";
2868 OS << " /* Operand List Mnemonic, Mask, Operand Class, Features */\n";
28682869 for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) {
28692870 const MatchableInfo &II = *OMI.MI;
28702871
28712872 OS << " { ";
28722873
2873 // Write the required features mask.
2874 if (!II.RequiredFeatures.empty()) {
2875 for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
2876 if (i) OS << "|";
2877 OS << II.RequiredFeatures[i]->getEnumName();
2878 }
2879 } else
2880 OS << "0";
2881
28822874 // Store a pascal-style length byte in the mnemonic.
28832875 std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
2884 OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
2876 OS << StringTable.GetOrAddStringOffset(LenMnemonic, false)
28852877 << " /* " << II.Mnemonic << " */, ";
28862878
2887 OS << OMI.CI->Name;
2888
2889 OS << ", " << OMI.OperandMask;
2879 OS << OMI.OperandMask;
28902880 OS << " /* ";
28912881 bool printComma = false;
28922882 for (int i = 0, e = 31; i !=e; ++i)
28962886 OS << i;
28972887 printComma = true;
28982888 }
2899 OS << " */";
2889 OS << " */, ";
2890
2891 OS << OMI.CI->Name;
2892
2893 // Write the required features mask.
2894 OS << ", AMFBS";
2895 if (II.RequiredFeatures.empty())
2896 OS << "_None";
2897 else
2898 for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i)
2899 OS << '_' << II.RequiredFeatures[i]->TheDef->getName();
29002900
29012901 OS << " },\n";
29022902 }
29322932
29332933 // Emit code to get the available features.
29342934 OS << " // Get the current feature set.\n";
2935 OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
2935 OS << " const FeatureBitset &AvailableFeatures = getAvailableFeatures();\n\n";
29362936
29372937 OS << " // Get the next operand index.\n";
29382938 OS << " unsigned NextOpNum = Operands.size()"
29662966
29672967 // Emit check that the required features are available.
29682968 OS << " // check if the available features match\n";
2969 OS << " const FeatureBitset &RequiredFeatures = "
2970 "FeatureBitsets[it->RequiredFeaturesIdx];\n";
29692971 OS << " if (!ParseForAllFeatures && (AvailableFeatures & "
2970 "it->RequiredFeatures) != it->RequiredFeatures)\n";
2972 "RequiredFeatures) != RequiredFeatures)\n";
29712973 OS << " continue;\n\n";
29722974
29732975 // Emit check to ensure the operand number matches.
30333035 static void emitMnemonicSpellChecker(raw_ostream &OS, CodeGenTarget &Target,
30343036 unsigned VariantCount) {
30353037 OS << "static std::string " << Target.getName()
3036 << "MnemonicSpellCheck(StringRef S, uint64_t FBS, unsigned VariantID) {\n";
3038 << "MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,"
3039 << " unsigned VariantID) {\n";
30373040 if (!VariantCount)
30383041 OS << " return \"\";";
30393042 else {
30543057 OS << " }\n\n";
30553058 OS << " for (auto I = Start; I < End; I++) {\n";
30563059 OS << " // Ignore unsupported instructions.\n";
3057 OS << " if ((FBS & I->RequiredFeatures) != I->RequiredFeatures)\n";
3060 OS << " const FeatureBitset &RequiredFeatures = "
3061 "FeatureBitsets[I->RequiredFeaturesIdx];\n";
3062 OS << " if ((FBS & RequiredFeatures) != RequiredFeatures)\n";
30583063 OS << " continue;\n";
30593064 OS << "\n";
30603065 OS << " StringRef T = I->getMnemonic();\n";
31023107 OS << "#endif // NDEBUG\n";
31033108 }
31043109
3110 static std::string
3111 getNameForFeatureBitset(const std::vector &FeatureBitset) {
3112 std::string Name = "AMFBS";
3113 for (const auto &Feature : FeatureBitset)
3114 Name += ("_" + Feature->getName()).str();
3115 return Name;
3116 }
3117
31053118 void AsmMatcherEmitter::run(raw_ostream &OS) {
31063119 CodeGenTarget Target(Records);
31073120 Record *AsmParser = Target.getAsmParser();
31733186 OS << "#undef GET_ASSEMBLER_HEADER\n";
31743187 OS << " // This should be included into the middle of the declaration of\n";
31753188 OS << " // your subclasses implementation of MCTargetAsmParser.\n";
3176 OS << " uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
3189 OS << " FeatureBitset ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
31773190 if (HasOptionalOperands) {
31783191 OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
31793192 << "unsigned Opcode,\n"
31913204 if (ReportMultipleNearMisses)
31923205 OS << " SmallVectorImpl *NearMisses,\n";
31933206 else
3194 OS << " uint64_t &ErrorInfo,\n";
3207 OS << " uint64_t &ErrorInfo,\n"
3208 << " FeatureBitset &MissingFeatures,\n";
31953209 OS << " bool matchingInlineAsm,\n"
31963210 << " unsigned VariantID = 0);\n";
3211 if (!ReportMultipleNearMisses)
3212 OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
3213 << " MCInst &Inst,\n"
3214 << " uint64_t &ErrorInfo,\n"
3215 << " bool matchingInlineAsm,\n"
3216 << " unsigned VariantID = 0) {\n"
3217 << " FeatureBitset MissingFeatures;\n"
3218 << " return MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,\n"
3219 << " matchingInlineAsm, VariantID);\n"
3220 << " }\n\n";
3221
31973222
31983223 if (!Info.OperandMatchInfo.empty()) {
31993224 OS << " OperandMatchResultTy MatchOperandParserImpl(\n";
32183243 OS << "#undef GET_REGISTER_MATCHER\n\n";
32193244
32203245 // Emit the subtarget feature enumeration.
3221 SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(
3246 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
32223247 Info.SubtargetFeatures, OS);
32233248
32243249 // Emit the function to match a register name to number.
32983323 OS << "static const char *const MnemonicTable =\n";
32993324 StringTable.EmitString(OS);
33003325 OS << ";\n\n";
3326
3327 std::vector> FeatureBitsets;
3328 for (const auto &MI : Info.Matchables) {
3329 if (MI->RequiredFeatures.empty())
3330 continue;
3331 FeatureBitsets.emplace_back();
3332 for (unsigned I = 0, E = MI->RequiredFeatures.size(); I != E; ++I)
3333 FeatureBitsets.back().push_back(MI->RequiredFeatures[I]->TheDef);
3334 }
3335
3336 llvm::sort(FeatureBitsets, [&](const std::vector &A,
3337 const std::vector &B) {
3338 if (A.size() < B.size())
3339 return true;
3340 if (A.size() > B.size())
3341 return false;
3342 for (const auto &Pair : zip(A, B)) {
3343 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
3344 return true;
3345 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
3346 return false;
3347 }
3348 return false;
3349 });
3350 FeatureBitsets.erase(
3351 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
3352 FeatureBitsets.end());
3353 OS << "// Feature bitsets.\n"
3354 << "enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
3355 << " AMFBS_None,\n";
3356 for (const auto &FeatureBitset : FeatureBitsets) {
3357 if (FeatureBitset.empty())
3358 continue;
3359 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
3360 }
3361 OS << "};\n\n"
3362 << "const static FeatureBitset FeatureBitsets[] {\n"
3363 << " {}, // AMFBS_None\n";
3364 for (const auto &FeatureBitset : FeatureBitsets) {
3365 if (FeatureBitset.empty())
3366 continue;
3367 OS << " {";
3368 for (const auto &Feature : FeatureBitset) {
3369 const auto &I = Info.SubtargetFeatures.find(Feature);
3370 assert(I != Info.SubtargetFeatures.end() && "Didn't import predicate?");
3371 OS << I->second.getEnumBitName() << ", ";
3372 }
3373 OS << "},\n";
3374 }
3375 OS << "};\n\n";
33013376
33023377 // Emit the static match table; unused classes get initialized to 0 which is
33033378 // guaranteed to be InvalidMatchClass.
33163391 OS << " uint16_t Opcode;\n";
33173392 OS << " " << getMinimalTypeForRange(Info.Matchables.size())
33183393 << " ConvertFn;\n";
3319 OS << " " << getMinimalTypeForEnumBitfield(Info.SubtargetFeatures.size())
3320 << " RequiredFeatures;\n";
3394 OS << " " << getMinimalTypeForRange(FeatureBitsets.size())
3395 << " RequiredFeaturesIdx;\n";
33213396 OS << " " << getMinimalTypeForRange(
33223397 std::distance(Info.Classes.begin(), Info.Classes.end()))
33233398 << " Classes[" << MaxNumOperands << "];\n";
33623437 << MI->ConversionFnKind << ", ";
33633438
33643439 // Write the required features mask.
3365 if (!MI->RequiredFeatures.empty()) {
3366 for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) {
3367 if (i) OS << "|";
3368 OS << MI->RequiredFeatures[i]->getEnumName();
3369 }
3370 } else
3371 OS << "0";
3440 OS << "AMFBS";
3441 if (MI->RequiredFeatures.empty())
3442 OS << "_None";
3443 else
3444 for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i)
3445 OS << '_' << MI->RequiredFeatures[i]->TheDef->getName();
33723446
33733447 OS << ", { ";
33743448 for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {
33933467 if (ReportMultipleNearMisses)
33943468 OS << " SmallVectorImpl *NearMisses,\n";
33953469 else
3396 OS << " uint64_t &ErrorInfo,\n";
3470 OS << " uint64_t &ErrorInfo,\n"
3471 << " FeatureBitset &MissingFeatures,\n";
33973472 OS << " bool matchingInlineAsm, unsigned VariantID) {\n";
33983473
33993474 if (!ReportMultipleNearMisses) {
34083483
34093484 // Emit code to get the available features.
34103485 OS << " // Get the current feature set.\n";
3411 OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
3486 OS << " const FeatureBitset &AvailableFeatures = getAvailableFeatures();\n\n";
34123487
34133488 OS << " // Get the instruction mnemonic, which is the first token.\n";
34143489 if (HasMnemonicFirst) {
34323507 OS << " bool HadMatchOtherThanFeatures = false;\n";
34333508 OS << " bool HadMatchOtherThanPredicate = false;\n";
34343509 OS << " unsigned RetCode = Match_InvalidOperand;\n";
3435 OS << " uint64_t MissingFeatures = ~0ULL;\n";
3510 OS << " MissingFeatures.set();\n";
34363511 OS << " // Set ErrorInfo to the operand that mismatches if it is\n";
34373512 OS << " // wrong for all instances of the instruction.\n";
34383513 OS << " ErrorInfo = ~0ULL;\n";
34783553 OS << " for (const MatchEntry *it = MnemonicRange.first, "
34793554 << "*ie = MnemonicRange.second;\n";
34803555 OS << " it != ie; ++it) {\n";
3556 OS << " const FeatureBitset &RequiredFeatures = "
3557 "FeatureBitsets[it->RequiredFeaturesIdx];\n";
34813558 OS << " bool HasRequiredFeatures =\n";
3482 OS << " (AvailableFeatures & it->RequiredFeatures) == "
3483 "it->RequiredFeatures;\n";
3559 OS << " (AvailableFeatures & RequiredFeatures) == RequiredFeatures;\n";
34843560 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Trying to match opcode \"\n";
34853561 OS << " << MII.getName(it->Opcode) << \"\\n\");\n";
34863562
36393715 OS << " if (!HasRequiredFeatures) {\n";
36403716 if (!ReportMultipleNearMisses)
36413717 OS << " HadMatchOtherThanFeatures = true;\n";
3642 OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & "
3718 OS << " FeatureBitset NewMissingFeatures = RequiredFeatures & "
36433719 "~AvailableFeatures;\n";
3644 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Missing target features: \"\n";
3645 OS << " << format_hex(NewMissingFeatures, 18)\n";
3646 OS << " << \"\\n\");\n";
3720 OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Missing target features:\";\n";
3721 OS << " for (unsigned I = 0, E = NewMissingFeatures.size(); I != E; ++I)\n";
3722 OS << " if (NewMissingFeatures[I])\n";
3723 OS << " dbgs() << ' ' << I;\n";
3724 OS << " dbgs() << \"\\n\");\n";
36473725 if (ReportMultipleNearMisses) {
36483726 OS << " FeaturesNearMiss = NearMissInfo::getMissedFeature(NewMissingFeatures);\n";
36493727 } else {
3650 OS << " if (countPopulation(NewMissingFeatures) <=\n"
3651 " countPopulation(MissingFeatures))\n";
3728 OS << " if (NewMissingFeatures.count() <=\n"
3729 " MissingFeatures.count())\n";
36523730 OS << " MissingFeatures = NewMissingFeatures;\n";
36533731 OS << " continue;\n";
36543732 }
38033881 OS << " // Okay, we had no match. Try to return a useful error code.\n";
38043882 OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
38053883 OS << " return RetCode;\n\n";
3806 OS << " // Missing feature matches return which features were missing\n";
3807 OS << " ErrorInfo = MissingFeatures;\n";
3884 OS << " ErrorInfo = 0;\n";
38083885 OS << " return Match_MissingFeature;\n";
38093886 }
38103887 OS << "}\n\n";
38113888
38123889 if (!Info.OperandMatchInfo.empty())
38133890 emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable,
3814 MaxMnemonicIndex, HasMnemonicFirst);
3891 MaxMnemonicIndex, FeatureBitsets.size(),
3892 HasMnemonicFirst);
38153893
38163894 OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n";
38173895
1414 #include "CodeGenInstruction.h"
1515 #include "CodeGenTarget.h"
1616 #include "SubtargetFeatureInfo.h"
17 #include "Types.h"
1718 #include "llvm/ADT/ArrayRef.h"
1819 #include "llvm/ADT/StringExtras.h"
1920 #include "llvm/Support/Casting.h"
227228 return Case;
228229 }
229230
231 static std::string
232 getNameForFeatureBitset(const std::vector &FeatureBitset) {
233 std::string Name = "CEFBS";
234 for (const auto &Feature : FeatureBitset)
235 Name += ("_" + Feature->getName()).str();
236 return Name;
237 }
238
230239 void CodeEmitterGen::run(raw_ostream &o) {
231240 CodeGenTarget Target(Records);
232241 std::vector Insts = Records.getAllDerivedDefinitions("Instruction");
325334 << "#include \n\n";
326335
327336 // Emit the subtarget feature enumeration.
328 SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(SubtargetFeatures,
329 o);
337 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
338 o);
330339
331340 // Emit the name table for error messages.
332341 o << "#ifndef NDEBUG\n";
338347 Target.getName(), "MCCodeEmitter", "computeAvailableFeatures",
339348 SubtargetFeatures, o);
340349
350 std::vector> FeatureBitsets;
351 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
352 FeatureBitsets.emplace_back();
353 for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
354 const auto &I = SubtargetFeatures.find(Predicate);
355 if (I != SubtargetFeatures.end())
356 FeatureBitsets.back().push_back(I->second.TheDef);
357 }
358 }
359
360 llvm::sort(FeatureBitsets, [&](const std::vector &A,
361 const std::vector &B) {
362 if (A.size() < B.size())
363 return true;
364 if (A.size() > B.size())
365 return false;
366 for (const auto &Pair : zip(A, B)) {
367 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
368 return true;
369 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
370 return false;
371 }
372 return false;
373 });
374 FeatureBitsets.erase(
375 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
376 FeatureBitsets.end());
377 o << "#ifndef NDEBUG\n"
378 << "// Feature bitsets.\n"
379 << "enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
380 << " CEFBS_None,\n";
381 for (const auto &FeatureBitset : FeatureBitsets) {
382 if (FeatureBitset.empty())
383 continue;
384 o << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
385 }
386 o << "};\n\n"
387 << "const static FeatureBitset FeatureBitsets[] {\n"
388 << " {}, // CEFBS_None\n";
389 for (const auto &FeatureBitset : FeatureBitsets) {
390 if (FeatureBitset.empty())
391 continue;
392 o << " {";
393 for (const auto &Feature : FeatureBitset) {
394 const auto &I = SubtargetFeatures.find(Feature);
395 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
396 o << I->second.getEnumBitName() << ", ";
397 }
398 o << "},\n";
399 }
400 o << "};\n"
401 << "#endif // NDEBUG\n\n";
402
403
341404 // Emit the predicate verifier.
342405 o << "void " << Target.getName()
343406 << "MCCodeEmitter::verifyInstructionPredicates(\n"
344 << " const MCInst &Inst, uint64_t AvailableFeatures) const {\n"
407 << " const MCInst &Inst, const FeatureBitset &AvailableFeatures) const {\n"
345408 << "#ifndef NDEBUG\n"
346 << " static uint64_t RequiredFeatures[] = {\n";
409 << " static " << getMinimalTypeForRange(FeatureBitsets.size())
410 << " RequiredFeaturesRefs[] = {\n";
347411 unsigned InstIdx = 0;
348412 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
349 o << " ";
413 o << " CEFBS";
414 unsigned NumPredicates = 0;
350415 for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
351416 const auto &I = SubtargetFeatures.find(Predicate);
352 if (I != SubtargetFeatures.end())
353 o << I->second.getEnumName() << " | ";
354 }
355 o << "0, // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
417 if (I != SubtargetFeatures.end()) {
418 o << '_' << I->second.TheDef->getName();
419 NumPredicates++;
420 }
421 }
422 if (!NumPredicates)
423 o << "_None";
424 o << ", // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
356425 InstIdx++;
357426 }
358427 o << " };\n\n";
359428 o << " assert(Inst.getOpcode() < " << InstIdx << ");\n";
360 o << " uint64_t MissingFeatures =\n"
361 << " (AvailableFeatures & RequiredFeatures[Inst.getOpcode()]) ^\n"
362 << " RequiredFeatures[Inst.getOpcode()];\n"
363 << " if (MissingFeatures) {\n"
429 o << " const FeatureBitset &RequiredFeatures = "
430 "FeatureBitsets[RequiredFeaturesRefs[Inst.getOpcode()]];\n";
431 o << " FeatureBitset MissingFeatures =\n"
432 << " (AvailableFeatures & RequiredFeatures) ^\n"
433 << " RequiredFeatures;\n"
434 << " if (MissingFeatures.any()) {\n"
364435 << " std::ostringstream Msg;\n"
365436 << " Msg << \"Attempting to emit \" << "
366437 "MCII.getName(Inst.getOpcode()).str()\n"
367438 << " << \" instruction but the \";\n"
368 << " for (unsigned i = 0; i < 8 * sizeof(MissingFeatures); ++i)\n"
369 << " if (MissingFeatures & (1ULL << i))\n"
439 << " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
440 << " if (MissingFeatures.test(i))\n"
370441 << " Msg << SubtargetFeatureNames[i] << \" \";\n"
371442 << " Msg << \"predicate(s) are not met\";\n"
372443 << " report_fatal_error(Msg.str());\n"
4141 Pred, SubtargetFeatureInfo(Pred, SubtargetFeatures.size()));
4242 }
4343 return SubtargetFeatures;
44 }
45
46 void SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(
47 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
48 OS << "// Flags for subtarget features that participate in "
49 << "instruction matching.\n";
50 OS << "enum SubtargetFeatureFlag : "
51 << getMinimalTypeForEnumBitfield(SubtargetFeatures.size()) << " {\n";
52 for (const auto &SF : SubtargetFeatures) {
53 const SubtargetFeatureInfo &SFI = SF.second;
54 OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n";
55 }
56 OS << " Feature_None = 0\n";
57 OS << "};\n\n";
5844 }
5945
6046 void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
119105 void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
120106 StringRef TargetName, StringRef ClassName, StringRef FuncName,
121107 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
122 OS << "uint64_t " << TargetName << ClassName << "::\n"
108 OS << "FeatureBitset " << TargetName << ClassName << "::\n"
123109 << FuncName << "(const FeatureBitset& FB) const {\n";
124 OS << " uint64_t Features = 0;\n";
110 OS << " FeatureBitset Features;\n";
125111 for (const auto &SF : SubtargetFeatures) {
126112 const SubtargetFeatureInfo &SFI = SF.second;
127113
155141 } while (true);
156142
157143 OS << ")\n";
158 OS << " Features |= " << SFI.getEnumName() << ";\n";
144 OS << " Features[" << SFI.getEnumBitName() << "] = 1;\n";
159145 }
160146 OS << " return Features;\n";
161147 OS << "}\n\n";
5454
5555 /// Emit the subtarget feature flag definitions.
5656 ///
57 /// This version emits the bit value for the feature and is therefore limited
58 /// to 64 feature bits.
59 static void emitSubtargetFeatureFlagEnumeration(
60 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS);
61
62 /// Emit the subtarget feature flag definitions.
63 ///
6457 /// This version emits the bit index for the feature and can therefore support
6558 /// more than 64 feature bits.
6659 static void