Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1971,7 +1971,7 @@ } bool Valid; - auto Mapper = AArch64PRFM::PRFMMapper(); + auto Mapper = AArch64PRFM::PRFMMapper(STI.getFeatureBits()); StringRef Name = Mapper.toString(MCE->getValue(), Valid); Operands.push_back(AArch64Operand::CreatePrefetch(prfop, Name, S, getContext())); @@ -1984,7 +1984,7 @@ } bool Valid; - auto Mapper = AArch64PRFM::PRFMMapper(); + auto Mapper = AArch64PRFM::PRFMMapper(STI.getFeatureBits()); unsigned prfop = Mapper.fromString(Tok.getString(), Valid); if (!Valid) { TokError("pre-fetch hint expected"); @@ -2596,7 +2596,7 @@ return MatchOperand_ParseFail; } bool Valid; - auto Mapper = AArch64DB::DBarrierMapper(); + auto Mapper = AArch64DB::DBarrierMapper(STI.getFeatureBits()); StringRef Name = Mapper.toString(MCE->getValue(), Valid); Operands.push_back( AArch64Operand::CreateBarrier(MCE->getValue(), Name, ExprLoc, getContext())); @@ -2609,7 +2609,7 @@ } bool Valid; - auto Mapper = AArch64DB::DBarrierMapper(); + auto Mapper = AArch64DB::DBarrierMapper(STI.getFeatureBits()); unsigned Opt = Mapper.fromString(Tok.getString(), Valid); if (!Valid) { TokError("invalid barrier option name"); @@ -2648,7 +2648,7 @@ assert(IsKnown == (MSRReg != -1U) && "register should be -1 if and only if it's unknown"); - auto PStateMapper = AArch64PState::PStateMapper(); + auto PStateMapper = AArch64PState::PStateMapper(STI.getFeatureBits()); uint32_t PStateField = PStateMapper.fromString(Tok.getString(), IsKnown); assert(IsKnown == (PStateField != -1U) && "register should be -1 if and only if it's unknown"); Index: lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp =================================================================== --- lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -1504,7 +1504,10 @@ Inst.addOperand(MCOperand::CreateImm(crm)); bool ValidNamed; - (void)AArch64PState::PStateMapper().toString(pstate_field, ValidNamed); + const AArch64Disassembler *Dis = + static_cast(Decoder); + AArch64PState::PStateMapper Mapper(Dis->getSubtargetInfo().getFeatureBits()); + Mapper.toString(pstate_field, ValidNamed); return ValidNamed ? Success : Fail; } Index: lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp =================================================================== --- lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1088,7 +1088,8 @@ raw_ostream &O) { unsigned prfop = MI->getOperand(OpNum).getImm(); bool Valid; - StringRef Name = AArch64PRFM::PRFMMapper().toString(prfop, Valid); + AArch64PRFM::PRFMMapper PRFMMapper(getAvailableFeatures()); + StringRef Name = PRFMMapper.toString(prfop, Valid); if (Valid) O << Name; else @@ -1263,9 +1264,11 @@ bool Valid; StringRef Name; if (Opcode == AArch64::ISB) - Name = AArch64ISB::ISBMapper().toString(Val, Valid); + Name = AArch64ISB::ISBMapper(getAvailableFeatures()).toString(Val, + Valid); else - Name = AArch64DB::DBarrierMapper().toString(Val, Valid); + Name = AArch64DB::DBarrierMapper(getAvailableFeatures()).toString(Val, + Valid); if (Valid) O << Name; else @@ -1297,7 +1300,8 @@ unsigned Val = MI->getOperand(OpNo).getImm(); bool Valid; - StringRef Name = AArch64PState::PStateMapper().toString(Val, Valid); + auto Mapper = AArch64PState::PStateMapper(getAvailableFeatures()); + StringRef Name = Mapper.toString(Val, Valid); if (Valid) O << StringRef(Name.str()).upper(); else Index: lib/Target/AArch64/Utils/AArch64BaseInfo.h =================================================================== --- lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -22,6 +22,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" // For AArch64::X0 and friends. #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/MC/SubtargetFeature.h" #include "llvm/Support/ErrorHandling.h" namespace llvm { @@ -282,11 +283,14 @@ struct Mapping { const char *Name; uint32_t Value; + FeatureBitset FeatureBits; // like "struct SubtargetFeatureKV" }; template - AArch64NamedImmMapper(const Mapping (&Mappings)[N], uint32_t TooBigImm) - : Mappings(&Mappings[0]), NumMappings(N), TooBigImm(TooBigImm) {} + AArch64NamedImmMapper(const FeatureBitset &FeatureBits, + const Mapping (&Mappings)[N], uint32_t TooBigImm) + : FeatureBits(FeatureBits), Mappings(&Mappings[0]), NumMappings(N), + TooBigImm(TooBigImm) {} StringRef toString(uint32_t Value, bool &Valid) const; uint32_t fromString(StringRef Name, bool &Valid) const; @@ -296,9 +300,14 @@ /// N being 0 indicates no immediate syntax-form is allowed. bool validImm(uint32_t Value) const; protected: + const FeatureBitset &FeatureBits; const Mapping *Mappings; size_t NumMappings; uint32_t TooBigImm; + bool hasFeature(const FeatureBitset &Features) const { + // empty Features means "always-on" + return Features.none() || (FeatureBits & Features).any(); + } }; namespace AArch64AT { @@ -321,7 +330,7 @@ struct ATMapper : AArch64NamedImmMapper { const static Mapping ATMappings[]; - ATMapper(); + ATMapper(const FeatureBitset &FeatureBits); }; } @@ -345,7 +354,7 @@ struct DBarrierMapper : AArch64NamedImmMapper { const static Mapping DBarrierMappings[]; - DBarrierMapper(); + DBarrierMapper(const FeatureBitset &FeatureBits); }; } @@ -365,7 +374,7 @@ struct DCMapper : AArch64NamedImmMapper { const static Mapping DCMappings[]; - DCMapper(); + DCMapper(const FeatureBitset &FeatureBits); }; } @@ -382,7 +391,7 @@ struct ICMapper : AArch64NamedImmMapper { const static Mapping ICMappings[]; - ICMapper(); + ICMapper(const FeatureBitset &FeatureBits); }; static inline bool NeedsRegister(ICValues Val) { @@ -398,7 +407,7 @@ struct ISBMapper : AArch64NamedImmMapper { const static Mapping ISBMappings[]; - ISBMapper(); + ISBMapper(const FeatureBitset &FeatureBits); }; } @@ -428,7 +437,7 @@ struct PRFMMapper : AArch64NamedImmMapper { const static Mapping PRFMMappings[]; - PRFMMapper(); + PRFMMapper(const FeatureBitset &FeatureBits); }; } @@ -443,7 +452,7 @@ struct PStateMapper : AArch64NamedImmMapper { const static Mapping PStateMappings[]; - PStateMapper(); + PStateMapper(const FeatureBitset &FeatureBits); }; } @@ -1142,6 +1151,10 @@ const AArch64NamedImmMapper::Mapping *InstMappings; size_t NumInstMappings; const FeatureBitset &FeatureBits; + bool hasFeature(const FeatureBitset &Features) const { + // empty Features means "always-on" + return Features.none() || (FeatureBits & Features).any(); + } SysRegMapper(const FeatureBitset &FeatureBits) : FeatureBits(FeatureBits) { } uint32_t fromString(StringRef Name, bool &Valid) const; @@ -1201,7 +1214,7 @@ struct TLBIMapper : AArch64NamedImmMapper { const static Mapping TLBIMappings[]; - TLBIMapper(); + TLBIMapper(const FeatureBitset &FeatureBits); }; static inline bool NeedsRegister(TLBIValues Val) { Index: lib/Target/AArch64/Utils/AArch64BaseInfo.cpp =================================================================== --- lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -21,7 +21,8 @@ StringRef AArch64NamedImmMapper::toString(uint32_t Value, bool &Valid) const { for (unsigned i = 0; i < NumMappings; ++i) { - if (Mappings[i].Value == Value) { + if (hasFeature(Mappings[i].FeatureBits) && + Mappings[i].Value == Value) { Valid = true; return Mappings[i].Name; } @@ -34,7 +35,8 @@ uint32_t AArch64NamedImmMapper::fromString(StringRef Name, bool &Valid) const { std::string LowerCaseName = Name.lower(); for (unsigned i = 0; i < NumMappings; ++i) { - if (Mappings[i].Name == LowerCaseName) { + if (hasFeature(Mappings[i].FeatureBits) && + Mappings[i].Name == LowerCaseName) { Valid = true; return Mappings[i].Value; } @@ -63,8 +65,8 @@ {"s12e0w", S12E0W}, }; -AArch64AT::ATMapper::ATMapper() - : AArch64NamedImmMapper(ATMappings, 0) {} +AArch64AT::ATMapper::ATMapper(const FeatureBitset &FeatureBits) + : AArch64NamedImmMapper(FeatureBits, ATMappings, 0) {} const AArch64NamedImmMapper::Mapping AArch64DB::DBarrierMapper::DBarrierMappings[] = { {"oshld", OSHLD}, @@ -81,8 +83,8 @@ {"sy", SY} }; -AArch64DB::DBarrierMapper::DBarrierMapper() - : AArch64NamedImmMapper(DBarrierMappings, 16u) {} +AArch64DB::DBarrierMapper::DBarrierMapper(const FeatureBitset &FeatureBits) + : AArch64NamedImmMapper(FeatureBits, DBarrierMappings, 16u) {} const AArch64NamedImmMapper::Mapping AArch64DC::DCMapper::DCMappings[] = { {"zva", ZVA}, @@ -95,8 +97,8 @@ {"cisw", CISW} }; -AArch64DC::DCMapper::DCMapper() - : AArch64NamedImmMapper(DCMappings, 0) {} +AArch64DC::DCMapper::DCMapper(const FeatureBitset &FeatureBits) + : AArch64NamedImmMapper(FeatureBits, DCMappings, 0) {} const AArch64NamedImmMapper::Mapping AArch64IC::ICMapper::ICMappings[] = { {"ialluis", IALLUIS}, @@ -104,15 +106,15 @@ {"ivau", IVAU} }; -AArch64IC::ICMapper::ICMapper() - : AArch64NamedImmMapper(ICMappings, 0) {} +AArch64IC::ICMapper::ICMapper(const FeatureBitset &FeatureBits) + : AArch64NamedImmMapper(FeatureBits, ICMappings, 0) {} const AArch64NamedImmMapper::Mapping AArch64ISB::ISBMapper::ISBMappings[] = { {"sy", SY}, }; -AArch64ISB::ISBMapper::ISBMapper() - : AArch64NamedImmMapper(ISBMappings, 16) {} +AArch64ISB::ISBMapper::ISBMapper(const FeatureBitset &FeatureBits) + : AArch64NamedImmMapper(FeatureBits, ISBMappings, 16) {} const AArch64NamedImmMapper::Mapping AArch64PRFM::PRFMMapper::PRFMMappings[] = { {"pldl1keep", PLDL1KEEP}, @@ -135,8 +137,8 @@ {"pstl3strm", PSTL3STRM} }; -AArch64PRFM::PRFMMapper::PRFMMapper() - : AArch64NamedImmMapper(PRFMMappings, 32) {} +AArch64PRFM::PRFMMapper::PRFMMapper(const FeatureBitset &FeatureBits) + : AArch64NamedImmMapper(FeatureBits, PRFMMappings, 32) {} const AArch64NamedImmMapper::Mapping AArch64PState::PStateMapper::PStateMappings[] = { {"spsel", SPSel}, @@ -144,8 +146,8 @@ {"daifclr", DAIFClr} }; -AArch64PState::PStateMapper::PStateMapper() - : AArch64NamedImmMapper(PStateMappings, 0) {} +AArch64PState::PStateMapper::PStateMapper(const FeatureBitset &FeatureBits) + : AArch64NamedImmMapper(FeatureBits, PStateMappings, 0) {} const AArch64NamedImmMapper::Mapping AArch64SysReg::MRSMapper::MRSMappings[] = { {"mdccsr_el0", MDCCSR_EL0}, @@ -767,7 +769,8 @@ // First search the registers shared by all for (unsigned i = 0; i < array_lengthof(SysRegMappings); ++i) { - if (SysRegMappings[i].Name == NameLower) { + if (hasFeature(SysRegMappings[i].FeatureBits) && + SysRegMappings[i].Name == NameLower) { Valid = true; return SysRegMappings[i].Value; } @@ -786,7 +789,8 @@ // Now try the instruction-specific registers (either read-only or // write-only). for (unsigned i = 0; i < NumInstMappings; ++i) { - if (InstMappings[i].Name == NameLower) { + if (hasFeature(InstMappings[i].FeatureBits) && + InstMappings[i].Name == NameLower) { Valid = true; return InstMappings[i].Value; } @@ -818,7 +822,8 @@ AArch64SysReg::SysRegMapper::toString(uint32_t Bits) const { // First search the registers shared by all for (unsigned i = 0; i < array_lengthof(SysRegMappings); ++i) { - if (SysRegMappings[i].Value == Bits) { + if (hasFeature(SysRegMappings[i].FeatureBits) && + SysRegMappings[i].Value == Bits) { return SysRegMappings[i].Name; } } @@ -835,7 +840,8 @@ // Now try the instruction-specific registers (either read-only or // write-only). for (unsigned i = 0; i < NumInstMappings; ++i) { - if (InstMappings[i].Value == Bits) { + if (hasFeature(InstMappings[i].FeatureBits) && + InstMappings[i].Value == Bits) { return InstMappings[i].Name; } } @@ -886,5 +892,5 @@ {"vaale1", VAALE1} }; -AArch64TLBI::TLBIMapper::TLBIMapper() - : AArch64NamedImmMapper(TLBIMappings, 0) {} +AArch64TLBI::TLBIMapper::TLBIMapper(const FeatureBitset &FeatureBits) + : AArch64NamedImmMapper(FeatureBits, TLBIMappings, 0) {}