forked from OSchip/llvm-project
[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 llvm-svn: 235089
This commit is contained in:
parent
f8aa57aa3b
commit
a98f6897a2
|
@ -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");
|
||||
|
||||
|
|
|
@ -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<const AArch64Disassembler *>(Decoder);
|
||||
(void)AArch64PState::PStateMapper().toString(pstate_field,
|
||||
Dis->getSubtargetInfo().getFeatureBits(), ValidNamed);
|
||||
|
||||
return ValidNamed ? Success : Fail;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<int N>
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue