[llvm-commits] [llvm] r78530 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp lib/Target/X86/X86InstrInfo.td test/MC/AsmParser/x86_instructions.s utils/TableGen/AsmMatcherEmitter.cpp
Daniel Dunbar
daniel at zuster.org
Sun Aug 9 00:20:21 PDT 2009
Author: ddunbar
Date: Sun Aug 9 02:20:21 2009
New Revision: 78530
URL: http://llvm.org/viewvc/llvm-project?rev=78530&view=rev
Log:
llvm-mc/AsmParser: Implement user defined super classes.
- We can now discriminate SUB32ri8 from SUB32ri, for example.
Modified:
llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
llvm/trunk/lib/Target/X86/X86InstrInfo.td
llvm/trunk/test/MC/AsmParser/x86_instructions.s
llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=78530&r1=78529&r2=78530&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Sun Aug 9 02:20:21 2009
@@ -137,6 +137,19 @@
bool isImm() const { return Kind == Immediate; }
+ bool isImmSExt8() const {
+ // Accept immediates which fit in 8 bits when sign extended, and
+ // non-absolute immediates.
+ if (!isImm())
+ return false;
+
+ if (!getImm().isAbsolute())
+ return true;
+
+ int64_t Value = getImm().getConstant();
+ return Value == (int64_t) (int8_t) Value;
+ }
+
bool isMem() const { return Kind == Memory; }
bool isReg() const { return Kind == Register; }
@@ -151,6 +164,12 @@
Inst.addOperand(MCOperand::CreateMCValue(getImm()));
}
+ void addImmSExt8Operands(MCInst &Inst, unsigned N) {
+ // FIXME: Support user customization of the render method.
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateMCValue(getImm()));
+ }
+
void addMemOperands(MCInst &Inst, unsigned N) {
assert((N == 4 || N == 5) && "Invalid number of operands!");
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=78530&r1=78529&r2=78530&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sun Aug 9 02:20:21 2009
@@ -212,9 +212,15 @@
// A couple of more descriptive operand definitions.
// 16-bits but only 8 bits are significant.
-def i16i8imm : Operand<i16>;
+def i16i8imm : Operand<i16> {
+ let ParserMatchClass = "ImmSExt8";
+ let ParserMatchSuperClass = "Imm";
+}
// 32-bits but only 8 bits are significant.
-def i32i8imm : Operand<i32>;
+def i32i8imm : Operand<i32> {
+ let ParserMatchClass = "ImmSExt8";
+ let ParserMatchSuperClass = "Imm";
+}
// Branch targets have OtherVT type and print as pc-relative values.
def brtarget : Operand<OtherVT> {
Modified: llvm/trunk/test/MC/AsmParser/x86_instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/x86_instructions.s?rev=78530&r1=78529&r2=78530&view=diff
==============================================================================
--- llvm/trunk/test/MC/AsmParser/x86_instructions.s (original)
+++ llvm/trunk/test/MC/AsmParser/x86_instructions.s Sun Aug 9 02:20:21 2009
@@ -16,3 +16,17 @@
movl %eax, 10(%ebp, %ebx, 4)
// RUN: grep {MCInst(opcode=.*, operands=.reg:0, imm:4, reg:21, val:10, reg:0, reg:19.)} %t
movl %eax, 10(, %ebx, 4)
+
+// FIXME: Check that this matches SUB32ri8
+// RUN: grep {MCInst(opcode=.*, operands=.reg:19, reg:0, val:1.)} %t
+ subl $1, %eax
+
+// FIXME: Check that this matches SUB32ri8
+// RUN: grep {MCInst(opcode=.*, operands=.reg:19, reg:0, val:-1.)} %t
+ subl $-1, %eax
+
+// FIXME: Check that this matches SUB32ri
+// RUN: grep {MCInst(opcode=.*, operands=.reg:19, reg:0, val:256.)} %t
+ subl $256, %eax
+
+
Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=78530&r1=78529&r2=78530&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Sun Aug 9 02:20:21 2009
@@ -289,6 +289,12 @@
/// N) for the Nth user defined class.
unsigned Kind;
+ /// SuperClassKind - The super class kind for user classes.
+ unsigned SuperClassKind;
+
+ /// SuperClass - The super class, or 0.
+ ClassInfo *SuperClass;
+
/// Name - The full class name, suitable for use in an enum.
std::string Name;
@@ -308,27 +314,40 @@
/// MCInst; this is not valid for Token kinds.
std::string RenderMethod;
+ /// isUserClass() - Check if this is a user defined class.
+ bool isUserClass() const {
+ return Kind >= UserClass0;
+ }
+
+ /// getRootClass - Return the root class of this one.
+ const ClassInfo *getRootClass() const {
+ const ClassInfo *CI = this;
+ while (CI->SuperClass)
+ CI = CI->SuperClass;
+ return CI;
+ }
+
/// operator< - Compare two classes.
bool operator<(const ClassInfo &RHS) const {
- // Incompatible kinds are comparable.
- if (Kind != RHS.Kind)
+ // Incompatible kinds are comparable for classes in disjoint hierarchies.
+ if (Kind != RHS.Kind && getRootClass() != RHS.getRootClass())
return Kind < RHS.Kind;
switch (Kind) {
case Invalid:
assert(0 && "Invalid kind!");
case Token:
- // Tokens are always comparable.
+ // Tokens are comparable by value.
//
// FIXME: Compare by enum value.
return ValueName < RHS.ValueName;
- case Register:
- // FIXME: Compare by subset relation.
- return false;
-
default:
- // FIXME: Allow user defined relation.
+ // This class preceeds the RHS if the RHS is a super class.
+ for (ClassInfo *Parent = SuperClass; Parent; Parent = Parent->SuperClass)
+ if (Parent == &RHS)
+ return true;
+
return false;
}
}
@@ -525,6 +544,7 @@
ClassInfo *
AsmMatcherInfo::getOperandClass(const StringRef &Token,
const CodeGenInstruction::OperandInfo &OI) {
+ unsigned SuperClass = ClassInfo::Invalid;
std::string ClassName;
if (OI.Rec->isSubClassOf("RegisterClass")) {
ClassName = "Reg";
@@ -536,17 +556,24 @@
PrintError(OI.Rec->getLoc(), "operand has no match class!");
ClassName = "Invalid";
}
+
+ // Determine the super class.
+ try {
+ std::string SuperClassName =
+ OI.Rec->getValueAsString("ParserMatchSuperClass");
+ SuperClass = getUserClassKind(SuperClassName);
+ } catch(...) { }
}
ClassInfo *&Entry = OperandClasses[ClassName];
if (!Entry) {
Entry = new ClassInfo();
- // FIXME: Hack.
if (ClassName == "Reg") {
Entry->Kind = ClassInfo::Register;
} else {
Entry->Kind = getUserClassKind(ClassName);
+ Entry->SuperClassKind = SuperClass;
}
Entry->ClassName = ClassName;
Entry->Name = "MCK_" + ClassName;
@@ -622,6 +649,27 @@
Instructions.push_back(II.take());
}
+
+ // Bind user super classes.
+ std::map<unsigned, ClassInfo*> UserClasses;
+ for (unsigned i = 0, e = Classes.size(); i != e; ++i) {
+ ClassInfo &CI = *Classes[i];
+ if (CI.isUserClass())
+ UserClasses[CI.Kind] = &CI;
+ }
+
+ for (unsigned i = 0, e = Classes.size(); i != e; ++i) {
+ ClassInfo &CI = *Classes[i];
+ if (CI.isUserClass() && CI.SuperClassKind != ClassInfo::Invalid) {
+ CI.SuperClass = UserClasses[CI.SuperClassKind];
+ assert(CI.SuperClass && "Missing super class definition!");
+ } else {
+ CI.SuperClass = 0;
+ }
+ }
+
+ // Reorder classes so that classes preceed super classes.
+ std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>());
}
static void EmitConvertToMCInst(CodeGenTarget &Target,
@@ -790,8 +838,22 @@
ClassInfo &CI = **it;
if (CI.Kind != ClassInfo::Token) {
- OS << " if (Operand." << CI.PredicateMethod << "())\n";
+ OS << " // '" << CI.ClassName << "' class";
+ if (CI.SuperClass) {
+ OS << ", subclass of '" << CI.SuperClass->ClassName << "'";
+ assert(CI < *CI.SuperClass && "Invalid class relation!");
+ }
+ OS << "\n";
+
+ OS << " if (Operand." << CI.PredicateMethod << "()) {\n";
+
+ // Validate subclass relationships.
+ if (CI.SuperClass)
+ OS << " assert(Operand." << CI.SuperClass->PredicateMethod
+ << "() && \"Invalid class relationship!\");\n";
+
OS << " return " << CI.Name << ";\n\n";
+ OS << " }";
}
}
OS << " return InvalidMatchClass;\n";
More information about the llvm-commits
mailing list