mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 12:19:53 +00:00
[TableGen] Add 'register alternative name matching' support
Summary: This adds a new attribute which targets can set in TableGen which causes a function to be generated which matches register alternative names. This is very similar to `ShouldEmitMatchRegisterName`, except it works on alt names. This patch is currently used by the out of tree part of the AVR backend. It reduces code duplication greatly, and has the effect that you do not need to hardcode altname to register mappings in C++. It will not work on targets which have registers which share the same aliases. Reviewers: stoklund, arsenm, dsanders, hfinkel, vkalintiris Subscribers: hfinkel, dylanmckay, llvm-commits Differential Revision: http://reviews.llvm.org/D16312 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259636 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2eb4c2ae70
commit
f4afd08249
@ -941,6 +941,14 @@ class AsmParser {
|
||||
// written register name matcher
|
||||
bit ShouldEmitMatchRegisterName = 1;
|
||||
|
||||
// Set to true if the target needs a generated 'alternative register name'
|
||||
// matcher.
|
||||
//
|
||||
// This generates a function which can be used to lookup registers from
|
||||
// their aliases. This function will fail when called on targets where
|
||||
// several registers share the same alias (i.e. not a 1:1 mapping).
|
||||
bit ShouldEmitMatchRegisterAltName = 0;
|
||||
|
||||
// HasMnemonicFirst - Set to false if target instructions don't always
|
||||
// start with a mnemonic as the first token.
|
||||
bit HasMnemonicFirst = 1;
|
||||
|
@ -2276,6 +2276,37 @@ static void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
|
||||
OS << "}\n\n";
|
||||
}
|
||||
|
||||
/// Emit the function to match a string to the target
|
||||
/// specific register enum.
|
||||
static void emitMatchRegisterAltName(CodeGenTarget &Target, Record *AsmParser,
|
||||
raw_ostream &OS) {
|
||||
// Construct the match list.
|
||||
std::vector<StringMatcher::StringPair> Matches;
|
||||
const auto &Regs = Target.getRegBank().getRegisters();
|
||||
for (const CodeGenRegister &Reg : Regs) {
|
||||
|
||||
auto AltNames = Reg.TheDef->getValueAsListOfStrings("AltNames");
|
||||
|
||||
for (auto AltName : AltNames) {
|
||||
AltName = StringRef(AltName).trim();
|
||||
|
||||
// don't handle empty alternative names
|
||||
if (AltName.empty())
|
||||
continue;
|
||||
|
||||
Matches.emplace_back(AltName,
|
||||
"return " + utostr(Reg.EnumValue) + ";");
|
||||
}
|
||||
}
|
||||
|
||||
OS << "static unsigned MatchRegisterAltName(StringRef Name) {\n";
|
||||
|
||||
StringMatcher("Name", Matches, OS).Emit();
|
||||
|
||||
OS << " return 0;\n";
|
||||
OS << "}\n\n";
|
||||
}
|
||||
|
||||
static const char *getMinimalTypeForRange(uint64_t Range) {
|
||||
assert(Range <= 0xFFFFFFFFFFFFFFFFULL && "Enum too large");
|
||||
if (Range > 0xFFFFFFFFULL)
|
||||
@ -2816,6 +2847,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterName"))
|
||||
emitMatchRegisterName(Target, AsmParser, OS);
|
||||
|
||||
if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterAltName"))
|
||||
emitMatchRegisterAltName(Target, AsmParser, OS);
|
||||
|
||||
OS << "#endif // GET_REGISTER_MATCHER\n\n";
|
||||
|
||||
OS << "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n";
|
||||
|
Loading…
Reference in New Issue
Block a user