return Exts.count(Ext.str()) != 0;
}
+// We rank extensions in the following order:
+// -Single letter extensions in canonical order.
+// -Unknown single letter extensions in alphabetical order.
+// -Multi-letter extensions starting with 's' in alphabetical order.
+// -Multi-letter extensions starting with 'z' sorted by canonical order of
+// the second letter then sorted alphabetically.
+// -X extensions in alphabetical order.
+// These flags are used to indicate the category. The first 6 bits store the
+// single letter extension rank for single letter and multi-letter extensions
+// starting with 'z'.
+enum RankFlags {
+ RF_S_EXTENSION = 1 << 6,
+ RF_Z_EXTENSION = 1 << 7,
+ RF_X_EXTENSION = 1 << 8,
+};
+
// Get the rank for single-letter extension, lower value meaning higher
// priority.
-static int singleLetterExtensionRank(char Ext) {
+static unsigned singleLetterExtensionRank(char Ext) {
+ assert(Ext >= 'a' && Ext <= 'z');
switch (Ext) {
case 'i':
- return -2;
+ return 0;
case 'e':
- return -1;
- default:
- break;
+ return 1;
}
size_t Pos = AllStdExts.find(Ext);
- int Rank;
- if (Pos == StringRef::npos)
- // If we got an unknown extension letter, then give it an alphabetical
- // order, but after all known standard extensions.
- Rank = AllStdExts.size() + (Ext - 'a');
- else
- Rank = Pos;
+ if (Pos != StringRef::npos)
+ return Pos + 2; // Skip 'e' and 'i' from above.
- return Rank;
+ // If we got an unknown extension letter, then give it an alphabetical
+ // order, but after all known standard extensions.
+ return 2 + AllStdExts.size() + (Ext - 'a');
}
// Get the rank for multi-letter extension, lower value meaning higher
// priority/order in canonical order.
-static int multiLetterExtensionRank(const std::string &ExtName) {
- assert(ExtName.length() >= 2);
- int HighOrder;
- int LowOrder = 0;
- // The order between multi-char extensions: s -> h -> z -> x.
- char ExtClass = ExtName[0];
- switch (ExtClass) {
+static unsigned getExtensionRank(const std::string &ExtName) {
+ assert(ExtName.size() >= 1);
+ switch (ExtName[0]) {
case 's':
- HighOrder = 0;
- break;
+ return RF_S_EXTENSION;
case 'z':
- HighOrder = 1;
+ assert(ExtName.size() >= 2);
// `z` extension must be sorted by canonical order of second letter.
// e.g. zmx has higher rank than zax.
- LowOrder = singleLetterExtensionRank(ExtName[1]);
- break;
+ return RF_Z_EXTENSION | singleLetterExtensionRank(ExtName[1]);
case 'x':
- HighOrder = 2;
- break;
+ return RF_X_EXTENSION;
default:
- llvm_unreachable("Unknown prefix for multi-char extension");
- return -1;
+ assert(ExtName.size() == 1);
+ return singleLetterExtensionRank(ExtName[0]);
}
-
- return (HighOrder << 8) + LowOrder;
}
// Compare function for extension.
// Only compare the extension name, ignore version comparison.
bool RISCVISAInfo::compareExtension(const std::string &LHS,
const std::string &RHS) {
- size_t LHSLen = LHS.length();
- size_t RHSLen = RHS.length();
- if (LHSLen == 1 && RHSLen != 1)
- return true;
-
- if (LHSLen != 1 && RHSLen == 1)
- return false;
-
- if (LHSLen == 1 && RHSLen == 1)
- return singleLetterExtensionRank(LHS[0]) <
- singleLetterExtensionRank(RHS[0]);
+ unsigned LHSRank = getExtensionRank(LHS);
+ unsigned RHSRank = getExtensionRank(RHS);
- // Both are multi-char ext here.
- int LHSRank = multiLetterExtensionRank(LHS);
- int RHSRank = multiLetterExtensionRank(RHS);
+ // If the ranks differ, pick the lower rank.
if (LHSRank != RHSRank)
return LHSRank < RHSRank;