From f61a467a5904a380ec9af743f2739ef68955ffb2 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 15 May 2014 11:16:32 +0000 Subject: TableGen/ARM64: print aliases even if they have syntax variants. To get at least one use of the change (and some actual tests) in with its commit, I've enabled the AArch64 & ARM64 NEON mov aliases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208867 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 3 +- utils/TableGen/AsmWriterEmitter.cpp | 76 +++++++++++++++++++++-------------- utils/TableGen/CodeGenInstruction.cpp | 8 +++- utils/TableGen/CodeGenInstruction.h | 2 +- 4 files changed, 54 insertions(+), 35 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 77f92ff614..43c2b1a1c1 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1375,7 +1375,8 @@ void AsmMatcherInfo::buildInfo() { std::vector AllInstAliases = Records.getAllDerivedDefinitions("InstAlias"); for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) { - CodeGenInstAlias *Alias = new CodeGenInstAlias(AllInstAliases[i], Target); + CodeGenInstAlias *Alias = + new CodeGenInstAlias(AllInstAliases[i], AsmVariantNo, Target); // If the tblgen -match-prefix option is specified (for tblgen hackers), // filter the set of instruction aliases we consider, based on the target diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 221976a842..77d92c3cb4 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -651,6 +651,25 @@ public: int getOpIndex(StringRef Op) { return OpMap[Op].first; } std::pair &getOpData(StringRef Op) { return OpMap[Op]; } + std::pair parseName(StringRef::iterator Start, + StringRef::iterator End) { + StringRef::iterator I = Start; + if (*I == '{') { + // ${some_name} + Start = ++I; + while (I != End && *I != '}') + ++I; + } else { + // $name, just eat the usual suspects. + while (I != End && + ((*I >= 'a' && *I <= 'z') || (*I >= 'A' && *I <= 'Z') || + (*I >= '0' && *I <= '9') || *I == '_')) + ++I; + } + + return std::make_pair(StringRef(Start, I - Start), I); + } + void print(raw_ostream &O) { if (Conds.empty() && ReqFeatures.empty()) { O.indent(6) << "return true;\n"; @@ -675,37 +694,30 @@ public: // Directly mangle mapped operands into the string. Each operand is // identified by a '$' sign followed by a byte identifying the number of the // operand. We add one to the index to avoid zero bytes. - std::pair ASM = StringRef(AsmString).split(' '); - SmallString<128> OutString = ASM.first; - if (!ASM.second.empty()) { - raw_svector_ostream OS(OutString); - OS << ' '; - for (StringRef::iterator I = ASM.second.begin(), E = ASM.second.end(); - I != E;) { - OS << *I; - if (*I == '$') { - StringRef::iterator Start = ++I; - while (I != E && - ((*I >= 'a' && *I <= 'z') || (*I >= 'A' && *I <= 'Z') || - (*I >= '0' && *I <= '9') || *I == '_')) - ++I; - StringRef Name(Start, I - Start); - assert(isOpMapped(Name) && "Unmapped operand!"); - - int OpIndex, PrintIndex; - std::tie(OpIndex, PrintIndex) = getOpData(Name); - if (PrintIndex == -1) { - // Can use the default printOperand route. - OS << format("\\x%02X", (unsigned char)OpIndex + 1); - } else - // 3 bytes if a PrintMethod is needed: 0xFF, the MCInst operand - // number, and which of our pre-detected Methods to call. - OS << format("\\xFF\\x%02X\\x%02X", OpIndex + 1, PrintIndex + 1); - } else { - ++I; - } + StringRef ASM(AsmString); + SmallString<128> OutString; + raw_svector_ostream OS(OutString); + for (StringRef::iterator I = ASM.begin(), E = ASM.end(); I != E;) { + OS << *I; + if (*I == '$') { + StringRef Name; + std::tie(Name, I) = parseName(++I, E); + assert(isOpMapped(Name) && "Unmapped operand!"); + + int OpIndex, PrintIndex; + std::tie(OpIndex, PrintIndex) = getOpData(Name); + if (PrintIndex == -1) { + // Can use the default printOperand route. + OS << format("\\x%02X", (unsigned char)OpIndex + 1); + } else + // 3 bytes if a PrintMethod is needed: 0xFF, the MCInst operand + // number, and which of our pre-detected Methods to call. + OS << format("\\xFF\\x%02X\\x%02X", OpIndex + 1, PrintIndex + 1); + } else { + ++I; } } + OS.flush(); // Emit the string. O.indent(6) << "AsmString = \"" << OutString.str() << "\";\n"; @@ -781,9 +793,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { // Create a map from the qualified name to a list of potential matches. std::map > AliasMap; + unsigned Variant = AsmWriter->getValueAsInt("Variant"); for (std::vector::iterator I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { - CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target); + CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Variant, Target); const Record *R = *I; if (!R->getValueAsBit("EmitAlias")) continue; // We were told not to emit the alias, but to emit the aliasee. @@ -976,7 +989,8 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { // Code that prints the alias, replacing the operands with the ones from the // MCInst. O << " unsigned I = 0;\n"; - O << " while (AsmString[I] != ' ' && AsmString[I] != '\\0')\n"; + O << " while (AsmString[I] != ' ' && AsmString[I] != '\t' &&\n"; + O << " AsmString[I] != '\\0')\n"; O << " ++I;\n"; O << " OS << '\\t' << StringRef(AsmString, I);\n"; diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index e124764545..c924ce8d83 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -536,9 +536,13 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, return false; } -CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) { - AsmString = R->getValueAsString("AsmString"); +CodeGenInstAlias::CodeGenInstAlias(Record *R, unsigned Variant, + CodeGenTarget &T) + : TheDef(R) { Result = R->getValueAsDag("ResultInst"); + AsmString = R->getValueAsString("AsmString"); + AsmString = CodeGenInstruction::FlattenAsmStringVariants(AsmString, Variant); + // Verify that the root of the result is an instruction. DefInit *DI = dyn_cast(Result->getOperator()); diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index dc39eb973b..818d0e1d36 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -336,7 +336,7 @@ namespace llvm { /// of them are matched by the operand, the second value should be -1. std::vector > ResultInstOperandIndex; - CodeGenInstAlias(Record *R, CodeGenTarget &T); + CodeGenInstAlias(Record *R, unsigned Variant, CodeGenTarget &T); bool tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, Record *InstOpRec, bool hasSubOps, ArrayRef Loc, -- cgit v1.2.3