@@ -360,9 +360,6 @@ fieldFromInsn(const insn_t &Insn, unsigned StartBit, unsigned NumBits) {
360360
361361namespace {
362362
363- static constexpr uint64_t NO_FIXED_SEGMENTS_SENTINEL =
364- std::numeric_limits<uint64_t >::max();
365-
366363class FilterChooser ;
367364
368365// / Filter - Filter works with FilterChooser to produce the decoding tree for
@@ -416,6 +413,9 @@ class Filter {
416413 // Map of well-known segment value to its delegate.
417414 std::map<uint64_t , std::unique_ptr<const FilterChooser>> FilterChooserMap;
418415
416+ // A filter chooser for encodings that contain some '?' in the filtered range.
417+ std::unique_ptr<const FilterChooser> VariableFC;
418+
419419 // Number of instructions which fall under FilteredInstructions category.
420420 unsigned NumFiltered;
421421
@@ -435,8 +435,8 @@ class Filter {
435435 // Return the filter chooser for the group of instructions without constant
436436 // segment values.
437437 const FilterChooser &getVariableFC () const {
438- assert (NumFiltered == 1 && FilterChooserMap.size () == 1 );
439- return *(FilterChooserMap. find (NO_FIXED_SEGMENTS_SENTINEL)-> second ) ;
438+ assert (NumFiltered == 1 && FilterChooserMap.empty () );
439+ return *VariableFC ;
440440 }
441441
442442 // Divides the decoding task into sub tasks and delegates them to the
@@ -647,7 +647,7 @@ Filter::Filter(Filter &&f)
647647 FilteredIDs(std::move(f.FilteredIDs)),
648648 VariableIDs(std::move(f.VariableIDs)),
649649 FilterChooserMap(std::move(f.FilterChooserMap)),
650- NumFiltered(f.NumFiltered) {}
650+ VariableFC(std::move(f.VariableFC)), NumFiltered(f.NumFiltered) {}
651651
652652Filter::Filter (const FilterChooser &owner, unsigned startBit, unsigned numBits)
653653 : Owner(owner), StartBit(startBit), NumBits(numBits) {
@@ -694,16 +694,15 @@ void Filter::recurse() {
694694
695695 // Delegates to an inferior filter chooser for further processing on this
696696 // group of instructions whose segment values are variable.
697- FilterChooserMap.try_emplace (
698- NO_FIXED_SEGMENTS_SENTINEL,
697+ VariableFC =
699698 std::make_unique<FilterChooser>(Owner.AllInstructions , VariableIDs,
700- Owner.Operands , BitValueArray, Owner)) ;
699+ Owner.Operands , BitValueArray, Owner);
701700 }
702701
703702 // No need to recurse for a singleton filtered instruction.
704703 // See also Filter::emit*().
705704 if (getNumFiltered () == 1 ) {
706- assert (FilterChooserMap. size () == 1 );
705+ assert (VariableFC && " Shouldn't have created a filter for one encoding! " );
707706 return ;
708707 }
709708
@@ -733,46 +732,30 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
733732 TableInfo.Table .insertULEB128 (StartBit);
734733 TableInfo.Table .push_back (NumBits);
735734
736- // If the NO_FIXED_SEGMENTS_SENTINEL is present, we need to add a new scope
737- // for this filter. Otherwise, we can skip adding a new scope and any
738- // patching added will automatically be added to the enclosing scope.
739-
740- // If NO_FIXED_SEGMENTS_SENTINEL is present, it will be last entry in
741- // FilterChooserMap.
742-
735+ // If VariableFC is present, we need to add a new scope for this filter.
736+ // Otherwise, we can skip adding a new scope and any patching added will
737+ // automatically be added to the enclosing scope.
743738 const uint64_t LastFilter = FilterChooserMap.rbegin ()->first ;
744- bool HasFallthrough = LastFilter == NO_FIXED_SEGMENTS_SENTINEL;
745- if (HasFallthrough)
746- TableInfo.pushScope ();
739+ if (VariableFC)
740+ TableInfo.FixupStack .emplace_back ();
747741
748742 DecoderTable &Table = TableInfo.Table ;
749743
750744 size_t PrevFilter = 0 ;
751745 for (const auto &[FilterVal, Delegate] : FilterChooserMap) {
752- // Field value NO_FIXED_SEGMENTS_SENTINEL implies a non-empty set of
753- // variable instructions. See also recurse().
754- if (FilterVal == NO_FIXED_SEGMENTS_SENTINEL) {
755- // Each scope should always have at least one filter value to check
756- // for.
757- assert (PrevFilter != 0 && " empty filter set!" );
758- TableInfo.popScope ();
759- PrevFilter = 0 ; // Don't re-process the filter's fallthrough.
746+ // The last filtervalue emitted can be OPC_FilterValue if we are at
747+ // outermost scope.
748+ const uint8_t DecoderOp =
749+ FilterVal == LastFilter && TableInfo.isOutermostScope ()
750+ ? MCD::OPC_FilterValueOrFail
751+ : MCD::OPC_FilterValue;
752+ Table.push_back (DecoderOp);
753+ Table.insertULEB128 (FilterVal);
754+ if (DecoderOp == MCD::OPC_FilterValue) {
755+ // Reserve space for the NumToSkip entry. We'll backpatch the value later.
756+ PrevFilter = Table.insertNumToSkip ();
760757 } else {
761- // The last filtervalue emitted can be OPC_FilterValue if we are at
762- // outermost scope.
763- const uint8_t DecoderOp =
764- FilterVal == LastFilter && TableInfo.isOutermostScope ()
765- ? MCD::OPC_FilterValueOrFail
766- : MCD::OPC_FilterValue;
767- Table.push_back (DecoderOp);
768- Table.insertULEB128 (FilterVal);
769- if (DecoderOp == MCD::OPC_FilterValue) {
770- // Reserve space for the NumToSkip entry. We'll backpatch the value
771- // later.
772- PrevFilter = Table.insertNumToSkip ();
773- } else {
774- PrevFilter = 0 ;
775- }
758+ PrevFilter = 0 ;
776759 }
777760
778761 // We arrive at a category of instructions with the same segment value.
@@ -787,6 +770,16 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
787770 Table.patchNumToSkip (PrevFilter, Table.size ());
788771 }
789772
773+ if (VariableFC) {
774+ // Each scope should always have at least one filter value to check for.
775+ assert (PrevFilter != 0 && " empty filter set!" );
776+ TableInfo.popScope ();
777+ PrevFilter = 0 ; // Don't re-process the filter's fallthrough.
778+
779+ // Delegate to the sub filter chooser for further decoding.
780+ VariableFC->emitTableEntries (TableInfo);
781+ }
782+
790783 // If there is no fallthrough and the final filter was not in the outermost
791784 // scope, then it must be fixed up according to the enclosing scope rather
792785 // than the current position.
0 commit comments