@@ -360,9 +360,6 @@ fieldFromInsn(const insn_t &Insn, unsigned StartBit, unsigned NumBits) {
360
360
361
361
namespace {
362
362
363
- static constexpr uint64_t NO_FIXED_SEGMENTS_SENTINEL =
364
- std::numeric_limits<uint64_t >::max();
365
-
366
363
class FilterChooser ;
367
364
368
365
// / Filter - Filter works with FilterChooser to produce the decoding tree for
@@ -416,6 +413,9 @@ class Filter {
416
413
// Map of well-known segment value to its delegate.
417
414
std::map<uint64_t , std::unique_ptr<const FilterChooser>> FilterChooserMap;
418
415
416
+ // A filter chooser for encodings that contain some '?' in the filtered range.
417
+ std::unique_ptr<const FilterChooser> VariableFC;
418
+
419
419
// Number of instructions which fall under FilteredInstructions category.
420
420
unsigned NumFiltered;
421
421
@@ -435,8 +435,8 @@ class Filter {
435
435
// Return the filter chooser for the group of instructions without constant
436
436
// segment values.
437
437
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 ;
440
440
}
441
441
442
442
// Divides the decoding task into sub tasks and delegates them to the
@@ -647,7 +647,7 @@ Filter::Filter(Filter &&f)
647
647
FilteredIDs(std::move(f.FilteredIDs)),
648
648
VariableIDs(std::move(f.VariableIDs)),
649
649
FilterChooserMap(std::move(f.FilterChooserMap)),
650
- NumFiltered(f.NumFiltered) {}
650
+ VariableFC(std::move(f.VariableFC)), NumFiltered(f.NumFiltered) {}
651
651
652
652
Filter::Filter (const FilterChooser &owner, unsigned startBit, unsigned numBits)
653
653
: Owner(owner), StartBit(startBit), NumBits(numBits) {
@@ -694,16 +694,15 @@ void Filter::recurse() {
694
694
695
695
// Delegates to an inferior filter chooser for further processing on this
696
696
// group of instructions whose segment values are variable.
697
- FilterChooserMap.try_emplace (
698
- NO_FIXED_SEGMENTS_SENTINEL,
697
+ VariableFC =
699
698
std::make_unique<FilterChooser>(Owner.AllInstructions , VariableIDs,
700
- Owner.Operands , BitValueArray, Owner)) ;
699
+ Owner.Operands , BitValueArray, Owner);
701
700
}
702
701
703
702
// No need to recurse for a singleton filtered instruction.
704
703
// See also Filter::emit*().
705
704
if (getNumFiltered () == 1 ) {
706
- assert (FilterChooserMap. size () == 1 );
705
+ assert (VariableFC && " Shouldn't have created a filter for one encoding! " );
707
706
return ;
708
707
}
709
708
@@ -733,46 +732,30 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
733
732
TableInfo.Table .insertULEB128 (StartBit);
734
733
TableInfo.Table .push_back (NumBits);
735
734
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.
743
738
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 ();
747
741
748
742
DecoderTable &Table = TableInfo.Table ;
749
743
750
744
size_t PrevFilter = 0 ;
751
745
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 ();
760
757
} 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 ;
776
759
}
777
760
778
761
// We arrive at a category of instructions with the same segment value.
@@ -787,6 +770,16 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
787
770
Table.patchNumToSkip (PrevFilter, Table.size ());
788
771
}
789
772
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
+
790
783
// If there is no fallthrough and the final filter was not in the outermost
791
784
// scope, then it must be fixed up according to the enclosing scope rather
792
785
// than the current position.
0 commit comments