Index: utils/TableGen/FixedLenDecoderEmitter.cpp =================================================================== --- utils/TableGen/FixedLenDecoderEmitter.cpp +++ utils/TableGen/FixedLenDecoderEmitter.cpp @@ -87,8 +87,23 @@ DecoderSet Decoders; }; +struct EncodingAndInst { + const Record *EncodingDef; + const CodeGenInstruction *Inst; + + EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst) + : EncodingDef(EncodingDef), Inst(Inst) {} +}; + +raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) { + if (Value.EncodingDef != Value.Inst->TheDef) + OS << Value.EncodingDef->getName() << ":"; + OS << Value.Inst->TheDef->getName(); + return OS; +} + class FixedLenDecoderEmitter { - ArrayRef NumberedInstructions; + std::vector NumberedEncodings; public: // Defaults preserved here for documentation, even though they aren't @@ -323,7 +338,7 @@ friend class Filter; // Vector of codegen instructions to choose our filter. - ArrayRef AllInstructions; + ArrayRef AllInstructions; // Vector of uid's for this filter chooser to work on. const std::vector &Opcodes; @@ -351,25 +366,24 @@ const FixedLenDecoderEmitter *Emitter; public: - FilterChooser(ArrayRef Insts, + FilterChooser(ArrayRef Insts, const std::vector &IDs, const std::map> &Ops, - unsigned BW, - const FixedLenDecoderEmitter *E) - : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), - FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1), - BitWidth(BW), Emitter(E) { + unsigned BW, const FixedLenDecoderEmitter *E) + : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), + FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1), + BitWidth(BW), Emitter(E) { doFilter(); } - FilterChooser(ArrayRef Insts, + FilterChooser(ArrayRef Insts, const std::vector &IDs, const std::map> &Ops, const std::vector &ParentFilterBitValues, const FilterChooser &parent) - : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), - FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1), - BitWidth(parent.BitWidth), Emitter(parent.Emitter) { + : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), + FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1), + BitWidth(parent.BitWidth), Emitter(parent.Emitter) { doFilter(); } @@ -381,7 +395,7 @@ protected: // Populates the insn given the uid. void insnWithID(insn_t &Insn, unsigned Opcode) const { - BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst"); + BitsInit &Bits = getBitsField(*AllInstructions[Opcode].EncodingDef, "Inst"); // We may have a SoftFail bitmask, which specifies a mask where an encoding // may differ from the value in "Inst" and yet still be valid, but the @@ -389,7 +403,7 @@ // // This is used for marking UNPREDICTABLE instructions in the ARM world. BitsInit *SFBits = - AllInstructions[Opcode]->TheDef->getValueAsBitsInit("SoftFail"); + AllInstructions[Opcode].EncodingDef->getValueAsBitsInit("SoftFail"); for (unsigned i = 0; i < BitWidth; ++i) { if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE) @@ -399,9 +413,13 @@ } } - // Returns the record name. - const StringRef nameWithID(unsigned Opcode) const { - return AllInstructions[Opcode]->TheDef->getName(); + // Emit the name of the encoding/instruction pair. + void emitNameWithID(raw_ostream &OS, unsigned Opcode) const { + const Record *EncodingDef = AllInstructions[Opcode].EncodingDef; + const Record *InstDef = AllInstructions[Opcode].Inst->TheDef; + if (EncodingDef != InstDef) + OS << EncodingDef->getName() << ":"; + OS << InstDef->getName(); } // Populates the field of the insn given the start position and the number of @@ -828,7 +846,8 @@ if (!IsTry) { OS << "// Opcode: " - << NumberedInstructions[Opc]->TheDef->getName() << "\n"; + << NumberedEncodings[Opc].EncodingDef->getName() << " => " + << NumberedEncodings[Opc].Inst->TheDef->getName() << "\n"; break; } @@ -845,8 +864,8 @@ OS << utostr(Byte) << ", "; NumToSkip |= Byte << 16; - OS << "// Opcode: " - << NumberedInstructions[Opc]->TheDef->getName() + OS << "// Opcode: " << NumberedEncodings[Opc].EncodingDef->getName() + << " => " << NumberedEncodings[Opc].Inst->TheDef->getName() << ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; break; } @@ -1153,7 +1172,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, unsigned Opc) const { ListInit *Predicates = - AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); + AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates"); bool IsFirstEmission = true; for (unsigned i = 0; i < Predicates->size(); ++i) { Record *Pred = Predicates->getElementAsRecord(i); @@ -1182,7 +1201,7 @@ bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const { ListInit *Predicates = - AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); + AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates"); for (unsigned i = 0; i < Predicates->size(); ++i) { Record *Pred = Predicates->getElementAsRecord(i); if (!Pred->getValue("AssemblerMatcherPredicate")) @@ -1247,9 +1266,10 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const { BitsInit *SFBits = - AllInstructions[Opc]->TheDef->getValueAsBitsInit("SoftFail"); + AllInstructions[Opc].EncodingDef->getValueAsBitsInit("SoftFail"); if (!SFBits) return; - BitsInit *InstBits = AllInstructions[Opc]->TheDef->getValueAsBitsInit("Inst"); + BitsInit *InstBits = + AllInstructions[Opc].EncodingDef->getValueAsBitsInit("Inst"); APInt PositiveMask(BitWidth, 0ULL); APInt NegativeMask(BitWidth, 0ULL); @@ -1270,9 +1290,9 @@ break; default: // The bit is not set; this must be an error! - StringRef Name = AllInstructions[Opc]->TheDef->getName(); - errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in " << Name - << " is set but Inst{" << i << "} is unset!\n" + errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in " + << AllInstructions[Opc] << " is set but Inst{" << i + << "} is unset!\n" << " - You can only mark a bit as SoftFail if it is fully defined" << " (1/0 - not '?') in Inst\n"; return; @@ -1709,9 +1729,11 @@ dumpStack(errs(), "\t\t"); for (unsigned i = 0; i < Opcodes.size(); ++i) { - errs() << '\t' << nameWithID(Opcodes[i]) << " "; + errs() << '\t'; + emitNameWithID(errs(), Opcodes[i]); + errs() << " "; dumpBits(errs(), - getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); + getBitsField(*AllInstructions[Opcodes[i]].EncodingDef, "Inst")); errs() << '\n'; } } @@ -2326,13 +2348,17 @@ Target.reverseBitsForLittleEndianEncoding(); // Parameterize the decoders based on namespace and instruction width. - NumberedInstructions = Target.getInstructionsByEnumValue(); + const auto &NumberedInstructions = Target.getInstructionsByEnumValue(); + NumberedEncodings.reserve(NumberedInstructions.size()); + for (const auto &NumberedInstruction : NumberedInstructions) + NumberedEncodings.emplace_back(NumberedInstruction->TheDef, NumberedInstruction); + std::map, std::vector> OpcMap; std::map> Operands; - for (unsigned i = 0; i < NumberedInstructions.size(); ++i) { - const CodeGenInstruction *Inst = NumberedInstructions[i]; + for (unsigned i = 0; i < NumberedEncodings.size(); ++i) { + const CodeGenInstruction *Inst = NumberedEncodings[i].Inst; const Record *Def = Inst->TheDef; unsigned Size = Def->getValueAsInt("Size"); if (Def->getValueAsString("Namespace") == "TargetOpcode" || @@ -2353,8 +2379,10 @@ DecoderTableInfo TableInfo; for (const auto &Opc : OpcMap) { // Emit the decoder for this namespace+width combination. - FilterChooser FC(NumberedInstructions, Opc.second, Operands, - 8*Opc.first.second, this); + ArrayRef NumberedEncodingsRef( + NumberedEncodings.data(), NumberedEncodings.size()); + FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands, + 8 * Opc.first.second, this); // The decode table is cleared for each top level decoder function. The // predicates and decoders themselves, however, are shared across all