1145449b1SDimitry Andric //===---------------- DecoderEmitter.cpp - Decoder Generator --------------===//
2cf099d11SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cf099d11SDimitry Andric //
7cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
8cf099d11SDimitry Andric //
9cf099d11SDimitry Andric // It contains the tablegen backend that emits the decoder functions for
10145449b1SDimitry Andric // targets with fixed/variable length instruction set.
11cf099d11SDimitry Andric //
12cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
13cf099d11SDimitry Andric
14ac9a064cSDimitry Andric #include "Common/CodeGenHwModes.h"
15ac9a064cSDimitry Andric #include "Common/CodeGenInstruction.h"
16ac9a064cSDimitry Andric #include "Common/CodeGenTarget.h"
17ac9a064cSDimitry Andric #include "Common/InfoByHwMode.h"
18ac9a064cSDimitry Andric #include "Common/VarLenCodeEmitterGen.h"
197fa27ce4SDimitry Andric #include "TableGenBackends.h"
2063faed5bSDimitry Andric #include "llvm/ADT/APInt.h"
21b915e9e0SDimitry Andric #include "llvm/ADT/ArrayRef.h"
22b915e9e0SDimitry Andric #include "llvm/ADT/CachedHashString.h"
23b915e9e0SDimitry Andric #include "llvm/ADT/STLExtras.h"
24e6d15924SDimitry Andric #include "llvm/ADT/SetVector.h"
25ac9a064cSDimitry Andric #include "llvm/ADT/SmallBitVector.h"
26e6d15924SDimitry Andric #include "llvm/ADT/SmallString.h"
27e6d15924SDimitry Andric #include "llvm/ADT/Statistic.h"
28cf099d11SDimitry Andric #include "llvm/ADT/StringExtras.h"
29902a7b52SDimitry Andric #include "llvm/ADT/StringRef.h"
30145449b1SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
31b915e9e0SDimitry Andric #include "llvm/Support/Casting.h"
32ac9a064cSDimitry Andric #include "llvm/Support/CommandLine.h"
33cf099d11SDimitry Andric #include "llvm/Support/Debug.h"
34b915e9e0SDimitry Andric #include "llvm/Support/ErrorHandling.h"
35902a7b52SDimitry Andric #include "llvm/Support/FormattedStream.h"
36902a7b52SDimitry Andric #include "llvm/Support/LEB128.h"
37cf099d11SDimitry Andric #include "llvm/Support/raw_ostream.h"
384a16efa3SDimitry Andric #include "llvm/TableGen/Error.h"
394a16efa3SDimitry Andric #include "llvm/TableGen/Record.h"
40b915e9e0SDimitry Andric #include <algorithm>
41b915e9e0SDimitry Andric #include <cassert>
42b915e9e0SDimitry Andric #include <cstddef>
43b915e9e0SDimitry Andric #include <cstdint>
44cf099d11SDimitry Andric #include <map>
45b915e9e0SDimitry Andric #include <memory>
46b915e9e0SDimitry Andric #include <set>
47cf099d11SDimitry Andric #include <string>
4801095a5dSDimitry Andric #include <utility>
494a16efa3SDimitry Andric #include <vector>
50cf099d11SDimitry Andric
51cf099d11SDimitry Andric using namespace llvm;
52cf099d11SDimitry Andric
535ca98fd9SDimitry Andric #define DEBUG_TYPE "decoder-emitter"
545ca98fd9SDimitry Andric
55ac9a064cSDimitry Andric extern cl::OptionCategory DisassemblerEmitterCat;
56ac9a064cSDimitry Andric
57ac9a064cSDimitry Andric enum SuppressLevel {
58ac9a064cSDimitry Andric SUPPRESSION_DISABLE,
59ac9a064cSDimitry Andric SUPPRESSION_LEVEL1,
60ac9a064cSDimitry Andric SUPPRESSION_LEVEL2
61ac9a064cSDimitry Andric };
62ac9a064cSDimitry Andric
63ac9a064cSDimitry Andric cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates(
64ac9a064cSDimitry Andric "suppress-per-hwmode-duplicates",
65ac9a064cSDimitry Andric cl::desc("Suppress duplication of instrs into per-HwMode decoder tables"),
66ac9a064cSDimitry Andric cl::values(
67ac9a064cSDimitry Andric clEnumValN(
68ac9a064cSDimitry Andric SUPPRESSION_DISABLE, "O0",
69ac9a064cSDimitry Andric "Do not prevent DecoderTable duplications caused by HwModes"),
70ac9a064cSDimitry Andric clEnumValN(
71ac9a064cSDimitry Andric SUPPRESSION_LEVEL1, "O1",
72ac9a064cSDimitry Andric "Remove duplicate DecoderTable entries generated due to HwModes"),
73ac9a064cSDimitry Andric clEnumValN(
74ac9a064cSDimitry Andric SUPPRESSION_LEVEL2, "O2",
75ac9a064cSDimitry Andric "Extract HwModes-specific instructions into new DecoderTables, "
76ac9a064cSDimitry Andric "significantly reducing Table Duplications")),
77ac9a064cSDimitry Andric cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
78ac9a064cSDimitry Andric
7958b69754SDimitry Andric namespace {
80b915e9e0SDimitry Andric
81e6d15924SDimitry Andric STATISTIC(NumEncodings, "Number of encodings considered");
82ac9a064cSDimitry Andric STATISTIC(NumEncodingsLackingDisasm,
83ac9a064cSDimitry Andric "Number of encodings without disassembler info");
84e6d15924SDimitry Andric STATISTIC(NumInstructions, "Number of instructions considered");
85e6d15924SDimitry Andric STATISTIC(NumEncodingsSupported, "Number of encodings supported");
86e6d15924SDimitry Andric STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
87e6d15924SDimitry Andric
8858b69754SDimitry Andric struct EncodingField {
8958b69754SDimitry Andric unsigned Base, Width, Offset;
EncodingField__anon260f03c00111::EncodingField9058b69754SDimitry Andric EncodingField(unsigned B, unsigned W, unsigned O)
9158b69754SDimitry Andric : Base(B), Width(W), Offset(O) {}
9258b69754SDimitry Andric };
9358b69754SDimitry Andric
9458b69754SDimitry Andric struct OperandInfo {
9558b69754SDimitry Andric std::vector<EncodingField> Fields;
9658b69754SDimitry Andric std::string Decoder;
97dd58ef01SDimitry Andric bool HasCompleteDecoder;
981d5ae102SDimitry Andric uint64_t InitValue;
9958b69754SDimitry Andric
OperandInfo__anon260f03c00111::OperandInfo100dd58ef01SDimitry Andric OperandInfo(std::string D, bool HCD)
1011d5ae102SDimitry Andric : Decoder(std::move(D)), HasCompleteDecoder(HCD), InitValue(0) {}
10258b69754SDimitry Andric
addField__anon260f03c00111::OperandInfo10358b69754SDimitry Andric void addField(unsigned Base, unsigned Width, unsigned Offset) {
10458b69754SDimitry Andric Fields.push_back(EncodingField(Base, Width, Offset));
10558b69754SDimitry Andric }
10658b69754SDimitry Andric
numFields__anon260f03c00111::OperandInfo10758b69754SDimitry Andric unsigned numFields() const { return Fields.size(); }
10858b69754SDimitry Andric
10958b69754SDimitry Andric typedef std::vector<EncodingField>::const_iterator const_iterator;
11058b69754SDimitry Andric
begin__anon260f03c00111::OperandInfo11158b69754SDimitry Andric const_iterator begin() const { return Fields.begin(); }
end__anon260f03c00111::OperandInfo11258b69754SDimitry Andric const_iterator end() const { return Fields.end(); }
11358b69754SDimitry Andric };
114902a7b52SDimitry Andric
115902a7b52SDimitry Andric typedef std::vector<uint8_t> DecoderTable;
116902a7b52SDimitry Andric typedef uint32_t DecoderFixup;
117902a7b52SDimitry Andric typedef std::vector<DecoderFixup> FixupList;
118902a7b52SDimitry Andric typedef std::vector<FixupList> FixupScopeList;
119b915e9e0SDimitry Andric typedef SmallSetVector<CachedHashString, 16> PredicateSet;
120b915e9e0SDimitry Andric typedef SmallSetVector<CachedHashString, 16> DecoderSet;
121902a7b52SDimitry Andric struct DecoderTableInfo {
122902a7b52SDimitry Andric DecoderTable Table;
123902a7b52SDimitry Andric FixupScopeList FixupStack;
124902a7b52SDimitry Andric PredicateSet Predicates;
125902a7b52SDimitry Andric DecoderSet Decoders;
126902a7b52SDimitry Andric };
127902a7b52SDimitry Andric
128d8e91e46SDimitry Andric struct EncodingAndInst {
129d8e91e46SDimitry Andric const Record *EncodingDef;
130d8e91e46SDimitry Andric const CodeGenInstruction *Inst;
1311d5ae102SDimitry Andric StringRef HwModeName;
132d8e91e46SDimitry Andric
EncodingAndInst__anon260f03c00111::EncodingAndInst1331d5ae102SDimitry Andric EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst,
1341d5ae102SDimitry Andric StringRef HwModeName = "")
1351d5ae102SDimitry Andric : EncodingDef(EncodingDef), Inst(Inst), HwModeName(HwModeName) {}
136d8e91e46SDimitry Andric };
137d8e91e46SDimitry Andric
138e6d15924SDimitry Andric struct EncodingIDAndOpcode {
139e6d15924SDimitry Andric unsigned EncodingID;
140e6d15924SDimitry Andric unsigned Opcode;
141e6d15924SDimitry Andric
EncodingIDAndOpcode__anon260f03c00111::EncodingIDAndOpcode142e6d15924SDimitry Andric EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {}
EncodingIDAndOpcode__anon260f03c00111::EncodingIDAndOpcode143e6d15924SDimitry Andric EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode)
144e6d15924SDimitry Andric : EncodingID(EncodingID), Opcode(Opcode) {}
145e6d15924SDimitry Andric };
146e6d15924SDimitry Andric
147ac9a064cSDimitry Andric using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
148ac9a064cSDimitry Andric using NamespacesHwModesMap = std::map<std::string, std::set<StringRef>>;
149ac9a064cSDimitry Andric
operator <<(raw_ostream & OS,const EncodingAndInst & Value)150d8e91e46SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
151d8e91e46SDimitry Andric if (Value.EncodingDef != Value.Inst->TheDef)
152d8e91e46SDimitry Andric OS << Value.EncodingDef->getName() << ":";
153d8e91e46SDimitry Andric OS << Value.Inst->TheDef->getName();
154d8e91e46SDimitry Andric return OS;
155d8e91e46SDimitry Andric }
156d8e91e46SDimitry Andric
157145449b1SDimitry Andric class DecoderEmitter {
158e6d15924SDimitry Andric RecordKeeper &RK;
159d8e91e46SDimitry Andric std::vector<EncodingAndInst> NumberedEncodings;
16058b69754SDimitry Andric
161b915e9e0SDimitry Andric public:
DecoderEmitter(RecordKeeper & R,std::string PredicateNamespace)162e3b55780SDimitry Andric DecoderEmitter(RecordKeeper &R, std::string PredicateNamespace)
163e3b55780SDimitry Andric : RK(R), Target(R), PredicateNamespace(std::move(PredicateNamespace)) {}
16458b69754SDimitry Andric
165902a7b52SDimitry Andric // Emit the decoder state machine table.
166902a7b52SDimitry Andric void emitTable(formatted_raw_ostream &o, DecoderTable &Table,
167ac9a064cSDimitry Andric unsigned Indentation, unsigned BitWidth, StringRef Namespace,
168ac9a064cSDimitry Andric const EncodingIDsVec &EncodingIDs) const;
169145449b1SDimitry Andric void emitInstrLenTable(formatted_raw_ostream &OS,
170145449b1SDimitry Andric std::vector<unsigned> &InstrLen) const;
171902a7b52SDimitry Andric void emitPredicateFunction(formatted_raw_ostream &OS,
172902a7b52SDimitry Andric PredicateSet &Predicates,
173902a7b52SDimitry Andric unsigned Indentation) const;
174ac9a064cSDimitry Andric void emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
175902a7b52SDimitry Andric unsigned Indentation) const;
176902a7b52SDimitry Andric
17758b69754SDimitry Andric // run - Output the code emitter
17858b69754SDimitry Andric void run(raw_ostream &o);
17958b69754SDimitry Andric
18058b69754SDimitry Andric private:
18158b69754SDimitry Andric CodeGenTarget Target;
182b915e9e0SDimitry Andric
18358b69754SDimitry Andric public:
18458b69754SDimitry Andric std::string PredicateNamespace;
18558b69754SDimitry Andric };
186b915e9e0SDimitry Andric
187b915e9e0SDimitry Andric } // end anonymous namespace
18858b69754SDimitry Andric
189cf099d11SDimitry Andric // The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
190cf099d11SDimitry Andric // for a bit value.
191cf099d11SDimitry Andric //
192cf099d11SDimitry Andric // BIT_UNFILTERED is used as the init value for a filter position. It is used
193cf099d11SDimitry Andric // only for filter processings.
194cf099d11SDimitry Andric typedef enum {
195cf099d11SDimitry Andric BIT_TRUE, // '1'
196cf099d11SDimitry Andric BIT_FALSE, // '0'
197cf099d11SDimitry Andric BIT_UNSET, // '?'
198cf099d11SDimitry Andric BIT_UNFILTERED // unfiltered
199cf099d11SDimitry Andric } bit_value_t;
200cf099d11SDimitry Andric
ValueSet(bit_value_t V)201cf099d11SDimitry Andric static bool ValueSet(bit_value_t V) {
202cf099d11SDimitry Andric return (V == BIT_TRUE || V == BIT_FALSE);
203cf099d11SDimitry Andric }
204b915e9e0SDimitry Andric
ValueNotSet(bit_value_t V)205ac9a064cSDimitry Andric static bool ValueNotSet(bit_value_t V) { return (V == BIT_UNSET); }
206b915e9e0SDimitry Andric
Value(bit_value_t V)207cf099d11SDimitry Andric static int Value(bit_value_t V) {
208cf099d11SDimitry Andric return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1);
209cf099d11SDimitry Andric }
210b915e9e0SDimitry Andric
bitFromBits(const BitsInit & bits,unsigned index)21163faed5bSDimitry Andric static bit_value_t bitFromBits(const BitsInit &bits, unsigned index) {
212522600a2SDimitry Andric if (BitInit *bit = dyn_cast<BitInit>(bits.getBit(index)))
213cf099d11SDimitry Andric return bit->getValue() ? BIT_TRUE : BIT_FALSE;
214cf099d11SDimitry Andric
215cf099d11SDimitry Andric // The bit is uninitialized.
216cf099d11SDimitry Andric return BIT_UNSET;
217cf099d11SDimitry Andric }
218b915e9e0SDimitry Andric
219cf099d11SDimitry Andric // Prints the bit value for each position.
dumpBits(raw_ostream & o,const BitsInit & bits)22063faed5bSDimitry Andric static void dumpBits(raw_ostream &o, const BitsInit &bits) {
221902a7b52SDimitry Andric for (unsigned index = bits.getNumBits(); index > 0; --index) {
222cf099d11SDimitry Andric switch (bitFromBits(bits, index - 1)) {
223cf099d11SDimitry Andric case BIT_TRUE:
224cf099d11SDimitry Andric o << "1";
225cf099d11SDimitry Andric break;
226cf099d11SDimitry Andric case BIT_FALSE:
227cf099d11SDimitry Andric o << "0";
228cf099d11SDimitry Andric break;
229cf099d11SDimitry Andric case BIT_UNSET:
230cf099d11SDimitry Andric o << "_";
231cf099d11SDimitry Andric break;
232cf099d11SDimitry Andric default:
23363faed5bSDimitry Andric llvm_unreachable("unexpected return value from bitFromBits");
234cf099d11SDimitry Andric }
235cf099d11SDimitry Andric }
236cf099d11SDimitry Andric }
237cf099d11SDimitry Andric
getBitsField(const Record & def,StringRef str)238b915e9e0SDimitry Andric static BitsInit &getBitsField(const Record &def, StringRef str) {
239145449b1SDimitry Andric const RecordVal *RV = def.getValue(str);
240145449b1SDimitry Andric if (BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue()))
241145449b1SDimitry Andric return *Bits;
242145449b1SDimitry Andric
243145449b1SDimitry Andric // variable length instruction
244145449b1SDimitry Andric VarLenInst VLI = VarLenInst(cast<DagInit>(RV->getValue()), RV);
245145449b1SDimitry Andric SmallVector<Init *, 16> Bits;
246145449b1SDimitry Andric
247ac9a064cSDimitry Andric for (const auto &SI : VLI) {
248145449b1SDimitry Andric if (const BitsInit *BI = dyn_cast<BitsInit>(SI.Value)) {
249145449b1SDimitry Andric for (unsigned Idx = 0U; Idx < BI->getNumBits(); ++Idx) {
250145449b1SDimitry Andric Bits.push_back(BI->getBit(Idx));
251145449b1SDimitry Andric }
252145449b1SDimitry Andric } else if (const BitInit *BI = dyn_cast<BitInit>(SI.Value)) {
253145449b1SDimitry Andric Bits.push_back(const_cast<BitInit *>(BI));
254145449b1SDimitry Andric } else {
255145449b1SDimitry Andric for (unsigned Idx = 0U; Idx < SI.BitWidth; ++Idx)
256145449b1SDimitry Andric Bits.push_back(UnsetInit::get(def.getRecords()));
257145449b1SDimitry Andric }
258145449b1SDimitry Andric }
259145449b1SDimitry Andric
260145449b1SDimitry Andric return *BitsInit::get(def.getRecords(), Bits);
261cf099d11SDimitry Andric }
262cf099d11SDimitry Andric
263cf099d11SDimitry Andric // Representation of the instruction to work on.
26430815c53SDimitry Andric typedef std::vector<bit_value_t> insn_t;
265cf099d11SDimitry Andric
266b915e9e0SDimitry Andric namespace {
267b915e9e0SDimitry Andric
268b60736ecSDimitry Andric static const uint64_t NO_FIXED_SEGMENTS_SENTINEL = -1ULL;
269b60736ecSDimitry Andric
270b915e9e0SDimitry Andric class FilterChooser;
271b915e9e0SDimitry Andric
272cf099d11SDimitry Andric /// Filter - Filter works with FilterChooser to produce the decoding tree for
273cf099d11SDimitry Andric /// the ISA.
274cf099d11SDimitry Andric ///
275cf099d11SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
276cf099d11SDimitry Andric /// decoding tree in a certain level. Each case stmt delegates to an inferior
277cf099d11SDimitry Andric /// FilterChooser to decide what further decoding logic to employ, or in another
278cf099d11SDimitry Andric /// words, what other remaining bits to look at. The FilterChooser eventually
279cf099d11SDimitry Andric /// chooses a best Filter to do its job.
280cf099d11SDimitry Andric ///
281cf099d11SDimitry Andric /// This recursive scheme ends when the number of Opcodes assigned to the
282cf099d11SDimitry Andric /// FilterChooser becomes 1 or if there is a conflict. A conflict happens when
283cf099d11SDimitry Andric /// the Filter/FilterChooser combo does not know how to distinguish among the
284cf099d11SDimitry Andric /// Opcodes assigned.
285cf099d11SDimitry Andric ///
286cf099d11SDimitry Andric /// An example of a conflict is
287cf099d11SDimitry Andric ///
288cf099d11SDimitry Andric /// Conflict:
289cf099d11SDimitry Andric /// 111101000.00........00010000....
290cf099d11SDimitry Andric /// 111101000.00........0001........
291cf099d11SDimitry Andric /// 1111010...00........0001........
292cf099d11SDimitry Andric /// 1111010...00....................
293cf099d11SDimitry Andric /// 1111010.........................
294cf099d11SDimitry Andric /// 1111............................
295cf099d11SDimitry Andric /// ................................
296cf099d11SDimitry Andric /// VST4q8a 111101000_00________00010000____
297cf099d11SDimitry Andric /// VST4q8b 111101000_00________00010000____
298cf099d11SDimitry Andric ///
299cf099d11SDimitry Andric /// The Debug output shows the path that the decoding tree follows to reach the
300cf099d11SDimitry Andric /// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced
301ee8648bdSDimitry Andric /// even registers, while VST4q8b is a vst4 to double-spaced odd registers.
302cf099d11SDimitry Andric ///
303cf099d11SDimitry Andric /// The encoding info in the .td files does not specify this meta information,
304cf099d11SDimitry Andric /// which could have been used by the decoder to resolve the conflict. The
305cf099d11SDimitry Andric /// decoder could try to decode the even/odd register numbering and assign to
306cf099d11SDimitry Andric /// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
307cf099d11SDimitry Andric /// version and return the Opcode since the two have the same Asm format string.
308cf099d11SDimitry Andric class Filter {
309cf099d11SDimitry Andric protected:
310ac9a064cSDimitry Andric const FilterChooser
311ac9a064cSDimitry Andric *Owner; // points to the FilterChooser who owns this filter
312cf099d11SDimitry Andric unsigned StartBit; // the starting bit position
313cf099d11SDimitry Andric unsigned NumBits; // number of bits to filter
314cf099d11SDimitry Andric bool Mixed; // a mixed region contains both set and unset bits
315cf099d11SDimitry Andric
316cf099d11SDimitry Andric // Map of well-known segment value to the set of uid's with that value.
317ac9a064cSDimitry Andric std::map<uint64_t, std::vector<EncodingIDAndOpcode>> FilteredInstructions;
318cf099d11SDimitry Andric
319cf099d11SDimitry Andric // Set of uid's with non-constant segment values.
320e6d15924SDimitry Andric std::vector<EncodingIDAndOpcode> VariableInstructions;
321cf099d11SDimitry Andric
322cf099d11SDimitry Andric // Map of well-known segment value to its delegate.
323b60736ecSDimitry Andric std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;
324cf099d11SDimitry Andric
325cf099d11SDimitry Andric // Number of instructions which fall under FilteredInstructions category.
326cf099d11SDimitry Andric unsigned NumFiltered;
327cf099d11SDimitry Andric
328cf099d11SDimitry Andric // Keeps track of the last opcode in the filtered bucket.
329e6d15924SDimitry Andric EncodingIDAndOpcode LastOpcFiltered;
330cf099d11SDimitry Andric
331cf099d11SDimitry Andric public:
332b915e9e0SDimitry Andric Filter(Filter &&f);
333b915e9e0SDimitry Andric Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed);
334b915e9e0SDimitry Andric
335b915e9e0SDimitry Andric ~Filter() = default;
336b915e9e0SDimitry Andric
getNumFiltered() const33763faed5bSDimitry Andric unsigned getNumFiltered() const { return NumFiltered; }
338b915e9e0SDimitry Andric
getSingletonOpc() const339e6d15924SDimitry Andric EncodingIDAndOpcode getSingletonOpc() const {
340cf099d11SDimitry Andric assert(NumFiltered == 1);
341cf099d11SDimitry Andric return LastOpcFiltered;
342cf099d11SDimitry Andric }
343b915e9e0SDimitry Andric
344cf099d11SDimitry Andric // Return the filter chooser for the group of instructions without constant
345cf099d11SDimitry Andric // segment values.
getVariableFC() const34663faed5bSDimitry Andric const FilterChooser &getVariableFC() const {
347cf099d11SDimitry Andric assert(NumFiltered == 1);
348cf099d11SDimitry Andric assert(FilterChooserMap.size() == 1);
349b60736ecSDimitry Andric return *(FilterChooserMap.find(NO_FIXED_SEGMENTS_SENTINEL)->second);
350cf099d11SDimitry Andric }
351cf099d11SDimitry Andric
352cf099d11SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the
353cf099d11SDimitry Andric // inferior FilterChooser's.
354cf099d11SDimitry Andric //
355cf099d11SDimitry Andric // A special case arises when there's only one entry in the filtered
356cf099d11SDimitry Andric // instructions. In order to unambiguously decode the singleton, we need to
357cf099d11SDimitry Andric // match the remaining undecoded encoding bits against the singleton.
358cf099d11SDimitry Andric void recurse();
359cf099d11SDimitry Andric
360902a7b52SDimitry Andric // Emit table entries to decode instructions given a segment or segments of
361902a7b52SDimitry Andric // bits.
362902a7b52SDimitry Andric void emitTableEntry(DecoderTableInfo &TableInfo) const;
363cf099d11SDimitry Andric
364cf099d11SDimitry Andric // Returns the number of fanout produced by the filter. More fanout implies
365cf099d11SDimitry Andric // the filter distinguishes more categories of instructions.
366cf099d11SDimitry Andric unsigned usefulness() const;
367b915e9e0SDimitry Andric }; // end class Filter
368b915e9e0SDimitry Andric
369b915e9e0SDimitry Andric } // end anonymous namespace
370cf099d11SDimitry Andric
371cf099d11SDimitry Andric // These are states of our finite state machines used in FilterChooser's
372cf099d11SDimitry Andric // filterProcessor() which produces the filter candidates to use.
373cf099d11SDimitry Andric typedef enum {
374cf099d11SDimitry Andric ATTR_NONE,
375cf099d11SDimitry Andric ATTR_FILTERED,
376cf099d11SDimitry Andric ATTR_ALL_SET,
377cf099d11SDimitry Andric ATTR_ALL_UNSET,
378cf099d11SDimitry Andric ATTR_MIXED
379cf099d11SDimitry Andric } bitAttr_t;
380cf099d11SDimitry Andric
381cf099d11SDimitry Andric /// FilterChooser - FilterChooser chooses the best filter among a set of Filters
382cf099d11SDimitry Andric /// in order to perform the decoding of instructions at the current level.
383cf099d11SDimitry Andric ///
384cf099d11SDimitry Andric /// Decoding proceeds from the top down. Based on the well-known encoding bits
385cf099d11SDimitry Andric /// of instructions available, FilterChooser builds up the possible Filters that
386cf099d11SDimitry Andric /// can further the task of decoding by distinguishing among the remaining
387cf099d11SDimitry Andric /// candidate instructions.
388cf099d11SDimitry Andric ///
389cf099d11SDimitry Andric /// Once a filter has been chosen, it is called upon to divide the decoding task
390cf099d11SDimitry Andric /// into sub-tasks and delegates them to its inferior FilterChoosers for further
391cf099d11SDimitry Andric /// processings.
392cf099d11SDimitry Andric ///
393cf099d11SDimitry Andric /// It is useful to think of a Filter as governing the switch stmts of the
394cf099d11SDimitry Andric /// decoding tree. And each case is delegated to an inferior FilterChooser to
395cf099d11SDimitry Andric /// decide what further remaining bits to look at.
39658b69754SDimitry Andric namespace {
397b915e9e0SDimitry Andric
398cf099d11SDimitry Andric class FilterChooser {
399cf099d11SDimitry Andric protected:
400cf099d11SDimitry Andric friend class Filter;
401cf099d11SDimitry Andric
402cf099d11SDimitry Andric // Vector of codegen instructions to choose our filter.
403d8e91e46SDimitry Andric ArrayRef<EncodingAndInst> AllInstructions;
404cf099d11SDimitry Andric
405cf099d11SDimitry Andric // Vector of uid's for this filter chooser to work on.
406e6d15924SDimitry Andric // The first member of the pair is the opcode id being decoded, the second is
407e6d15924SDimitry Andric // the opcode id that should be emitted.
408e6d15924SDimitry Andric const std::vector<EncodingIDAndOpcode> &Opcodes;
409cf099d11SDimitry Andric
410cf099d11SDimitry Andric // Lookup table for the operand decoding of instructions.
41163faed5bSDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Operands;
412cf099d11SDimitry Andric
413cf099d11SDimitry Andric // Vector of candidate filters.
414cf099d11SDimitry Andric std::vector<Filter> Filters;
415cf099d11SDimitry Andric
416cf099d11SDimitry Andric // Array of bit values passed down from our parent.
417cf099d11SDimitry Andric // Set to all BIT_UNFILTERED's for Parent == NULL.
41830815c53SDimitry Andric std::vector<bit_value_t> FilterBitValues;
419cf099d11SDimitry Andric
420cf099d11SDimitry Andric // Links to the FilterChooser above us in the decoding tree.
42163faed5bSDimitry Andric const FilterChooser *Parent;
422cf099d11SDimitry Andric
423cf099d11SDimitry Andric // Index of the best filter from Filters.
424cf099d11SDimitry Andric int BestIndex;
425cf099d11SDimitry Andric
42630815c53SDimitry Andric // Width of instructions
42730815c53SDimitry Andric unsigned BitWidth;
42830815c53SDimitry Andric
42930815c53SDimitry Andric // Parent emitter
430145449b1SDimitry Andric const DecoderEmitter *Emitter;
43130815c53SDimitry Andric
432cf099d11SDimitry Andric public:
FilterChooser(ArrayRef<EncodingAndInst> Insts,const std::vector<EncodingIDAndOpcode> & IDs,const std::map<unsigned,std::vector<OperandInfo>> & Ops,unsigned BW,const DecoderEmitter * E)433d8e91e46SDimitry Andric FilterChooser(ArrayRef<EncodingAndInst> Insts,
434e6d15924SDimitry Andric const std::vector<EncodingIDAndOpcode> &IDs,
43563faed5bSDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Ops,
436145449b1SDimitry Andric unsigned BW, const DecoderEmitter *E)
437b915e9e0SDimitry Andric : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
43867c32a98SDimitry Andric FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1),
43967c32a98SDimitry Andric BitWidth(BW), Emitter(E) {
440cf099d11SDimitry Andric doFilter();
441cf099d11SDimitry Andric }
442cf099d11SDimitry Andric
FilterChooser(ArrayRef<EncodingAndInst> Insts,const std::vector<EncodingIDAndOpcode> & IDs,const std::map<unsigned,std::vector<OperandInfo>> & Ops,const std::vector<bit_value_t> & ParentFilterBitValues,const FilterChooser & parent)443d8e91e46SDimitry Andric FilterChooser(ArrayRef<EncodingAndInst> Insts,
444e6d15924SDimitry Andric const std::vector<EncodingIDAndOpcode> &IDs,
44563faed5bSDimitry Andric const std::map<unsigned, std::vector<OperandInfo>> &Ops,
44663faed5bSDimitry Andric const std::vector<bit_value_t> &ParentFilterBitValues,
44763faed5bSDimitry Andric const FilterChooser &parent)
44863faed5bSDimitry Andric : AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
449b915e9e0SDimitry Andric FilterBitValues(ParentFilterBitValues), Parent(&parent), BestIndex(-1),
450b915e9e0SDimitry Andric BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
451cf099d11SDimitry Andric doFilter();
452cf099d11SDimitry Andric }
453cf099d11SDimitry Andric
454b915e9e0SDimitry Andric FilterChooser(const FilterChooser &) = delete;
455b915e9e0SDimitry Andric void operator=(const FilterChooser &) = delete;
456b915e9e0SDimitry Andric
getBitWidth() const457902a7b52SDimitry Andric unsigned getBitWidth() const { return BitWidth; }
458cf099d11SDimitry Andric
459cf099d11SDimitry Andric protected:
460cf099d11SDimitry Andric // Populates the insn given the uid.
insnWithID(insn_t & Insn,unsigned Opcode) const461cf099d11SDimitry Andric void insnWithID(insn_t &Insn, unsigned Opcode) const {
462ac9a064cSDimitry Andric const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
463ac9a064cSDimitry Andric BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
464ac9a064cSDimitry Andric Insn.resize(std::max(BitWidth, Bits.getNumBits()), BIT_UNSET);
46563faed5bSDimitry Andric // We may have a SoftFail bitmask, which specifies a mask where an encoding
46663faed5bSDimitry Andric // may differ from the value in "Inst" and yet still be valid, but the
46763faed5bSDimitry Andric // disassembler should return SoftFail instead of Success.
46863faed5bSDimitry Andric //
46963faed5bSDimitry Andric // This is used for marking UNPREDICTABLE instructions in the ARM world.
470ac9a064cSDimitry Andric const RecordVal *RV = EncodingDef->getValue("SoftFail");
471145449b1SDimitry Andric const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
472145449b1SDimitry Andric for (unsigned i = 0; i < Bits.getNumBits(); ++i) {
47363faed5bSDimitry Andric if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE)
474145449b1SDimitry Andric Insn[i] = BIT_UNSET;
47563faed5bSDimitry Andric else
476145449b1SDimitry Andric Insn[i] = bitFromBits(Bits, i);
477cf099d11SDimitry Andric }
47863faed5bSDimitry Andric }
479cf099d11SDimitry Andric
480e6d15924SDimitry Andric // Emit the name of the encoding/instruction pair.
emitNameWithID(raw_ostream & OS,unsigned Opcode) const481e6d15924SDimitry Andric void emitNameWithID(raw_ostream &OS, unsigned Opcode) const {
482e6d15924SDimitry Andric const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
483e6d15924SDimitry Andric const Record *InstDef = AllInstructions[Opcode].Inst->TheDef;
484e6d15924SDimitry Andric if (EncodingDef != InstDef)
485e6d15924SDimitry Andric OS << EncodingDef->getName() << ":";
486e6d15924SDimitry Andric OS << InstDef->getName();
487e6d15924SDimitry Andric }
488e6d15924SDimitry Andric
489cf099d11SDimitry Andric // Populates the field of the insn given the start position and the number of
490cf099d11SDimitry Andric // consecutive bits to scan for.
491cf099d11SDimitry Andric //
492ac9a064cSDimitry Andric // Returns a pair of values (indicator, field), where the indicator is false
493ac9a064cSDimitry Andric // if there exists any uninitialized bit value in the range and true if all
494ac9a064cSDimitry Andric // bits are well-known. The second value is the potentially populated field.
495ac9a064cSDimitry Andric std::pair<bool, uint64_t> fieldFromInsn(const insn_t &Insn, unsigned StartBit,
496cf099d11SDimitry Andric unsigned NumBits) const;
497cf099d11SDimitry Andric
498cf099d11SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
499cf099d11SDimitry Andric /// filter array as a series of chars.
50063faed5bSDimitry Andric void dumpFilterArray(raw_ostream &o,
50163faed5bSDimitry Andric const std::vector<bit_value_t> &filter) const;
502cf099d11SDimitry Andric
503cf099d11SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls
504cf099d11SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one.
50563faed5bSDimitry Andric void dumpStack(raw_ostream &o, const char *prefix) const;
506cf099d11SDimitry Andric
bestFilter()507cf099d11SDimitry Andric Filter &bestFilter() {
508cf099d11SDimitry Andric assert(BestIndex != -1 && "BestIndex not set");
509cf099d11SDimitry Andric return Filters[BestIndex];
510cf099d11SDimitry Andric }
511cf099d11SDimitry Andric
PositionFiltered(unsigned i) const51263faed5bSDimitry Andric bool PositionFiltered(unsigned i) const {
513cf099d11SDimitry Andric return ValueSet(FilterBitValues[i]);
514cf099d11SDimitry Andric }
515cf099d11SDimitry Andric
516cf099d11SDimitry Andric // Calculates the island(s) needed to decode the instruction.
517cf099d11SDimitry Andric // This returns a lit of undecoded bits of an instructions, for example,
518cf099d11SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
519cf099d11SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode.
520cf099d11SDimitry Andric unsigned getIslands(std::vector<unsigned> &StartBits,
52163faed5bSDimitry Andric std::vector<unsigned> &EndBits,
52263faed5bSDimitry Andric std::vector<uint64_t> &FieldVals,
52363faed5bSDimitry Andric const insn_t &Insn) const;
524cf099d11SDimitry Andric
52530815c53SDimitry Andric // Emits code to check the Predicates member of an instruction are true.
52630815c53SDimitry Andric // Returns true if predicate matches were emitted, false otherwise.
52763faed5bSDimitry Andric bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
52863faed5bSDimitry Andric unsigned Opc) const;
529145449b1SDimitry Andric bool emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
530145449b1SDimitry Andric raw_ostream &OS) const;
53163faed5bSDimitry Andric
532902a7b52SDimitry Andric bool doesOpcodeNeedPredicate(unsigned Opc) const;
533902a7b52SDimitry Andric unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
534ac9a064cSDimitry Andric void emitPredicateTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const;
53530815c53SDimitry Andric
536ac9a064cSDimitry Andric void emitSoftFailTableEntry(DecoderTableInfo &TableInfo, unsigned Opc) const;
537902a7b52SDimitry Andric
538902a7b52SDimitry Andric // Emits table entries to decode the singleton.
539902a7b52SDimitry Andric void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
540e6d15924SDimitry Andric EncodingIDAndOpcode Opc) const;
541cf099d11SDimitry Andric
542cf099d11SDimitry Andric // Emits code to decode the singleton, and then to decode the rest.
543902a7b52SDimitry Andric void emitSingletonTableEntry(DecoderTableInfo &TableInfo,
54463faed5bSDimitry Andric const Filter &Best) const;
545cf099d11SDimitry Andric
54630815c53SDimitry Andric void emitBinaryParser(raw_ostream &o, unsigned &Indentation,
547dd58ef01SDimitry Andric const OperandInfo &OpInfo,
548dd58ef01SDimitry Andric bool &OpHasCompleteDecoder) const;
54930815c53SDimitry Andric
550dd58ef01SDimitry Andric void emitDecoder(raw_ostream &OS, unsigned Indentation, unsigned Opc,
551dd58ef01SDimitry Andric bool &HasCompleteDecoder) const;
552dd58ef01SDimitry Andric unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
553dd58ef01SDimitry Andric bool &HasCompleteDecoder) const;
554902a7b52SDimitry Andric
555cf099d11SDimitry Andric // Assign a single filter and run with it.
55663faed5bSDimitry Andric void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed);
557cf099d11SDimitry Andric
558cf099d11SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as
559cf099d11SDimitry Andric // eligible for use as a filter region.
560cf099d11SDimitry Andric void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex,
561cf099d11SDimitry Andric bool AllowMixed);
562cf099d11SDimitry Andric
563cf099d11SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and
564cf099d11SDimitry Andric // builds up a list of candidate filters. It chooses the best filter and
565cf099d11SDimitry Andric // recursively descends down the decoding tree.
566cf099d11SDimitry Andric bool filterProcessor(bool AllowMixed, bool Greedy = true);
567cf099d11SDimitry Andric
568cf099d11SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode
569cf099d11SDimitry Andric // the instructions. A conflict of instructions may occur, in which case we
570cf099d11SDimitry Andric // dump the conflict set to the standard error.
571cf099d11SDimitry Andric void doFilter();
572cf099d11SDimitry Andric
573902a7b52SDimitry Andric public:
574902a7b52SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of
575902a7b52SDimitry Andric // instructions.
576902a7b52SDimitry Andric void emitTableEntries(DecoderTableInfo &TableInfo) const;
577cf099d11SDimitry Andric };
578b915e9e0SDimitry Andric
579b915e9e0SDimitry Andric } // end anonymous namespace
580cf099d11SDimitry Andric
581cf099d11SDimitry Andric ///////////////////////////
582cf099d11SDimitry Andric // //
58363faed5bSDimitry Andric // Filter Implementation //
584cf099d11SDimitry Andric // //
585cf099d11SDimitry Andric ///////////////////////////
586cf099d11SDimitry Andric
Filter(Filter && f)58767c32a98SDimitry Andric Filter::Filter(Filter &&f)
58863faed5bSDimitry Andric : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed),
58967c32a98SDimitry Andric FilteredInstructions(std::move(f.FilteredInstructions)),
59067c32a98SDimitry Andric VariableInstructions(std::move(f.VariableInstructions)),
591ac9a064cSDimitry Andric FilterChooserMap(std::move(f.FilterChooserMap)),
592ac9a064cSDimitry Andric NumFiltered(f.NumFiltered), LastOpcFiltered(f.LastOpcFiltered) {}
593cf099d11SDimitry Andric
Filter(FilterChooser & owner,unsigned startBit,unsigned numBits,bool mixed)594cf099d11SDimitry Andric Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits,
59563faed5bSDimitry Andric bool mixed)
59663faed5bSDimitry Andric : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) {
59730815c53SDimitry Andric assert(StartBit + NumBits - 1 < Owner->BitWidth);
598cf099d11SDimitry Andric
599cf099d11SDimitry Andric NumFiltered = 0;
600e6d15924SDimitry Andric LastOpcFiltered = {0, 0};
601cf099d11SDimitry Andric
602ac9a064cSDimitry Andric for (const auto &OpcPair : Owner->Opcodes) {
603cf099d11SDimitry Andric insn_t Insn;
604cf099d11SDimitry Andric
605cf099d11SDimitry Andric // Populates the insn given the uid.
606ac9a064cSDimitry Andric Owner->insnWithID(Insn, OpcPair.EncodingID);
607cf099d11SDimitry Andric
608cf099d11SDimitry Andric // Scans the segment for possibly well-specified encoding bits.
609ac9a064cSDimitry Andric auto [Ok, Field] = Owner->fieldFromInsn(Insn, StartBit, NumBits);
610cf099d11SDimitry Andric
611ac9a064cSDimitry Andric if (Ok) {
612cf099d11SDimitry Andric // The encoding bits are well-known. Lets add the uid of the
613cf099d11SDimitry Andric // instruction into the bucket keyed off the constant field value.
614ac9a064cSDimitry Andric LastOpcFiltered = OpcPair;
615cf099d11SDimitry Andric FilteredInstructions[Field].push_back(LastOpcFiltered);
616cf099d11SDimitry Andric ++NumFiltered;
617cf099d11SDimitry Andric } else {
61863faed5bSDimitry Andric // Some of the encoding bit(s) are unspecified. This contributes to
619cf099d11SDimitry Andric // one additional member of "Variable" instructions.
620ac9a064cSDimitry Andric VariableInstructions.push_back(OpcPair);
621cf099d11SDimitry Andric }
622cf099d11SDimitry Andric }
623cf099d11SDimitry Andric
624ac9a064cSDimitry Andric assert((FilteredInstructions.size() + VariableInstructions.size() > 0) &&
625ac9a064cSDimitry Andric "Filter returns no instruction categories");
626cf099d11SDimitry Andric }
627cf099d11SDimitry Andric
628cf099d11SDimitry Andric // Divides the decoding task into sub tasks and delegates them to the
629cf099d11SDimitry Andric // inferior FilterChooser's.
630cf099d11SDimitry Andric //
631cf099d11SDimitry Andric // A special case arises when there's only one entry in the filtered
632cf099d11SDimitry Andric // instructions. In order to unambiguously decode the singleton, we need to
633cf099d11SDimitry Andric // match the remaining undecoded encoding bits against the singleton.
recurse()634cf099d11SDimitry Andric void Filter::recurse() {
635cf099d11SDimitry Andric // Starts by inheriting our parent filter chooser's filter bit values.
63630815c53SDimitry Andric std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues);
637cf099d11SDimitry Andric
6385a5ac124SDimitry Andric if (!VariableInstructions.empty()) {
639cf099d11SDimitry Andric // Conservatively marks each segment position as BIT_UNSET.
640902a7b52SDimitry Andric for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
641cf099d11SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_UNSET;
642cf099d11SDimitry Andric
6436b943ff3SDimitry Andric // Delegates to an inferior filter chooser for further processing on this
644cf099d11SDimitry Andric // group of instructions whose segment values are variable.
645ac9a064cSDimitry Andric FilterChooserMap.insert(std::pair(
646ac9a064cSDimitry Andric NO_FIXED_SEGMENTS_SENTINEL,
647b60736ecSDimitry Andric std::make_unique<FilterChooser>(Owner->AllInstructions,
648ac9a064cSDimitry Andric VariableInstructions, Owner->Operands,
649ac9a064cSDimitry Andric BitValueArray, *Owner)));
650cf099d11SDimitry Andric }
651cf099d11SDimitry Andric
652cf099d11SDimitry Andric // No need to recurse for a singleton filtered instruction.
653902a7b52SDimitry Andric // See also Filter::emit*().
654cf099d11SDimitry Andric if (getNumFiltered() == 1) {
655cf099d11SDimitry Andric assert(FilterChooserMap.size() == 1);
656cf099d11SDimitry Andric return;
657cf099d11SDimitry Andric }
658cf099d11SDimitry Andric
659cf099d11SDimitry Andric // Otherwise, create sub choosers.
66067c32a98SDimitry Andric for (const auto &Inst : FilteredInstructions) {
661cf099d11SDimitry Andric
662cf099d11SDimitry Andric // Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
663902a7b52SDimitry Andric for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) {
66467c32a98SDimitry Andric if (Inst.first & (1ULL << bitIndex))
665cf099d11SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_TRUE;
666cf099d11SDimitry Andric else
667cf099d11SDimitry Andric BitValueArray[StartBit + bitIndex] = BIT_FALSE;
668cf099d11SDimitry Andric }
669cf099d11SDimitry Andric
6706b943ff3SDimitry Andric // Delegates to an inferior filter chooser for further processing on this
671cf099d11SDimitry Andric // category of instructions.
672ac9a064cSDimitry Andric FilterChooserMap.insert(
673ac9a064cSDimitry Andric std::pair(Inst.first, std::make_unique<FilterChooser>(
67467c32a98SDimitry Andric Owner->AllInstructions, Inst.second,
67567c32a98SDimitry Andric Owner->Operands, BitValueArray, *Owner)));
676cf099d11SDimitry Andric }
677cf099d11SDimitry Andric }
678cf099d11SDimitry Andric
resolveTableFixups(DecoderTable & Table,const FixupList & Fixups,uint32_t DestIdx)679902a7b52SDimitry Andric static void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups,
680902a7b52SDimitry Andric uint32_t DestIdx) {
681902a7b52SDimitry Andric // Any NumToSkip fixups in the current scope can resolve to the
682902a7b52SDimitry Andric // current location.
683ac9a064cSDimitry Andric for (FixupList::const_reverse_iterator I = Fixups.rbegin(), E = Fixups.rend();
684902a7b52SDimitry Andric I != E; ++I) {
685902a7b52SDimitry Andric // Calculate the distance from the byte following the fixup entry byte
686902a7b52SDimitry Andric // to the destination. The Target is calculated from after the 16-bit
687902a7b52SDimitry Andric // NumToSkip entry itself, so subtract two from the displacement here
688902a7b52SDimitry Andric // to account for that.
689902a7b52SDimitry Andric uint32_t FixupIdx = *I;
690eb11fae6SDimitry Andric uint32_t Delta = DestIdx - FixupIdx - 3;
691eb11fae6SDimitry Andric // Our NumToSkip entries are 24-bits. Make sure our table isn't too
692902a7b52SDimitry Andric // big.
693eb11fae6SDimitry Andric assert(Delta < (1u << 24));
694902a7b52SDimitry Andric Table[FixupIdx] = (uint8_t)Delta;
695902a7b52SDimitry Andric Table[FixupIdx + 1] = (uint8_t)(Delta >> 8);
696eb11fae6SDimitry Andric Table[FixupIdx + 2] = (uint8_t)(Delta >> 16);
697902a7b52SDimitry Andric }
698902a7b52SDimitry Andric }
699cf099d11SDimitry Andric
700902a7b52SDimitry Andric // Emit table entries to decode instructions given a segment or segments
701902a7b52SDimitry Andric // of bits.
emitTableEntry(DecoderTableInfo & TableInfo) const702902a7b52SDimitry Andric void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
703ac9a064cSDimitry Andric assert((NumBits < (1u << 8)) && "NumBits overflowed uint8 table entry!");
704902a7b52SDimitry Andric TableInfo.Table.push_back(MCD::OPC_ExtractField);
705ac9a064cSDimitry Andric
706ac9a064cSDimitry Andric SmallString<16> SBytes;
707ac9a064cSDimitry Andric raw_svector_ostream S(SBytes);
708ac9a064cSDimitry Andric encodeULEB128(StartBit, S);
709ac9a064cSDimitry Andric TableInfo.Table.insert(TableInfo.Table.end(), SBytes.begin(), SBytes.end());
710902a7b52SDimitry Andric TableInfo.Table.push_back(NumBits);
711cf099d11SDimitry Andric
712902a7b52SDimitry Andric // A new filter entry begins a new scope for fixup resolution.
71385d8b2bbSDimitry Andric TableInfo.FixupStack.emplace_back();
714cf099d11SDimitry Andric
715902a7b52SDimitry Andric DecoderTable &Table = TableInfo.Table;
716902a7b52SDimitry Andric
717902a7b52SDimitry Andric size_t PrevFilter = 0;
718902a7b52SDimitry Andric bool HasFallthrough = false;
719ac9a064cSDimitry Andric for (const auto &Filter : FilterChooserMap) {
720cf099d11SDimitry Andric // Field value -1 implies a non-empty set of variable instructions.
721cf099d11SDimitry Andric // See also recurse().
722b60736ecSDimitry Andric if (Filter.first == NO_FIXED_SEGMENTS_SENTINEL) {
723902a7b52SDimitry Andric HasFallthrough = true;
724cf099d11SDimitry Andric
725902a7b52SDimitry Andric // Each scope should always have at least one filter value to check
726902a7b52SDimitry Andric // for.
727902a7b52SDimitry Andric assert(PrevFilter != 0 && "empty filter set!");
728902a7b52SDimitry Andric FixupList &CurScope = TableInfo.FixupStack.back();
729902a7b52SDimitry Andric // Resolve any NumToSkip fixups in the current scope.
730902a7b52SDimitry Andric resolveTableFixups(Table, CurScope, Table.size());
731902a7b52SDimitry Andric CurScope.clear();
732902a7b52SDimitry Andric PrevFilter = 0; // Don't re-process the filter's fallthrough.
733902a7b52SDimitry Andric } else {
734902a7b52SDimitry Andric Table.push_back(MCD::OPC_FilterValue);
735902a7b52SDimitry Andric // Encode and emit the value to filter against.
736eb11fae6SDimitry Andric uint8_t Buffer[16];
73767c32a98SDimitry Andric unsigned Len = encodeULEB128(Filter.first, Buffer);
738902a7b52SDimitry Andric Table.insert(Table.end(), Buffer, Buffer + Len);
739902a7b52SDimitry Andric // Reserve space for the NumToSkip entry. We'll backpatch the value
740902a7b52SDimitry Andric // later.
741902a7b52SDimitry Andric PrevFilter = Table.size();
742902a7b52SDimitry Andric Table.push_back(0);
743902a7b52SDimitry Andric Table.push_back(0);
744eb11fae6SDimitry Andric Table.push_back(0);
745902a7b52SDimitry Andric }
746cf099d11SDimitry Andric
747cf099d11SDimitry Andric // We arrive at a category of instructions with the same segment value.
748cf099d11SDimitry Andric // Now delegate to the sub filter chooser for further decodings.
749cf099d11SDimitry Andric // The case may fallthrough, which happens if the remaining well-known
750cf099d11SDimitry Andric // encoding bits do not match exactly.
75167c32a98SDimitry Andric Filter.second->emitTableEntries(TableInfo);
752cf099d11SDimitry Andric
753902a7b52SDimitry Andric // Now that we've emitted the body of the handler, update the NumToSkip
754902a7b52SDimitry Andric // of the filter itself to be able to skip forward when false. Subtract
755902a7b52SDimitry Andric // two as to account for the width of the NumToSkip field itself.
756902a7b52SDimitry Andric if (PrevFilter) {
757eb11fae6SDimitry Andric uint32_t NumToSkip = Table.size() - PrevFilter - 3;
758ac9a064cSDimitry Andric assert(NumToSkip < (1u << 24) &&
759ac9a064cSDimitry Andric "disassembler decoding table too large!");
760902a7b52SDimitry Andric Table[PrevFilter] = (uint8_t)NumToSkip;
761902a7b52SDimitry Andric Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8);
762eb11fae6SDimitry Andric Table[PrevFilter + 2] = (uint8_t)(NumToSkip >> 16);
763902a7b52SDimitry Andric }
764cf099d11SDimitry Andric }
765cf099d11SDimitry Andric
766902a7b52SDimitry Andric // Any remaining unresolved fixups bubble up to the parent fixup scope.
767902a7b52SDimitry Andric assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!");
768902a7b52SDimitry Andric FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1;
769902a7b52SDimitry Andric FixupScopeList::iterator Dest = Source - 1;
770b60736ecSDimitry Andric llvm::append_range(*Dest, *Source);
771902a7b52SDimitry Andric TableInfo.FixupStack.pop_back();
772902a7b52SDimitry Andric
773902a7b52SDimitry Andric // If there is no fallthrough, then the final filter should get fixed
774902a7b52SDimitry Andric // up according to the enclosing scope rather than the current position.
775902a7b52SDimitry Andric if (!HasFallthrough)
776902a7b52SDimitry Andric TableInfo.FixupStack.back().push_back(PrevFilter);
777cf099d11SDimitry Andric }
778cf099d11SDimitry Andric
779cf099d11SDimitry Andric // Returns the number of fanout produced by the filter. More fanout implies
780cf099d11SDimitry Andric // the filter distinguishes more categories of instructions.
usefulness() const781cf099d11SDimitry Andric unsigned Filter::usefulness() const {
7825a5ac124SDimitry Andric if (!VariableInstructions.empty())
783cf099d11SDimitry Andric return FilteredInstructions.size();
784cf099d11SDimitry Andric else
785cf099d11SDimitry Andric return FilteredInstructions.size() + 1;
786cf099d11SDimitry Andric }
787cf099d11SDimitry Andric
788cf099d11SDimitry Andric //////////////////////////////////
789cf099d11SDimitry Andric // //
790cf099d11SDimitry Andric // Filterchooser Implementation //
791cf099d11SDimitry Andric // //
792cf099d11SDimitry Andric //////////////////////////////////
793cf099d11SDimitry Andric
794902a7b52SDimitry Andric // Emit the decoder state machine table.
emitTable(formatted_raw_ostream & OS,DecoderTable & Table,unsigned Indentation,unsigned BitWidth,StringRef Namespace,const EncodingIDsVec & EncodingIDs) const795145449b1SDimitry Andric void DecoderEmitter::emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
796145449b1SDimitry Andric unsigned Indentation, unsigned BitWidth,
797ac9a064cSDimitry Andric StringRef Namespace,
798ac9a064cSDimitry Andric const EncodingIDsVec &EncodingIDs) const {
799ac9a064cSDimitry Andric // We'll need to be able to map from a decoded opcode into the corresponding
800ac9a064cSDimitry Andric // EncodingID for this specific combination of BitWidth and Namespace. This
801ac9a064cSDimitry Andric // is used below to index into NumberedEncodings.
802ac9a064cSDimitry Andric DenseMap<unsigned, unsigned> OpcodeToEncodingID;
803ac9a064cSDimitry Andric OpcodeToEncodingID.reserve(EncodingIDs.size());
804ac9a064cSDimitry Andric for (const auto &EI : EncodingIDs)
805ac9a064cSDimitry Andric OpcodeToEncodingID[EI.Opcode] = EI.EncodingID;
806ac9a064cSDimitry Andric
807902a7b52SDimitry Andric OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace
808902a7b52SDimitry Andric << BitWidth << "[] = {\n";
809cf099d11SDimitry Andric
810902a7b52SDimitry Andric Indentation += 2;
811cf099d11SDimitry Andric
812ac9a064cSDimitry Andric // Emit ULEB128 encoded value to OS, returning the number of bytes emitted.
813ac9a064cSDimitry Andric auto emitULEB128 = [](DecoderTable::const_iterator I,
814ac9a064cSDimitry Andric formatted_raw_ostream &OS) {
815ac9a064cSDimitry Andric unsigned Len = 0;
816ac9a064cSDimitry Andric while (*I >= 128) {
817ac9a064cSDimitry Andric OS << (unsigned)*I++ << ", ";
818ac9a064cSDimitry Andric Len++;
819ac9a064cSDimitry Andric }
820ac9a064cSDimitry Andric OS << (unsigned)*I++ << ", ";
821ac9a064cSDimitry Andric return Len + 1;
822ac9a064cSDimitry Andric };
823ac9a064cSDimitry Andric
824ac9a064cSDimitry Andric // Emit 24-bit numtoskip value to OS, returning the NumToSkip value.
825ac9a064cSDimitry Andric auto emitNumToSkip = [](DecoderTable::const_iterator I,
826ac9a064cSDimitry Andric formatted_raw_ostream &OS) {
827ac9a064cSDimitry Andric uint8_t Byte = *I++;
828ac9a064cSDimitry Andric uint32_t NumToSkip = Byte;
829ac9a064cSDimitry Andric OS << (unsigned)Byte << ", ";
830ac9a064cSDimitry Andric Byte = *I++;
831ac9a064cSDimitry Andric OS << (unsigned)Byte << ", ";
832ac9a064cSDimitry Andric NumToSkip |= Byte << 8;
833ac9a064cSDimitry Andric Byte = *I++;
834ac9a064cSDimitry Andric OS << utostr(Byte) << ", ";
835ac9a064cSDimitry Andric NumToSkip |= Byte << 16;
836ac9a064cSDimitry Andric return NumToSkip;
837ac9a064cSDimitry Andric };
838ac9a064cSDimitry Andric
839902a7b52SDimitry Andric // FIXME: We may be able to use the NumToSkip values to recover
840902a7b52SDimitry Andric // appropriate indentation levels.
841902a7b52SDimitry Andric DecoderTable::const_iterator I = Table.begin();
842902a7b52SDimitry Andric DecoderTable::const_iterator E = Table.end();
843902a7b52SDimitry Andric while (I != E) {
844902a7b52SDimitry Andric assert(I < E && "incomplete decode table entry!");
845cf099d11SDimitry Andric
846902a7b52SDimitry Andric uint64_t Pos = I - Table.begin();
847902a7b52SDimitry Andric OS << "/* " << Pos << " */";
848902a7b52SDimitry Andric OS.PadToColumn(12);
849cf099d11SDimitry Andric
850902a7b52SDimitry Andric switch (*I) {
851902a7b52SDimitry Andric default:
852522600a2SDimitry Andric PrintFatalError("invalid decode table opcode");
853902a7b52SDimitry Andric case MCD::OPC_ExtractField: {
854902a7b52SDimitry Andric ++I;
855ac9a064cSDimitry Andric OS.indent(Indentation) << "MCD::OPC_ExtractField, ";
856ac9a064cSDimitry Andric
857ac9a064cSDimitry Andric // ULEB128 encoded start value.
858ac9a064cSDimitry Andric const char *ErrMsg = nullptr;
859ac9a064cSDimitry Andric unsigned Start = decodeULEB128(Table.data() + Pos + 1, nullptr,
860ac9a064cSDimitry Andric Table.data() + Table.size(), &ErrMsg);
861ac9a064cSDimitry Andric assert(ErrMsg == nullptr && "ULEB128 value too large!");
862ac9a064cSDimitry Andric I += emitULEB128(I, OS);
863ac9a064cSDimitry Andric
864902a7b52SDimitry Andric unsigned Len = *I++;
865ac9a064cSDimitry Andric OS << Len << ", // Inst{";
866902a7b52SDimitry Andric if (Len > 1)
867902a7b52SDimitry Andric OS << (Start + Len - 1) << "-";
868902a7b52SDimitry Andric OS << Start << "} ...\n";
869902a7b52SDimitry Andric break;
870902a7b52SDimitry Andric }
871902a7b52SDimitry Andric case MCD::OPC_FilterValue: {
872902a7b52SDimitry Andric ++I;
873902a7b52SDimitry Andric OS.indent(Indentation) << "MCD::OPC_FilterValue, ";
874902a7b52SDimitry Andric // The filter value is ULEB128 encoded.
875ac9a064cSDimitry Andric I += emitULEB128(I, OS);
876902a7b52SDimitry Andric
877eb11fae6SDimitry Andric // 24-bit numtoskip value.
878ac9a064cSDimitry Andric uint32_t NumToSkip = emitNumToSkip(I, OS);
879ac9a064cSDimitry Andric I += 3;
880902a7b52SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
881902a7b52SDimitry Andric break;
882902a7b52SDimitry Andric }
883902a7b52SDimitry Andric case MCD::OPC_CheckField: {
884902a7b52SDimitry Andric ++I;
885ac9a064cSDimitry Andric OS.indent(Indentation) << "MCD::OPC_CheckField, ";
886ac9a064cSDimitry Andric // ULEB128 encoded start value.
887ac9a064cSDimitry Andric I += emitULEB128(I, OS);
888ac9a064cSDimitry Andric // 8-bit length.
889902a7b52SDimitry Andric unsigned Len = *I++;
890ac9a064cSDimitry Andric OS << Len << ", ";
891902a7b52SDimitry Andric // ULEB128 encoded field value.
892ac9a064cSDimitry Andric I += emitULEB128(I, OS);
893ac9a064cSDimitry Andric
894eb11fae6SDimitry Andric // 24-bit numtoskip value.
895ac9a064cSDimitry Andric uint32_t NumToSkip = emitNumToSkip(I, OS);
896ac9a064cSDimitry Andric I += 3;
897902a7b52SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
898902a7b52SDimitry Andric break;
899902a7b52SDimitry Andric }
900902a7b52SDimitry Andric case MCD::OPC_CheckPredicate: {
901902a7b52SDimitry Andric ++I;
902902a7b52SDimitry Andric OS.indent(Indentation) << "MCD::OPC_CheckPredicate, ";
903ac9a064cSDimitry Andric I += emitULEB128(I, OS);
904902a7b52SDimitry Andric
905eb11fae6SDimitry Andric // 24-bit numtoskip value.
906ac9a064cSDimitry Andric uint32_t NumToSkip = emitNumToSkip(I, OS);
907ac9a064cSDimitry Andric I += 3;
908902a7b52SDimitry Andric OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
909902a7b52SDimitry Andric break;
910902a7b52SDimitry Andric }
911dd58ef01SDimitry Andric case MCD::OPC_Decode:
912dd58ef01SDimitry Andric case MCD::OPC_TryDecode: {
913dd58ef01SDimitry Andric bool IsTry = *I == MCD::OPC_TryDecode;
914902a7b52SDimitry Andric ++I;
915902a7b52SDimitry Andric // Decode the Opcode value.
916ac9a064cSDimitry Andric const char *ErrMsg = nullptr;
917ac9a064cSDimitry Andric unsigned Opc = decodeULEB128(Table.data() + Pos + 1, nullptr,
918ac9a064cSDimitry Andric Table.data() + Table.size(), &ErrMsg);
919ac9a064cSDimitry Andric assert(ErrMsg == nullptr && "ULEB128 value too large!");
920ac9a064cSDimitry Andric
921ac9a064cSDimitry Andric OS.indent(Indentation)
922ac9a064cSDimitry Andric << "MCD::OPC_" << (IsTry ? "Try" : "") << "Decode, ";
923ac9a064cSDimitry Andric I += emitULEB128(I, OS);
924902a7b52SDimitry Andric
925902a7b52SDimitry Andric // Decoder index.
926ac9a064cSDimitry Andric I += emitULEB128(I, OS);
927ac9a064cSDimitry Andric
928ac9a064cSDimitry Andric auto EncI = OpcodeToEncodingID.find(Opc);
929ac9a064cSDimitry Andric assert(EncI != OpcodeToEncodingID.end() && "no encoding entry");
930ac9a064cSDimitry Andric auto EncodingID = EncI->second;
931902a7b52SDimitry Andric
932dd58ef01SDimitry Andric if (!IsTry) {
933ac9a064cSDimitry Andric OS << "// Opcode: " << NumberedEncodings[EncodingID] << "\n";
934902a7b52SDimitry Andric break;
935902a7b52SDimitry Andric }
936dd58ef01SDimitry Andric
937dd58ef01SDimitry Andric // Fallthrough for OPC_TryDecode.
938dd58ef01SDimitry Andric
939eb11fae6SDimitry Andric // 24-bit numtoskip value.
940ac9a064cSDimitry Andric uint32_t NumToSkip = emitNumToSkip(I, OS);
941ac9a064cSDimitry Andric I += 3;
942dd58ef01SDimitry Andric
943ac9a064cSDimitry Andric OS << "// Opcode: " << NumberedEncodings[EncodingID]
944dd58ef01SDimitry Andric << ", skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
945dd58ef01SDimitry Andric break;
946dd58ef01SDimitry Andric }
947902a7b52SDimitry Andric case MCD::OPC_SoftFail: {
948902a7b52SDimitry Andric ++I;
949902a7b52SDimitry Andric OS.indent(Indentation) << "MCD::OPC_SoftFail";
950902a7b52SDimitry Andric // Positive mask
951902a7b52SDimitry Andric uint64_t Value = 0;
952902a7b52SDimitry Andric unsigned Shift = 0;
953902a7b52SDimitry Andric do {
95401095a5dSDimitry Andric OS << ", " << (unsigned)*I;
955ac9a064cSDimitry Andric Value += ((uint64_t)(*I & 0x7f)) << Shift;
956902a7b52SDimitry Andric Shift += 7;
957902a7b52SDimitry Andric } while (*I++ >= 128);
95801095a5dSDimitry Andric if (Value > 127) {
95901095a5dSDimitry Andric OS << " /* 0x";
96001095a5dSDimitry Andric OS.write_hex(Value);
96101095a5dSDimitry Andric OS << " */";
96201095a5dSDimitry Andric }
963902a7b52SDimitry Andric // Negative mask
964902a7b52SDimitry Andric Value = 0;
965902a7b52SDimitry Andric Shift = 0;
966902a7b52SDimitry Andric do {
96701095a5dSDimitry Andric OS << ", " << (unsigned)*I;
968ac9a064cSDimitry Andric Value += ((uint64_t)(*I & 0x7f)) << Shift;
969902a7b52SDimitry Andric Shift += 7;
970902a7b52SDimitry Andric } while (*I++ >= 128);
97101095a5dSDimitry Andric if (Value > 127) {
97201095a5dSDimitry Andric OS << " /* 0x";
97301095a5dSDimitry Andric OS.write_hex(Value);
97401095a5dSDimitry Andric OS << " */";
97501095a5dSDimitry Andric }
976902a7b52SDimitry Andric OS << ",\n";
977902a7b52SDimitry Andric break;
978902a7b52SDimitry Andric }
979902a7b52SDimitry Andric case MCD::OPC_Fail: {
980902a7b52SDimitry Andric ++I;
981902a7b52SDimitry Andric OS.indent(Indentation) << "MCD::OPC_Fail,\n";
982902a7b52SDimitry Andric break;
983902a7b52SDimitry Andric }
984902a7b52SDimitry Andric }
985902a7b52SDimitry Andric }
986902a7b52SDimitry Andric OS.indent(Indentation) << "0\n";
987902a7b52SDimitry Andric
988902a7b52SDimitry Andric Indentation -= 2;
989902a7b52SDimitry Andric
990902a7b52SDimitry Andric OS.indent(Indentation) << "};\n\n";
991902a7b52SDimitry Andric }
992902a7b52SDimitry Andric
emitInstrLenTable(formatted_raw_ostream & OS,std::vector<unsigned> & InstrLen) const993145449b1SDimitry Andric void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
994145449b1SDimitry Andric std::vector<unsigned> &InstrLen) const {
995145449b1SDimitry Andric OS << "static const uint8_t InstrLenTable[] = {\n";
996145449b1SDimitry Andric for (unsigned &Len : InstrLen) {
997145449b1SDimitry Andric OS << Len << ",\n";
998145449b1SDimitry Andric }
999145449b1SDimitry Andric OS << "};\n\n";
1000145449b1SDimitry Andric }
1001145449b1SDimitry Andric
emitPredicateFunction(formatted_raw_ostream & OS,PredicateSet & Predicates,unsigned Indentation) const1002145449b1SDimitry Andric void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
1003145449b1SDimitry Andric PredicateSet &Predicates,
1004902a7b52SDimitry Andric unsigned Indentation) const {
1005902a7b52SDimitry Andric // The predicate function is just a big switch statement based on the
1006902a7b52SDimitry Andric // input predicate index.
1007902a7b52SDimitry Andric OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
10085a5ac124SDimitry Andric << "const FeatureBitset &Bits) {\n";
1009902a7b52SDimitry Andric Indentation += 2;
1010f8af5cf6SDimitry Andric if (!Predicates.empty()) {
1011902a7b52SDimitry Andric OS.indent(Indentation) << "switch (Idx) {\n";
1012ac9a064cSDimitry Andric OS.indent(Indentation)
1013ac9a064cSDimitry Andric << "default: llvm_unreachable(\"Invalid index!\");\n";
1014902a7b52SDimitry Andric unsigned Index = 0;
101567c32a98SDimitry Andric for (const auto &Predicate : Predicates) {
101667c32a98SDimitry Andric OS.indent(Indentation) << "case " << Index++ << ":\n";
101767c32a98SDimitry Andric OS.indent(Indentation + 2) << "return (" << Predicate << ");\n";
1018902a7b52SDimitry Andric }
1019902a7b52SDimitry Andric OS.indent(Indentation) << "}\n";
1020f8af5cf6SDimitry Andric } else {
1021f8af5cf6SDimitry Andric // No case statement to emit
1022f8af5cf6SDimitry Andric OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
1023f8af5cf6SDimitry Andric }
1024902a7b52SDimitry Andric Indentation -= 2;
1025902a7b52SDimitry Andric OS.indent(Indentation) << "}\n\n";
1026902a7b52SDimitry Andric }
1027902a7b52SDimitry Andric
emitDecoderFunction(formatted_raw_ostream & OS,DecoderSet & Decoders,unsigned Indentation) const1028145449b1SDimitry Andric void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
1029145449b1SDimitry Andric DecoderSet &Decoders,
1030902a7b52SDimitry Andric unsigned Indentation) const {
1031902a7b52SDimitry Andric // The decoder function is just a big switch statement based on the
1032902a7b52SDimitry Andric // input decoder index.
1033902a7b52SDimitry Andric OS.indent(Indentation) << "template <typename InsnType>\n";
1034902a7b52SDimitry Andric OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
1035902a7b52SDimitry Andric << " unsigned Idx, InsnType insn, MCInst &MI,\n";
1036145449b1SDimitry Andric OS.indent(Indentation)
1037145449b1SDimitry Andric << " uint64_t "
1038145449b1SDimitry Andric << "Address, const MCDisassembler *Decoder, bool &DecodeComplete) {\n";
1039902a7b52SDimitry Andric Indentation += 2;
1040dd58ef01SDimitry Andric OS.indent(Indentation) << "DecodeComplete = true;\n";
1041344a3780SDimitry Andric // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
1042344a3780SDimitry Andric // It would be better for emitBinaryParser to use a 64-bit tmp whenever
1043344a3780SDimitry Andric // possible but fall back to an InsnType-sized tmp for truly large fields.
1044344a3780SDimitry Andric OS.indent(Indentation) << "using TmpType = "
1045344a3780SDimitry Andric "std::conditional_t<std::is_integral<InsnType>::"
1046344a3780SDimitry Andric "value, InsnType, uint64_t>;\n";
1047344a3780SDimitry Andric OS.indent(Indentation) << "TmpType tmp;\n";
1048902a7b52SDimitry Andric OS.indent(Indentation) << "switch (Idx) {\n";
1049902a7b52SDimitry Andric OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
1050902a7b52SDimitry Andric unsigned Index = 0;
105167c32a98SDimitry Andric for (const auto &Decoder : Decoders) {
105267c32a98SDimitry Andric OS.indent(Indentation) << "case " << Index++ << ":\n";
105367c32a98SDimitry Andric OS << Decoder;
1054902a7b52SDimitry Andric OS.indent(Indentation + 2) << "return S;\n";
1055902a7b52SDimitry Andric }
1056902a7b52SDimitry Andric OS.indent(Indentation) << "}\n";
1057902a7b52SDimitry Andric Indentation -= 2;
1058ac9a064cSDimitry Andric OS.indent(Indentation) << "}\n";
1059cf099d11SDimitry Andric }
1060cf099d11SDimitry Andric
1061cf099d11SDimitry Andric // Populates the field of the insn given the start position and the number of
1062cf099d11SDimitry Andric // consecutive bits to scan for.
1063cf099d11SDimitry Andric //
1064ac9a064cSDimitry Andric // Returns a pair of values (indicator, field), where the indicator is false
1065ac9a064cSDimitry Andric // if there exists any uninitialized bit value in the range and true if all
1066ac9a064cSDimitry Andric // bits are well-known. The second value is the potentially populated field.
fieldFromInsn(const insn_t & Insn,unsigned StartBit,unsigned NumBits) const1067ac9a064cSDimitry Andric std::pair<bool, uint64_t> FilterChooser::fieldFromInsn(const insn_t &Insn,
1068ac9a064cSDimitry Andric unsigned StartBit,
1069ac9a064cSDimitry Andric unsigned NumBits) const {
1070ac9a064cSDimitry Andric uint64_t Field = 0;
1071cf099d11SDimitry Andric
1072cf099d11SDimitry Andric for (unsigned i = 0; i < NumBits; ++i) {
1073cf099d11SDimitry Andric if (Insn[StartBit + i] == BIT_UNSET)
1074ac9a064cSDimitry Andric return {false, Field};
1075cf099d11SDimitry Andric
1076cf099d11SDimitry Andric if (Insn[StartBit + i] == BIT_TRUE)
1077cf099d11SDimitry Andric Field = Field | (1ULL << i);
1078cf099d11SDimitry Andric }
1079cf099d11SDimitry Andric
1080ac9a064cSDimitry Andric return {true, Field};
1081cf099d11SDimitry Andric }
1082cf099d11SDimitry Andric
1083cf099d11SDimitry Andric /// dumpFilterArray - dumpFilterArray prints out debugging info for the given
1084cf099d11SDimitry Andric /// filter array as a series of chars.
dumpFilterArray(raw_ostream & o,const std::vector<bit_value_t> & filter) const1085ac9a064cSDimitry Andric void FilterChooser::dumpFilterArray(
1086ac9a064cSDimitry Andric raw_ostream &o, const std::vector<bit_value_t> &filter) const {
1087902a7b52SDimitry Andric for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) {
1088cf099d11SDimitry Andric switch (filter[bitIndex - 1]) {
1089cf099d11SDimitry Andric case BIT_UNFILTERED:
1090cf099d11SDimitry Andric o << ".";
1091cf099d11SDimitry Andric break;
1092cf099d11SDimitry Andric case BIT_UNSET:
1093cf099d11SDimitry Andric o << "_";
1094cf099d11SDimitry Andric break;
1095cf099d11SDimitry Andric case BIT_TRUE:
1096cf099d11SDimitry Andric o << "1";
1097cf099d11SDimitry Andric break;
1098cf099d11SDimitry Andric case BIT_FALSE:
1099cf099d11SDimitry Andric o << "0";
1100cf099d11SDimitry Andric break;
1101cf099d11SDimitry Andric }
1102cf099d11SDimitry Andric }
1103cf099d11SDimitry Andric }
1104cf099d11SDimitry Andric
1105cf099d11SDimitry Andric /// dumpStack - dumpStack traverses the filter chooser chain and calls
1106cf099d11SDimitry Andric /// dumpFilterArray on each filter chooser up to the top level one.
dumpStack(raw_ostream & o,const char * prefix) const110763faed5bSDimitry Andric void FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const {
110863faed5bSDimitry Andric const FilterChooser *current = this;
1109cf099d11SDimitry Andric
1110cf099d11SDimitry Andric while (current) {
1111cf099d11SDimitry Andric o << prefix;
1112cf099d11SDimitry Andric dumpFilterArray(o, current->FilterBitValues);
1113cf099d11SDimitry Andric o << '\n';
1114cf099d11SDimitry Andric current = current->Parent;
1115cf099d11SDimitry Andric }
1116cf099d11SDimitry Andric }
1117cf099d11SDimitry Andric
1118cf099d11SDimitry Andric // Calculates the island(s) needed to decode the instruction.
1119cf099d11SDimitry Andric // This returns a list of undecoded bits of an instructions, for example,
1120cf099d11SDimitry Andric // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be
1121cf099d11SDimitry Andric // decoded bits in order to verify that the instruction matches the Opcode.
getIslands(std::vector<unsigned> & StartBits,std::vector<unsigned> & EndBits,std::vector<uint64_t> & FieldVals,const insn_t & Insn) const1122cf099d11SDimitry Andric unsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits,
112363faed5bSDimitry Andric std::vector<unsigned> &EndBits,
112463faed5bSDimitry Andric std::vector<uint64_t> &FieldVals,
112563faed5bSDimitry Andric const insn_t &Insn) const {
1126cf099d11SDimitry Andric unsigned Num, BitNo;
1127cf099d11SDimitry Andric Num = BitNo = 0;
1128cf099d11SDimitry Andric
1129cf099d11SDimitry Andric uint64_t FieldVal = 0;
1130cf099d11SDimitry Andric
1131cf099d11SDimitry Andric // 0: Init
1132cf099d11SDimitry Andric // 1: Water (the bit value does not affect decoding)
1133cf099d11SDimitry Andric // 2: Island (well-known bit value needed for decoding)
1134cf099d11SDimitry Andric int State = 0;
1135cf099d11SDimitry Andric
113630815c53SDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) {
1137706b4fc4SDimitry Andric int64_t Val = Value(Insn[i]);
1138cf099d11SDimitry Andric bool Filtered = PositionFiltered(i);
1139cf099d11SDimitry Andric switch (State) {
1140ac9a064cSDimitry Andric default:
1141ac9a064cSDimitry Andric llvm_unreachable("Unreachable code!");
1142cf099d11SDimitry Andric case 0:
1143cf099d11SDimitry Andric case 1:
1144cf099d11SDimitry Andric if (Filtered || Val == -1)
1145cf099d11SDimitry Andric State = 1; // Still in Water
1146cf099d11SDimitry Andric else {
1147cf099d11SDimitry Andric State = 2; // Into the Island
1148cf099d11SDimitry Andric BitNo = 0;
1149cf099d11SDimitry Andric StartBits.push_back(i);
1150cf099d11SDimitry Andric FieldVal = Val;
1151cf099d11SDimitry Andric }
1152cf099d11SDimitry Andric break;
1153cf099d11SDimitry Andric case 2:
1154cf099d11SDimitry Andric if (Filtered || Val == -1) {
1155cf099d11SDimitry Andric State = 1; // Into the Water
1156cf099d11SDimitry Andric EndBits.push_back(i - 1);
1157cf099d11SDimitry Andric FieldVals.push_back(FieldVal);
1158cf099d11SDimitry Andric ++Num;
1159cf099d11SDimitry Andric } else {
1160cf099d11SDimitry Andric State = 2; // Still in Island
1161cf099d11SDimitry Andric ++BitNo;
1162cf099d11SDimitry Andric FieldVal = FieldVal | Val << BitNo;
1163cf099d11SDimitry Andric }
1164cf099d11SDimitry Andric break;
1165cf099d11SDimitry Andric }
1166cf099d11SDimitry Andric }
1167cf099d11SDimitry Andric // If we are still in Island after the loop, do some housekeeping.
1168cf099d11SDimitry Andric if (State == 2) {
116930815c53SDimitry Andric EndBits.push_back(BitWidth - 1);
1170cf099d11SDimitry Andric FieldVals.push_back(FieldVal);
1171cf099d11SDimitry Andric ++Num;
1172cf099d11SDimitry Andric }
1173cf099d11SDimitry Andric
1174cf099d11SDimitry Andric assert(StartBits.size() == Num && EndBits.size() == Num &&
1175cf099d11SDimitry Andric FieldVals.size() == Num);
1176cf099d11SDimitry Andric return Num;
1177cf099d11SDimitry Andric }
1178cf099d11SDimitry Andric
emitBinaryParser(raw_ostream & o,unsigned & Indentation,const OperandInfo & OpInfo,bool & OpHasCompleteDecoder) const117930815c53SDimitry Andric void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
1180dd58ef01SDimitry Andric const OperandInfo &OpInfo,
1181dd58ef01SDimitry Andric bool &OpHasCompleteDecoder) const {
118263faed5bSDimitry Andric const std::string &Decoder = OpInfo.Decoder;
118330815c53SDimitry Andric
1184344a3780SDimitry Andric bool UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0;
1185344a3780SDimitry Andric
1186344a3780SDimitry Andric if (UseInsertBits) {
11871d5ae102SDimitry Andric o.indent(Indentation) << "tmp = 0x";
11881d5ae102SDimitry Andric o.write_hex(OpInfo.InitValue);
11891d5ae102SDimitry Andric o << ";\n";
11901d5ae102SDimitry Andric }
119167c32a98SDimitry Andric
119267c32a98SDimitry Andric for (const EncodingField &EF : OpInfo) {
1193344a3780SDimitry Andric o.indent(Indentation);
1194344a3780SDimitry Andric if (UseInsertBits)
1195344a3780SDimitry Andric o << "insertBits(tmp, ";
1196344a3780SDimitry Andric else
1197344a3780SDimitry Andric o << "tmp = ";
1198344a3780SDimitry Andric o << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
1199344a3780SDimitry Andric if (UseInsertBits)
1200344a3780SDimitry Andric o << ", " << EF.Offset << ", " << EF.Width << ')';
1201344a3780SDimitry Andric else if (EF.Offset != 0)
120267c32a98SDimitry Andric o << " << " << EF.Offset;
120367c32a98SDimitry Andric o << ";\n";
120430815c53SDimitry Andric }
120530815c53SDimitry Andric
1206dd58ef01SDimitry Andric if (Decoder != "") {
1207dd58ef01SDimitry Andric OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
1208e3b55780SDimitry Andric o.indent(Indentation) << "if (!Check(S, " << Decoder
1209e3b55780SDimitry Andric << "(MI, tmp, Address, Decoder))) { "
1210e3b55780SDimitry Andric << (OpHasCompleteDecoder ? ""
1211e3b55780SDimitry Andric : "DecodeComplete = false; ")
1212dd58ef01SDimitry Andric << "return MCDisassembler::Fail; }\n";
1213dd58ef01SDimitry Andric } else {
1214dd58ef01SDimitry Andric OpHasCompleteDecoder = true;
12155a5ac124SDimitry Andric o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n";
1216dd58ef01SDimitry Andric }
121730815c53SDimitry Andric }
121830815c53SDimitry Andric
emitDecoder(raw_ostream & OS,unsigned Indentation,unsigned Opc,bool & HasCompleteDecoder) const1219902a7b52SDimitry Andric void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
1220dd58ef01SDimitry Andric unsigned Opc, bool &HasCompleteDecoder) const {
1221dd58ef01SDimitry Andric HasCompleteDecoder = true;
1222dd58ef01SDimitry Andric
122367c32a98SDimitry Andric for (const auto &Op : Operands.find(Opc)->second) {
1224902a7b52SDimitry Andric // If a custom instruction decoder was specified, use that.
1225b915e9e0SDimitry Andric if (Op.numFields() == 0 && !Op.Decoder.empty()) {
1226dd58ef01SDimitry Andric HasCompleteDecoder = Op.HasCompleteDecoder;
1227e3b55780SDimitry Andric OS.indent(Indentation)
1228e3b55780SDimitry Andric << "if (!Check(S, " << Op.Decoder
1229e3b55780SDimitry Andric << "(MI, insn, Address, Decoder))) { "
1230e3b55780SDimitry Andric << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
1231dd58ef01SDimitry Andric << "return MCDisassembler::Fail; }\n";
1232902a7b52SDimitry Andric break;
1233902a7b52SDimitry Andric }
1234902a7b52SDimitry Andric
1235dd58ef01SDimitry Andric bool OpHasCompleteDecoder;
1236dd58ef01SDimitry Andric emitBinaryParser(OS, Indentation, Op, OpHasCompleteDecoder);
1237dd58ef01SDimitry Andric if (!OpHasCompleteDecoder)
1238dd58ef01SDimitry Andric HasCompleteDecoder = false;
1239902a7b52SDimitry Andric }
1240902a7b52SDimitry Andric }
1241902a7b52SDimitry Andric
getDecoderIndex(DecoderSet & Decoders,unsigned Opc,bool & HasCompleteDecoder) const1242ac9a064cSDimitry Andric unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, unsigned Opc,
1243dd58ef01SDimitry Andric bool &HasCompleteDecoder) const {
1244902a7b52SDimitry Andric // Build up the predicate string.
1245902a7b52SDimitry Andric SmallString<256> Decoder;
1246902a7b52SDimitry Andric // FIXME: emitDecoder() function can take a buffer directly rather than
1247902a7b52SDimitry Andric // a stream.
1248902a7b52SDimitry Andric raw_svector_ostream S(Decoder);
1249902a7b52SDimitry Andric unsigned I = 4;
1250dd58ef01SDimitry Andric emitDecoder(S, I, Opc, HasCompleteDecoder);
1251902a7b52SDimitry Andric
1252902a7b52SDimitry Andric // Using the full decoder string as the key value here is a bit
1253902a7b52SDimitry Andric // heavyweight, but is effective. If the string comparisons become a
1254902a7b52SDimitry Andric // performance concern, we can implement a mangling of the predicate
1255dd58ef01SDimitry Andric // data easily enough with a map back to the actual string. That's
1256902a7b52SDimitry Andric // overkill for now, though.
1257902a7b52SDimitry Andric
1258902a7b52SDimitry Andric // Make sure the predicate is in the table.
1259b915e9e0SDimitry Andric Decoders.insert(CachedHashString(Decoder));
1260902a7b52SDimitry Andric // Now figure out the index for when we write out the table.
1261b915e9e0SDimitry Andric DecoderSet::const_iterator P = find(Decoders, Decoder.str());
1262902a7b52SDimitry Andric return (unsigned)(P - Decoders.begin());
1263902a7b52SDimitry Andric }
1264902a7b52SDimitry Andric
1265145449b1SDimitry Andric // If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
emitPredicateMatchAux(const Init & Val,bool ParenIfBinOp,raw_ostream & OS) const1266145449b1SDimitry Andric bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
1267145449b1SDimitry Andric raw_ostream &OS) const {
1268ac9a064cSDimitry Andric if (const auto *D = dyn_cast<DefInit>(&Val)) {
1269145449b1SDimitry Andric if (!D->getDef()->isSubClassOf("SubtargetFeature"))
1270145449b1SDimitry Andric return true;
1271145449b1SDimitry Andric OS << "Bits[" << Emitter->PredicateNamespace << "::" << D->getAsString()
1272145449b1SDimitry Andric << "]";
1273145449b1SDimitry Andric return false;
1274145449b1SDimitry Andric }
1275ac9a064cSDimitry Andric if (const auto *D = dyn_cast<DagInit>(&Val)) {
1276145449b1SDimitry Andric std::string Op = D->getOperator()->getAsString();
1277145449b1SDimitry Andric if (Op == "not" && D->getNumArgs() == 1) {
1278145449b1SDimitry Andric OS << '!';
1279145449b1SDimitry Andric return emitPredicateMatchAux(*D->getArg(0), true, OS);
1280145449b1SDimitry Andric }
1281145449b1SDimitry Andric if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) {
1282145449b1SDimitry Andric bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true);
1283145449b1SDimitry Andric if (Paren)
1284145449b1SDimitry Andric OS << '(';
1285145449b1SDimitry Andric ListSeparator LS(Op == "any_of" ? " || " : " && ");
1286145449b1SDimitry Andric for (auto *Arg : D->getArgs()) {
1287145449b1SDimitry Andric OS << LS;
1288145449b1SDimitry Andric if (emitPredicateMatchAux(*Arg, ParenIfBinOp, OS))
1289145449b1SDimitry Andric return true;
1290145449b1SDimitry Andric }
1291145449b1SDimitry Andric if (Paren)
1292145449b1SDimitry Andric OS << ')';
1293145449b1SDimitry Andric return false;
1294145449b1SDimitry Andric }
1295145449b1SDimitry Andric }
1296145449b1SDimitry Andric return true;
1297145449b1SDimitry Andric }
1298145449b1SDimitry Andric
emitPredicateMatch(raw_ostream & o,unsigned & Indentation,unsigned Opc) const129930815c53SDimitry Andric bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
130063faed5bSDimitry Andric unsigned Opc) const {
130163faed5bSDimitry Andric ListInit *Predicates =
1302d8e91e46SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
13035a5ac124SDimitry Andric bool IsFirstEmission = true;
130485d8b2bbSDimitry Andric for (unsigned i = 0; i < Predicates->size(); ++i) {
130530815c53SDimitry Andric Record *Pred = Predicates->getElementAsRecord(i);
130630815c53SDimitry Andric if (!Pred->getValue("AssemblerMatcherPredicate"))
130730815c53SDimitry Andric continue;
130830815c53SDimitry Andric
1309b60736ecSDimitry Andric if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
131030815c53SDimitry Andric continue;
131130815c53SDimitry Andric
13125a5ac124SDimitry Andric if (!IsFirstEmission)
131330815c53SDimitry Andric o << " && ";
1314145449b1SDimitry Andric if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
1315145449b1SDimitry Andric Predicates->size() > 1, o))
1316cfca06d7SDimitry Andric PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
13175a5ac124SDimitry Andric IsFirstEmission = false;
131830815c53SDimitry Andric }
131985d8b2bbSDimitry Andric return !Predicates->empty();
132030815c53SDimitry Andric }
132130815c53SDimitry Andric
doesOpcodeNeedPredicate(unsigned Opc) const1322902a7b52SDimitry Andric bool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const {
1323902a7b52SDimitry Andric ListInit *Predicates =
1324d8e91e46SDimitry Andric AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
132585d8b2bbSDimitry Andric for (unsigned i = 0; i < Predicates->size(); ++i) {
1326902a7b52SDimitry Andric Record *Pred = Predicates->getElementAsRecord(i);
1327902a7b52SDimitry Andric if (!Pred->getValue("AssemblerMatcherPredicate"))
1328902a7b52SDimitry Andric continue;
1329902a7b52SDimitry Andric
1330344a3780SDimitry Andric if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
1331902a7b52SDimitry Andric return true;
1332902a7b52SDimitry Andric }
1333902a7b52SDimitry Andric return false;
1334902a7b52SDimitry Andric }
1335902a7b52SDimitry Andric
getPredicateIndex(DecoderTableInfo & TableInfo,StringRef Predicate) const1336902a7b52SDimitry Andric unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
1337902a7b52SDimitry Andric StringRef Predicate) const {
1338902a7b52SDimitry Andric // Using the full predicate string as the key value here is a bit
1339902a7b52SDimitry Andric // heavyweight, but is effective. If the string comparisons become a
1340902a7b52SDimitry Andric // performance concern, we can implement a mangling of the predicate
1341dd58ef01SDimitry Andric // data easily enough with a map back to the actual string. That's
1342902a7b52SDimitry Andric // overkill for now, though.
1343902a7b52SDimitry Andric
1344902a7b52SDimitry Andric // Make sure the predicate is in the table.
1345b915e9e0SDimitry Andric TableInfo.Predicates.insert(CachedHashString(Predicate));
1346902a7b52SDimitry Andric // Now figure out the index for when we write out the table.
1347b915e9e0SDimitry Andric PredicateSet::const_iterator P = find(TableInfo.Predicates, Predicate);
1348902a7b52SDimitry Andric return (unsigned)(P - TableInfo.Predicates.begin());
1349902a7b52SDimitry Andric }
1350902a7b52SDimitry Andric
emitPredicateTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const1351902a7b52SDimitry Andric void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
1352902a7b52SDimitry Andric unsigned Opc) const {
1353902a7b52SDimitry Andric if (!doesOpcodeNeedPredicate(Opc))
1354902a7b52SDimitry Andric return;
1355902a7b52SDimitry Andric
1356902a7b52SDimitry Andric // Build up the predicate string.
1357902a7b52SDimitry Andric SmallString<256> Predicate;
1358902a7b52SDimitry Andric // FIXME: emitPredicateMatch() functions can take a buffer directly rather
1359902a7b52SDimitry Andric // than a stream.
1360902a7b52SDimitry Andric raw_svector_ostream PS(Predicate);
1361902a7b52SDimitry Andric unsigned I = 0;
1362902a7b52SDimitry Andric emitPredicateMatch(PS, I, Opc);
1363902a7b52SDimitry Andric
1364902a7b52SDimitry Andric // Figure out the index into the predicate table for the predicate just
1365902a7b52SDimitry Andric // computed.
1366902a7b52SDimitry Andric unsigned PIdx = getPredicateIndex(TableInfo, PS.str());
1367902a7b52SDimitry Andric SmallString<16> PBytes;
1368902a7b52SDimitry Andric raw_svector_ostream S(PBytes);
1369902a7b52SDimitry Andric encodeULEB128(PIdx, S);
1370902a7b52SDimitry Andric
1371902a7b52SDimitry Andric TableInfo.Table.push_back(MCD::OPC_CheckPredicate);
1372ac9a064cSDimitry Andric // Predicate index.
1373ac9a064cSDimitry Andric for (const auto PB : PBytes)
1374ac9a064cSDimitry Andric TableInfo.Table.push_back(PB);
1375902a7b52SDimitry Andric // Push location for NumToSkip backpatching.
1376902a7b52SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1377902a7b52SDimitry Andric TableInfo.Table.push_back(0);
1378902a7b52SDimitry Andric TableInfo.Table.push_back(0);
1379eb11fae6SDimitry Andric TableInfo.Table.push_back(0);
1380902a7b52SDimitry Andric }
1381902a7b52SDimitry Andric
emitSoftFailTableEntry(DecoderTableInfo & TableInfo,unsigned Opc) const1382902a7b52SDimitry Andric void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
138363faed5bSDimitry Andric unsigned Opc) const {
1384ac9a064cSDimitry Andric const Record *EncodingDef = AllInstructions[Opc].EncodingDef;
1385ac9a064cSDimitry Andric const RecordVal *RV = EncodingDef->getValue("SoftFail");
1386145449b1SDimitry Andric BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
1387145449b1SDimitry Andric
1388ac9a064cSDimitry Andric if (!SFBits)
1389ac9a064cSDimitry Andric return;
1390ac9a064cSDimitry Andric BitsInit *InstBits = EncodingDef->getValueAsBitsInit("Inst");
139163faed5bSDimitry Andric
139263faed5bSDimitry Andric APInt PositiveMask(BitWidth, 0ULL);
139363faed5bSDimitry Andric APInt NegativeMask(BitWidth, 0ULL);
139463faed5bSDimitry Andric for (unsigned i = 0; i < BitWidth; ++i) {
139563faed5bSDimitry Andric bit_value_t B = bitFromBits(*SFBits, i);
139663faed5bSDimitry Andric bit_value_t IB = bitFromBits(*InstBits, i);
139763faed5bSDimitry Andric
1398ac9a064cSDimitry Andric if (B != BIT_TRUE)
1399ac9a064cSDimitry Andric continue;
140063faed5bSDimitry Andric
140163faed5bSDimitry Andric switch (IB) {
140263faed5bSDimitry Andric case BIT_FALSE:
140363faed5bSDimitry Andric // The bit is meant to be false, so emit a check to see if it is true.
140463faed5bSDimitry Andric PositiveMask.setBit(i);
140563faed5bSDimitry Andric break;
140663faed5bSDimitry Andric case BIT_TRUE:
140763faed5bSDimitry Andric // The bit is meant to be true, so emit a check to see if it is false.
140863faed5bSDimitry Andric NegativeMask.setBit(i);
140963faed5bSDimitry Andric break;
141063faed5bSDimitry Andric default:
141163faed5bSDimitry Andric // The bit is not set; this must be an error!
1412d8e91e46SDimitry Andric errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
1413d8e91e46SDimitry Andric << AllInstructions[Opc] << " is set but Inst{" << i
1414d8e91e46SDimitry Andric << "} is unset!\n"
141563faed5bSDimitry Andric << " - You can only mark a bit as SoftFail if it is fully defined"
141663faed5bSDimitry Andric << " (1/0 - not '?') in Inst\n";
1417902a7b52SDimitry Andric return;
141863faed5bSDimitry Andric }
141963faed5bSDimitry Andric }
142063faed5bSDimitry Andric
142163faed5bSDimitry Andric bool NeedPositiveMask = PositiveMask.getBoolValue();
142263faed5bSDimitry Andric bool NeedNegativeMask = NegativeMask.getBoolValue();
142363faed5bSDimitry Andric
142463faed5bSDimitry Andric if (!NeedPositiveMask && !NeedNegativeMask)
142563faed5bSDimitry Andric return;
142663faed5bSDimitry Andric
1427902a7b52SDimitry Andric TableInfo.Table.push_back(MCD::OPC_SoftFail);
142863faed5bSDimitry Andric
1429902a7b52SDimitry Andric SmallString<16> MaskBytes;
1430902a7b52SDimitry Andric raw_svector_ostream S(MaskBytes);
1431902a7b52SDimitry Andric if (NeedPositiveMask) {
1432902a7b52SDimitry Andric encodeULEB128(PositiveMask.getZExtValue(), S);
1433902a7b52SDimitry Andric for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
1434902a7b52SDimitry Andric TableInfo.Table.push_back(MaskBytes[i]);
1435902a7b52SDimitry Andric } else
1436902a7b52SDimitry Andric TableInfo.Table.push_back(0);
1437902a7b52SDimitry Andric if (NeedNegativeMask) {
1438902a7b52SDimitry Andric MaskBytes.clear();
1439902a7b52SDimitry Andric encodeULEB128(NegativeMask.getZExtValue(), S);
1440902a7b52SDimitry Andric for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i)
1441902a7b52SDimitry Andric TableInfo.Table.push_back(MaskBytes[i]);
1442902a7b52SDimitry Andric } else
1443902a7b52SDimitry Andric TableInfo.Table.push_back(0);
144463faed5bSDimitry Andric }
144563faed5bSDimitry Andric
1446902a7b52SDimitry Andric // Emits table entries to decode the singleton.
emitSingletonTableEntry(DecoderTableInfo & TableInfo,EncodingIDAndOpcode Opc) const1447902a7b52SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1448e6d15924SDimitry Andric EncodingIDAndOpcode Opc) const {
1449cf099d11SDimitry Andric std::vector<unsigned> StartBits;
1450cf099d11SDimitry Andric std::vector<unsigned> EndBits;
1451cf099d11SDimitry Andric std::vector<uint64_t> FieldVals;
1452cf099d11SDimitry Andric insn_t Insn;
1453e6d15924SDimitry Andric insnWithID(Insn, Opc.EncodingID);
1454cf099d11SDimitry Andric
1455cf099d11SDimitry Andric // Look for islands of undecoded bits of the singleton.
1456cf099d11SDimitry Andric getIslands(StartBits, EndBits, FieldVals, Insn);
1457cf099d11SDimitry Andric
1458cf099d11SDimitry Andric unsigned Size = StartBits.size();
1459cf099d11SDimitry Andric
1460902a7b52SDimitry Andric // Emit the predicate table entry if one is needed.
1461e6d15924SDimitry Andric emitPredicateTableEntry(TableInfo, Opc.EncodingID);
1462902a7b52SDimitry Andric
1463902a7b52SDimitry Andric // Check any additional encoding fields needed.
1464902a7b52SDimitry Andric for (unsigned I = Size; I != 0; --I) {
1465902a7b52SDimitry Andric unsigned NumBits = EndBits[I - 1] - StartBits[I - 1] + 1;
1466ac9a064cSDimitry Andric assert((NumBits < (1u << 8)) && "NumBits overflowed uint8 table entry!");
1467902a7b52SDimitry Andric TableInfo.Table.push_back(MCD::OPC_CheckField);
1468ac9a064cSDimitry Andric uint8_t Buffer[16], *P;
1469ac9a064cSDimitry Andric encodeULEB128(StartBits[I - 1], Buffer);
1470ac9a064cSDimitry Andric for (P = Buffer; *P >= 128; ++P)
1471ac9a064cSDimitry Andric TableInfo.Table.push_back(*P);
1472ac9a064cSDimitry Andric TableInfo.Table.push_back(*P);
1473902a7b52SDimitry Andric TableInfo.Table.push_back(NumBits);
1474902a7b52SDimitry Andric encodeULEB128(FieldVals[I - 1], Buffer);
1475ac9a064cSDimitry Andric for (P = Buffer; *P >= 128; ++P)
1476ac9a064cSDimitry Andric TableInfo.Table.push_back(*P);
1477ac9a064cSDimitry Andric TableInfo.Table.push_back(*P);
1478902a7b52SDimitry Andric // Push location for NumToSkip backpatching.
1479902a7b52SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1480eb11fae6SDimitry Andric // The fixup is always 24-bits, so go ahead and allocate the space
1481902a7b52SDimitry Andric // in the table so all our relative position calculations work OK even
1482902a7b52SDimitry Andric // before we fully resolve the real value here.
1483902a7b52SDimitry Andric TableInfo.Table.push_back(0);
1484902a7b52SDimitry Andric TableInfo.Table.push_back(0);
1485eb11fae6SDimitry Andric TableInfo.Table.push_back(0);
1486cf099d11SDimitry Andric }
1487cf099d11SDimitry Andric
1488902a7b52SDimitry Andric // Check for soft failure of the match.
1489e6d15924SDimitry Andric emitSoftFailTableEntry(TableInfo, Opc.EncodingID);
1490902a7b52SDimitry Andric
1491dd58ef01SDimitry Andric bool HasCompleteDecoder;
1492e6d15924SDimitry Andric unsigned DIdx =
1493e6d15924SDimitry Andric getDecoderIndex(TableInfo.Decoders, Opc.EncodingID, HasCompleteDecoder);
1494dd58ef01SDimitry Andric
1495dd58ef01SDimitry Andric // Produce OPC_Decode or OPC_TryDecode opcode based on the information
1496dd58ef01SDimitry Andric // whether the instruction decoder is complete or not. If it is complete
1497dd58ef01SDimitry Andric // then it handles all possible values of remaining variable/unfiltered bits
1498dd58ef01SDimitry Andric // and for any value can determine if the bitpattern is a valid instruction
1499dd58ef01SDimitry Andric // or not. This means OPC_Decode will be the final step in the decoding
1500dd58ef01SDimitry Andric // process. If it is not complete, then the Fail return code from the
1501dd58ef01SDimitry Andric // decoder method indicates that additional processing should be done to see
1502dd58ef01SDimitry Andric // if there is any other instruction that also matches the bitpattern and
1503dd58ef01SDimitry Andric // can decode it.
1504ac9a064cSDimitry Andric TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode
1505ac9a064cSDimitry Andric : MCD::OPC_TryDecode);
1506e6d15924SDimitry Andric NumEncodingsSupported++;
1507eb11fae6SDimitry Andric uint8_t Buffer[16], *p;
1508e6d15924SDimitry Andric encodeULEB128(Opc.Opcode, Buffer);
1509902a7b52SDimitry Andric for (p = Buffer; *p >= 128; ++p)
1510902a7b52SDimitry Andric TableInfo.Table.push_back(*p);
1511902a7b52SDimitry Andric TableInfo.Table.push_back(*p);
1512902a7b52SDimitry Andric
1513902a7b52SDimitry Andric SmallString<16> Bytes;
1514902a7b52SDimitry Andric raw_svector_ostream S(Bytes);
1515902a7b52SDimitry Andric encodeULEB128(DIdx, S);
1516902a7b52SDimitry Andric
1517ac9a064cSDimitry Andric // Decoder index.
1518ac9a064cSDimitry Andric for (const auto B : Bytes)
1519ac9a064cSDimitry Andric TableInfo.Table.push_back(B);
1520dd58ef01SDimitry Andric
1521dd58ef01SDimitry Andric if (!HasCompleteDecoder) {
1522dd58ef01SDimitry Andric // Push location for NumToSkip backpatching.
1523dd58ef01SDimitry Andric TableInfo.FixupStack.back().push_back(TableInfo.Table.size());
1524dd58ef01SDimitry Andric // Allocate the space for the fixup.
1525dd58ef01SDimitry Andric TableInfo.Table.push_back(0);
1526dd58ef01SDimitry Andric TableInfo.Table.push_back(0);
1527eb11fae6SDimitry Andric TableInfo.Table.push_back(0);
1528dd58ef01SDimitry Andric }
1529cf099d11SDimitry Andric }
1530cf099d11SDimitry Andric
1531902a7b52SDimitry Andric // Emits table entries to decode the singleton, and then to decode the rest.
emitSingletonTableEntry(DecoderTableInfo & TableInfo,const Filter & Best) const1532902a7b52SDimitry Andric void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
153363faed5bSDimitry Andric const Filter &Best) const {
1534e6d15924SDimitry Andric EncodingIDAndOpcode Opc = Best.getSingletonOpc();
1535cf099d11SDimitry Andric
1536902a7b52SDimitry Andric // complex singletons need predicate checks from the first singleton
1537902a7b52SDimitry Andric // to refer forward to the variable filterchooser that follows.
153885d8b2bbSDimitry Andric TableInfo.FixupStack.emplace_back();
1539cf099d11SDimitry Andric
1540902a7b52SDimitry Andric emitSingletonTableEntry(TableInfo, Opc);
1541cf099d11SDimitry Andric
1542902a7b52SDimitry Andric resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
1543902a7b52SDimitry Andric TableInfo.Table.size());
1544902a7b52SDimitry Andric TableInfo.FixupStack.pop_back();
1545902a7b52SDimitry Andric
1546902a7b52SDimitry Andric Best.getVariableFC().emitTableEntries(TableInfo);
1547cf099d11SDimitry Andric }
1548cf099d11SDimitry Andric
1549cf099d11SDimitry Andric // Assign a single filter and run with it. Top level API client can initialize
1550cf099d11SDimitry Andric // with a single filter to start the filtering process.
runSingleFilter(unsigned startBit,unsigned numBit,bool mixed)155163faed5bSDimitry Andric void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit,
155263faed5bSDimitry Andric bool mixed) {
1553cf099d11SDimitry Andric Filters.clear();
155485d8b2bbSDimitry Andric Filters.emplace_back(*this, startBit, numBit, true);
1555cf099d11SDimitry Andric BestIndex = 0; // Sole Filter instance to choose from.
1556cf099d11SDimitry Andric bestFilter().recurse();
1557cf099d11SDimitry Andric }
1558cf099d11SDimitry Andric
1559cf099d11SDimitry Andric // reportRegion is a helper function for filterProcessor to mark a region as
1560cf099d11SDimitry Andric // eligible for use as a filter region.
reportRegion(bitAttr_t RA,unsigned StartBit,unsigned BitIndex,bool AllowMixed)1561cf099d11SDimitry Andric void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
1562cf099d11SDimitry Andric unsigned BitIndex, bool AllowMixed) {
1563cf099d11SDimitry Andric if (RA == ATTR_MIXED && AllowMixed)
156485d8b2bbSDimitry Andric Filters.emplace_back(*this, StartBit, BitIndex - StartBit, true);
1565cf099d11SDimitry Andric else if (RA == ATTR_ALL_SET && !AllowMixed)
156685d8b2bbSDimitry Andric Filters.emplace_back(*this, StartBit, BitIndex - StartBit, false);
1567cf099d11SDimitry Andric }
1568cf099d11SDimitry Andric
1569cf099d11SDimitry Andric // FilterProcessor scans the well-known encoding bits of the instructions and
1570cf099d11SDimitry Andric // builds up a list of candidate filters. It chooses the best filter and
1571cf099d11SDimitry Andric // recursively descends down the decoding tree.
filterProcessor(bool AllowMixed,bool Greedy)1572cf099d11SDimitry Andric bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
1573cf099d11SDimitry Andric Filters.clear();
1574cf099d11SDimitry Andric BestIndex = -1;
1575cf099d11SDimitry Andric unsigned numInstructions = Opcodes.size();
1576cf099d11SDimitry Andric
1577cf099d11SDimitry Andric assert(numInstructions && "Filter created with no instructions");
1578cf099d11SDimitry Andric
1579cf099d11SDimitry Andric // No further filtering is necessary.
1580cf099d11SDimitry Andric if (numInstructions == 1)
1581cf099d11SDimitry Andric return true;
1582cf099d11SDimitry Andric
1583cf099d11SDimitry Andric // Heuristics. See also doFilter()'s "Heuristics" comment when num of
1584cf099d11SDimitry Andric // instructions is 3.
1585cf099d11SDimitry Andric if (AllowMixed && !Greedy) {
1586cf099d11SDimitry Andric assert(numInstructions == 3);
1587cf099d11SDimitry Andric
1588ac9a064cSDimitry Andric for (const auto &Opcode : Opcodes) {
1589cf099d11SDimitry Andric std::vector<unsigned> StartBits;
1590cf099d11SDimitry Andric std::vector<unsigned> EndBits;
1591cf099d11SDimitry Andric std::vector<uint64_t> FieldVals;
1592cf099d11SDimitry Andric insn_t Insn;
1593cf099d11SDimitry Andric
1594344a3780SDimitry Andric insnWithID(Insn, Opcode.EncodingID);
1595cf099d11SDimitry Andric
1596cf099d11SDimitry Andric // Look for islands of undecoded bits of any instruction.
1597cf099d11SDimitry Andric if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
1598cf099d11SDimitry Andric // Found an instruction with island(s). Now just assign a filter.
159963faed5bSDimitry Andric runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true);
1600cf099d11SDimitry Andric return true;
1601cf099d11SDimitry Andric }
1602cf099d11SDimitry Andric }
1603cf099d11SDimitry Andric }
1604cf099d11SDimitry Andric
1605902a7b52SDimitry Andric unsigned BitIndex;
1606cf099d11SDimitry Andric
1607cf099d11SDimitry Andric // We maintain BIT_WIDTH copies of the bitAttrs automaton.
1608cf099d11SDimitry Andric // The automaton consumes the corresponding bit from each
1609cf099d11SDimitry Andric // instruction.
1610cf099d11SDimitry Andric //
1611cf099d11SDimitry Andric // Input symbols: 0, 1, and _ (unset).
1612cf099d11SDimitry Andric // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
1613cf099d11SDimitry Andric // Initial state: NONE.
1614cf099d11SDimitry Andric //
1615cf099d11SDimitry Andric // (NONE) ------- [01] -> (ALL_SET)
1616cf099d11SDimitry Andric // (NONE) ------- _ ----> (ALL_UNSET)
1617cf099d11SDimitry Andric // (ALL_SET) ---- [01] -> (ALL_SET)
1618cf099d11SDimitry Andric // (ALL_SET) ---- _ ----> (MIXED)
1619cf099d11SDimitry Andric // (ALL_UNSET) -- [01] -> (MIXED)
1620cf099d11SDimitry Andric // (ALL_UNSET) -- _ ----> (ALL_UNSET)
1621cf099d11SDimitry Andric // (MIXED) ------ . ----> (MIXED)
1622cf099d11SDimitry Andric // (FILTERED)---- . ----> (FILTERED)
1623cf099d11SDimitry Andric
162430815c53SDimitry Andric std::vector<bitAttr_t> bitAttrs;
1625cf099d11SDimitry Andric
1626cf099d11SDimitry Andric // FILTERED bit positions provide no entropy and are not worthy of pursuing.
1627cf099d11SDimitry Andric // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
162830815c53SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
1629cf099d11SDimitry Andric if (FilterBitValues[BitIndex] == BIT_TRUE ||
1630cf099d11SDimitry Andric FilterBitValues[BitIndex] == BIT_FALSE)
163130815c53SDimitry Andric bitAttrs.push_back(ATTR_FILTERED);
1632cf099d11SDimitry Andric else
163330815c53SDimitry Andric bitAttrs.push_back(ATTR_NONE);
1634cf099d11SDimitry Andric
1635ac9a064cSDimitry Andric for (const auto &OpcPair : Opcodes) {
1636cf099d11SDimitry Andric insn_t insn;
1637cf099d11SDimitry Andric
1638ac9a064cSDimitry Andric insnWithID(insn, OpcPair.EncodingID);
1639cf099d11SDimitry Andric
164030815c53SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1641cf099d11SDimitry Andric switch (bitAttrs[BitIndex]) {
1642cf099d11SDimitry Andric case ATTR_NONE:
1643cf099d11SDimitry Andric if (insn[BitIndex] == BIT_UNSET)
1644cf099d11SDimitry Andric bitAttrs[BitIndex] = ATTR_ALL_UNSET;
1645cf099d11SDimitry Andric else
1646cf099d11SDimitry Andric bitAttrs[BitIndex] = ATTR_ALL_SET;
1647cf099d11SDimitry Andric break;
1648cf099d11SDimitry Andric case ATTR_ALL_SET:
1649cf099d11SDimitry Andric if (insn[BitIndex] == BIT_UNSET)
1650cf099d11SDimitry Andric bitAttrs[BitIndex] = ATTR_MIXED;
1651cf099d11SDimitry Andric break;
1652cf099d11SDimitry Andric case ATTR_ALL_UNSET:
1653cf099d11SDimitry Andric if (insn[BitIndex] != BIT_UNSET)
1654cf099d11SDimitry Andric bitAttrs[BitIndex] = ATTR_MIXED;
1655cf099d11SDimitry Andric break;
1656cf099d11SDimitry Andric case ATTR_MIXED:
1657cf099d11SDimitry Andric case ATTR_FILTERED:
1658cf099d11SDimitry Andric break;
1659cf099d11SDimitry Andric }
1660cf099d11SDimitry Andric }
1661cf099d11SDimitry Andric }
1662cf099d11SDimitry Andric
1663cf099d11SDimitry Andric // The regionAttr automaton consumes the bitAttrs automatons' state,
1664cf099d11SDimitry Andric // lowest-to-highest.
1665cf099d11SDimitry Andric //
1666cf099d11SDimitry Andric // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed)
1667cf099d11SDimitry Andric // States: NONE, ALL_SET, MIXED
1668cf099d11SDimitry Andric // Initial state: NONE
1669cf099d11SDimitry Andric //
1670cf099d11SDimitry Andric // (NONE) ----- F --> (NONE)
1671cf099d11SDimitry Andric // (NONE) ----- S --> (ALL_SET) ; and set region start
1672cf099d11SDimitry Andric // (NONE) ----- U --> (NONE)
1673cf099d11SDimitry Andric // (NONE) ----- M --> (MIXED) ; and set region start
1674cf099d11SDimitry Andric // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region
1675cf099d11SDimitry Andric // (ALL_SET) -- S --> (ALL_SET)
1676cf099d11SDimitry Andric // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region
1677cf099d11SDimitry Andric // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region
1678cf099d11SDimitry Andric // (MIXED) ---- F --> (NONE) ; and report a MIXED region
1679cf099d11SDimitry Andric // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region
1680cf099d11SDimitry Andric // (MIXED) ---- U --> (NONE) ; and report a MIXED region
1681cf099d11SDimitry Andric // (MIXED) ---- M --> (MIXED)
1682cf099d11SDimitry Andric
1683cf099d11SDimitry Andric bitAttr_t RA = ATTR_NONE;
1684cf099d11SDimitry Andric unsigned StartBit = 0;
1685cf099d11SDimitry Andric
1686902a7b52SDimitry Andric for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1687cf099d11SDimitry Andric bitAttr_t bitAttr = bitAttrs[BitIndex];
1688cf099d11SDimitry Andric
1689cf099d11SDimitry Andric assert(bitAttr != ATTR_NONE && "Bit without attributes");
1690cf099d11SDimitry Andric
1691cf099d11SDimitry Andric switch (RA) {
1692cf099d11SDimitry Andric case ATTR_NONE:
1693cf099d11SDimitry Andric switch (bitAttr) {
1694cf099d11SDimitry Andric case ATTR_FILTERED:
1695cf099d11SDimitry Andric break;
1696cf099d11SDimitry Andric case ATTR_ALL_SET:
1697cf099d11SDimitry Andric StartBit = BitIndex;
1698cf099d11SDimitry Andric RA = ATTR_ALL_SET;
1699cf099d11SDimitry Andric break;
1700cf099d11SDimitry Andric case ATTR_ALL_UNSET:
1701cf099d11SDimitry Andric break;
1702cf099d11SDimitry Andric case ATTR_MIXED:
1703cf099d11SDimitry Andric StartBit = BitIndex;
1704cf099d11SDimitry Andric RA = ATTR_MIXED;
1705cf099d11SDimitry Andric break;
1706cf099d11SDimitry Andric default:
170763faed5bSDimitry Andric llvm_unreachable("Unexpected bitAttr!");
1708cf099d11SDimitry Andric }
1709cf099d11SDimitry Andric break;
1710cf099d11SDimitry Andric case ATTR_ALL_SET:
1711cf099d11SDimitry Andric switch (bitAttr) {
1712cf099d11SDimitry Andric case ATTR_FILTERED:
1713cf099d11SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
1714cf099d11SDimitry Andric RA = ATTR_NONE;
1715cf099d11SDimitry Andric break;
1716cf099d11SDimitry Andric case ATTR_ALL_SET:
1717cf099d11SDimitry Andric break;
1718cf099d11SDimitry Andric case ATTR_ALL_UNSET:
1719cf099d11SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
1720cf099d11SDimitry Andric RA = ATTR_NONE;
1721cf099d11SDimitry Andric break;
1722cf099d11SDimitry Andric case ATTR_MIXED:
1723cf099d11SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
1724cf099d11SDimitry Andric StartBit = BitIndex;
1725cf099d11SDimitry Andric RA = ATTR_MIXED;
1726cf099d11SDimitry Andric break;
1727cf099d11SDimitry Andric default:
172863faed5bSDimitry Andric llvm_unreachable("Unexpected bitAttr!");
1729cf099d11SDimitry Andric }
1730cf099d11SDimitry Andric break;
1731cf099d11SDimitry Andric case ATTR_MIXED:
1732cf099d11SDimitry Andric switch (bitAttr) {
1733cf099d11SDimitry Andric case ATTR_FILTERED:
1734cf099d11SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
1735cf099d11SDimitry Andric StartBit = BitIndex;
1736cf099d11SDimitry Andric RA = ATTR_NONE;
1737cf099d11SDimitry Andric break;
1738cf099d11SDimitry Andric case ATTR_ALL_SET:
1739cf099d11SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
1740cf099d11SDimitry Andric StartBit = BitIndex;
1741cf099d11SDimitry Andric RA = ATTR_ALL_SET;
1742cf099d11SDimitry Andric break;
1743cf099d11SDimitry Andric case ATTR_ALL_UNSET:
1744cf099d11SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
1745cf099d11SDimitry Andric RA = ATTR_NONE;
1746cf099d11SDimitry Andric break;
1747cf099d11SDimitry Andric case ATTR_MIXED:
1748cf099d11SDimitry Andric break;
1749cf099d11SDimitry Andric default:
175063faed5bSDimitry Andric llvm_unreachable("Unexpected bitAttr!");
1751cf099d11SDimitry Andric }
1752cf099d11SDimitry Andric break;
1753cf099d11SDimitry Andric case ATTR_ALL_UNSET:
175463faed5bSDimitry Andric llvm_unreachable("regionAttr state machine has no ATTR_UNSET state");
1755cf099d11SDimitry Andric case ATTR_FILTERED:
175663faed5bSDimitry Andric llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state");
1757cf099d11SDimitry Andric }
1758cf099d11SDimitry Andric }
1759cf099d11SDimitry Andric
1760cf099d11SDimitry Andric // At the end, if we're still in ALL_SET or MIXED states, report a region
1761cf099d11SDimitry Andric switch (RA) {
1762cf099d11SDimitry Andric case ATTR_NONE:
1763cf099d11SDimitry Andric break;
1764cf099d11SDimitry Andric case ATTR_FILTERED:
1765cf099d11SDimitry Andric break;
1766cf099d11SDimitry Andric case ATTR_ALL_SET:
1767cf099d11SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
1768cf099d11SDimitry Andric break;
1769cf099d11SDimitry Andric case ATTR_ALL_UNSET:
1770cf099d11SDimitry Andric break;
1771cf099d11SDimitry Andric case ATTR_MIXED:
1772cf099d11SDimitry Andric reportRegion(RA, StartBit, BitIndex, AllowMixed);
1773cf099d11SDimitry Andric break;
1774cf099d11SDimitry Andric }
1775cf099d11SDimitry Andric
1776cf099d11SDimitry Andric // We have finished with the filter processings. Now it's time to choose
1777cf099d11SDimitry Andric // the best performing filter.
1778cf099d11SDimitry Andric BestIndex = 0;
1779cf099d11SDimitry Andric bool AllUseless = true;
1780cf099d11SDimitry Andric unsigned BestScore = 0;
1781cf099d11SDimitry Andric
1782ac9a064cSDimitry Andric for (const auto &[Idx, Filter] : enumerate(Filters)) {
1783ac9a064cSDimitry Andric unsigned Usefulness = Filter.usefulness();
1784cf099d11SDimitry Andric
1785cf099d11SDimitry Andric if (Usefulness)
1786cf099d11SDimitry Andric AllUseless = false;
1787cf099d11SDimitry Andric
1788cf099d11SDimitry Andric if (Usefulness > BestScore) {
1789ac9a064cSDimitry Andric BestIndex = Idx;
1790cf099d11SDimitry Andric BestScore = Usefulness;
1791cf099d11SDimitry Andric }
1792cf099d11SDimitry Andric }
1793cf099d11SDimitry Andric
1794cf099d11SDimitry Andric if (!AllUseless)
1795cf099d11SDimitry Andric bestFilter().recurse();
1796cf099d11SDimitry Andric
1797cf099d11SDimitry Andric return !AllUseless;
1798cf099d11SDimitry Andric } // end of FilterChooser::filterProcessor(bool)
1799cf099d11SDimitry Andric
1800cf099d11SDimitry Andric // Decides on the best configuration of filter(s) to use in order to decode
1801cf099d11SDimitry Andric // the instructions. A conflict of instructions may occur, in which case we
1802cf099d11SDimitry Andric // dump the conflict set to the standard error.
doFilter()1803cf099d11SDimitry Andric void FilterChooser::doFilter() {
1804cf099d11SDimitry Andric unsigned Num = Opcodes.size();
1805cf099d11SDimitry Andric assert(Num && "FilterChooser created with no instructions");
1806cf099d11SDimitry Andric
1807cf099d11SDimitry Andric // Try regions of consecutive known bit values first.
1808cf099d11SDimitry Andric if (filterProcessor(false))
1809cf099d11SDimitry Andric return;
1810cf099d11SDimitry Andric
1811cf099d11SDimitry Andric // Then regions of mixed bits (both known and unitialized bit values allowed).
1812cf099d11SDimitry Andric if (filterProcessor(true))
1813cf099d11SDimitry Andric return;
1814cf099d11SDimitry Andric
1815cf099d11SDimitry Andric // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
1816cf099d11SDimitry Andric // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
1817cf099d11SDimitry Andric // well-known encoding pattern. In such case, we backtrack and scan for the
1818cf099d11SDimitry Andric // the very first consecutive ATTR_ALL_SET region and assign a filter to it.
1819cf099d11SDimitry Andric if (Num == 3 && filterProcessor(true, false))
1820cf099d11SDimitry Andric return;
1821cf099d11SDimitry Andric
1822cf099d11SDimitry Andric // If we come to here, the instruction decoding has failed.
1823cf099d11SDimitry Andric // Set the BestIndex to -1 to indicate so.
1824cf099d11SDimitry Andric BestIndex = -1;
1825cf099d11SDimitry Andric }
1826cf099d11SDimitry Andric
1827902a7b52SDimitry Andric // emitTableEntries - Emit state machine entries to decode our share of
1828902a7b52SDimitry Andric // instructions.
emitTableEntries(DecoderTableInfo & TableInfo) const1829902a7b52SDimitry Andric void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
1830902a7b52SDimitry Andric if (Opcodes.size() == 1) {
1831cf099d11SDimitry Andric // There is only one instruction in the set, which is great!
1832cf099d11SDimitry Andric // Call emitSingletonDecoder() to see whether there are any remaining
1833cf099d11SDimitry Andric // encodings bits.
1834902a7b52SDimitry Andric emitSingletonTableEntry(TableInfo, Opcodes[0]);
1835902a7b52SDimitry Andric return;
1836902a7b52SDimitry Andric }
1837cf099d11SDimitry Andric
1838cf099d11SDimitry Andric // Choose the best filter to do the decodings!
1839cf099d11SDimitry Andric if (BestIndex != -1) {
184063faed5bSDimitry Andric const Filter &Best = Filters[BestIndex];
1841cf099d11SDimitry Andric if (Best.getNumFiltered() == 1)
1842902a7b52SDimitry Andric emitSingletonTableEntry(TableInfo, Best);
1843cf099d11SDimitry Andric else
1844902a7b52SDimitry Andric Best.emitTableEntry(TableInfo);
1845902a7b52SDimitry Andric return;
1846cf099d11SDimitry Andric }
1847cf099d11SDimitry Andric
1848902a7b52SDimitry Andric // We don't know how to decode these instructions! Dump the
1849902a7b52SDimitry Andric // conflict set and bail.
1850cf099d11SDimitry Andric
1851cf099d11SDimitry Andric // Print out useful conflict information for postmortem analysis.
1852cf099d11SDimitry Andric errs() << "Decoding Conflict:\n";
1853cf099d11SDimitry Andric
1854cf099d11SDimitry Andric dumpStack(errs(), "\t\t");
1855cf099d11SDimitry Andric
1856344a3780SDimitry Andric for (auto Opcode : Opcodes) {
1857e6d15924SDimitry Andric errs() << '\t';
1858344a3780SDimitry Andric emitNameWithID(errs(), Opcode.EncodingID);
1859e6d15924SDimitry Andric errs() << " ";
1860e6d15924SDimitry Andric dumpBits(
1861e6d15924SDimitry Andric errs(),
1862344a3780SDimitry Andric getBitsField(*AllInstructions[Opcode.EncodingID].EncodingDef, "Inst"));
1863cf099d11SDimitry Andric errs() << '\n';
1864cf099d11SDimitry Andric }
1865cf099d11SDimitry Andric }
1866cf099d11SDimitry Andric
findOperandDecoderMethod(Record * Record)1867145449b1SDimitry Andric static std::string findOperandDecoderMethod(Record *Record) {
1868b915e9e0SDimitry Andric std::string Decoder;
1869b915e9e0SDimitry Andric
1870eb11fae6SDimitry Andric RecordVal *DecoderString = Record->getValue("DecoderMethod");
1871ac9a064cSDimitry Andric StringInit *String =
1872ac9a064cSDimitry Andric DecoderString ? dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
1873b915e9e0SDimitry Andric if (String) {
1874cfca06d7SDimitry Andric Decoder = std::string(String->getValue());
1875b915e9e0SDimitry Andric if (!Decoder.empty())
1876b915e9e0SDimitry Andric return Decoder;
1877b915e9e0SDimitry Andric }
1878b915e9e0SDimitry Andric
1879eb11fae6SDimitry Andric if (Record->isSubClassOf("RegisterOperand"))
1880ac9a064cSDimitry Andric // Allows use of a DecoderMethod in referenced RegisterClass if set.
1881ac9a064cSDimitry Andric return findOperandDecoderMethod(Record->getValueAsDef("RegClass"));
1882b915e9e0SDimitry Andric
1883eb11fae6SDimitry Andric if (Record->isSubClassOf("RegisterClass")) {
1884eb11fae6SDimitry Andric Decoder = "Decode" + Record->getName().str() + "RegisterClass";
1885eb11fae6SDimitry Andric } else if (Record->isSubClassOf("PointerLikeRegClass")) {
1886b915e9e0SDimitry Andric Decoder = "DecodePointerLikeRegClass" +
1887eb11fae6SDimitry Andric utostr(Record->getValueAsInt("RegClassKind"));
1888b915e9e0SDimitry Andric }
1889b915e9e0SDimitry Andric
1890b915e9e0SDimitry Andric return Decoder;
1891b915e9e0SDimitry Andric }
1892b915e9e0SDimitry Andric
getOpInfo(Record * TypeRecord)1893145449b1SDimitry Andric OperandInfo getOpInfo(Record *TypeRecord) {
1894145449b1SDimitry Andric std::string Decoder = findOperandDecoderMethod(TypeRecord);
1895145449b1SDimitry Andric
1896145449b1SDimitry Andric RecordVal *HasCompleteDecoderVal = TypeRecord->getValue("hasCompleteDecoder");
1897145449b1SDimitry Andric BitInit *HasCompleteDecoderBit =
1898145449b1SDimitry Andric HasCompleteDecoderVal
1899145449b1SDimitry Andric ? dyn_cast<BitInit>(HasCompleteDecoderVal->getValue())
1900145449b1SDimitry Andric : nullptr;
1901145449b1SDimitry Andric bool HasCompleteDecoder =
1902145449b1SDimitry Andric HasCompleteDecoderBit ? HasCompleteDecoderBit->getValue() : true;
1903145449b1SDimitry Andric
1904145449b1SDimitry Andric return OperandInfo(Decoder, HasCompleteDecoder);
1905145449b1SDimitry Andric }
1906145449b1SDimitry Andric
parseVarLenInstOperand(const Record & Def,std::vector<OperandInfo> & Operands,const CodeGenInstruction & CGI)1907145449b1SDimitry Andric void parseVarLenInstOperand(const Record &Def,
1908145449b1SDimitry Andric std::vector<OperandInfo> &Operands,
1909145449b1SDimitry Andric const CodeGenInstruction &CGI) {
1910145449b1SDimitry Andric
1911145449b1SDimitry Andric const RecordVal *RV = Def.getValue("Inst");
1912145449b1SDimitry Andric VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
1913145449b1SDimitry Andric SmallVector<int> TiedTo;
1914145449b1SDimitry Andric
1915ac9a064cSDimitry Andric for (const auto &[Idx, Op] : enumerate(CGI.Operands)) {
1916145449b1SDimitry Andric if (Op.MIOperandInfo && Op.MIOperandInfo->getNumArgs() > 0)
1917145449b1SDimitry Andric for (auto *Arg : Op.MIOperandInfo->getArgs())
1918145449b1SDimitry Andric Operands.push_back(getOpInfo(cast<DefInit>(Arg)->getDef()));
1919145449b1SDimitry Andric else
1920145449b1SDimitry Andric Operands.push_back(getOpInfo(Op.Rec));
1921145449b1SDimitry Andric
1922145449b1SDimitry Andric int TiedReg = Op.getTiedRegister();
1923145449b1SDimitry Andric TiedTo.push_back(-1);
1924145449b1SDimitry Andric if (TiedReg != -1) {
1925145449b1SDimitry Andric TiedTo[Idx] = TiedReg;
1926145449b1SDimitry Andric TiedTo[TiedReg] = Idx;
1927145449b1SDimitry Andric }
1928145449b1SDimitry Andric }
1929145449b1SDimitry Andric
1930145449b1SDimitry Andric unsigned CurrBitPos = 0;
1931ac9a064cSDimitry Andric for (const auto &EncodingSegment : VLI) {
1932145449b1SDimitry Andric unsigned Offset = 0;
1933145449b1SDimitry Andric StringRef OpName;
1934145449b1SDimitry Andric
1935145449b1SDimitry Andric if (const StringInit *SI = dyn_cast<StringInit>(EncodingSegment.Value)) {
1936145449b1SDimitry Andric OpName = SI->getValue();
1937145449b1SDimitry Andric } else if (const DagInit *DI = dyn_cast<DagInit>(EncodingSegment.Value)) {
1938145449b1SDimitry Andric OpName = cast<StringInit>(DI->getArg(0))->getValue();
1939145449b1SDimitry Andric Offset = cast<IntInit>(DI->getArg(2))->getValue();
1940145449b1SDimitry Andric }
1941145449b1SDimitry Andric
1942145449b1SDimitry Andric if (!OpName.empty()) {
1943145449b1SDimitry Andric auto OpSubOpPair =
1944145449b1SDimitry Andric const_cast<CodeGenInstruction &>(CGI).Operands.ParseOperandName(
1945145449b1SDimitry Andric OpName);
1946145449b1SDimitry Andric unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(OpSubOpPair);
1947145449b1SDimitry Andric Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
1948e3b55780SDimitry Andric if (!EncodingSegment.CustomDecoder.empty())
1949e3b55780SDimitry Andric Operands[OpIdx].Decoder = EncodingSegment.CustomDecoder.str();
1950145449b1SDimitry Andric
1951145449b1SDimitry Andric int TiedReg = TiedTo[OpSubOpPair.first];
1952145449b1SDimitry Andric if (TiedReg != -1) {
1953145449b1SDimitry Andric unsigned OpIdx = CGI.Operands.getFlattenedOperandNumber(
1954ac9a064cSDimitry Andric std::pair(TiedReg, OpSubOpPair.second));
1955145449b1SDimitry Andric Operands[OpIdx].addField(CurrBitPos, EncodingSegment.BitWidth, Offset);
1956145449b1SDimitry Andric }
1957145449b1SDimitry Andric }
1958145449b1SDimitry Andric
1959145449b1SDimitry Andric CurrBitPos += EncodingSegment.BitWidth;
1960145449b1SDimitry Andric }
1961145449b1SDimitry Andric }
1962145449b1SDimitry Andric
debugDumpRecord(const Record & Rec)1963e3b55780SDimitry Andric static void debugDumpRecord(const Record &Rec) {
1964e3b55780SDimitry Andric // Dump the record, so we can see what's going on...
1965e3b55780SDimitry Andric std::string E;
1966e3b55780SDimitry Andric raw_string_ostream S(E);
1967e3b55780SDimitry Andric S << "Dumping record for previous error:\n";
1968e3b55780SDimitry Andric S << Rec;
1969e3b55780SDimitry Andric PrintNote(E);
1970e3b55780SDimitry Andric }
1971e3b55780SDimitry Andric
1972e3b55780SDimitry Andric /// For an operand field named OpName: populate OpInfo.InitValue with the
1973e3b55780SDimitry Andric /// constant-valued bit values, and OpInfo.Fields with the ranges of bits to
1974e3b55780SDimitry Andric /// insert from the decoded instruction.
addOneOperandFields(const Record & EncodingDef,const BitsInit & Bits,std::map<std::string,std::string> & TiedNames,StringRef OpName,OperandInfo & OpInfo)1975e3b55780SDimitry Andric static void addOneOperandFields(const Record &EncodingDef, const BitsInit &Bits,
1976e3b55780SDimitry Andric std::map<std::string, std::string> &TiedNames,
1977e3b55780SDimitry Andric StringRef OpName, OperandInfo &OpInfo) {
1978e3b55780SDimitry Andric // Some bits of the operand may be required to be 1 depending on the
1979e3b55780SDimitry Andric // instruction's encoding. Collect those bits.
1980e3b55780SDimitry Andric if (const RecordVal *EncodedValue = EncodingDef.getValue(OpName))
1981e3b55780SDimitry Andric if (const BitsInit *OpBits = dyn_cast<BitsInit>(EncodedValue->getValue()))
1982e3b55780SDimitry Andric for (unsigned I = 0; I < OpBits->getNumBits(); ++I)
1983e3b55780SDimitry Andric if (const BitInit *OpBit = dyn_cast<BitInit>(OpBits->getBit(I)))
1984e3b55780SDimitry Andric if (OpBit->getValue())
1985e3b55780SDimitry Andric OpInfo.InitValue |= 1ULL << I;
1986e3b55780SDimitry Andric
1987e3b55780SDimitry Andric for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
1988e3b55780SDimitry Andric VarInit *Var;
1989e3b55780SDimitry Andric unsigned Offset = 0;
1990e3b55780SDimitry Andric for (; J != Bits.getNumBits(); ++J) {
1991e3b55780SDimitry Andric VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
1992e3b55780SDimitry Andric if (BJ) {
1993e3b55780SDimitry Andric Var = dyn_cast<VarInit>(BJ->getBitVar());
1994e3b55780SDimitry Andric if (I == J)
1995e3b55780SDimitry Andric Offset = BJ->getBitNum();
1996e3b55780SDimitry Andric else if (BJ->getBitNum() != Offset + J - I)
1997e3b55780SDimitry Andric break;
1998e3b55780SDimitry Andric } else {
1999e3b55780SDimitry Andric Var = dyn_cast<VarInit>(Bits.getBit(J));
2000e3b55780SDimitry Andric }
2001e3b55780SDimitry Andric if (!Var || (Var->getName() != OpName &&
2002e3b55780SDimitry Andric Var->getName() != TiedNames[std::string(OpName)]))
2003e3b55780SDimitry Andric break;
2004e3b55780SDimitry Andric }
2005e3b55780SDimitry Andric if (I == J)
2006e3b55780SDimitry Andric ++J;
2007e3b55780SDimitry Andric else
2008e3b55780SDimitry Andric OpInfo.addField(I, J - I, Offset);
2009e3b55780SDimitry Andric }
2010e3b55780SDimitry Andric }
2011e3b55780SDimitry Andric
2012145449b1SDimitry Andric static unsigned
populateInstruction(CodeGenTarget & Target,const Record & EncodingDef,const CodeGenInstruction & CGI,unsigned Opc,std::map<unsigned,std::vector<OperandInfo>> & Operands,bool IsVarLenInst)2013e6d15924SDimitry Andric populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,
20145ca98fd9SDimitry Andric const CodeGenInstruction &CGI, unsigned Opc,
2015145449b1SDimitry Andric std::map<unsigned, std::vector<OperandInfo>> &Operands,
2016145449b1SDimitry Andric bool IsVarLenInst) {
2017cf099d11SDimitry Andric const Record &Def = *CGI.TheDef;
2018cf099d11SDimitry Andric // If all the bit positions are not specified; do not decode this instruction.
2019cf099d11SDimitry Andric // We are bound to fail! For proper disassembly, the well-known encoding bits
2020cf099d11SDimitry Andric // of the instruction must be fully specified.
2021cf099d11SDimitry Andric
2022e6d15924SDimitry Andric BitsInit &Bits = getBitsField(EncodingDef, "Inst");
2023145449b1SDimitry Andric if (Bits.allInComplete())
2024145449b1SDimitry Andric return 0;
2025411bd29eSDimitry Andric
2026cf099d11SDimitry Andric std::vector<OperandInfo> InsnOperands;
2027cf099d11SDimitry Andric
2028cf099d11SDimitry Andric // If the instruction has specified a custom decoding hook, use that instead
2029cf099d11SDimitry Andric // of trying to auto-generate the decoder.
2030e6d15924SDimitry Andric StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");
2031cf099d11SDimitry Andric if (InstDecoder != "") {
2032ac9a064cSDimitry Andric bool HasCompleteInstDecoder =
2033ac9a064cSDimitry Andric EncodingDef.getValueAsBit("hasCompleteDecoder");
2034cfca06d7SDimitry Andric InsnOperands.push_back(
2035cfca06d7SDimitry Andric OperandInfo(std::string(InstDecoder), HasCompleteInstDecoder));
2036cf099d11SDimitry Andric Operands[Opc] = InsnOperands;
2037145449b1SDimitry Andric return Bits.getNumBits();
2038cf099d11SDimitry Andric }
2039cf099d11SDimitry Andric
2040cf099d11SDimitry Andric // Generate a description of the operand of the instruction that we know
2041cf099d11SDimitry Andric // how to decode automatically.
2042cf099d11SDimitry Andric // FIXME: We'll need to have a way to manually override this as needed.
2043cf099d11SDimitry Andric
2044cf099d11SDimitry Andric // Gather the outputs/inputs of the instruction, so we can find their
2045cf099d11SDimitry Andric // positions in the encoding. This assumes for now that they appear in the
2046cf099d11SDimitry Andric // MCInst in the order that they're listed.
2047b915e9e0SDimitry Andric std::vector<std::pair<Init *, StringRef>> InOutOperands;
2048cf099d11SDimitry Andric DagInit *Out = Def.getValueAsDag("OutOperandList");
2049cf099d11SDimitry Andric DagInit *In = Def.getValueAsDag("InOperandList");
2050ac9a064cSDimitry Andric for (const auto &[Idx, Arg] : enumerate(Out->getArgs()))
2051ac9a064cSDimitry Andric InOutOperands.push_back(std::pair(Arg, Out->getArgNameStr(Idx)));
2052ac9a064cSDimitry Andric for (const auto &[Idx, Arg] : enumerate(In->getArgs()))
2053ac9a064cSDimitry Andric InOutOperands.push_back(std::pair(Arg, In->getArgNameStr(Idx)));
2054cf099d11SDimitry Andric
205530815c53SDimitry Andric // Search for tied operands, so that we can correctly instantiate
205630815c53SDimitry Andric // operands that are not explicitly represented in the encoding.
205730815c53SDimitry Andric std::map<std::string, std::string> TiedNames;
2058ac9a064cSDimitry Andric for (const auto &[I, Op] : enumerate(CGI.Operands)) {
2059ac9a064cSDimitry Andric for (const auto &[J, CI] : enumerate(Op.Constraints)) {
2060e3b55780SDimitry Andric if (CI.isTied()) {
20615ca98fd9SDimitry Andric std::pair<unsigned, unsigned> SO =
2062ac9a064cSDimitry Andric CGI.Operands.getSubOperandNumber(CI.getTiedOperand());
2063e3b55780SDimitry Andric std::string TiedName = CGI.Operands[SO.first].SubOpNames[SO.second];
2064e3b55780SDimitry Andric if (TiedName.empty())
2065e3b55780SDimitry Andric TiedName = CGI.Operands[SO.first].Name;
2066ac9a064cSDimitry Andric std::string MyName = Op.SubOpNames[J];
2067e3b55780SDimitry Andric if (MyName.empty())
2068e3b55780SDimitry Andric MyName = Op.Name;
2069e3b55780SDimitry Andric
2070e3b55780SDimitry Andric TiedNames[MyName] = TiedName;
2071e3b55780SDimitry Andric TiedNames[TiedName] = MyName;
2072e3b55780SDimitry Andric }
20735ca98fd9SDimitry Andric }
20745ca98fd9SDimitry Andric }
20755ca98fd9SDimitry Andric
2076145449b1SDimitry Andric if (IsVarLenInst) {
2077145449b1SDimitry Andric parseVarLenInstOperand(EncodingDef, InsnOperands, CGI);
2078145449b1SDimitry Andric } else {
2079cf099d11SDimitry Andric // For each operand, see if we can figure out where it is encoded.
208067c32a98SDimitry Andric for (const auto &Op : InOutOperands) {
2081e3b55780SDimitry Andric Init *OpInit = Op.first;
2082e3b55780SDimitry Andric StringRef OpName = Op.second;
2083e3b55780SDimitry Andric
2084ac9a064cSDimitry Andric // We're ready to find the instruction encoding locations for this
2085ac9a064cSDimitry Andric // operand.
208630815c53SDimitry Andric
2087e3b55780SDimitry Andric // First, find the operand type ("OpInit"), and sub-op names
2088e3b55780SDimitry Andric // ("SubArgDag") if present.
2089e3b55780SDimitry Andric DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
2090e3b55780SDimitry Andric if (SubArgDag)
2091e3b55780SDimitry Andric OpInit = SubArgDag->getOperator();
2092e3b55780SDimitry Andric Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
2093e3b55780SDimitry Andric // Lookup the sub-operands from the operand type record (note that only
2094e3b55780SDimitry Andric // Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
2095e3b55780SDimitry Andric DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
2096e3b55780SDimitry Andric ? OpTypeRec->getValueAsDag("MIOperandInfo")
2097e3b55780SDimitry Andric : nullptr;
20981d5ae102SDimitry Andric
2099ac9a064cSDimitry Andric // Lookup the decoder method and construct a new OperandInfo to hold our
2100ac9a064cSDimitry Andric // result.
2101e3b55780SDimitry Andric OperandInfo OpInfo = getOpInfo(OpTypeRec);
21021d5ae102SDimitry Andric
2103e3b55780SDimitry Andric // If we have named sub-operands...
2104e3b55780SDimitry Andric if (SubArgDag) {
2105e3b55780SDimitry Andric // Then there should not be a custom decoder specified on the top-level
2106e3b55780SDimitry Andric // type.
2107e3b55780SDimitry Andric if (!OpInfo.Decoder.empty()) {
2108e3b55780SDimitry Andric PrintError(EncodingDef.getLoc(),
2109e3b55780SDimitry Andric "DecoderEmitter: operand \"" + OpName + "\" has type \"" +
2110e3b55780SDimitry Andric OpInit->getAsString() +
2111e3b55780SDimitry Andric "\" with a custom DecoderMethod, but also named "
2112e3b55780SDimitry Andric "sub-operands.");
2113e3b55780SDimitry Andric continue;
2114e3b55780SDimitry Andric }
211530815c53SDimitry Andric
2116e3b55780SDimitry Andric // Decode each of the sub-ops separately.
2117e3b55780SDimitry Andric assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
2118ac9a064cSDimitry Andric for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) {
2119ac9a064cSDimitry Andric StringRef SubOpName = SubArgDag->getArgNameStr(I);
2120ac9a064cSDimitry Andric OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef());
212130815c53SDimitry Andric
2122e3b55780SDimitry Andric addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName,
2123e3b55780SDimitry Andric SubOpInfo);
2124e3b55780SDimitry Andric InsnOperands.push_back(SubOpInfo);
212530815c53SDimitry Andric }
212630815c53SDimitry Andric continue;
2127cf099d11SDimitry Andric }
2128cf099d11SDimitry Andric
2129e3b55780SDimitry Andric // Otherwise, if we have an operand with sub-operands, but they aren't
2130e3b55780SDimitry Andric // named...
2131e3b55780SDimitry Andric if (SubOps && OpInfo.Decoder.empty()) {
2132e3b55780SDimitry Andric // If it's a single sub-operand, and no custom decoder, use the decoder
2133e3b55780SDimitry Andric // from the one sub-operand.
2134e3b55780SDimitry Andric if (SubOps->getNumArgs() == 1)
2135e3b55780SDimitry Andric OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
2136e3b55780SDimitry Andric
2137e3b55780SDimitry Andric // If we have multiple sub-ops, there'd better have a custom
2138e3b55780SDimitry Andric // decoder. (Otherwise we don't know how to populate them properly...)
2139e3b55780SDimitry Andric if (SubOps->getNumArgs() > 1) {
2140e3b55780SDimitry Andric PrintError(EncodingDef.getLoc(),
2141e3b55780SDimitry Andric "DecoderEmitter: operand \"" + OpName +
2142e3b55780SDimitry Andric "\" uses MIOperandInfo with multiple ops, but doesn't "
2143e3b55780SDimitry Andric "have a custom decoder!");
2144e3b55780SDimitry Andric debugDumpRecord(EncodingDef);
214530815c53SDimitry Andric continue;
214630815c53SDimitry Andric }
214730815c53SDimitry Andric }
214830815c53SDimitry Andric
2149e3b55780SDimitry Andric addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
2150e3b55780SDimitry Andric // FIXME: it should be an error not to find a definition for a given
2151e3b55780SDimitry Andric // operand, rather than just failing to add it to the resulting
2152e3b55780SDimitry Andric // instruction! (This is a longstanding bug, which will be addressed in an
2153e3b55780SDimitry Andric // upcoming change.)
215430815c53SDimitry Andric if (OpInfo.numFields() > 0)
215530815c53SDimitry Andric InsnOperands.push_back(OpInfo);
2156cf099d11SDimitry Andric }
2157145449b1SDimitry Andric }
2158cf099d11SDimitry Andric Operands[Opc] = InsnOperands;
2159cf099d11SDimitry Andric
2160cf099d11SDimitry Andric #if 0
2161eb11fae6SDimitry Andric LLVM_DEBUG({
2162cf099d11SDimitry Andric // Dumps the instruction encoding bits.
2163cf099d11SDimitry Andric dumpBits(errs(), Bits);
2164cf099d11SDimitry Andric
2165cf099d11SDimitry Andric errs() << '\n';
2166cf099d11SDimitry Andric
2167cf099d11SDimitry Andric // Dumps the list of operand info.
2168cf099d11SDimitry Andric for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
2169cf099d11SDimitry Andric const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
2170cf099d11SDimitry Andric const std::string &OperandName = Info.Name;
2171cf099d11SDimitry Andric const Record &OperandDef = *Info.Rec;
2172cf099d11SDimitry Andric
2173cf099d11SDimitry Andric errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
2174cf099d11SDimitry Andric }
2175cf099d11SDimitry Andric });
2176cf099d11SDimitry Andric #endif
2177cf099d11SDimitry Andric
2178145449b1SDimitry Andric return Bits.getNumBits();
2179cf099d11SDimitry Andric }
2180cf099d11SDimitry Andric
2181902a7b52SDimitry Andric // emitFieldFromInstruction - Emit the templated helper function
2182902a7b52SDimitry Andric // fieldFromInstruction().
2183eb11fae6SDimitry Andric // On Windows we make sure that this function is not inlined when
2184eb11fae6SDimitry Andric // using the VS compiler. It has a bug which causes the function
2185e3b55780SDimitry Andric // to be optimized out in some circumstances. See llvm.org/pr38292
emitFieldFromInstruction(formatted_raw_ostream & OS)2186902a7b52SDimitry Andric static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
2187ac9a064cSDimitry Andric OS << R"(
2188ac9a064cSDimitry Andric // Helper functions for extracting fields from encoded instructions.
2189ac9a064cSDimitry Andric // InsnType must either be integral or an APInt-like object that must:
2190ac9a064cSDimitry Andric // * be default-constructible and copy-constructible
2191ac9a064cSDimitry Andric // * be constructible from an APInt (this can be private)
2192ac9a064cSDimitry Andric // * Support insertBits(bits, startBit, numBits)
2193ac9a064cSDimitry Andric // * Support extractBitsAsZExtValue(numBits, startBit)
2194ac9a064cSDimitry Andric // * Support the ~, &, ==, and != operators with other objects of the same type
2195ac9a064cSDimitry Andric // * Support the != and bitwise & with uint64_t
2196ac9a064cSDimitry Andric // * Support put (<<) to raw_ostream&
2197ac9a064cSDimitry Andric template <typename InsnType>
2198ac9a064cSDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
2199ac9a064cSDimitry Andric __declspec(noinline)
2200ac9a064cSDimitry Andric #endif
2201ac9a064cSDimitry Andric static std::enable_if_t<std::is_integral<InsnType>::value, InsnType>
2202ac9a064cSDimitry Andric fieldFromInstruction(const InsnType &insn, unsigned startBit,
2203ac9a064cSDimitry Andric unsigned numBits) {
2204ac9a064cSDimitry Andric assert(startBit + numBits <= 64 && "Cannot support >64-bit extractions!");
2205ac9a064cSDimitry Andric assert(startBit + numBits <= (sizeof(InsnType) * 8) &&
2206ac9a064cSDimitry Andric "Instruction field out of bounds!");
2207ac9a064cSDimitry Andric InsnType fieldMask;
2208ac9a064cSDimitry Andric if (numBits == sizeof(InsnType) * 8)
2209ac9a064cSDimitry Andric fieldMask = (InsnType)(-1LL);
2210ac9a064cSDimitry Andric else
2211ac9a064cSDimitry Andric fieldMask = (((InsnType)1 << numBits) - 1) << startBit;
2212ac9a064cSDimitry Andric return (insn & fieldMask) >> startBit;
2213ac9a064cSDimitry Andric }
2214ac9a064cSDimitry Andric
2215ac9a064cSDimitry Andric template <typename InsnType>
2216ac9a064cSDimitry Andric static std::enable_if_t<!std::is_integral<InsnType>::value, uint64_t>
2217ac9a064cSDimitry Andric fieldFromInstruction(const InsnType &insn, unsigned startBit,
2218ac9a064cSDimitry Andric unsigned numBits) {
2219ac9a064cSDimitry Andric return insn.extractBitsAsZExtValue(numBits, startBit);
2220ac9a064cSDimitry Andric }
2221ac9a064cSDimitry Andric )";
2222344a3780SDimitry Andric }
2223344a3780SDimitry Andric
2224344a3780SDimitry Andric // emitInsertBits - Emit the templated helper function insertBits().
emitInsertBits(formatted_raw_ostream & OS)2225344a3780SDimitry Andric static void emitInsertBits(formatted_raw_ostream &OS) {
2226ac9a064cSDimitry Andric OS << R"(
2227ac9a064cSDimitry Andric // Helper function for inserting bits extracted from an encoded instruction into
2228ac9a064cSDimitry Andric // a field.
2229ac9a064cSDimitry Andric template <typename InsnType>
2230ac9a064cSDimitry Andric static std::enable_if_t<std::is_integral<InsnType>::value>
2231ac9a064cSDimitry Andric insertBits(InsnType &field, InsnType bits, unsigned startBit, unsigned numBits) {
2232ac9a064cSDimitry Andric assert(startBit + numBits <= sizeof field * 8);
2233ac9a064cSDimitry Andric field |= (InsnType)bits << startBit;
2234ac9a064cSDimitry Andric }
2235ac9a064cSDimitry Andric
2236ac9a064cSDimitry Andric template <typename InsnType>
2237ac9a064cSDimitry Andric static std::enable_if_t<!std::is_integral<InsnType>::value>
2238ac9a064cSDimitry Andric insertBits(InsnType &field, uint64_t bits, unsigned startBit, unsigned numBits) {
2239ac9a064cSDimitry Andric field.insertBits(bits, startBit, numBits);
2240ac9a064cSDimitry Andric }
2241ac9a064cSDimitry Andric )";
2242902a7b52SDimitry Andric }
2243cf099d11SDimitry Andric
2244902a7b52SDimitry Andric // emitDecodeInstruction - Emit the templated helper function
2245902a7b52SDimitry Andric // decodeInstruction().
emitDecodeInstruction(formatted_raw_ostream & OS,bool IsVarLenInst)2246145449b1SDimitry Andric static void emitDecodeInstruction(formatted_raw_ostream &OS,
2247145449b1SDimitry Andric bool IsVarLenInst) {
2248ac9a064cSDimitry Andric OS << R"(
2249ac9a064cSDimitry Andric template <typename InsnType>
2250ac9a064cSDimitry Andric static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
2251ac9a064cSDimitry Andric InsnType insn, uint64_t Address,
2252ac9a064cSDimitry Andric const MCDisassembler *DisAsm,
2253ac9a064cSDimitry Andric const MCSubtargetInfo &STI)";
2254145449b1SDimitry Andric if (IsVarLenInst) {
2255145449b1SDimitry Andric OS << ",\n "
2256ac9a064cSDimitry Andric "llvm::function_ref<void(APInt &, uint64_t)> makeUp";
2257145449b1SDimitry Andric }
2258ac9a064cSDimitry Andric OS << R"() {
2259ac9a064cSDimitry Andric const FeatureBitset &Bits = STI.getFeatureBits();
2260ac9a064cSDimitry Andric
2261ac9a064cSDimitry Andric const uint8_t *Ptr = DecodeTable;
2262ac9a064cSDimitry Andric uint64_t CurFieldValue = 0;
2263ac9a064cSDimitry Andric DecodeStatus S = MCDisassembler::Success;
2264ac9a064cSDimitry Andric while (true) {
2265ac9a064cSDimitry Andric ptrdiff_t Loc = Ptr - DecodeTable;
2266ac9a064cSDimitry Andric switch (*Ptr) {
2267ac9a064cSDimitry Andric default:
2268ac9a064cSDimitry Andric errs() << Loc << ": Unexpected decode table opcode!\n";
2269ac9a064cSDimitry Andric return MCDisassembler::Fail;
2270ac9a064cSDimitry Andric case MCD::OPC_ExtractField: {
2271ac9a064cSDimitry Andric // Decode the start value.
2272ac9a064cSDimitry Andric unsigned Start = decodeULEB128AndIncUnsafe(++Ptr);
2273ac9a064cSDimitry Andric unsigned Len = *Ptr++;)";
2274145449b1SDimitry Andric if (IsVarLenInst)
2275ac9a064cSDimitry Andric OS << "\n makeUp(insn, Start + Len);";
2276ac9a064cSDimitry Andric OS << R"(
2277ac9a064cSDimitry Andric CurFieldValue = fieldFromInstruction(insn, Start, Len);
2278ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_ExtractField(" << Start << ", "
2279ac9a064cSDimitry Andric << Len << "): " << CurFieldValue << "\n");
2280ac9a064cSDimitry Andric break;
2281ac9a064cSDimitry Andric }
2282ac9a064cSDimitry Andric case MCD::OPC_FilterValue: {
2283ac9a064cSDimitry Andric // Decode the field value.
2284ac9a064cSDimitry Andric uint64_t Val = decodeULEB128AndIncUnsafe(++Ptr);
2285ac9a064cSDimitry Andric // NumToSkip is a plain 24-bit integer.
2286ac9a064cSDimitry Andric unsigned NumToSkip = *Ptr++;
2287ac9a064cSDimitry Andric NumToSkip |= (*Ptr++) << 8;
2288ac9a064cSDimitry Andric NumToSkip |= (*Ptr++) << 16;
2289ac9a064cSDimitry Andric
2290ac9a064cSDimitry Andric // Perform the filter operation.
2291ac9a064cSDimitry Andric if (Val != CurFieldValue)
2292ac9a064cSDimitry Andric Ptr += NumToSkip;
2293ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_FilterValue(" << Val << ", " << NumToSkip
2294ac9a064cSDimitry Andric << "): " << ((Val != CurFieldValue) ? "FAIL:" : "PASS:")
2295ac9a064cSDimitry Andric << " continuing at " << (Ptr - DecodeTable) << "\n");
2296ac9a064cSDimitry Andric
2297ac9a064cSDimitry Andric break;
2298ac9a064cSDimitry Andric }
2299ac9a064cSDimitry Andric case MCD::OPC_CheckField: {
2300ac9a064cSDimitry Andric // Decode the start value.
2301ac9a064cSDimitry Andric unsigned Start = decodeULEB128AndIncUnsafe(++Ptr);
2302ac9a064cSDimitry Andric unsigned Len = *Ptr;)";
2303145449b1SDimitry Andric if (IsVarLenInst)
2304ac9a064cSDimitry Andric OS << "\n makeUp(insn, Start + Len);";
2305ac9a064cSDimitry Andric OS << R"(
2306ac9a064cSDimitry Andric uint64_t FieldValue = fieldFromInstruction(insn, Start, Len);
2307ac9a064cSDimitry Andric // Decode the field value.
2308ac9a064cSDimitry Andric unsigned PtrLen = 0;
2309ac9a064cSDimitry Andric uint64_t ExpectedValue = decodeULEB128(++Ptr, &PtrLen);
2310ac9a064cSDimitry Andric Ptr += PtrLen;
2311ac9a064cSDimitry Andric // NumToSkip is a plain 24-bit integer.
2312ac9a064cSDimitry Andric unsigned NumToSkip = *Ptr++;
2313ac9a064cSDimitry Andric NumToSkip |= (*Ptr++) << 8;
2314ac9a064cSDimitry Andric NumToSkip |= (*Ptr++) << 16;
2315ac9a064cSDimitry Andric
2316ac9a064cSDimitry Andric // If the actual and expected values don't match, skip.
2317ac9a064cSDimitry Andric if (ExpectedValue != FieldValue)
2318ac9a064cSDimitry Andric Ptr += NumToSkip;
2319ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckField(" << Start << ", "
2320ac9a064cSDimitry Andric << Len << ", " << ExpectedValue << ", " << NumToSkip
2321ac9a064cSDimitry Andric << "): FieldValue = " << FieldValue << ", ExpectedValue = "
2322ac9a064cSDimitry Andric << ExpectedValue << ": "
2323ac9a064cSDimitry Andric << ((ExpectedValue == FieldValue) ? "PASS\n" : "FAIL\n"));
2324ac9a064cSDimitry Andric break;
2325ac9a064cSDimitry Andric }
2326ac9a064cSDimitry Andric case MCD::OPC_CheckPredicate: {
2327ac9a064cSDimitry Andric // Decode the Predicate Index value.
2328ac9a064cSDimitry Andric unsigned PIdx = decodeULEB128AndIncUnsafe(++Ptr);
2329ac9a064cSDimitry Andric // NumToSkip is a plain 24-bit integer.
2330ac9a064cSDimitry Andric unsigned NumToSkip = *Ptr++;
2331ac9a064cSDimitry Andric NumToSkip |= (*Ptr++) << 8;
2332ac9a064cSDimitry Andric NumToSkip |= (*Ptr++) << 16;
2333ac9a064cSDimitry Andric // Check the predicate.
2334ac9a064cSDimitry Andric bool Pred;
2335ac9a064cSDimitry Andric if (!(Pred = checkDecoderPredicate(PIdx, Bits)))
2336ac9a064cSDimitry Andric Ptr += NumToSkip;
2337ac9a064cSDimitry Andric (void)Pred;
2338ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_CheckPredicate(" << PIdx << "): "
2339ac9a064cSDimitry Andric << (Pred ? "PASS\n" : "FAIL\n"));
2340ac9a064cSDimitry Andric
2341ac9a064cSDimitry Andric break;
2342ac9a064cSDimitry Andric }
2343ac9a064cSDimitry Andric case MCD::OPC_Decode: {
2344ac9a064cSDimitry Andric // Decode the Opcode value.
2345ac9a064cSDimitry Andric unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr);
2346ac9a064cSDimitry Andric unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2347ac9a064cSDimitry Andric
2348ac9a064cSDimitry Andric MI.clear();
2349ac9a064cSDimitry Andric MI.setOpcode(Opc);
2350ac9a064cSDimitry Andric bool DecodeComplete;)";
2351145449b1SDimitry Andric if (IsVarLenInst) {
2352ac9a064cSDimitry Andric OS << "\n unsigned Len = InstrLenTable[Opc];\n"
2353ac9a064cSDimitry Andric << " makeUp(insn, Len);";
2354145449b1SDimitry Andric }
2355ac9a064cSDimitry Andric OS << R"(
2356ac9a064cSDimitry Andric S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, DecodeComplete);
2357ac9a064cSDimitry Andric assert(DecodeComplete);
2358ac9a064cSDimitry Andric
2359ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc
2360ac9a064cSDimitry Andric << ", using decoder " << DecodeIdx << ": "
2361ac9a064cSDimitry Andric << (S != MCDisassembler::Fail ? "PASS" : "FAIL") << "\n");
2362ac9a064cSDimitry Andric return S;
2363ac9a064cSDimitry Andric }
2364ac9a064cSDimitry Andric case MCD::OPC_TryDecode: {
2365ac9a064cSDimitry Andric // Decode the Opcode value.
2366ac9a064cSDimitry Andric unsigned Opc = decodeULEB128AndIncUnsafe(++Ptr);
2367ac9a064cSDimitry Andric unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
2368ac9a064cSDimitry Andric // NumToSkip is a plain 24-bit integer.
2369ac9a064cSDimitry Andric unsigned NumToSkip = *Ptr++;
2370ac9a064cSDimitry Andric NumToSkip |= (*Ptr++) << 8;
2371ac9a064cSDimitry Andric NumToSkip |= (*Ptr++) << 16;
2372ac9a064cSDimitry Andric
2373ac9a064cSDimitry Andric // Perform the decode operation.
2374ac9a064cSDimitry Andric MCInst TmpMI;
2375ac9a064cSDimitry Andric TmpMI.setOpcode(Opc);
2376ac9a064cSDimitry Andric bool DecodeComplete;
2377ac9a064cSDimitry Andric S = decodeToMCInst(S, DecodeIdx, insn, TmpMI, Address, DisAsm, DecodeComplete);
2378ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc
2379ac9a064cSDimitry Andric << ", using decoder " << DecodeIdx << ": ");
2380ac9a064cSDimitry Andric
2381ac9a064cSDimitry Andric if (DecodeComplete) {
2382ac9a064cSDimitry Andric // Decoding complete.
2383ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS" : "FAIL") << "\n");
2384ac9a064cSDimitry Andric MI = TmpMI;
2385ac9a064cSDimitry Andric return S;
2386ac9a064cSDimitry Andric } else {
2387ac9a064cSDimitry Andric assert(S == MCDisassembler::Fail);
2388ac9a064cSDimitry Andric // If the decoding was incomplete, skip.
2389ac9a064cSDimitry Andric Ptr += NumToSkip;
2390ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << "FAIL: continuing at " << (Ptr - DecodeTable) << "\n");
2391ac9a064cSDimitry Andric // Reset decode status. This also drops a SoftFail status that could be
2392ac9a064cSDimitry Andric // set before the decode attempt.
2393ac9a064cSDimitry Andric S = MCDisassembler::Success;
2394ac9a064cSDimitry Andric }
2395ac9a064cSDimitry Andric break;
2396ac9a064cSDimitry Andric }
2397ac9a064cSDimitry Andric case MCD::OPC_SoftFail: {
2398ac9a064cSDimitry Andric // Decode the mask values.
2399ac9a064cSDimitry Andric uint64_t PositiveMask = decodeULEB128AndIncUnsafe(++Ptr);
2400ac9a064cSDimitry Andric uint64_t NegativeMask = decodeULEB128AndIncUnsafe(Ptr);
2401ac9a064cSDimitry Andric bool Fail = (insn & PositiveMask) != 0 || (~insn & NegativeMask) != 0;
2402ac9a064cSDimitry Andric if (Fail)
2403ac9a064cSDimitry Andric S = MCDisassembler::SoftFail;
2404ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_SoftFail: " << (Fail ? "FAIL\n" : "PASS\n"));
2405ac9a064cSDimitry Andric break;
2406ac9a064cSDimitry Andric }
2407ac9a064cSDimitry Andric case MCD::OPC_Fail: {
2408ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << Loc << ": OPC_Fail\n");
2409ac9a064cSDimitry Andric return MCDisassembler::Fail;
2410ac9a064cSDimitry Andric }
2411ac9a064cSDimitry Andric }
2412ac9a064cSDimitry Andric }
2413ac9a064cSDimitry Andric llvm_unreachable("bogosity detected in disassembler state machine!");
2414ac9a064cSDimitry Andric }
2415ac9a064cSDimitry Andric
2416ac9a064cSDimitry Andric )";
2417cf099d11SDimitry Andric }
2418cf099d11SDimitry Andric
2419e3b55780SDimitry Andric // Helper to propagate SoftFail status. Returns false if the status is Fail;
2420e3b55780SDimitry Andric // callers are expected to early-exit in that condition. (Note, the '&' operator
2421e3b55780SDimitry Andric // is correct to propagate the values of this enum; see comment on 'enum
2422e3b55780SDimitry Andric // DecodeStatus'.)
emitCheck(formatted_raw_ostream & OS)2423e3b55780SDimitry Andric static void emitCheck(formatted_raw_ostream &OS) {
2424ac9a064cSDimitry Andric OS << R"(
2425ac9a064cSDimitry Andric static bool Check(DecodeStatus &Out, DecodeStatus In) {
2426ac9a064cSDimitry Andric Out = static_cast<DecodeStatus>(Out & In);
2427ac9a064cSDimitry Andric return Out != MCDisassembler::Fail;
2428ac9a064cSDimitry Andric }
2429ac9a064cSDimitry Andric
2430ac9a064cSDimitry Andric )";
2431ac9a064cSDimitry Andric }
2432ac9a064cSDimitry Andric
2433ac9a064cSDimitry Andric // Collect all HwModes referenced by the target for encoding purposes,
2434ac9a064cSDimitry Andric // returning a vector of corresponding names.
collectHwModesReferencedForEncodings(const CodeGenHwModes & HWM,std::vector<StringRef> & Names,NamespacesHwModesMap & NamespacesWithHwModes)2435ac9a064cSDimitry Andric static void collectHwModesReferencedForEncodings(
2436ac9a064cSDimitry Andric const CodeGenHwModes &HWM, std::vector<StringRef> &Names,
2437ac9a064cSDimitry Andric NamespacesHwModesMap &NamespacesWithHwModes) {
2438ac9a064cSDimitry Andric SmallBitVector BV(HWM.getNumModeIds());
2439ac9a064cSDimitry Andric for (const auto &MS : HWM.getHwModeSelects()) {
2440ac9a064cSDimitry Andric for (const HwModeSelect::PairType &P : MS.second.Items) {
2441ac9a064cSDimitry Andric if (P.second->isSubClassOf("InstructionEncoding")) {
2442ac9a064cSDimitry Andric std::string DecoderNamespace =
2443ac9a064cSDimitry Andric std::string(P.second->getValueAsString("DecoderNamespace"));
2444ac9a064cSDimitry Andric if (P.first == DefaultMode) {
2445ac9a064cSDimitry Andric NamespacesWithHwModes[DecoderNamespace].insert("");
2446ac9a064cSDimitry Andric } else {
2447ac9a064cSDimitry Andric NamespacesWithHwModes[DecoderNamespace].insert(
2448ac9a064cSDimitry Andric HWM.getMode(P.first).Name);
2449ac9a064cSDimitry Andric }
2450ac9a064cSDimitry Andric BV.set(P.first);
2451ac9a064cSDimitry Andric }
2452ac9a064cSDimitry Andric }
2453ac9a064cSDimitry Andric }
2454ac9a064cSDimitry Andric transform(BV.set_bits(), std::back_inserter(Names), [&HWM](const int &M) {
2455ac9a064cSDimitry Andric if (M == DefaultMode)
2456ac9a064cSDimitry Andric return StringRef("");
2457ac9a064cSDimitry Andric return HWM.getModeName(M, /*IncludeDefault=*/true);
2458ac9a064cSDimitry Andric });
2459ac9a064cSDimitry Andric }
2460ac9a064cSDimitry Andric
2461ac9a064cSDimitry Andric static void
handleHwModesUnrelatedEncodings(const CodeGenInstruction * Instr,const std::vector<StringRef> & HwModeNames,NamespacesHwModesMap & NamespacesWithHwModes,std::vector<EncodingAndInst> & GlobalEncodings)2462ac9a064cSDimitry Andric handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
2463ac9a064cSDimitry Andric const std::vector<StringRef> &HwModeNames,
2464ac9a064cSDimitry Andric NamespacesHwModesMap &NamespacesWithHwModes,
2465ac9a064cSDimitry Andric std::vector<EncodingAndInst> &GlobalEncodings) {
2466ac9a064cSDimitry Andric const Record *InstDef = Instr->TheDef;
2467ac9a064cSDimitry Andric
2468ac9a064cSDimitry Andric switch (DecoderEmitterSuppressDuplicates) {
2469ac9a064cSDimitry Andric case SUPPRESSION_DISABLE: {
2470ac9a064cSDimitry Andric for (StringRef HwModeName : HwModeNames)
2471ac9a064cSDimitry Andric GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
2472ac9a064cSDimitry Andric break;
2473ac9a064cSDimitry Andric }
2474ac9a064cSDimitry Andric case SUPPRESSION_LEVEL1: {
2475ac9a064cSDimitry Andric std::string DecoderNamespace =
2476ac9a064cSDimitry Andric std::string(InstDef->getValueAsString("DecoderNamespace"));
2477ac9a064cSDimitry Andric auto It = NamespacesWithHwModes.find(DecoderNamespace);
2478ac9a064cSDimitry Andric if (It != NamespacesWithHwModes.end()) {
2479ac9a064cSDimitry Andric for (StringRef HwModeName : It->second)
2480ac9a064cSDimitry Andric GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
2481ac9a064cSDimitry Andric } else {
2482ac9a064cSDimitry Andric // Only emit the encoding once, as it's DecoderNamespace doesn't
2483ac9a064cSDimitry Andric // contain any HwModes.
2484ac9a064cSDimitry Andric GlobalEncodings.emplace_back(InstDef, Instr, "");
2485ac9a064cSDimitry Andric }
2486ac9a064cSDimitry Andric break;
2487ac9a064cSDimitry Andric }
2488ac9a064cSDimitry Andric case SUPPRESSION_LEVEL2:
2489ac9a064cSDimitry Andric GlobalEncodings.emplace_back(InstDef, Instr, "");
2490ac9a064cSDimitry Andric break;
2491ac9a064cSDimitry Andric }
2492e3b55780SDimitry Andric }
2493e3b55780SDimitry Andric
2494cf099d11SDimitry Andric // Emits disassembler code for instruction decoding.
run(raw_ostream & o)2495145449b1SDimitry Andric void DecoderEmitter::run(raw_ostream &o) {
2496902a7b52SDimitry Andric formatted_raw_ostream OS(o);
2497ac9a064cSDimitry Andric OS << R"(
2498ac9a064cSDimitry Andric #include "llvm/MC/MCInst.h"
2499ac9a064cSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
2500ac9a064cSDimitry Andric #include "llvm/Support/DataTypes.h"
2501ac9a064cSDimitry Andric #include "llvm/Support/Debug.h"
2502ac9a064cSDimitry Andric #include "llvm/Support/LEB128.h"
2503ac9a064cSDimitry Andric #include "llvm/Support/raw_ostream.h"
2504ac9a064cSDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
2505ac9a064cSDimitry Andric #include <assert.h>
2506ac9a064cSDimitry Andric
2507ac9a064cSDimitry Andric namespace llvm {
2508ac9a064cSDimitry Andric )";
2509902a7b52SDimitry Andric
2510902a7b52SDimitry Andric emitFieldFromInstruction(OS);
2511344a3780SDimitry Andric emitInsertBits(OS);
2512e3b55780SDimitry Andric emitCheck(OS);
2513cf099d11SDimitry Andric
25145ca98fd9SDimitry Andric Target.reverseBitsForLittleEndianEncoding();
25155ca98fd9SDimitry Andric
251630815c53SDimitry Andric // Parameterize the decoders based on namespace and instruction width.
2517ac9a064cSDimitry Andric
2518ac9a064cSDimitry Andric // First, collect all encoding-related HwModes referenced by the target.
2519ac9a064cSDimitry Andric // And establish a mapping table between DecoderNamespace and HwMode.
2520ac9a064cSDimitry Andric // If HwModeNames is empty, add the empty string so we always have one HwMode.
2521ac9a064cSDimitry Andric const CodeGenHwModes &HWM = Target.getHwModes();
2522ac9a064cSDimitry Andric std::vector<StringRef> HwModeNames;
2523ac9a064cSDimitry Andric NamespacesHwModesMap NamespacesWithHwModes;
2524ac9a064cSDimitry Andric collectHwModesReferencedForEncodings(HWM, HwModeNames, NamespacesWithHwModes);
2525ac9a064cSDimitry Andric if (HwModeNames.empty())
2526ac9a064cSDimitry Andric HwModeNames.push_back("");
2527ac9a064cSDimitry Andric
2528d8e91e46SDimitry Andric const auto &NumberedInstructions = Target.getInstructionsByEnumValue();
2529d8e91e46SDimitry Andric NumberedEncodings.reserve(NumberedInstructions.size());
2530e6d15924SDimitry Andric for (const auto &NumberedInstruction : NumberedInstructions) {
2531ac9a064cSDimitry Andric const Record *InstDef = NumberedInstruction->TheDef;
2532ac9a064cSDimitry Andric if (const RecordVal *RV = InstDef->getValue("EncodingInfos")) {
25331d5ae102SDimitry Andric if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
25341d5ae102SDimitry Andric EncodingInfoByHwMode EBM(DI->getDef(), HWM);
2535ac9a064cSDimitry Andric for (auto &[ModeId, Encoding] : EBM) {
2536ac9a064cSDimitry Andric // DecoderTables with DefaultMode should not have any suffix.
2537ac9a064cSDimitry Andric if (ModeId == DefaultMode) {
2538ac9a064cSDimitry Andric NumberedEncodings.emplace_back(Encoding, NumberedInstruction, "");
2539ac9a064cSDimitry Andric } else {
2540ac9a064cSDimitry Andric NumberedEncodings.emplace_back(Encoding, NumberedInstruction,
2541ac9a064cSDimitry Andric HWM.getMode(ModeId).Name);
2542ac9a064cSDimitry Andric }
25431d5ae102SDimitry Andric }
25441d5ae102SDimitry Andric continue;
25451d5ae102SDimitry Andric }
25461d5ae102SDimitry Andric }
2547ac9a064cSDimitry Andric // This instruction is encoded the same on all HwModes.
2548ac9a064cSDimitry Andric // According to user needs, provide varying degrees of suppression.
2549ac9a064cSDimitry Andric handleHwModesUnrelatedEncodings(NumberedInstruction, HwModeNames,
2550ac9a064cSDimitry Andric NamespacesWithHwModes, NumberedEncodings);
2551e6d15924SDimitry Andric }
2552ac9a064cSDimitry Andric for (const auto &NumberedAlias :
2553ac9a064cSDimitry Andric RK.getAllDerivedDefinitions("AdditionalEncoding"))
2554e6d15924SDimitry Andric NumberedEncodings.emplace_back(
2555e6d15924SDimitry Andric NumberedAlias,
2556e6d15924SDimitry Andric &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf")));
2557d8e91e46SDimitry Andric
2558e6d15924SDimitry Andric std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>>
2559e6d15924SDimitry Andric OpcMap;
256030815c53SDimitry Andric std::map<unsigned, std::vector<OperandInfo>> Operands;
2561145449b1SDimitry Andric std::vector<unsigned> InstrLen;
2562ac9a064cSDimitry Andric bool IsVarLenInst = Target.hasVariableLengthEncodings();
2563145449b1SDimitry Andric unsigned MaxInstLen = 0;
256430815c53SDimitry Andric
2565ac9a064cSDimitry Andric for (const auto &[NEI, NumberedEncoding] : enumerate(NumberedEncodings)) {
2566ac9a064cSDimitry Andric const Record *EncodingDef = NumberedEncoding.EncodingDef;
2567ac9a064cSDimitry Andric const CodeGenInstruction *Inst = NumberedEncoding.Inst;
256863faed5bSDimitry Andric const Record *Def = Inst->TheDef;
2569e6d15924SDimitry Andric unsigned Size = EncodingDef->getValueAsInt("Size");
257030815c53SDimitry Andric if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
257130815c53SDimitry Andric Def->getValueAsBit("isPseudo") ||
257230815c53SDimitry Andric Def->getValueAsBit("isAsmParserOnly") ||
2573e6d15924SDimitry Andric Def->getValueAsBit("isCodeGenOnly")) {
2574e6d15924SDimitry Andric NumEncodingsLackingDisasm++;
257530815c53SDimitry Andric continue;
2576e6d15924SDimitry Andric }
257730815c53SDimitry Andric
2578ac9a064cSDimitry Andric if (NEI < NumberedInstructions.size())
2579e6d15924SDimitry Andric NumInstructions++;
2580e6d15924SDimitry Andric NumEncodings++;
2581e6d15924SDimitry Andric
2582145449b1SDimitry Andric if (!Size && !IsVarLenInst)
25831d5ae102SDimitry Andric continue;
258430815c53SDimitry Andric
2585145449b1SDimitry Andric if (IsVarLenInst)
2586145449b1SDimitry Andric InstrLen.resize(NumberedInstructions.size(), 0);
2587145449b1SDimitry Andric
2588ac9a064cSDimitry Andric if (unsigned Len = populateInstruction(Target, *EncodingDef, *Inst, NEI,
2589145449b1SDimitry Andric Operands, IsVarLenInst)) {
2590145449b1SDimitry Andric if (IsVarLenInst) {
2591145449b1SDimitry Andric MaxInstLen = std::max(MaxInstLen, Len);
2592ac9a064cSDimitry Andric InstrLen[NEI] = Len;
2593145449b1SDimitry Andric }
25941d5ae102SDimitry Andric std::string DecoderNamespace =
2595cfca06d7SDimitry Andric std::string(EncodingDef->getValueAsString("DecoderNamespace"));
2596ac9a064cSDimitry Andric if (!NumberedEncoding.HwModeName.empty())
25971d5ae102SDimitry Andric DecoderNamespace +=
2598ac9a064cSDimitry Andric std::string("_") + NumberedEncoding.HwModeName.str();
2599ac9a064cSDimitry Andric OpcMap[std::pair(DecoderNamespace, Size)].emplace_back(
2600ac9a064cSDimitry Andric NEI, Target.getInstrIntValue(Def));
26011d5ae102SDimitry Andric } else {
2602e6d15924SDimitry Andric NumEncodingsOmitted++;
260330815c53SDimitry Andric }
260430815c53SDimitry Andric }
260530815c53SDimitry Andric
2606902a7b52SDimitry Andric DecoderTableInfo TableInfo;
260767c32a98SDimitry Andric for (const auto &Opc : OpcMap) {
260830815c53SDimitry Andric // Emit the decoder for this namespace+width combination.
2609ac9a064cSDimitry Andric ArrayRef<EncodingAndInst> NumberedEncodingsRef(NumberedEncodings.data(),
2610ac9a064cSDimitry Andric NumberedEncodings.size());
2611d8e91e46SDimitry Andric FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands,
2612145449b1SDimitry Andric IsVarLenInst ? MaxInstLen : 8 * Opc.first.second, this);
2613902a7b52SDimitry Andric
2614902a7b52SDimitry Andric // The decode table is cleared for each top level decoder function. The
2615902a7b52SDimitry Andric // predicates and decoders themselves, however, are shared across all
2616902a7b52SDimitry Andric // decoders to give more opportunities for uniqueing.
2617902a7b52SDimitry Andric TableInfo.Table.clear();
2618902a7b52SDimitry Andric TableInfo.FixupStack.clear();
2619902a7b52SDimitry Andric TableInfo.Table.reserve(16384);
262085d8b2bbSDimitry Andric TableInfo.FixupStack.emplace_back();
2621902a7b52SDimitry Andric FC.emitTableEntries(TableInfo);
2622902a7b52SDimitry Andric // Any NumToSkip fixups in the top level scope can resolve to the
2623902a7b52SDimitry Andric // OPC_Fail at the end of the table.
2624902a7b52SDimitry Andric assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!");
2625902a7b52SDimitry Andric // Resolve any NumToSkip fixups in the current scope.
2626902a7b52SDimitry Andric resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(),
2627902a7b52SDimitry Andric TableInfo.Table.size());
2628902a7b52SDimitry Andric TableInfo.FixupStack.clear();
2629902a7b52SDimitry Andric
2630902a7b52SDimitry Andric TableInfo.Table.push_back(MCD::OPC_Fail);
2631902a7b52SDimitry Andric
2632902a7b52SDimitry Andric // Print the table to the output stream.
2633ac9a064cSDimitry Andric emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first,
2634ac9a064cSDimitry Andric Opc.second);
263530815c53SDimitry Andric }
2636cf099d11SDimitry Andric
2637145449b1SDimitry Andric // For variable instruction, we emit a instruction length table
2638145449b1SDimitry Andric // to let the decoder know how long the instructions are.
2639145449b1SDimitry Andric // You can see example usage in M68k's disassembler.
2640145449b1SDimitry Andric if (IsVarLenInst)
2641145449b1SDimitry Andric emitInstrLenTable(OS, InstrLen);
2642902a7b52SDimitry Andric // Emit the predicate function.
2643902a7b52SDimitry Andric emitPredicateFunction(OS, TableInfo.Predicates, 0);
2644902a7b52SDimitry Andric
2645902a7b52SDimitry Andric // Emit the decoder function.
2646902a7b52SDimitry Andric emitDecoderFunction(OS, TableInfo.Decoders, 0);
2647902a7b52SDimitry Andric
2648902a7b52SDimitry Andric // Emit the main entry point for the decoder, decodeInstruction().
2649145449b1SDimitry Andric emitDecodeInstruction(OS, IsVarLenInst);
2650902a7b52SDimitry Andric
26511d5ae102SDimitry Andric OS << "\n} // end namespace llvm\n";
2652cf099d11SDimitry Andric }
265358b69754SDimitry Andric
265458b69754SDimitry Andric namespace llvm {
265558b69754SDimitry Andric
EmitDecoder(RecordKeeper & RK,raw_ostream & OS,const std::string & PredicateNamespace)2656145449b1SDimitry Andric void EmitDecoder(RecordKeeper &RK, raw_ostream &OS,
2657e3b55780SDimitry Andric const std::string &PredicateNamespace) {
2658e3b55780SDimitry Andric DecoderEmitter(RK, PredicateNamespace).run(OS);
265958b69754SDimitry Andric }
266058b69754SDimitry Andric
2661b915e9e0SDimitry Andric } // end namespace llvm
2662