X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenInstruction.cpp;h=38e2b832f2f95fc36c04ab39b33f561f11a2a2bb;hb=0bad086d6dd2ee2d4ab8269ace959f7fb9cb3b9d;hp=73fe9162585a5db16f91e303c08a39c44fdc9337;hpb=ae1920b1efa72c1789d562df4746110d0c2e10bd;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 73fe9162585..38e2b832f2f 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -13,7 +13,8 @@ #include "CodeGenInstruction.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/STLExtras.h" @@ -66,10 +67,14 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { Record *Rec = Arg->getDef(); std::string PrintMethod = "printOperand"; std::string EncoderMethod; + std::string OperandType = "OPERAND_UNKNOWN"; unsigned NumOps = 1; DagInit *MIOpInfo = 0; - if (Rec->isSubClassOf("Operand")) { + if (Rec->isSubClassOf("RegisterOperand")) { PrintMethod = Rec->getValueAsString("PrintMethod"); + } else if (Rec->isSubClassOf("Operand")) { + PrintMethod = Rec->getValueAsString("PrintMethod"); + OperandType = Rec->getValueAsString("OperandType"); // If there is an explicit encoder method, use it. EncoderMethod = Rec->getValueAsString("EncoderMethod"); MIOpInfo = Rec->getValueAsDag("MIOperandInfo"); @@ -93,8 +98,9 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { } else if (Rec->getName() == "variable_ops") { isVariadic = true; continue; - } else if (!Rec->isSubClassOf("RegisterClass") && - !Rec->isSubClassOf("PointerLikeRegClass") && + } else if (Rec->isSubClassOf("RegisterClass")) { + OperandType = "OPERAND_REGISTER"; + } else if (!Rec->isSubClassOf("PointerLikeRegClass") && Rec->getName() != "unknown") throw "Unknown operand class '" + Rec->getName() + "' in '" + R->getName() + "' instruction!"; @@ -108,7 +114,8 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { " has the same name as a previous operand!"; OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod, - MIOperandNo, NumOps, MIOpInfo)); + OperandType, MIOperandNo, NumOps, + MIOpInfo)); MIOperandNo += NumOps; } @@ -238,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) { @@ -260,8 +267,9 @@ static void ParseConstraints(const std::string &CStr, CGIOperandList &Ops) { void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) { while (1) { - std::string OpName; - tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t"); + std::pair P = getToken(DisableEncoding, " ,\t"); + std::string OpName = P.first; + DisableEncoding = P.second; if (OpName.empty()) break; // Figure out which operand this is. @@ -279,7 +287,8 @@ void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) { // CodeGenInstruction Implementation //===----------------------------------------------------------------------===// -CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) { +CodeGenInstruction::CodeGenInstruction(Record *R) + : TheDef(R), Operands(R), InferredFrom(0) { Namespace = R->getValueAsString("Namespace"); AsmString = R->getValueAsString("AsmString"); @@ -289,11 +298,10 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) { isCompare = R->getValueAsBit("isCompare"); isMoveImm = R->getValueAsBit("isMoveImm"); isBitcast = R->getValueAsBit("isBitcast"); + isSelect = R->getValueAsBit("isSelect"); isBarrier = R->getValueAsBit("isBarrier"); isCall = R->getValueAsBit("isCall"); canFoldAsLoad = R->getValueAsBit("canFoldAsLoad"); - mayLoad = R->getValueAsBit("mayLoad"); - mayStore = R->getValueAsBit("mayStore"); isPredicable = Operands.isPredicable || R->getValueAsBit("isPredicable"); isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress"); isCommutable = R->getValueAsBit("isCommutable"); @@ -301,13 +309,21 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) { isReMaterializable = R->getValueAsBit("isReMaterializable"); hasDelaySlot = R->getValueAsBit("hasDelaySlot"); usesCustomInserter = R->getValueAsBit("usesCustomInserter"); + hasPostISelHook = R->getValueAsBit("hasPostISelHook"); hasCtrlDep = R->getValueAsBit("hasCtrlDep"); isNotDuplicable = R->getValueAsBit("isNotDuplicable"); - hasSideEffects = R->getValueAsBit("hasSideEffects"); + + mayLoad = R->getValueAsBitOrUnset("mayLoad", mayLoad_Unset); + mayStore = R->getValueAsBitOrUnset("mayStore", mayStore_Unset); + hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects", + hasSideEffects_Unset); neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); + isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove"); hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq"); hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq"); + isCodeGenOnly = R->getValueAsBit("isCodeGenOnly"); + isPseudo = R->getValueAsBit("isPseudo"); ImplicitDefs = R->getValueAsListOfDefs("Defs"); ImplicitUses = R->getValueAsListOfDefs("Uses"); @@ -397,7 +413,7 @@ FlattenAsmStringVariants(StringRef Cur, unsigned Variant) { /// successful match, with ResOp set to the result operand to be used. bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, Record *InstOpRec, bool hasSubOps, - SMLoc Loc, CodeGenTarget &T, + ArrayRef Loc, CodeGenTarget &T, ResultOperand &ResOp) { Init *Arg = Result->getArg(AliasOpNo); DefInit *ADI = dynamic_cast(Arg); @@ -412,15 +428,37 @@ 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")) { + DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo"); + // The operand info should only have a single (register) entry. We + // want the register class of it. + InstOpRec = dynamic_cast(DI->getArg(0))->getDef(); + } + + if (InstOpRec->isSubClassOf("RegisterOperand")) + InstOpRec = InstOpRec->getValueAsDef("RegClass"); + if (!InstOpRec->isSubClassOf("RegisterClass")) return false; if (!T.getRegisterClass(InstOpRec) .contains(T.getRegBank().getReg(ADI->getDef()))) - throw TGError(Loc, "fixed register " +ADI->getDef()->getName() - + " is not a member of the " + InstOpRec->getName() + + throw TGError(Loc, "fixed register " + ADI->getDef()->getName() + + " is not a member of the " + InstOpRec->getName() + " register class!"); if (!Result->getArgName(AliasOpNo).empty()) @@ -435,14 +473,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(0)); return true; } + // Literal integers. if (IntInit *II = dynamic_cast(Arg)) { if (hasSubOps || !InstOpRec->isSubClassOf("Operand")) return false; @@ -454,6 +497,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; } @@ -490,8 +546,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()) @@ -502,9 +561,31 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) { ResultOperand ResOp(static_cast(0)); if (tryAliasOpMatch(Result, AliasOpNo, InstOpRec, (NumSubOps > 1), R->getLoc(), T, ResOp)) { - ResultOperands.push_back(ResOp); - ResultInstOperandIndex.push_back(std::make_pair(i, -1)); - ++AliasOpNo; + // If this is a simple operand, or a complex operand with a custom match + // class, then we can match is verbatim. + if (NumSubOps == 1 || + (InstOpRec->getValue("ParserMatchClass") && + InstOpRec->getValueAsDef("ParserMatchClass") + ->getValueAsString("Name") != "Imm")) { + ResultOperands.push_back(ResOp); + ResultInstOperandIndex.push_back(std::make_pair(i, -1)); + ++AliasOpNo; + + // Otherwise, we need to match each of the suboperands individually. + } else { + DagInit *MIOI = ResultInst->Operands[i].MIOperandInfo; + for (unsigned SubOp = 0; SubOp != NumSubOps; ++SubOp) { + Record *SubRec = dynamic_cast(MIOI->getArg(SubOp))->getDef(); + + // Take care to instantiate each of the suboperands with the correct + // nomenclature: $foo.bar + ResultOperands.push_back( + ResultOperand(Result->getArgName(AliasOpNo) + "." + + MIOI->getArgName(SubOp), SubRec)); + ResultInstOperandIndex.push_back(std::make_pair(i, SubOp)); + } + ++AliasOpNo; + } continue; }