diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 59c0a6abe1b..facb89ade63 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -697,6 +697,15 @@ class InstrInfo { // generator has better support for complex operands and targets have // migrated away from using positionally encoded operands. bit decodePositionallyEncodedOperands = 0; + + // When set, this indicates that there will be no overlap between those + // operands that are matched by ordering (positional operands) and those + // matched by name. + // + // This option is temporary; it will go away once the TableGen decoder + // generator has better support for complex operands and targets have + // migrated away from using positionally encoded operands. + bit noNamedPositionallyEncodedOperands = 0; } // Standard Pseudo Instructions. diff --git a/lib/Target/PowerPC/PPC.td b/lib/Target/PowerPC/PPC.td index b27004d1ef9..2a9f65a6b19 100644 --- a/lib/Target/PowerPC/PPC.td +++ b/lib/Target/PowerPC/PPC.td @@ -288,6 +288,8 @@ def PPCInstrInfo : InstrInfo { // FIXME: Unset this when no longer needed! let decodePositionallyEncodedOperands = 1; + + let noNamedPositionallyEncodedOperands = 1; } def PPCAsmParser : AsmParser { diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index a4ff4eec1e4..a7fca06cf0f 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -48,6 +48,7 @@ private: void AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, unsigned &NumberedOp, + std::set &NamedOpIndices, std::string &Case, CodeGenTarget &Target); }; @@ -71,6 +72,7 @@ int CodeEmitterGen::getVariableBit(const std::string &VarName, void CodeEmitterGen:: AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, unsigned &NumberedOp, + std::set &NamedOpIndices, std::string &Case, CodeGenTarget &Target) { CodeGenInstruction &CGI = Target.getInstruction(R); @@ -103,7 +105,9 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, /// If this operand is not supposed to be emitted by the /// generated emitter, skip it. while (NumberedOp < NumberOps && - CGI.Operands.isFlatOperandNotEmitted(NumberedOp)) + (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) || + (NamedOpIndices.size() && NamedOpIndices.count( + CGI.Operands.getSubOperandNumber(NumberedOp).first)))) ++NumberedOp; OpIdx = NumberedOp++; @@ -180,6 +184,21 @@ std::string CodeEmitterGen::getInstructionCase(Record *R, const std::vector &Vals = R->getValues(); unsigned NumberedOp = 0; + std::set NamedOpIndices; + // Collect the set of operand indices that might correspond to named + // operand, and skip these when assigning operands based on position. + if (Target.getInstructionSet()-> + getValueAsBit("noNamedPositionallyEncodedOperands")) { + CodeGenInstruction &CGI = Target.getInstruction(R); + for (unsigned i = 0, e = Vals.size(); i != e; ++i) { + unsigned OpIdx; + if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx)) + continue; + + NamedOpIndices.insert(OpIdx); + } + } + // Loop over all of the fields in the instruction, determining which are the // operands to the instruction. for (unsigned i = 0, e = Vals.size(); i != e; ++i) { @@ -188,7 +207,8 @@ std::string CodeEmitterGen::getInstructionCase(Record *R, if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete()) continue; - AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, Case, Target); + AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, + NamedOpIndices, Case, Target); } std::string PostEmitter = R->getValueAsString("PostEncoderMethod"); diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp index 66ce30b540c..e249a94de4e 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -1754,6 +1754,19 @@ static bool populateInstruction(CodeGenTarget &Target, const std::vector &Vals = Def.getValues(); unsigned NumberedOp = 0; + std::set NamedOpIndices; + if (Target.getInstructionSet()-> + getValueAsBit("noNamedPositionallyEncodedOperands")) + // Collect the set of operand indices that might correspond to named + // operand, and skip these when assigning operands based on position. + for (unsigned i = 0, e = Vals.size(); i != e; ++i) { + unsigned OpIdx; + if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx)) + continue; + + NamedOpIndices.insert(OpIdx); + } + for (unsigned i = 0, e = Vals.size(); i != e; ++i) { // Ignore fixed fields in the record, we're looking for values like: // bits<5> RST = { ?, ?, ?, ?, ? }; @@ -1803,7 +1816,9 @@ static bool populateInstruction(CodeGenTarget &Target, unsigned NumberOps = CGI.Operands.size(); while (NumberedOp < NumberOps && - CGI.Operands.isFlatOperandNotEmitted(NumberedOp)) + (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) || + (NamedOpIndices.size() && NamedOpIndices.count( + CGI.Operands.getSubOperandNumber(NumberedOp).first)))) ++NumberedOp; OpIdx = NumberedOp++;