From 24c3ef3325d8e9d00a5f893ffce29f052cacfb08 Mon Sep 17 00:00:00 2001 From: Vladimir Sukharev Date: Thu, 16 Apr 2015 12:15:27 +0000 Subject: [PATCH] [AArch64] Refactor AArch64NamedImmMapper to become dependent on subtarget features. In order to introduce v8.1a-specific entities, Mappers should be aware of SubtargetFeatures available. This patch introduces refactoring, that will then allow to easily introduce: - v8.1-specific "pan" PState for PStateMapper (PAN extension) - v8.1-specific sysregs for SysRegMapper (LOR,VHE extensions) Reviewers: jmolloy Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8496 Patch by Tom Coxon git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235089 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AArch64/AsmParser/AArch64AsmParser.cpp | 15 ++++++++++----- .../Disassembler/AArch64Disassembler.cpp | 5 ++++- .../AArch64/InstPrinter/AArch64InstPrinter.cpp | 12 ++++++++---- lib/Target/AArch64/Utils/AArch64BaseInfo.cpp | 18 ++++++++++-------- lib/Target/AArch64/Utils/AArch64BaseInfo.h | 16 ++++++++++++++-- 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index e2070030797..063c7142564 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1972,7 +1972,8 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { bool Valid; auto Mapper = AArch64PRFM::PRFMMapper(); - StringRef Name = Mapper.toString(MCE->getValue(), Valid); + StringRef Name = + Mapper.toString(MCE->getValue(), STI.getFeatureBits(), Valid); Operands.push_back(AArch64Operand::CreatePrefetch(prfop, Name, S, getContext())); return MatchOperand_Success; @@ -1985,7 +1986,8 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { bool Valid; auto Mapper = AArch64PRFM::PRFMMapper(); - unsigned prfop = Mapper.fromString(Tok.getString(), Valid); + unsigned prfop = + Mapper.fromString(Tok.getString(), STI.getFeatureBits(), Valid); if (!Valid) { TokError("pre-fetch hint expected"); return MatchOperand_ParseFail; @@ -2598,7 +2600,8 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { } bool Valid; auto Mapper = AArch64DB::DBarrierMapper(); - StringRef Name = Mapper.toString(MCE->getValue(), Valid); + StringRef Name = + Mapper.toString(MCE->getValue(), STI.getFeatureBits(), Valid); Operands.push_back( AArch64Operand::CreateBarrier(MCE->getValue(), Name, ExprLoc, getContext())); return MatchOperand_Success; @@ -2611,7 +2614,8 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { bool Valid; auto Mapper = AArch64DB::DBarrierMapper(); - unsigned Opt = Mapper.fromString(Tok.getString(), Valid); + unsigned Opt = + Mapper.fromString(Tok.getString(), STI.getFeatureBits(), Valid); if (!Valid) { TokError("invalid barrier option name"); return MatchOperand_ParseFail; @@ -2652,7 +2656,8 @@ AArch64AsmParser::tryParseSysReg(OperandVector &Operands) { "register should be -1 if and only if it's unknown"); auto PStateMapper = AArch64PState::PStateMapper(); - uint32_t PStateField = PStateMapper.fromString(Tok.getString(), IsKnown); + uint32_t PStateField = + PStateMapper.fromString(Tok.getString(), STI.getFeatureBits(), IsKnown); assert(IsKnown == (PStateField != -1U) && "register should be -1 if and only if it's unknown"); diff --git a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index fb25089580f..6f964c81372 100644 --- a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -1504,7 +1504,10 @@ static DecodeStatus DecodeSystemPStateInstruction(llvm::MCInst &Inst, Inst.addOperand(MCOperand::CreateImm(crm)); bool ValidNamed; - (void)AArch64PState::PStateMapper().toString(pstate_field, ValidNamed); + const AArch64Disassembler *Dis = + static_cast(Decoder); + (void)AArch64PState::PStateMapper().toString(pstate_field, + Dis->getSubtargetInfo().getFeatureBits(), ValidNamed); return ValidNamed ? Success : Fail; } diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp index 6ee1a3292ab..febd332414d 100644 --- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1101,7 +1101,8 @@ void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum, raw_ostream &O) { unsigned prfop = MI->getOperand(OpNum).getImm(); bool Valid; - StringRef Name = AArch64PRFM::PRFMMapper().toString(prfop, Valid); + StringRef Name = + AArch64PRFM::PRFMMapper().toString(prfop, STI.getFeatureBits(), Valid); if (Valid) O << Name; else @@ -1285,9 +1286,11 @@ void AArch64InstPrinter::printBarrierOption(const MCInst *MI, unsigned OpNo, bool Valid; StringRef Name; if (Opcode == AArch64::ISB) - Name = AArch64ISB::ISBMapper().toString(Val, Valid); + Name = AArch64ISB::ISBMapper().toString(Val, STI.getFeatureBits(), + Valid); else - Name = AArch64DB::DBarrierMapper().toString(Val, Valid); + Name = AArch64DB::DBarrierMapper().toString(Val, STI.getFeatureBits(), + Valid); if (Valid) O << Name; else @@ -1322,7 +1325,8 @@ void AArch64InstPrinter::printSystemPStateField(const MCInst *MI, unsigned OpNo, unsigned Val = MI->getOperand(OpNo).getImm(); bool Valid; - StringRef Name = AArch64PState::PStateMapper().toString(Val, Valid); + StringRef Name = + AArch64PState::PStateMapper().toString(Val, STI.getFeatureBits(), Valid); if (Valid) O << StringRef(Name.str()).upper(); else diff --git a/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp index d8991f8c049..50b311318e0 100644 --- a/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ b/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -18,9 +18,10 @@ using namespace llvm; -StringRef AArch64NamedImmMapper::toString(uint32_t Value, bool &Valid) const { +StringRef AArch64NamedImmMapper::toString(uint32_t Value, uint64_t FeatureBits, + bool &Valid) const { for (unsigned i = 0; i < NumMappings; ++i) { - if (Mappings[i].Value == Value) { + if (Mappings[i].isValueEqual(Value, FeatureBits)) { Valid = true; return Mappings[i].Name; } @@ -30,10 +31,11 @@ StringRef AArch64NamedImmMapper::toString(uint32_t Value, bool &Valid) const { return StringRef(); } -uint32_t AArch64NamedImmMapper::fromString(StringRef Name, bool &Valid) const { +uint32_t AArch64NamedImmMapper::fromString(StringRef Name, uint64_t FeatureBits, + bool &Valid) const { std::string LowerCaseName = Name.lower(); for (unsigned i = 0; i < NumMappings; ++i) { - if (Mappings[i].Name == LowerCaseName) { + if (Mappings[i].isNameEqual(LowerCaseName, FeatureBits)) { Valid = true; return Mappings[i].Value; } @@ -765,7 +767,7 @@ AArch64SysReg::SysRegMapper::fromString(StringRef Name, uint64_t FeatureBits, // First search the registers shared by all for (unsigned i = 0; i < array_lengthof(SysRegMappings); ++i) { - if (SysRegMappings[i].Name == NameLower) { + if (SysRegMappings[i].isNameEqual(NameLower, FeatureBits)) { Valid = true; return SysRegMappings[i].Value; } @@ -784,7 +786,7 @@ AArch64SysReg::SysRegMapper::fromString(StringRef Name, uint64_t FeatureBits, // 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 (InstMappings[i].isNameEqual(NameLower, FeatureBits)) { Valid = true; return InstMappings[i].Value; } @@ -816,7 +818,7 @@ std::string AArch64SysReg::SysRegMapper::toString(uint32_t Bits, uint64_t FeatureBits) const { // First search the registers shared by all for (unsigned i = 0; i < array_lengthof(SysRegMappings); ++i) { - if (SysRegMappings[i].Value == Bits) { + if (SysRegMappings[i].isValueEqual(Bits, FeatureBits)) { return SysRegMappings[i].Name; } } @@ -833,7 +835,7 @@ AArch64SysReg::SysRegMapper::toString(uint32_t Bits, uint64_t FeatureBits) const // 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 (InstMappings[i].isValueEqual(Bits, FeatureBits)) { return InstMappings[i].Name; } } diff --git a/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/lib/Target/AArch64/Utils/AArch64BaseInfo.h index 61718153e3c..2fcb4bb2c60 100644 --- a/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -280,14 +280,26 @@ struct AArch64NamedImmMapper { struct Mapping { const char *Name; uint32_t Value; + uint64_t AvailableForFeatures; + // empty AvailableForFeatures means "always-on" + bool isNameEqual(std::string Other, uint64_t FeatureBits=~0ULL) const { + if (AvailableForFeatures && !(AvailableForFeatures & FeatureBits)) + return false; + return Name == Other; + } + bool isValueEqual(uint32_t Other, uint64_t FeatureBits=~0ULL) const { + if (AvailableForFeatures && !(AvailableForFeatures & FeatureBits)) + return false; + return Value == Other; + } }; template AArch64NamedImmMapper(const Mapping (&Mappings)[N], uint32_t TooBigImm) : Mappings(&Mappings[0]), NumMappings(N), TooBigImm(TooBigImm) {} - StringRef toString(uint32_t Value, bool &Valid) const; - uint32_t fromString(StringRef Name, bool &Valid) const; + StringRef toString(uint32_t Value, uint64_t FeatureBits, bool &Valid) const; + uint32_t fromString(StringRef Name, uint64_t FeatureBits, bool &Valid) const; /// Many of the instructions allow an alternative assembly form consisting of /// a simple immediate. Currently the only valid forms are ranges [0, N) where -- 2.34.1