@@ -215,16 +215,6 @@ struct EncodingAndInst {
215
215
: EncodingDef(EncodingDef), Inst(Inst), HwModeName(HwModeName) {}
216
216
};
217
217
218
- struct EncodingIDAndOpcode {
219
- unsigned EncodingID;
220
- unsigned Opcode;
221
-
222
- EncodingIDAndOpcode () : EncodingID(0 ), Opcode(0 ) {}
223
- EncodingIDAndOpcode (unsigned EncodingID, unsigned Opcode)
224
- : EncodingID(EncodingID), Opcode(Opcode) {}
225
- };
226
-
227
- using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
228
218
using NamespacesHwModesMap = std::map<std::string, std::set<StringRef>>;
229
219
230
220
class DecoderEmitter {
@@ -235,11 +225,13 @@ class DecoderEmitter {
235
225
DecoderEmitter (const RecordKeeper &R, StringRef PredicateNamespace)
236
226
: RK(R), Target(R), PredicateNamespace(PredicateNamespace) {}
237
227
228
+ const CodeGenTarget &getTarget () const { return Target; }
229
+
238
230
// Emit the decoder state machine table. Returns a mask of MCD decoder ops
239
231
// that were emitted.
240
232
unsigned emitTable (formatted_raw_ostream &OS, DecoderTable &Table,
241
233
unsigned BitWidth, StringRef Namespace,
242
- const EncodingIDsVec & EncodingIDs) const ;
234
+ ArrayRef< unsigned > EncodingIDs) const ;
243
235
void emitInstrLenTable (formatted_raw_ostream &OS,
244
236
ArrayRef<unsigned > InstrLen) const ;
245
237
void emitPredicateFunction (formatted_raw_ostream &OS,
@@ -416,10 +408,10 @@ class Filter {
416
408
unsigned NumBits; // number of bits to filter
417
409
418
410
// Map of well-known segment value to the set of uid's with that value.
419
- std::map<uint64_t , std::vector<EncodingIDAndOpcode >> FilteredInstructions ;
411
+ std::map<uint64_t , std::vector<unsigned >> FilteredIDs ;
420
412
421
413
// Set of uid's with non-constant segment values.
422
- std::vector<EncodingIDAndOpcode> VariableInstructions ;
414
+ std::vector<unsigned > VariableIDs ;
423
415
424
416
// Map of well-known segment value to its delegate.
425
417
std::map<uint64_t , std::unique_ptr<const FilterChooser>> FilterChooserMap;
@@ -435,9 +427,9 @@ class Filter {
435
427
436
428
unsigned getNumFiltered () const { return NumFiltered; }
437
429
438
- EncodingIDAndOpcode getSingletonOpc () const {
430
+ unsigned getSingletonEncodingID () const {
439
431
assert (NumFiltered == 1 );
440
- return FilteredInstructions .begin ()->second .front ();
432
+ return FilteredIDs .begin ()->second .front ();
441
433
}
442
434
443
435
// Return the filter chooser for the group of instructions without constant
@@ -498,9 +490,7 @@ class FilterChooser {
498
490
ArrayRef<EncodingAndInst> AllInstructions;
499
491
500
492
// Vector of uid's for this filter chooser to work on.
501
- // The first member of the pair is the opcode id being decoded, the second is
502
- // the opcode id that should be emitted.
503
- ArrayRef<EncodingIDAndOpcode> Opcodes;
493
+ ArrayRef<unsigned > EncodingIDs;
504
494
505
495
// Lookup table for the operand decoding of instructions.
506
496
const std::map<unsigned , std::vector<OperandInfo>> &Operands;
@@ -528,22 +518,20 @@ class FilterChooser {
528
518
};
529
519
530
520
public:
531
- FilterChooser (ArrayRef<EncodingAndInst> Insts,
532
- ArrayRef<EncodingIDAndOpcode> IDs,
521
+ FilterChooser (ArrayRef<EncodingAndInst> Insts, ArrayRef<unsigned > EncodingIDs,
533
522
const std::map<unsigned , std::vector<OperandInfo>> &Ops,
534
523
unsigned BW, const DecoderEmitter *E)
535
- : AllInstructions(Insts), Opcodes(IDs ), Operands(Ops),
524
+ : AllInstructions(Insts), EncodingIDs(EncodingIDs ), Operands(Ops),
536
525
FilterBitValues (BW, BitValue::BIT_UNFILTERED), Parent(nullptr ),
537
526
BitWidth(BW), Emitter(E) {
538
527
doFilter ();
539
528
}
540
529
541
- FilterChooser (ArrayRef<EncodingAndInst> Insts,
542
- ArrayRef<EncodingIDAndOpcode> IDs,
530
+ FilterChooser (ArrayRef<EncodingAndInst> Insts, ArrayRef<unsigned > EncodingIDs,
543
531
const std::map<unsigned , std::vector<OperandInfo>> &Ops,
544
532
const std::vector<BitValue> &ParentFilterBitValues,
545
533
const FilterChooser &parent)
546
- : AllInstructions(Insts), Opcodes(IDs ), Operands(Ops),
534
+ : AllInstructions(Insts), EncodingIDs(EncodingIDs ), Operands(Ops),
547
535
FilterBitValues(ParentFilterBitValues), Parent(&parent),
548
536
BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
549
537
doFilter ();
@@ -608,7 +596,7 @@ class FilterChooser {
608
596
609
597
// Emits table entries to decode the singleton.
610
598
void emitSingletonTableEntry (DecoderTableInfo &TableInfo,
611
- EncodingIDAndOpcode Opc ) const ;
599
+ unsigned EncodingID ) const ;
612
600
613
601
// Emits code to decode the singleton, and then to decode the rest.
614
602
void emitSingletonTableEntry (DecoderTableInfo &TableInfo,
@@ -656,8 +644,8 @@ class FilterChooser {
656
644
657
645
Filter::Filter (Filter &&f)
658
646
: Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits),
659
- FilteredInstructions (std::move(f.FilteredInstructions )),
660
- VariableInstructions (std::move(f.VariableInstructions )),
647
+ FilteredIDs (std::move(f.FilteredIDs )),
648
+ VariableIDs (std::move(f.VariableIDs )),
661
649
FilterChooserMap(std::move(f.FilterChooserMap)),
662
650
NumFiltered(f.NumFiltered) {}
663
651
@@ -667,26 +655,26 @@ Filter::Filter(const FilterChooser &owner, unsigned startBit, unsigned numBits)
667
655
668
656
NumFiltered = 0 ;
669
657
670
- for (const auto &OpcPair : Owner.Opcodes ) {
658
+ for (unsigned EncodingID : Owner.EncodingIDs ) {
671
659
// Populates the insn given the uid.
672
- insn_t Insn = Owner.insnWithID (OpcPair. EncodingID );
660
+ insn_t Insn = Owner.insnWithID (EncodingID);
673
661
674
662
// Scans the segment for possibly well-specified encoding bits.
675
663
std::optional<uint64_t > Field = fieldFromInsn (Insn, StartBit, NumBits);
676
664
677
665
if (Field) {
678
666
// The encoding bits are well-known. Lets add the uid of the
679
667
// instruction into the bucket keyed off the constant field value.
680
- FilteredInstructions [*Field].push_back (OpcPair );
668
+ FilteredIDs [*Field].push_back (EncodingID );
681
669
++NumFiltered;
682
670
} else {
683
671
// Some of the encoding bit(s) are unspecified. This contributes to
684
672
// one additional member of "Variable" instructions.
685
- VariableInstructions .push_back (OpcPair );
673
+ VariableIDs .push_back (EncodingID );
686
674
}
687
675
}
688
676
689
- assert ((FilteredInstructions .size () + VariableInstructions .size () > 0 ) &&
677
+ assert ((FilteredIDs .size () + VariableIDs .size () > 0 ) &&
690
678
" Filter returns no instruction categories" );
691
679
}
692
680
@@ -700,17 +688,16 @@ void Filter::recurse() {
700
688
// Starts by inheriting our parent filter chooser's filter bit values.
701
689
std::vector<BitValue> BitValueArray (Owner.FilterBitValues );
702
690
703
- if (!VariableInstructions .empty ()) {
691
+ if (!VariableIDs .empty ()) {
704
692
for (unsigned bitIndex = 0 ; bitIndex < NumBits; ++bitIndex)
705
693
BitValueArray[StartBit + bitIndex] = BitValue::BIT_UNFILTERED;
706
694
707
695
// Delegates to an inferior filter chooser for further processing on this
708
696
// group of instructions whose segment values are variable.
709
697
FilterChooserMap.try_emplace (
710
698
NO_FIXED_SEGMENTS_SENTINEL,
711
- std::make_unique<FilterChooser>(Owner.AllInstructions ,
712
- VariableInstructions, Owner.Operands ,
713
- BitValueArray, Owner));
699
+ std::make_unique<FilterChooser>(Owner.AllInstructions , VariableIDs,
700
+ Owner.Operands , BitValueArray, Owner));
714
701
}
715
702
716
703
// No need to recurse for a singleton filtered instruction.
@@ -721,7 +708,7 @@ void Filter::recurse() {
721
708
}
722
709
723
710
// Otherwise, create sub choosers.
724
- for (const auto &Inst : FilteredInstructions ) {
711
+ for (const auto &Inst : FilteredIDs ) {
725
712
// Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
726
713
for (unsigned bitIndex = 0 ; bitIndex < NumBits; ++bitIndex)
727
714
BitValueArray[StartBit + bitIndex] = Inst.first & (1ULL << bitIndex)
@@ -810,7 +797,7 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
810
797
// Returns the number of fanout produced by the filter. More fanout implies
811
798
// the filter distinguishes more categories of instructions.
812
799
unsigned Filter::usefulness () const {
813
- return FilteredInstructions .size () + VariableInstructions .empty ();
800
+ return FilteredIDs .size () + VariableIDs .empty ();
814
801
}
815
802
816
803
// ////////////////////////////////
@@ -824,14 +811,16 @@ unsigned Filter::usefulness() const {
824
811
unsigned DecoderEmitter::emitTable (formatted_raw_ostream &OS,
825
812
DecoderTable &Table, unsigned BitWidth,
826
813
StringRef Namespace,
827
- const EncodingIDsVec & EncodingIDs) const {
814
+ ArrayRef< unsigned > EncodingIDs) const {
828
815
// We'll need to be able to map from a decoded opcode into the corresponding
829
816
// EncodingID for this specific combination of BitWidth and Namespace. This
830
817
// is used below to index into NumberedEncodings.
831
818
DenseMap<unsigned , unsigned > OpcodeToEncodingID;
832
819
OpcodeToEncodingID.reserve (EncodingIDs.size ());
833
- for (const auto &EI : EncodingIDs)
834
- OpcodeToEncodingID[EI.Opcode ] = EI.EncodingID ;
820
+ for (unsigned EncodingID : EncodingIDs) {
821
+ const Record *InstDef = NumberedEncodings[EncodingID].Inst ->TheDef ;
822
+ OpcodeToEncodingID[Target.getInstrIntValue (InstDef)] = EncodingID;
823
+ }
835
824
836
825
OS << " static const uint8_t DecoderTable" << Namespace << BitWidth
837
826
<< " [] = {\n " ;
@@ -1419,14 +1408,14 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
1419
1408
1420
1409
// Emits table entries to decode the singleton.
1421
1410
void FilterChooser::emitSingletonTableEntry (DecoderTableInfo &TableInfo,
1422
- EncodingIDAndOpcode Opc ) const {
1423
- insn_t Insn = insnWithID (Opc. EncodingID );
1411
+ unsigned EncodingID ) const {
1412
+ insn_t Insn = insnWithID (EncodingID);
1424
1413
1425
1414
// Look for islands of undecoded bits of the singleton.
1426
1415
std::vector<Island> Islands = getIslands (Insn);
1427
1416
1428
1417
// Emit the predicate table entry if one is needed.
1429
- emitPredicateTableEntry (TableInfo, Opc. EncodingID );
1418
+ emitPredicateTableEntry (TableInfo, EncodingID);
1430
1419
1431
1420
// Check any additional encoding fields needed.
1432
1421
for (const Island &Ilnd : reverse (Islands)) {
@@ -1451,10 +1440,10 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1451
1440
}
1452
1441
1453
1442
// Check for soft failure of the match.
1454
- emitSoftFailTableEntry (TableInfo, Opc. EncodingID );
1443
+ emitSoftFailTableEntry (TableInfo, EncodingID);
1455
1444
1456
1445
auto [DIdx, HasCompleteDecoder] =
1457
- getDecoderIndex (TableInfo.Decoders , Opc. EncodingID );
1446
+ getDecoderIndex (TableInfo.Decoders , EncodingID);
1458
1447
1459
1448
// Produce OPC_Decode or OPC_TryDecode opcode based on the information
1460
1449
// whether the instruction decoder is complete or not. If it is complete
@@ -1471,7 +1460,8 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1471
1460
: MCD::OPC_TryDecode);
1472
1461
TableInfo.Table .push_back (DecoderOp);
1473
1462
NumEncodingsSupported++;
1474
- TableInfo.Table .insertULEB128 (Opc.Opcode );
1463
+ const Record *InstDef = AllInstructions[EncodingID].Inst ->TheDef ;
1464
+ TableInfo.Table .insertULEB128 (Emitter->getTarget ().getInstrIntValue (InstDef));
1475
1465
TableInfo.Table .insertULEB128 (DIdx);
1476
1466
1477
1467
if (DecoderOp == MCD::OPC_TryDecode) {
@@ -1483,12 +1473,10 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1483
1473
// Emits table entries to decode the singleton, and then to decode the rest.
1484
1474
void FilterChooser::emitSingletonTableEntry (DecoderTableInfo &TableInfo,
1485
1475
const Filter &Best) const {
1486
- EncodingIDAndOpcode Opc = Best.getSingletonOpc ();
1487
-
1488
1476
// complex singletons need predicate checks from the first singleton
1489
1477
// to refer forward to the variable filterchooser that follows.
1490
1478
TableInfo.pushScope ();
1491
- emitSingletonTableEntry (TableInfo, Opc );
1479
+ emitSingletonTableEntry (TableInfo, Best. getSingletonEncodingID () );
1492
1480
TableInfo.popScope ();
1493
1481
1494
1482
Best.getVariableFC ().emitTableEntries (TableInfo);
@@ -1516,15 +1504,15 @@ void FilterChooser::reportRegion(std::vector<std::unique_ptr<Filter>> &Filters,
1516
1504
// recursively descends down the decoding tree.
1517
1505
bool FilterChooser::filterProcessor (ArrayRef<bitAttr_t> BitAttrs,
1518
1506
bool AllowMixed, bool Greedy) {
1519
- assert (Opcodes .size () >= 2 && " Nothing to filter" );
1507
+ assert (EncodingIDs .size () >= 2 && " Nothing to filter" );
1520
1508
1521
1509
// Heuristics. See also doFilter()'s "Heuristics" comment when num of
1522
1510
// instructions is 3.
1523
1511
if (AllowMixed && !Greedy) {
1524
- assert (Opcodes .size () == 3 );
1512
+ assert (EncodingIDs .size () == 3 );
1525
1513
1526
- for (const auto &Opcode : Opcodes ) {
1527
- insn_t Insn = insnWithID (Opcode. EncodingID );
1514
+ for (unsigned EncodingID : EncodingIDs ) {
1515
+ insn_t Insn = insnWithID (EncodingID);
1528
1516
1529
1517
// Look for islands of undecoded bits of any instruction.
1530
1518
std::vector<Island> Islands = getIslands (Insn);
@@ -1681,10 +1669,10 @@ bool FilterChooser::filterProcessor(ArrayRef<bitAttr_t> BitAttrs,
1681
1669
// the instructions. A conflict of instructions may occur, in which case we
1682
1670
// dump the conflict set to the standard error.
1683
1671
void FilterChooser::doFilter () {
1684
- assert (!Opcodes .empty () && " FilterChooser created with no instructions" );
1672
+ assert (!EncodingIDs .empty () && " FilterChooser created with no instructions" );
1685
1673
1686
1674
// No filter needed.
1687
- if (Opcodes .size () < 2 )
1675
+ if (EncodingIDs .size () < 2 )
1688
1676
return ;
1689
1677
1690
1678
// We maintain BIT_WIDTH copies of the bitAttrs automaton.
@@ -1712,8 +1700,8 @@ void FilterChooser::doFilter() {
1712
1700
if (FilterBitValues[BitIndex].isSet ())
1713
1701
BitAttrs[BitIndex] = ATTR_FILTERED;
1714
1702
1715
- for (const EncodingIDAndOpcode &OpcPair : Opcodes ) {
1716
- insn_t EncodingBits = insnWithID (OpcPair. EncodingID );
1703
+ for (unsigned EncodingID : EncodingIDs ) {
1704
+ insn_t EncodingBits = insnWithID (EncodingID);
1717
1705
1718
1706
for (unsigned BitIndex = 0 ; BitIndex < BitWidth; ++BitIndex) {
1719
1707
switch (BitAttrs[BitIndex]) {
@@ -1750,7 +1738,7 @@ void FilterChooser::doFilter() {
1750
1738
// no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
1751
1739
// well-known encoding pattern. In such case, we backtrack and scan for the
1752
1740
// the very first consecutive ATTR_ALL_SET region and assign a filter to it.
1753
- if (Opcodes .size () == 3 &&
1741
+ if (EncodingIDs .size () == 3 &&
1754
1742
filterProcessor (BitAttrs, /* AllowMixed=*/ true , /* Greedy=*/ false ))
1755
1743
return ;
1756
1744
@@ -1766,8 +1754,8 @@ void FilterChooser::doFilter() {
1766
1754
dumpStack (errs (), Indent);
1767
1755
1768
1756
// Dump encodings.
1769
- for (EncodingIDAndOpcode Opcode : Opcodes ) {
1770
- const EncodingAndInst &Enc = AllInstructions[Opcode. EncodingID ];
1757
+ for (unsigned EncodingID : EncodingIDs ) {
1758
+ const EncodingAndInst &Enc = AllInstructions[EncodingID];
1771
1759
errs () << Indent;
1772
1760
dumpBits (errs (), getBitsField (*Enc.EncodingDef , " Inst" ), BitWidth);
1773
1761
errs () << " " << Enc << ' \n ' ;
@@ -1778,11 +1766,11 @@ void FilterChooser::doFilter() {
1778
1766
// emitTableEntries - Emit state machine entries to decode our share of
1779
1767
// instructions.
1780
1768
void FilterChooser::emitTableEntries (DecoderTableInfo &TableInfo) const {
1781
- if (Opcodes .size () == 1 ) {
1769
+ if (EncodingIDs .size () == 1 ) {
1782
1770
// There is only one instruction in the set, which is great!
1783
1771
// Call emitSingletonDecoder() to see whether there are any remaining
1784
1772
// encodings bits.
1785
- emitSingletonTableEntry (TableInfo, Opcodes [0 ]);
1773
+ emitSingletonTableEntry (TableInfo, EncodingIDs [0 ]);
1786
1774
return ;
1787
1775
}
1788
1776
@@ -2528,8 +2516,8 @@ namespace {
2528
2516
NumberedAlias,
2529
2517
&Target.getInstruction (NumberedAlias->getValueAsDef (" AliasOf" )));
2530
2518
2531
- std::map<std::pair<std::string, unsigned >, std::vector<EncodingIDAndOpcode>>
2532
- OpcMap ;
2519
+ // Map of (namespace, size) tuple to encoding IDs.
2520
+ std::map<std::pair<std::string, unsigned >, std::vector< unsigned >> EncMap ;
2533
2521
std::map<unsigned , std::vector<OperandInfo>> Operands;
2534
2522
std::vector<unsigned > InstrLen;
2535
2523
bool IsVarLenInst = Target.hasVariableLengthEncodings ();
@@ -2568,16 +2556,15 @@ namespace {
2568
2556
EncodingDef->getValueAsString (" DecoderNamespace" ).str ();
2569
2557
if (!NumberedEncoding.HwModeName .empty ())
2570
2558
DecoderNamespace += " _" + NumberedEncoding.HwModeName .str ();
2571
- OpcMap[{DecoderNamespace, Size}].emplace_back (
2572
- NEI, Target.getInstrIntValue (Def));
2559
+ EncMap[{DecoderNamespace, Size}].push_back (NEI);
2573
2560
} else {
2574
2561
NumEncodingsOmitted++;
2575
2562
}
2576
2563
}
2577
2564
2578
2565
DecoderTableInfo TableInfo;
2579
2566
unsigned OpcodeMask = 0 ;
2580
- for (const auto &[NSAndByteSize, EncodingIDs] : OpcMap ) {
2567
+ for (const auto &[NSAndByteSize, EncodingIDs] : EncMap ) {
2581
2568
const std::string &DecoderNamespace = NSAndByteSize.first ;
2582
2569
const unsigned BitWidth = 8 * NSAndByteSize.second ;
2583
2570
// Emit the decoder for this namespace+width combination.
0 commit comments