diff options
| author | Jim Grosbach <grosbach@apple.com> | 2011-10-28 22:32:53 +0000 |
|---|---|---|
| committer | Jim Grosbach <grosbach@apple.com> | 2011-10-28 22:32:53 +0000 |
| commit | d1f1b79b523f1b9292b19d93e2e92d85dcb60113 (patch) | |
| tree | f99b4fd52fcaa39cbf56d687c00f9fc694d0175e /llvm/utils | |
| parent | 5524ce7d829cdbb3938711cf11916946a985ee0d (diff) | |
| download | bcm5719-llvm-d1f1b79b523f1b9292b19d93e2e92d85dcb60113.tar.gz bcm5719-llvm-d1f1b79b523f1b9292b19d93e2e92d85dcb60113.zip | |
Allow InstAlias's to use immediate matcher patterns that xform the value.
For example,
On ARM, "mov r3, #-3" is an alias for "mvn r3, #2", so we want to use a
matcher pattern that handles the bitwise negation when mapping to t2MVNi.
llvm-svn: 143233
Diffstat (limited to 'llvm/utils')
| -rw-r--r-- | llvm/utils/TableGen/AsmMatcherEmitter.cpp | 13 | ||||
| -rw-r--r-- | llvm/utils/TableGen/CodeGenInstruction.cpp | 21 |
2 files changed, 29 insertions, 5 deletions
diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp index ba69aefac6b..01754c3f91e 100644 --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -591,7 +591,8 @@ private: /// getOperandClass - Lookup or create the class for the given operand. ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI, - int SubOpIdx = -1); + int SubOpIdx); + ClassInfo *getOperandClass(Record *Rec, int SubOpIdx); /// BuildRegisterClasses - Build the ClassInfo* instances for register /// classes. @@ -870,7 +871,11 @@ AsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI, Record *Rec = OI.Rec; if (SubOpIdx != -1) Rec = dynamic_cast<DefInit*>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef(); + return getOperandClass(Rec, SubOpIdx); +} +ClassInfo * +AsmMatcherInfo::getOperandClass(Record *Rec, int SubOpIdx) { if (Rec->isSubClassOf("RegisterOperand")) { // RegisterOperand may have an associated ParserMatchClass. If it does, // use it, else just fall back to the underlying register class. @@ -1375,9 +1380,11 @@ void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II, CGA.ResultOperands[i].getName() == OperandName) { // It's safe to go with the first one we find, because CodeGenInstAlias // validates that all operands with the same name have the same record. - unsigned ResultIdx = CGA.ResultInstOperandIndex[i].first; Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second; - Op.Class = getOperandClass(CGA.ResultInst->Operands[ResultIdx], + // Use the match class from the Alias definition, not the + // destination instruction, as we may have an immediate that's + // being munged by the match class. + Op.Class = getOperandClass(CGA.ResultOperands[i].getRecord(), Op.SubOpIdx); Op.SrcOpName = OperandName; return; diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp index 9822de819db..d6515cade27 100644 --- a/llvm/utils/TableGen/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/CodeGenInstruction.cpp @@ -428,8 +428,11 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) { if (!InstOpRec->isSubClassOf("RegisterClass")) return false; - return T.getRegisterClass(InstOpRec) - .hasSubClass(&T.getRegisterClass(ADI->getDef())); + if (!T.getRegisterClass(InstOpRec) + .hasSubClass(&T.getRegisterClass(ADI->getDef()))) + return false; + ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef()); + return true; } // Handle explicit registers. @@ -473,6 +476,7 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, return true; } + // Literal integers. if (IntInit *II = dynamic_cast<IntInit*>(Arg)) { if (hasSubOps || !InstOpRec->isSubClassOf("Operand")) return false; @@ -484,6 +488,19 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, return true; } + // If both are Operands with the same MVT, allow the conversion. It's + // up to the user to make sure the values are appropriate, just like + // for isel Pat's. + if (InstOpRec->isSubClassOf("Operand") && + ADI->getDef()->isSubClassOf("Operand")) { + // FIXME: What other attributes should we check here? Identical + // MIOperandInfo perhaps? + if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type")) + return false; + ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef()); + return true; + } + return false; } |

