mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 14:10:41 +00:00
Extend AsmMatcher token literal matching to allow aliasing.
For example, ARM allows: vmov.u32 s4, #0 -> vmov.i32, #0 'u32' is a more specific designator for the 32-bit integer type specifier and is legal for any instruction which accepts 'i32' as a datatype suffix. We want to say, def : TokenAlias<".u32", ".i32">; This works by marking the match class of 'From' as a subclass of the match class of 'To'. rdar://10435076 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145992 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f8de54f37b
commit
a66512e591
@ -738,7 +738,20 @@ class AssemblerPredicate<string cond> {
|
||||
string AssemblerCondString = cond;
|
||||
}
|
||||
|
||||
|
||||
/// TokenAlias - This class allows targets to define assembler token
|
||||
/// operand aliases. That is, a token literal operand which is equivalent
|
||||
/// to another, canonical, token literal. For example, ARM allows:
|
||||
/// vmov.u32 s4, #0 -> vmov.i32, #0
|
||||
/// 'u32' is a more specific designator for the 32-bit integer type specifier
|
||||
/// and is legal for any instruction which accepts 'i32' as a datatype suffix.
|
||||
/// def : TokenAlias<".u32", ".i32">;
|
||||
///
|
||||
/// This works by marking the match class of 'From' as a subclass of the
|
||||
/// match class of 'To'.
|
||||
class TokenAlias<string From, string To> {
|
||||
string FromToken = From;
|
||||
string ToToken = To;
|
||||
}
|
||||
|
||||
/// MnemonicAlias - This class allows targets to define assembler mnemonic
|
||||
/// aliases. This should be used when all forms of one mnemonic are accepted
|
||||
|
@ -252,11 +252,6 @@ public:
|
||||
switch (Kind) {
|
||||
case Invalid:
|
||||
assert(0 && "Invalid kind!");
|
||||
case Token:
|
||||
// Tokens are comparable by value.
|
||||
//
|
||||
// FIXME: Compare by enum value.
|
||||
return ValueName < RHS.ValueName;
|
||||
|
||||
default:
|
||||
// This class precedes the RHS if it is a proper subset of the RHS.
|
||||
@ -1304,6 +1299,17 @@ void AsmMatcherInfo::BuildInfo() {
|
||||
II->BuildAliasResultOperands();
|
||||
}
|
||||
|
||||
// Process token alias definitions and set up the associated superclass
|
||||
// information.
|
||||
std::vector<Record*> AllTokenAliases =
|
||||
Records.getAllDerivedDefinitions("TokenAlias");
|
||||
for (unsigned i = 0, e = AllTokenAliases.size(); i != e; ++i) {
|
||||
Record *Rec = AllTokenAliases[i];
|
||||
ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken"));
|
||||
ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken"));
|
||||
FromClass->SuperClasses.push_back(ToClass);
|
||||
}
|
||||
|
||||
// Reorder classes so that classes precede super classes.
|
||||
std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
|
||||
}
|
||||
@ -1676,7 +1682,8 @@ static void EmitValidateOperandClass(AsmMatcherInfo &Info,
|
||||
|
||||
// Check for Token operands first.
|
||||
OS << " if (Operand.isToken())\n";
|
||||
OS << " return matchTokenString(Operand.getToken()) == Kind;\n\n";
|
||||
OS << " return isSubclass(matchTokenString(Operand.getToken()), Kind);"
|
||||
<< "\n\n";
|
||||
|
||||
// Check for register operands, including sub-classes.
|
||||
OS << " if (Operand.isReg()) {\n";
|
||||
@ -1729,32 +1736,30 @@ static void EmitIsSubclass(CodeGenTarget &Target,
|
||||
ie = Infos.end(); it != ie; ++it) {
|
||||
ClassInfo &A = **it;
|
||||
|
||||
if (A.Kind != ClassInfo::Token) {
|
||||
std::vector<StringRef> SuperClasses;
|
||||
for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
|
||||
ie = Infos.end(); it != ie; ++it) {
|
||||
ClassInfo &B = **it;
|
||||
std::vector<StringRef> SuperClasses;
|
||||
for (std::vector<ClassInfo*>::iterator it = Infos.begin(),
|
||||
ie = Infos.end(); it != ie; ++it) {
|
||||
ClassInfo &B = **it;
|
||||
|
||||
if (&A != &B && A.isSubsetOf(B))
|
||||
SuperClasses.push_back(B.Name);
|
||||
}
|
||||
|
||||
if (SuperClasses.empty())
|
||||
continue;
|
||||
|
||||
OS << "\n case " << A.Name << ":\n";
|
||||
|
||||
if (SuperClasses.size() == 1) {
|
||||
OS << " return B == " << SuperClasses.back() << ";\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
OS << " switch (B) {\n";
|
||||
OS << " default: return false;\n";
|
||||
for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
|
||||
OS << " case " << SuperClasses[i] << ": return true;\n";
|
||||
OS << " }\n";
|
||||
if (&A != &B && A.isSubsetOf(B))
|
||||
SuperClasses.push_back(B.Name);
|
||||
}
|
||||
|
||||
if (SuperClasses.empty())
|
||||
continue;
|
||||
|
||||
OS << "\n case " << A.Name << ":\n";
|
||||
|
||||
if (SuperClasses.size() == 1) {
|
||||
OS << " return B == " << SuperClasses.back() << ";\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
OS << " switch (B) {\n";
|
||||
OS << " default: return false;\n";
|
||||
for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
|
||||
OS << " case " << SuperClasses[i] << ": return true;\n";
|
||||
OS << " }\n";
|
||||
}
|
||||
OS << " }\n";
|
||||
OS << "}\n\n";
|
||||
|
Loading…
Reference in New Issue
Block a user