llvm.org GIT mirror llvm / 049ffbb
TableGen: allow use of uint64_t for available features mask. ARM in particular is getting dangerously close to exceeding 32 bits worth of possible subtarget features. When this happens, various parts of MC start to fail inexplicably as masks get truncated to "unsigned". Mostly just refactoring at present, and there's probably no way to test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215887 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 6 years ago
10 changed file(s) with 65 addition(s) and 63 deletion(s). Raw diff Collapse all Expand all
9292 MCTargetAsmParser();
9393
9494 /// AvailableFeatures - The current set of available features.
95 unsigned AvailableFeatures;
95 uint64_t AvailableFeatures;
9696
9797 /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
9898 bool ParsingInlineAsm;
107107 public:
108108 virtual ~MCTargetAsmParser();
109109
110 unsigned getAvailableFeatures() const { return AvailableFeatures; }
111 void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
110 uint64_t getAvailableFeatures() const { return AvailableFeatures; }
111 void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
112112
113113 bool isParsingInlineAsm () { return ParsingInlineAsm; }
114114 void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
160160 /// explaining the match failure.
161161 virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
162162 OperandVector &Operands, MCStreamer &Out,
163 unsigned &ErrorInfo,
163 uint64_t &ErrorInfo,
164164 bool MatchingInlineAsm) = 0;
165165
166166 /// Allows targets to let registers opt out of clobber lists.
16351635
16361636 // If parsing succeeded, match the instruction.
16371637 if (!HadError) {
1638 unsigned ErrorInfo;
1638 uint64_t ErrorInfo;
16391639 getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
16401640 Info.ParsedOperands, Out,
16411641 ErrorInfo, ParsingInlineAsm);
8484 bool validateInstruction(MCInst &Inst, SmallVectorImpl &Loc);
8585 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
8686 OperandVector &Operands, MCStreamer &Out,
87 unsigned &ErrorInfo,
87 uint64_t &ErrorInfo,
8888 bool MatchingInlineAsm) override;
8989 /// @name Auto-generated Match Functions
9090 /// {
35613561 }
35623562 }
35633563
3564 static const char *getSubtargetFeatureName(unsigned Val);
3564 static const char *getSubtargetFeatureName(uint64_t Val);
35653565
35663566 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
35673567 OperandVector &Operands,
35683568 MCStreamer &Out,
3569 unsigned &ErrorInfo,
3569 uint64_t &ErrorInfo,
35703570 bool MatchingInlineAsm) {
35713571 assert(!Operands.empty() && "Unexpect empty operand list!");
35723572 AArch64Operand &Op = static_cast(*Operands[0]);
38163816 // Special case the error message for the very common case where only
38173817 // a single subtarget feature is missing (neon, e.g.).
38183818 std::string Msg = "instruction requires:";
3819 unsigned Mask = 1;
3819 uint64_t Mask = 1;
38203820 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
38213821 if (ErrorInfo & Mask) {
38223822 Msg += " ";
38303830 return showMatchError(IDLoc, MatchResult);
38313831 case Match_InvalidOperand: {
38323832 SMLoc ErrorLoc = IDLoc;
3833 if (ErrorInfo != ~0U) {
3833 if (ErrorInfo != ~0ULL) {
38343834 if (ErrorInfo >= Operands.size())
38353835 return Error(IDLoc, "too few operands for instruction");
38363836
266266 }
267267
268268 void SwitchMode() {
269 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
269 uint64_t FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
270270 setAvailableFeatures(FB);
271271 }
272272 bool isMClass() const {
359359
360360 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
361361 OperandVector &Operands, MCStreamer &Out,
362 unsigned &ErrorInfo,
362 uint64_t &ErrorInfo,
363363 bool MatchingInlineAsm) override;
364364 void onLabelParsed(MCSymbol *Symbol) override;
365365 };
53625362 static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
53635363 return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
53645364 }
5365 static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
5365 static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
53665366 unsigned VariantID);
53675367
53685368 static bool RequiresVFPRegListValidation(StringRef Inst,
54005400 // The generic tblgen'erated code does this later, at the start of
54015401 // MatchInstructionImpl(), but that's too late for aliases that include
54025402 // any sort of suffix.
5403 unsigned AvailableFeatures = getAvailableFeatures();
5403 uint64_t AvailableFeatures = getAvailableFeatures();
54045404 unsigned AssemblerDialect = getParser().getAssemblerDialect();
54055405 applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect);
54065406
81618161 }
81628162 }
81638163
8164 static const char *getSubtargetFeatureName(unsigned Val);
8164 static const char *getSubtargetFeatureName(uint64_t Val);
81658165 bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
81668166 OperandVector &Operands,
8167 MCStreamer &Out, unsigned &ErrorInfo,
8167 MCStreamer &Out, uint64_t &ErrorInfo,
81688168 bool MatchingInlineAsm) {
81698169 MCInst Inst;
81708170 unsigned MatchResult;
82188218 // Special case the error message for the very common case where only
82198219 // a single subtarget feature is missing (Thumb vs. ARM, e.g.).
82208220 std::string Msg = "instruction requires:";
8221 unsigned Mask = 1;
8221 uint64_t Mask = 1;
82228222 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
82238223 if (ErrorInfo & Mask) {
82248224 Msg += " ";
82308230 }
82318231 case Match_InvalidOperand: {
82328232 SMLoc ErrorLoc = IDLoc;
8233 if (ErrorInfo != ~0U) {
8233 if (ErrorInfo != ~0ULL) {
82348234 if (ErrorInfo >= Operands.size())
82358235 return Error(IDLoc, "too few operands for instruction");
82368236
87958795
87968796 // Need to toggle features that should be on but are off and that
87978797 // should off but are on.
8798 unsigned Toggle = (Fpu.Enabled & ~STI.getFeatureBits()) |
8798 uint64_t Toggle = (Fpu.Enabled & ~STI.getFeatureBits()) |
87998799 (Fpu.Disabled & STI.getFeatureBits());
88008800 setAvailableFeatures(ComputeAvailableFeatures(STI.ToggleFeature(Toggle)));
88018801 break;
95799579 return false;
95809580 }
95819581
9582 unsigned ToggleFeatures = EnableFeature
9582 uint64_t ToggleFeatures = EnableFeature
95839583 ? (~STI.getFeatureBits() & Extension.Features)
95849584 : ( STI.getFeatureBits() & Extension.Features);
9585 unsigned Features =
9585 uint64_t Features =
95869586 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
95879587 setAvailableFeatures(Features);
95889588 return false;
9393
9494 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
9595 OperandVector &Operands, MCStreamer &Out,
96 unsigned &ErrorInfo,
96 uint64_t &ErrorInfo,
9797 bool MatchingInlineAsm) override;
9898
9999 /// Parse a register as used in CFI directives
15171517 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15181518 OperandVector &Operands,
15191519 MCStreamer &Out,
1520 unsigned &ErrorInfo,
1520 uint64_t &ErrorInfo,
15211521 bool MatchingInlineAsm) {
15221522
15231523 MCInst Inst;
15401540 return true;
15411541 case Match_InvalidOperand: {
15421542 SMLoc ErrorLoc = IDLoc;
1543 if (ErrorInfo != ~0U) {
1543 if (ErrorInfo != ~0ULL) {
15441544 if (ErrorInfo >= Operands.size())
15451545 return Error(IDLoc, "too few operands for instruction");
15461546
249249
250250 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
251251 OperandVector &Operands, MCStreamer &Out,
252 unsigned &ErrorInfo,
252 uint64_t &ErrorInfo,
253253 bool MatchingInlineAsm) override;
254254
255255 void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
10521052
10531053 bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
10541054 OperandVector &Operands,
1055 MCStreamer &Out, unsigned &ErrorInfo,
1055 MCStreamer &Out, uint64_t &ErrorInfo,
10561056 bool MatchingInlineAsm) {
10571057 MCInst Inst;
10581058
10701070 return Error(IDLoc, "unrecognized instruction mnemonic");
10711071 case Match_InvalidOperand: {
10721072 SMLoc ErrorLoc = IDLoc;
1073 if (ErrorInfo != ~0U) {
1073 if (ErrorInfo != ~0ULL) {
10741074 if (ErrorInfo >= Operands.size())
10751075 return Error(IDLoc, "too few operands for instruction");
10761076
4747 // public interface of the MCTargetAsmParser.
4848 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4949 OperandVector &Operands, MCStreamer &Out,
50 unsigned &ErrorInfo,
50 uint64_t &ErrorInfo,
5151 bool MatchingInlineAsm) override;
5252 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
5353 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
385385 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
386386 OperandVector &Operands,
387387 MCStreamer &Out,
388 unsigned &ErrorInfo,
388 uint64_t &ErrorInfo,
389389 bool MatchingInlineAsm) {
390390 MCInst Inst;
391391 SmallVector Instructions;
407407
408408 case Match_InvalidOperand: {
409409 SMLoc ErrorLoc = IDLoc;
410 if (ErrorInfo != ~0U) {
410 if (ErrorInfo != ~0ULL) {
411411 if (ErrorInfo >= Operands.size())
412412 return Error(IDLoc, "too few operands for instruction");
413413
443443 return Error(StartLoc, "invalid register name");
444444 }
445445
446 static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
446 static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
447447 unsigned VariantID);
448448
449449 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
344344 SMLoc NameLoc, OperandVector &Operands) override;
345345 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
346346 OperandVector &Operands, MCStreamer &Out,
347 unsigned &ErrorInfo,
347 uint64_t &ErrorInfo,
348348 bool MatchingInlineAsm) override;
349349
350350 // Used by the TableGen code to parse particular operand types.
676676 bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
677677 OperandVector &Operands,
678678 MCStreamer &Out,
679 unsigned &ErrorInfo,
679 uint64_t &ErrorInfo,
680680 bool MatchingInlineAsm) {
681681 MCInst Inst;
682682 unsigned MatchResult;
695695 // Special case the error message for the very common case where only
696696 // a single subtarget feature is missing
697697 std::string Msg = "instruction requires:";
698 unsigned Mask = 1;
698 uint64_t Mask = 1;
699699 for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) {
700700 if (ErrorInfo & Mask) {
701701 Msg += " ";
708708
709709 case Match_InvalidOperand: {
710710 SMLoc ErrorLoc = IDLoc;
711 if (ErrorInfo != ~0U) {
711 if (ErrorInfo != ~0ULL) {
712712 if (ErrorInfo >= Operands.size())
713713 return Error(IDLoc, "too few operands for instruction");
714714
693693
694694 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
695695 OperandVector &Operands, MCStreamer &Out,
696 unsigned &ErrorInfo,
696 uint64_t &ErrorInfo,
697697 bool MatchingInlineAsm) override;
698698
699699 virtual bool OmitRegisterFromClobberLists(unsigned RegNo) override;
22962296 }
22972297 }
22982298
2299 static const char *getSubtargetFeatureName(unsigned Val);
2299 static const char *getSubtargetFeatureName(uint64_t Val);
23002300
23012301 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
23022302 MCStreamer &Out) {
23062306
23072307 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
23082308 OperandVector &Operands,
2309 MCStreamer &Out, unsigned &ErrorInfo,
2309 MCStreamer &Out, uint64_t &ErrorInfo,
23102310 bool MatchingInlineAsm) {
23112311 assert(!Operands.empty() && "Unexpect empty operand list!");
23122312 X86Operand &Op = static_cast(*Operands[0]);
23622362 // Special case the error message for the very common case where only
23632363 // a single subtarget feature is missing.
23642364 std::string Msg = "instruction requires:";
2365 unsigned Mask = 1;
2365 uint64_t Mask = 1;
23662366 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
23672367 if (ErrorInfo & Mask) {
23682368 Msg += " ";
24002400 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
24012401
24022402 // Check for the various suffix matches.
2403 unsigned ErrorInfoIgnore;
2404 unsigned ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2403 uint64_t ErrorInfoIgnore;
2404 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
24052405 unsigned Match[4];
24062406
24072407 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
24682468 }
24692469
24702470 // Recover location info for the operand if we know which was the problem.
2471 if (ErrorInfo != ~0U) {
2471 if (ErrorInfo != ~0ULL) {
24722472 if (ErrorInfo >= Operands.size())
24732473 return Error(IDLoc, "too few operands for instruction",
24742474 EmptyRanges, MatchingInlineAsm);
24902490 if (std::count(std::begin(Match), std::end(Match),
24912491 Match_MissingFeature) == 1) {
24922492 std::string Msg = "instruction requires:";
2493 unsigned Mask = 1;
2493 uint64_t Mask = 1;
24942494 for (unsigned i = 0; i < (sizeof(ErrorInfoMissingFeature)*8-1); ++i) {
24952495 if (ErrorInfoMissingFeature & Mask) {
24962496 Msg += " ";
564564 Record *TheDef;
565565
566566 /// \brief An unique index assigned to represent this feature.
567 unsigned Index;
568
569 SubtargetFeatureInfo(Record *D, unsigned Idx) : TheDef(D), Index(Idx) {}
567 uint64_t Index;
568
569 SubtargetFeatureInfo(Record *D, uint64_t Idx) : TheDef(D), Index(Idx) {}
570570
571571 /// \brief The name of the enumerated constant identifying this feature.
572572 std::string getEnumName() const {
13261326 if (Pred->getName().empty())
13271327 PrintFatalError(Pred->getLoc(), "Predicate has no name!");
13281328
1329 unsigned FeatureNo = SubtargetFeatures.size();
1329 uint64_t FeatureNo = SubtargetFeatures.size();
13301330 SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo);
13311331 DEBUG(SubtargetFeatures[Pred]->dump());
1332 assert(FeatureNo < 32 && "Too many subtarget features!");
1332 assert(FeatureNo < 64 && "Too many subtarget features!");
13331333 }
13341334
13351335 // Parse the instructions; we need to do this first so that we can gather the
22042204 }
22052205
22062206 static const char *getMinimalTypeForRange(uint64_t Range) {
2207 assert(Range <= 0xFFFFFFFFULL && "Enum too large");
2207 assert(Range <= 0xFFFFFFFFFFFFFFFFULL && "Enum too large");
2208 if (Range > 0xFFFFFFFFULL)
2209 return "uint64_t";
22082210 if (Range > 0xFFFF)
22092211 return "uint32_t";
22102212 if (Range > 0xFF)
22312233 it = Info.SubtargetFeatures.begin(),
22322234 ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
22332235 SubtargetFeatureInfo &SFI = *it->second;
2234 OS << " " << SFI.getEnumName() << " = (1U << " << SFI.Index << "),\n";
2236 OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n";
22352237 }
22362238 OS << " Feature_None = 0\n";
22372239 OS << "};\n\n";
22622264 static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
22632265 OS << "// User-level names for subtarget features that participate in\n"
22642266 << "// instruction matching.\n"
2265 << "static const char *getSubtargetFeatureName(unsigned Val) {\n";
2267 << "static const char *getSubtargetFeatureName(uint64_t Val) {\n";
22662268 if (!Info.SubtargetFeatures.empty()) {
22672269 OS << " switch(Val) {\n";
22682270 typedef std::map RecFeatMap;
22892291 std::string ClassName =
22902292 Info.AsmParser->getValueAsString("AsmParserClassName");
22912293
2292 OS << "unsigned " << Info.Target.getName() << ClassName << "::\n"
2294 OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n"
22932295 << "ComputeAvailableFeatures(uint64_t FB) const {\n";
2294 OS << " unsigned Features = 0;\n";
2296 OS << " uint64_t Features = 0;\n";
22952297 for (std::map::const_iterator
22962298 it = Info.SubtargetFeatures.begin(),
22972299 ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
24452447 if (Aliases.empty()) return false;
24462448
24472449 OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
2448 "unsigned Features, unsigned VariantID) {\n";
2450 "uint64_t Features, unsigned VariantID) {\n";
24492451 OS << " switch (VariantID) {\n";
24502452 unsigned VariantCount = Target.getAsmParserVariantCount();
24512453 for (unsigned VC = 0; VC != VariantCount; ++VC) {
25882590
25892591 // Emit code to get the available features.
25902592 OS << " // Get the current feature set.\n";
2591 OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n";
2593 OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
25922594
25932595 OS << " // Get the next operand index.\n";
25942596 OS << " unsigned NextOpNum = Operands.size()-1;\n";
26902692 OS << "#undef GET_ASSEMBLER_HEADER\n";
26912693 OS << " // This should be included into the middle of the declaration of\n";
26922694 OS << " // your subclasses implementation of MCTargetAsmParser.\n";
2693 OS << " unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
2695 OS << " uint64_t ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
26942696 OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
26952697 << "unsigned Opcode,\n"
26962698 << " const OperandVector "
27022704 OS.indent(27);
27032705 OS << "const OperandVector &Operands,\n"
27042706 << " MCInst &Inst,\n"
2705 << " unsigned &ErrorInfo,"
2707 << " uint64_t &ErrorInfo,"
27062708 << " bool matchingInlineAsm,\n"
27072709 << " unsigned VariantID = 0);\n";
27082710
29112913 << "MatchInstructionImpl(const OperandVector"
29122914 << " &Operands,\n";
29132915 OS << " MCInst &Inst,\n"
2914 << "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
2916 << "uint64_t &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
29152917
29162918 OS << " // Eliminate obvious mismatches.\n";
29172919 OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
29212923
29222924 // Emit code to get the available features.
29232925 OS << " // Get the current feature set.\n";
2924 OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n";
2926 OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
29252927
29262928 OS << " // Get the instruction mnemonic, which is the first token.\n";
29272929 OS << " StringRef Mnemonic = ((" << Target.getName()
29372939 OS << " bool HadMatchOtherThanFeatures = false;\n";
29382940 OS << " bool HadMatchOtherThanPredicate = false;\n";
29392941 OS << " unsigned RetCode = Match_InvalidOperand;\n";
2940 OS << " unsigned MissingFeatures = ~0U;\n";
2942 OS << " uint64_t MissingFeatures = ~0ULL;\n";
29412943 OS << " // Set ErrorInfo to the operand that mismatches if it is\n";
29422944 OS << " // wrong for all instances of the instruction.\n";
29432945 OS << " ErrorInfo = ~0U;\n";
30133015 OS << " if ((AvailableFeatures & it->RequiredFeatures) "
30143016 << "!= it->RequiredFeatures) {\n";
30153017 OS << " HadMatchOtherThanFeatures = true;\n";
3016 OS << " unsigned NewMissingFeatures = it->RequiredFeatures & "
3018 OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & "
30173019 "~AvailableFeatures;\n";
3018 OS << " if (CountPopulation_32(NewMissingFeatures) <=\n"
3019 " CountPopulation_32(MissingFeatures))\n";
3020 OS << " if (CountPopulation_64(NewMissingFeatures) <=\n"
3021 " CountPopulation_64(MissingFeatures))\n";
30203022 OS << " MissingFeatures = NewMissingFeatures;\n";
30213023 OS << " continue;\n";
30223024 OS << " }\n";