diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:08:18 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:08:18 +0000 |
| commit | 5ca98fd98791947eba83a1ed3f2c8191ef7afa6c (patch) | |
| tree | f5944309621cee4fe0976be6f9ac619b7ebfc4c2 /utils/TableGen/CodeGenInstruction.cpp | |
| parent | 68bcb7db193e4bc81430063148253d30a791023e (diff) | |
Notes
Diffstat (limited to 'utils/TableGen/CodeGenInstruction.cpp')
| -rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 84 |
1 files changed, 56 insertions, 28 deletions
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 576388b2ed1c..2577ad4d919d 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -69,7 +69,7 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { std::string EncoderMethod; std::string OperandType = "OPERAND_UNKNOWN"; unsigned NumOps = 1; - DagInit *MIOpInfo = 0; + DagInit *MIOpInfo = nullptr; if (Rec->isSubClassOf("RegisterOperand")) { PrintMethod = Rec->getValueAsString("PrintMethod"); } else if (Rec->isSubClassOf("Operand")) { @@ -106,11 +106,11 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { // Check that the operand has a name and that it's unique. if (ArgName.empty()) - PrintFatalError("In instruction '" + R->getName() + "', operand #" + utostr(i) + - " has no name!"); + PrintFatalError("In instruction '" + R->getName() + "', operand #" + + Twine(i) + " has no name!"); if (!OperandNames.insert(ArgName).second) - PrintFatalError("In instruction '" + R->getName() + "', operand #" + utostr(i) + - " has the same name as a previous operand!"); + PrintFatalError("In instruction '" + R->getName() + "', operand #" + + Twine(i) + " has the same name as a previous operand!"); OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod, OperandType, MIOperandNo, NumOps, @@ -133,8 +133,8 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { unsigned CGIOperandList::getOperandNamed(StringRef Name) const { unsigned OpIdx; if (hasOperandNamed(Name, OpIdx)) return OpIdx; - PrintFatalError("'" + TheDef->getName() + "' does not have an operand named '$" + - Name.str() + "'!"); + PrintFatalError("'" + TheDef->getName() + + "' does not have an operand named '$" + Name + "'!"); } /// hasOperandNamed - Query whether the instruction has an operand of the @@ -182,7 +182,7 @@ CGIOperandList::ParseOperandName(const std::string &Op, bool AllowWholeOp) { // Find the suboperand number involved. DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo; - if (MIOpInfo == 0) + if (!MIOpInfo) PrintFatalError(TheDef->getName() + ": unknown suboperand name in '" + Op + "'"); // Find the operand with the right name. @@ -290,7 +290,7 @@ void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) { //===----------------------------------------------------------------------===// CodeGenInstruction::CodeGenInstruction(Record *R) - : TheDef(R), Operands(R), InferredFrom(0) { + : TheDef(R), Operands(R), InferredFrom(nullptr) { Namespace = R->getValueAsString("Namespace"); AsmString = R->getValueAsString("AsmString"); @@ -315,10 +315,13 @@ CodeGenInstruction::CodeGenInstruction(Record *R) hasCtrlDep = R->getValueAsBit("hasCtrlDep"); isNotDuplicable = R->getValueAsBit("isNotDuplicable"); - mayLoad = R->getValueAsBitOrUnset("mayLoad", mayLoad_Unset); - mayStore = R->getValueAsBitOrUnset("mayStore", mayStore_Unset); - hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects", - hasSideEffects_Unset); + bool Unset; + mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset); + mayLoad_Unset = Unset; + mayStore = R->getValueAsBitOrUnset("mayStore", Unset); + mayStore_Unset = Unset; + hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects", Unset); + hasSideEffects_Unset = Unset; neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove"); @@ -433,26 +436,33 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, ResultOperand &ResOp) { Init *Arg = Result->getArg(AliasOpNo); DefInit *ADI = dyn_cast<DefInit>(Arg); + Record *ResultRecord = ADI ? ADI->getDef() : nullptr; if (ADI && ADI->getDef() == InstOpRec) { // If the operand is a record, it must have a name, and the record type // must match up with the instruction's argument type. if (Result->getArgName(AliasOpNo).empty()) - PrintFatalError(Loc, "result argument #" + utostr(AliasOpNo) + - " must have a name!"); - ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef()); + PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) + + " must have a name!"); + ResOp = ResultOperand(Result->getArgName(AliasOpNo), ResultRecord); return true; } // For register operands, the source register class can be a subclass // of the instruction register class, not just an exact match. + if (InstOpRec->isSubClassOf("RegisterOperand")) + InstOpRec = InstOpRec->getValueAsDef("RegClass"); + + if (ADI && ADI->getDef()->isSubClassOf("RegisterOperand")) + ADI = ADI->getDef()->getValueAsDef("RegClass")->getDefInit(); + 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()); + ResOp = ResultOperand(Result->getArgName(AliasOpNo), ResultRecord); return true; } @@ -465,9 +475,6 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, InstOpRec = cast<DefInit>(DI->getArg(0))->getDef(); } - if (InstOpRec->isSubClassOf("RegisterOperand")) - InstOpRec = InstOpRec->getValueAsDef("RegClass"); - if (!InstOpRec->isSubClassOf("RegisterClass")) return false; @@ -481,7 +488,7 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, PrintFatalError(Loc, "result fixed register argument must " "not have a name!"); - ResOp = ResultOperand(ADI->getDef()); + ResOp = ResultOperand(ResultRecord); return true; } @@ -497,7 +504,7 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, // throw TGError(Loc, "reg0 used for result that is not an " // "OptionalDefOperand!"); - ResOp = ResultOperand(static_cast<Record*>(0)); + ResOp = ResultOperand(static_cast<Record*>(nullptr)); return true; } @@ -507,7 +514,7 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, return false; // Integer arguments can't have names. if (!Result->getArgName(AliasOpNo).empty()) - PrintFatalError(Loc, "result argument #" + utostr(AliasOpNo) + + PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) + " must not have a name!"); ResOp = ResultOperand(II->getValue()); return true; @@ -529,13 +536,34 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, return false; } -CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) { - AsmString = R->getValueAsString("AsmString"); +unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const { + if (!isRecord()) + return 1; + + Record *Rec = getRecord(); + if (!Rec->isSubClassOf("Operand")) + return 1; + + DagInit *MIOpInfo = Rec->getValueAsDag("MIOperandInfo"); + if (MIOpInfo->getNumArgs() == 0) { + // Unspecified, so it defaults to 1 + return 1; + } + + return MIOpInfo->getNumArgs(); +} + +CodeGenInstAlias::CodeGenInstAlias(Record *R, unsigned Variant, + CodeGenTarget &T) + : TheDef(R) { Result = R->getValueAsDag("ResultInst"); + AsmString = R->getValueAsString("AsmString"); + AsmString = CodeGenInstruction::FlattenAsmStringVariants(AsmString, Variant); + // Verify that the root of the result is an instruction. DefInit *DI = dyn_cast<DefInit>(Result->getOperator()); - if (DI == 0 || !DI->getDef()->isSubClassOf("Instruction")) + if (!DI || !DI->getDef()->isSubClassOf("Instruction")) PrintFatalError(R->getLoc(), "result of inst alias should be an instruction"); @@ -620,14 +648,14 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) { ResultInstOperandIndex.push_back(std::make_pair(i, SubOp)); ++AliasOpNo; } else { - PrintFatalError(R->getLoc(), "result argument #" + utostr(AliasOpNo) + + PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) + " does not match instruction operand class " + (SubOp == 0 ? InstOpRec->getName() :SubRec->getName())); } } continue; } - PrintFatalError(R->getLoc(), "result argument #" + utostr(AliasOpNo) + + PrintFatalError(R->getLoc(), "result argument #" + Twine(AliasOpNo) + " does not match instruction operand class " + InstOpRec->getName()); } |
