diff options
Diffstat (limited to 'utils/TableGen/CodeGenInstruction.cpp')
-rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 53d499f..fb9ad93 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -245,7 +245,7 @@ static void ParseConstraint(const std::string &CStr, CGIOperandList &Ops) { if (!Ops[DestOp.first].Constraints[DestOp.second].isNone()) throw "Operand '" + DestOpName + "' cannot have multiple constraints!"; Ops[DestOp.first].Constraints[DestOp.second] = - CGIOperandList::ConstraintInfo::getTied(FlatOpNo); + CGIOperandList::ConstraintInfo::getTied(FlatOpNo); } static void ParseConstraints(const std::string &CStr, CGIOperandList &Ops) { @@ -423,6 +423,18 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, return true; } + // For register operands, the source register class can be a subclass + // of the instruction register class, not just an exact match. + if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) { + if (!InstOpRec->isSubClassOf("RegisterClass")) + return false; + if (!T.getRegisterClass(InstOpRec) + .hasSubClass(&T.getRegisterClass(ADI->getDef()))) + return false; + ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef()); + return true; + } + // Handle explicit registers. if (ADI && ADI->getDef()->isSubClassOf("Register")) { if (InstOpRec->isSubClassOf("OptionalDefOperand")) { @@ -456,14 +468,19 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, if (ADI && ADI->getDef()->getName() == "zero_reg") { // Check if this is an optional def. - if (!InstOpRec->isSubClassOf("OptionalDefOperand")) - throw TGError(Loc, "reg0 used for result that is not an " - "OptionalDefOperand!"); + // Tied operands where the source is a sub-operand of a complex operand + // need to represent both operands in the alias destination instruction. + // Allow zero_reg for the tied portion. This can and should go away once + // the MC representation of things doesn't use tied operands at all. + //if (!InstOpRec->isSubClassOf("OptionalDefOperand")) + // throw TGError(Loc, "reg0 used for result that is not an " + // "OptionalDefOperand!"); ResOp = ResultOperand(static_cast<Record*>(0)); return true; } + // Literal integers. if (IntInit *II = dynamic_cast<IntInit*>(Arg)) { if (hasSubOps || !InstOpRec->isSubClassOf("Operand")) return false; @@ -475,6 +492,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; } @@ -511,8 +541,11 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) { unsigned AliasOpNo = 0; for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { - // Tied registers don't have an entry in the result dag. - if (ResultInst->Operands[i].getTiedRegister() != -1) + // Tied registers don't have an entry in the result dag unless they're part + // of a complex operand, in which case we include them anyways, as we + // don't have any other way to specify the whole operand. + if (ResultInst->Operands[i].MINumOperands == 1 && + ResultInst->Operands[i].getTiedRegister() != -1) continue; if (AliasOpNo >= Result->getNumArgs()) |