aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-08-09 05:18:30 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-08-09 05:18:30 +0000
commit6745d42e8e51ba6b9546d6fa62e0c1b1e0f3982a (patch)
tree59a17a5166e5f4faf2a48bbe1ccbdf26f7de8a88
parent606e8ad796f72824f5509e2657c44eca025d4baf (diff)
downloadexternal_llvm-6745d42e8e51ba6b9546d6fa62e0c1b1e0f3982a.zip
external_llvm-6745d42e8e51ba6b9546d6fa62e0c1b1e0f3982a.tar.gz
external_llvm-6745d42e8e51ba6b9546d6fa62e0c1b1e0f3982a.tar.bz2
llvm-mc/AsmParser: Define match classes in the .td file.
-2 FIXMEs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78523 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/Target.td11
-rw-r--r--lib/Target/X86/X86InstrInfo.td3
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp66
3 files changed, 53 insertions, 27 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 5262cce..98b4125 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -286,6 +286,17 @@ class Operand<ValueType ty> {
string PrintMethod = "printOperand";
string AsmOperandLowerMethod = ?;
dag MIOperandInfo = (ops);
+
+ // ParserMatchClass - The "match class" that operands of this type fit
+ // in. Match classes are used to define the order in which instructions are
+ // match, to ensure that which instructions gets matched is deterministic.
+ string ParserMatchClass = "Imm";
+
+ // ParserMatchSuperClass - The enclosing super class for this operand (if
+ // any). This operand *must* be a subset of the valid operands for the super
+ // class; i.e., the match predicate for this super class must return true
+ // for all instances of this class.
+ string ParserMatchSuperClass = ?;
}
def i1imm : Operand<i1>;
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 8263b27..c21cad9 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -173,6 +173,7 @@ def ptr_rc_nosp : PointerLikeRegClass<1>;
class X86MemOperand<string printMethod> : Operand<iPTR> {
let PrintMethod = printMethod;
let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
+ let ParserMatchClass = "Mem";
}
def i8mem : X86MemOperand<"printi8mem">;
@@ -192,11 +193,13 @@ def f256mem : X86MemOperand<"printf256mem">;
def i8mem_NOREX : Operand<i64> {
let PrintMethod = "printi8mem";
let MIOperandInfo = (ops GR64_NOREX, i8imm, GR64_NOREX_NOSP, i32imm, i8imm);
+ let ParserMatchClass = "Mem";
}
def lea32mem : Operand<i32> {
let PrintMethod = "printlea32mem";
let MIOperandInfo = (ops GR32, i8imm, GR32_NOSP, i32imm);
+ let ParserMatchClass = "Mem";
}
def SSECC : Operand<i8> {
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 9b12927..cbe214d 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -278,19 +278,23 @@ namespace {
/// class of operands which can be matched.
struct ClassInfo {
enum ClassInfoKind {
- Token, ///< The class for a particular token.
- Register, ///< A register class.
- UserClass0 ///< The (first) user defined class, subsequent user defined
- /// classes are UserClass0+1, and so on.
+ Invalid = 0, ///< Invalid kind, for use as a sentinel value.
+ Token, ///< The class for a particular token.
+ Register, ///< A register class.
+ UserClass0 ///< The (first) user defined class, subsequent user defined
+ /// classes are UserClass0+1, and so on.
};
/// Kind - The class kind, which is either a predefined kind, or (UserClass0 +
/// N) for the Nth user defined class.
unsigned Kind;
- /// Name - The class name, suitable for use as an enum.
+ /// Name - The full class name, suitable for use in an enum.
std::string Name;
+ /// ClassName - The unadorned generic name for this class (e.g., Token).
+ std::string ClassName;
+
/// ValueName - The name of the value this class represents; for a token this
/// is the literal token string, for an operand it is the TableGen class (or
/// empty if this is a derived class).
@@ -311,6 +315,8 @@ struct ClassInfo {
return Kind < RHS.Kind;
switch (Kind) {
+ case Invalid:
+ assert(0 && "Invalid kind!");
case Token:
// Tokens are always comparable.
//
@@ -412,10 +418,17 @@ private:
/// constructed.
std::map<std::string, ClassInfo*> OperandClasses;
+ /// Map of user class names to kind value.
+ std::map<std::string, unsigned> UserClasses;
+
private:
/// getTokenClass - Lookup or create the class for the given token.
ClassInfo *getTokenClass(const StringRef &Token);
+ /// getUserClassKind - Lookup or create the kind value for the given class
+ /// name.
+ unsigned getUserClassKind(const StringRef &Name);
+
/// getOperandClass - Lookup or create the class for the given operand.
ClassInfo *getOperandClass(const StringRef &Token,
const CodeGenInstruction::OperandInfo &OI);
@@ -439,7 +452,7 @@ void InstructionInfo::dump() {
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
Operand &Op = Operands[i];
- errs() << " op[" << i << "] = ";
+ errs() << " op[" << i << "] = " << Op.Class->ClassName << " - ";
if (Op.Class->Kind == ClassInfo::Token) {
errs() << '\"' << Tokens[i] << "\"\n";
continue;
@@ -478,6 +491,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass(const StringRef &Token) {
if (!Entry) {
Entry = new ClassInfo();
Entry->Kind = ClassInfo::Token;
+ Entry->ClassName = "Token";
Entry->Name = "MCK_" + getEnumNameForToken(Token);
Entry->ValueName = Token;
Entry->PredicateMethod = "<invalid>";
@@ -488,28 +502,28 @@ ClassInfo *AsmMatcherInfo::getTokenClass(const StringRef &Token) {
return Entry;
}
+unsigned AsmMatcherInfo::getUserClassKind(const StringRef &Name) {
+ unsigned &Entry = UserClasses[Name];
+
+ if (!Entry)
+ Entry = ClassInfo::UserClass0 + UserClasses.size() - 1;
+
+ return Entry;
+}
+
ClassInfo *
AsmMatcherInfo::getOperandClass(const StringRef &Token,
const CodeGenInstruction::OperandInfo &OI) {
std::string ClassName;
if (OI.Rec->isSubClassOf("RegisterClass")) {
ClassName = "Reg";
- } else if (OI.Rec->isSubClassOf("Operand")) {
- // FIXME: This should not be hard coded.
- const RecordVal *RV = OI.Rec->getValue("Type");
-
- // FIXME: Yet another total hack.
- if (RV->getValue()->getAsString() == "iPTR" ||
- OI.Rec->getName() == "i8mem_NOREX" ||
- OI.Rec->getName() == "lea32mem" ||
- OI.Rec->getName() == "lea64mem" ||
- OI.Rec->getName() == "i128mem" ||
- OI.Rec->getName() == "sdmem" ||
- OI.Rec->getName() == "ssmem" ||
- OI.Rec->getName() == "lea64_32mem") {
- ClassName = "Mem";
- } else {
- ClassName = "Imm";
+ } else {
+ try {
+ ClassName = OI.Rec->getValueAsString("ParserMatchClass");
+ assert(ClassName != "Reg" && "'Reg' class name is reserved!");
+ } catch(...) {
+ PrintError(OI.Rec->getLoc(), "operand has no match class!");
+ ClassName = "Invalid";
}
}
@@ -521,11 +535,9 @@ AsmMatcherInfo::getOperandClass(const StringRef &Token,
if (ClassName == "Reg") {
Entry->Kind = ClassInfo::Register;
} else {
- if (ClassName == "Mem")
- Entry->Kind = ClassInfo::UserClass0;
- else
- Entry->Kind = ClassInfo::UserClass0 + 1;
+ Entry->Kind = getUserClassKind(ClassName);
}
+ Entry->ClassName = ClassName;
Entry->Name = "MCK_" + ClassName;
Entry->ValueName = OI.Rec->getName();
Entry->PredicateMethod = "is" + ClassName;
@@ -665,7 +677,7 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex)
Signature += "Imp";
- Signature += Op.Class->Name;
+ Signature += Op.Class->ClassName;
Signature += utostr(Op.OperandInfo->MINumOperands);
Signature += "_" + utostr(MIOperandList[i].second);