FixedLenDecoderEmitter.cpp revision 8cd9eaef0102771b93b9336c9b99afa4e18fd45d
1d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson//===------------ FixedLenDecoderEmitter.cpp - Decoder Generator ----------===// 2d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 3d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// The LLVM Compiler Infrastructure 4d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 5d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// This file is distributed under the University of Illinois Open Source 6d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// License. See LICENSE.TXT for details. 7d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 8d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson//===----------------------------------------------------------------------===// 9d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 10d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// It contains the tablegen backend that emits the decoder functions for 11d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// targets with fixed length instruction set. 12d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 13d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson//===----------------------------------------------------------------------===// 14d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 15d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#define DEBUG_TYPE "decoder-emitter" 16d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 17d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "CodeGenTarget.h" 187c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Record.h" 193015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy#include "llvm/ADT/APInt.h" 20fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/SmallString.h" 21d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/ADT/StringExtras.h" 22fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/StringRef.h" 23fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/Twine.h" 24fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/MC/MCFixedLenDisassembler.h" 256f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/Support/DataTypes.h" 26d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/Support/Debug.h" 27fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/Support/FormattedStream.h" 28fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/Support/LEB128.h" 29d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/Support/raw_ostream.h" 306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 31d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 32d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <vector> 33d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <map> 34d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <string> 35d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 36d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonusing namespace llvm; 37d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenstruct EncodingField { 406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned Base, Width, Offset; 416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen EncodingField(unsigned B, unsigned W, unsigned O) 426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen : Base(B), Width(W), Offset(O) { } 436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenstruct OperandInfo { 466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<EncodingField> Fields; 476f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string Decoder; 486f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 496f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen OperandInfo(std::string D) 506f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen : Decoder(D) { } 516f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 526f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void addField(unsigned Base, unsigned Width, unsigned Offset) { 536f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen Fields.push_back(EncodingField(Base, Width, Offset)); 546f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen } 556f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned numFields() const { return Fields.size(); } 576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen typedef std::vector<EncodingField>::const_iterator const_iterator; 596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen const_iterator begin() const { return Fields.begin(); } 616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen const_iterator end() const { return Fields.end(); } 626f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 63fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 64fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef std::vector<uint8_t> DecoderTable; 65fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef uint32_t DecoderFixup; 66fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef std::vector<DecoderFixup> FixupList; 67fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef std::vector<FixupList> FixupScopeList; 68fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef SetVector<std::string> PredicateSet; 69fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef SetVector<std::string> DecoderSet; 70fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstruct DecoderTableInfo { 71fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable Table; 72fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FixupScopeList FixupStack; 73fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PredicateSet Predicates; 74fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderSet Decoders; 75fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach}; 76fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 776f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 786f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 796f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 806f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass FixedLenDecoderEmitter { 81fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const std::vector<const CodeGenInstruction*> *NumberedInstructions; 826f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 836f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 846f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen // Defaults preserved here for documentation, even though they aren't 856f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen // strictly necessary given the way that this is currently being called. 866f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen FixedLenDecoderEmitter(RecordKeeper &R, 876f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string PredicateNamespace, 886f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPrefix = "if (", 896f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPostfix = " == MCDisassembler::Fail)" 906f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen " return MCDisassembler::Fail;", 916f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string ROK = "MCDisassembler::Success", 926f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string RFail = "MCDisassembler::Fail", 936f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string L = "") : 946f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen Target(R), 956f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen PredicateNamespace(PredicateNamespace), 966f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen GuardPrefix(GPrefix), GuardPostfix(GPostfix), 976f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen ReturnOK(ROK), ReturnFail(RFail), Locals(L) {} 986f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 99fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the decoder state machine table. 100fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitTable(formatted_raw_ostream &o, DecoderTable &Table, 101fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation, unsigned BitWidth, 102fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach StringRef Namespace) const; 103fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitPredicateFunction(formatted_raw_ostream &OS, 104fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PredicateSet &Predicates, 105fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const; 106fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitDecoderFunction(formatted_raw_ostream &OS, 107fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderSet &Decoders, 108fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const; 109fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1106f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen // run - Output the code emitter 1116f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void run(raw_ostream &o); 1126f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 1136f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenprivate: 1146f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CodeGenTarget Target; 1156f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 1166f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string PredicateNamespace; 1176f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GuardPrefix, GuardPostfix; 1186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string ReturnOK, ReturnFail; 1196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string Locals; 1206f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 1216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 1226f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 123d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system 124d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// for a bit value. 125d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 126d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// BIT_UNFILTERED is used as the init value for a filter position. It is used 127d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// only for filter processings. 128d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersontypedef enum { 129d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_TRUE, // '1' 130d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_FALSE, // '0' 131d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_UNSET, // '?' 132d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_UNFILTERED // unfiltered 133d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} bit_value_t; 134d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 135d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic bool ValueSet(bit_value_t V) { 136d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return (V == BIT_TRUE || V == BIT_FALSE); 137d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 138d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic bool ValueNotSet(bit_value_t V) { 139d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return (V == BIT_UNSET); 140d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 141d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic int Value(bit_value_t V) { 142d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1); 143d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 144eb5cd610700661bc46c660640c36949033247d2dCraig Topperstatic bit_value_t bitFromBits(const BitsInit &bits, unsigned index) { 14505bce0beee87512e52428d4b80f5a8e79a949576David Greene if (BitInit *bit = dynamic_cast<BitInit*>(bits.getBit(index))) 146d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return bit->getValue() ? BIT_TRUE : BIT_FALSE; 147d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 148d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The bit is uninitialized. 149d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return BIT_UNSET; 150d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 151d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Prints the bit value for each position. 152eb5cd610700661bc46c660640c36949033247d2dCraig Topperstatic void dumpBits(raw_ostream &o, const BitsInit &bits) { 1538cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned index = bits.getNumBits(); index > 0; --index) { 154d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitFromBits(bits, index - 1)) { 155d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_TRUE: 156d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "1"; 157d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 158d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_FALSE: 159d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "0"; 160d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 161d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNSET: 162d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "_"; 163d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 164d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 165655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("unexpected return value from bitFromBits"); 166d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 167d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 168d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 169d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 17005bce0beee87512e52428d4b80f5a8e79a949576David Greenestatic BitsInit &getBitsField(const Record &def, const char *str) { 17105bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit *bits = def.getValueAsBitsInit(str); 172d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return *bits; 173d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 174d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 175d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Forward declaration. 1766f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 177d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass FilterChooser; 1786f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 179d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 180d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Representation of the instruction to work on. 181f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Andersontypedef std::vector<bit_value_t> insn_t; 182d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 183d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Filter - Filter works with FilterChooser to produce the decoding tree for 184d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the ISA. 185d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 186d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// It is useful to think of a Filter as governing the switch stmts of the 187d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoding tree in a certain level. Each case stmt delegates to an inferior 188d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser to decide what further decoding logic to employ, or in another 189d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// words, what other remaining bits to look at. The FilterChooser eventually 190d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// chooses a best Filter to do its job. 191d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 192d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// This recursive scheme ends when the number of Opcodes assigned to the 193d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser becomes 1 or if there is a conflict. A conflict happens when 194d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the Filter/FilterChooser combo does not know how to distinguish among the 195d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Opcodes assigned. 196d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 197d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// An example of a conflict is 198d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 199d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Conflict: 200d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 111101000.00........00010000.... 201d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 111101000.00........0001........ 202d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010...00........0001........ 203d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010...00.................... 204d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010......................... 205d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111............................ 206d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// ................................ 207d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8a 111101000_00________00010000____ 208d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8b 111101000_00________00010000____ 209d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 210d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// The Debug output shows the path that the decoding tree follows to reach the 211d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced 212d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// even registers, while VST4q8b is a vst4 to double-spaced odd regsisters. 213d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 214d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// The encoding info in the .td files does not specify this meta information, 215d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// which could have been used by the decoder to resolve the conflict. The 216d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoder could try to decode the even/odd register numbering and assign to 217d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a" 218d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// version and return the Opcode since the two have the same Asm format string. 2196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 220d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass Filter { 221d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 2225a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const FilterChooser *Owner;// points to the FilterChooser who owns this filter 223d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned StartBit; // the starting bit position 224d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned NumBits; // number of bits to filter 225d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool Mixed; // a mixed region contains both set and unset bits 226d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 227d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Map of well-known segment value to the set of uid's with that value. 228d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<uint64_t, std::vector<unsigned> > FilteredInstructions; 229d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 230d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set of uid's with non-constant segment values. 231d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> VariableInstructions; 232d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 233d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Map of well-known segment value to its delegate. 234eb5cd610700661bc46c660640c36949033247d2dCraig Topper std::map<unsigned, const FilterChooser*> FilterChooserMap; 235d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 236d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Number of instructions which fall under FilteredInstructions category. 237d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned NumFiltered; 238d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 239d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Keeps track of the last opcode in the filtered bucket. 240d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned LastOpcFiltered; 241d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 242d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonpublic: 243eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned getNumFiltered() const { return NumFiltered; } 244eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned getSingletonOpc() const { 245d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(NumFiltered == 1); 246d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return LastOpcFiltered; 247d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 248d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Return the filter chooser for the group of instructions without constant 249d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // segment values. 250eb5cd610700661bc46c660640c36949033247d2dCraig Topper const FilterChooser &getVariableFC() const { 251d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(NumFiltered == 1); 252d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(FilterChooserMap.size() == 1); 253d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return *(FilterChooserMap.find((unsigned)-1)->second); 254d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 255d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 256d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter(const Filter &f); 257d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed); 258d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 259d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ~Filter(); 260d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 261d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Divides the decoding task into sub tasks and delegates them to the 262d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // inferior FilterChooser's. 263d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 264d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // A special case arises when there's only one entry in the filtered 265d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instructions. In order to unambiguously decode the singleton, we need to 266d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // match the remaining undecoded encoding bits against the singleton. 267d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void recurse(); 268d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 269fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit table entries to decode instructions given a segment or segments of 270fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // bits. 271fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitTableEntry(DecoderTableInfo &TableInfo) const; 272d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 273d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns the number of fanout produced by the filter. More fanout implies 274d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the filter distinguishes more categories of instructions. 275d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned usefulness() const; 276d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson}; // End of class Filter 2776f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 278d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 279d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// These are states of our finite state machines used in FilterChooser's 280d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// filterProcessor() which produces the filter candidates to use. 281d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersontypedef enum { 282d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_NONE, 283d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_FILTERED, 284d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_ALL_SET, 285d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_ALL_UNSET, 286d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_MIXED 287d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} bitAttr_t; 288d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 289d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser - FilterChooser chooses the best filter among a set of Filters 290d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// in order to perform the decoding of instructions at the current level. 291d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 292d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Decoding proceeds from the top down. Based on the well-known encoding bits 293d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// of instructions available, FilterChooser builds up the possible Filters that 294d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// can further the task of decoding by distinguishing among the remaining 295d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// candidate instructions. 296d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 297d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Once a filter has been chosen, it is called upon to divide the decoding task 298d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// into sub-tasks and delegates them to its inferior FilterChoosers for further 299d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// processings. 300d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 301d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// It is useful to think of a Filter as governing the switch stmts of the 302d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoding tree. And each case is delegated to an inferior FilterChooser to 303d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decide what further remaining bits to look at. 3046f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 305d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass FilterChooser { 306d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 307d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson friend class Filter; 308d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 309d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of codegen instructions to choose our filter. 310d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<const CodeGenInstruction*> &AllInstructions; 311d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 312d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of uid's for this filter chooser to work on. 3135a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::vector<unsigned> &Opcodes; 314d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 315d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Lookup table for the operand decoding of instructions. 3165a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::map<unsigned, std::vector<OperandInfo> > &Operands; 317d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 318d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of candidate filters. 319d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<Filter> Filters; 320d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 321d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Array of bit values passed down from our parent. 322d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set to all BIT_UNFILTERED's for Parent == NULL. 323f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bit_value_t> FilterBitValues; 324d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 325d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Links to the FilterChooser above us in the decoding tree. 3265a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const FilterChooser *Parent; 327d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 328d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Index of the best filter from Filters. 329d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int BestIndex; 330d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 331f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Width of instructions 332f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned BitWidth; 333f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 33483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson // Parent emitter 33583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson const FixedLenDecoderEmitter *Emitter; 33683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson 337d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonpublic: 338d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper FilterChooser(const FilterChooser &FC) 339d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : AllInstructions(FC.AllInstructions), Opcodes(FC.Opcodes), 340f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Operands(FC.Operands), Filters(FC.Filters), 341f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson FilterBitValues(FC.FilterBitValues), Parent(FC.Parent), 342d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper BestIndex(FC.BestIndex), BitWidth(FC.BitWidth), 343d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper Emitter(FC.Emitter) { } 344d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 345d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser(const std::vector<const CodeGenInstruction*> &Insts, 346d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<unsigned> &IDs, 3475a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::map<unsigned, std::vector<OperandInfo> > &Ops, 34883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson unsigned BW, 349d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper const FixedLenDecoderEmitter *E) 350d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), Filters(), 35183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Parent(NULL), BestIndex(-1), BitWidth(BW), Emitter(E) { 352f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (unsigned i = 0; i < BitWidth; ++i) 353f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson FilterBitValues.push_back(BIT_UNFILTERED); 354d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 355d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson doFilter(); 356d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 357d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 358d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser(const std::vector<const CodeGenInstruction*> &Insts, 359d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<unsigned> &IDs, 3605a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::map<unsigned, std::vector<OperandInfo> > &Ops, 3615a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::vector<bit_value_t> &ParentFilterBitValues, 3625a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const FilterChooser &parent) 363d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), 364f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Filters(), FilterBitValues(ParentFilterBitValues), 36583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Parent(&parent), BestIndex(-1), BitWidth(parent.BitWidth), 36683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Emitter(parent.Emitter) { 367d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson doFilter(); 368d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 369d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 370fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned getBitWidth() const { return BitWidth; } 371d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 372d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 373d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the insn given the uid. 374d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void insnWithID(insn_t &Insn, unsigned Opcode) const { 37505bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst"); 376d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 3773015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // We may have a SoftFail bitmask, which specifies a mask where an encoding 3783015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // may differ from the value in "Inst" and yet still be valid, but the 3793015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // disassembler should return SoftFail instead of Success. 3803015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // 3813015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // This is used for marking UNPREDICTABLE instructions in the ARM world. 3829c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach BitsInit *SFBits = 3839c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach AllInstructions[Opcode]->TheDef->getValueAsBitsInit("SoftFail"); 3843015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 3853015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy for (unsigned i = 0; i < BitWidth; ++i) { 3863015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE) 3873015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy Insn.push_back(BIT_UNSET); 3883015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy else 3893015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy Insn.push_back(bitFromBits(Bits, i)); 3903015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy } 391d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 392d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 393d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns the record name. 394d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &nameWithID(unsigned Opcode) const { 395d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return AllInstructions[Opcode]->TheDef->getName(); 396d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 397d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 398d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the field of the insn given the start position and the number of 399d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // consecutive bits to scan for. 400d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 401d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns false if there exists any uninitialized bit value in the range. 402d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns true, otherwise. 403d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit, 404d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper unsigned NumBits) const; 405d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 406d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpFilterArray - dumpFilterArray prints out debugging info for the given 407d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// filter array as a series of chars. 408eb5cd610700661bc46c660640c36949033247d2dCraig Topper void dumpFilterArray(raw_ostream &o, 409eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::vector<bit_value_t> & filter) const; 410d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 411d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpStack - dumpStack traverses the filter chooser chain and calls 412d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpFilterArray on each filter chooser up to the top level one. 413eb5cd610700661bc46c660640c36949033247d2dCraig Topper void dumpStack(raw_ostream &o, const char *prefix) const; 414d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 415d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter &bestFilter() { 416d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(BestIndex != -1 && "BestIndex not set"); 417d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return Filters[BestIndex]; 418d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 419d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 420d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Called from Filter::recurse() when singleton exists. For debug purpose. 421eb5cd610700661bc46c660640c36949033247d2dCraig Topper void SingletonExists(unsigned Opc) const; 422d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 423eb5cd610700661bc46c660640c36949033247d2dCraig Topper bool PositionFiltered(unsigned i) const { 424d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return ValueSet(FilterBitValues[i]); 425d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 426d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 427d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Calculates the island(s) needed to decode the instruction. 428d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // This returns a lit of undecoded bits of an instructions, for example, 429d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 430d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // decoded bits in order to verify that the instruction matches the Opcode. 431d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned getIslands(std::vector<unsigned> &StartBits, 432d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::vector<unsigned> &EndBits, 433eb5cd610700661bc46c660640c36949033247d2dCraig Topper std::vector<uint64_t> &FieldVals, 434eb5cd610700661bc46c660640c36949033247d2dCraig Topper const insn_t &Insn) const; 435d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 436a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy // Emits code to check the Predicates member of an instruction are true. 437a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy // Returns true if predicate matches were emitted, false otherwise. 438eb5cd610700661bc46c660640c36949033247d2dCraig Topper bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 439eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned Opc) const; 440a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 441fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach bool doesOpcodeNeedPredicate(unsigned Opc) const; 442fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const; 443fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitPredicateTableEntry(DecoderTableInfo &TableInfo, 444fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const; 445fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 446fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitSoftFailTableEntry(DecoderTableInfo &TableInfo, 447fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const; 4483015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 449fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emits table entries to decode the singleton. 450fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitSingletonTableEntry(DecoderTableInfo &TableInfo, 451fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const; 452d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 453d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emits code to decode the singleton, and then to decode the rest. 454fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitSingletonTableEntry(DecoderTableInfo &TableInfo, 455fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const Filter &Best) const; 456d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 457fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitBinaryParser(raw_ostream &o, unsigned &Indentation, 458eb5cd610700661bc46c660640c36949033247d2dCraig Topper const OperandInfo &OpInfo) const; 459d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 460fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitDecoder(raw_ostream &OS, unsigned Indentation, unsigned Opc) const; 461fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc) const; 462fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 463d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Assign a single filter and run with it. 464eb5cd610700661bc46c660640c36949033247d2dCraig Topper void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed); 465d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 466d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // reportRegion is a helper function for filterProcessor to mark a region as 467d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // eligible for use as a filter region. 468d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex, 469d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper bool AllowMixed); 470d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 471d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FilterProcessor scans the well-known encoding bits of the instructions and 472d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // builds up a list of candidate filters. It chooses the best filter and 473d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // recursively descends down the decoding tree. 474d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool filterProcessor(bool AllowMixed, bool Greedy = true); 475d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 476d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Decides on the best configuration of filter(s) to use in order to decode 477d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the instructions. A conflict of instructions may occur, in which case we 478d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // dump the conflict set to the standard error. 479d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void doFilter(); 480d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 481fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachpublic: 482fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // emitTableEntries - Emit state machine entries to decode our share of 483fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // instructions. 484fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitTableEntries(DecoderTableInfo &TableInfo) const; 485d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson}; 4866f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 487d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 488d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/////////////////////////// 489d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 490797ba55e20fa5c6b0bcaf3ab676b54c65a4666acCraig Topper// Filter Implementation // 491d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 492d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/////////////////////////// 493d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 494d936045625ae2e101d3a9544586d7568c6dbacc0Craig TopperFilter::Filter(const Filter &f) 495d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed), 496d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper FilteredInstructions(f.FilteredInstructions), 497d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper VariableInstructions(f.VariableInstructions), 498d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper FilterChooserMap(f.FilterChooserMap), NumFiltered(f.NumFiltered), 499d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper LastOpcFiltered(f.LastOpcFiltered) { 500d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 501d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 502d8c87888a71c4433d76b48bca6c3e03a17890648Owen AndersonFilter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, 503d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper bool mixed) 504d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) { 505f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson assert(StartBit + NumBits - 1 < Owner->BitWidth); 506d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 507d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NumFiltered = 0; 508d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson LastOpcFiltered = 0; 509d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 510d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) { 511d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 512d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 513d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the insn given the uid. 514d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Owner->insnWithID(Insn, Owner->Opcodes[i]); 515d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 516d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson uint64_t Field; 517d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Scans the segment for possibly well-specified encoding bits. 518d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits); 519d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 520d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (ok) { 521d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The encoding bits are well-known. Lets add the uid of the 522d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instruction into the bucket keyed off the constant field value. 523d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson LastOpcFiltered = Owner->Opcodes[i]; 524d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilteredInstructions[Field].push_back(LastOpcFiltered); 525d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++NumFiltered; 526d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } else { 527797ba55e20fa5c6b0bcaf3ab676b54c65a4666acCraig Topper // Some of the encoding bit(s) are unspecified. This contributes to 528d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // one additional member of "Variable" instructions. 529d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson VariableInstructions.push_back(Owner->Opcodes[i]); 530d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 531d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 532d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 533d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert((FilteredInstructions.size() + VariableInstructions.size() > 0) 534d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson && "Filter returns no instruction categories"); 535d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 536d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 537d8c87888a71c4433d76b48bca6c3e03a17890648Owen AndersonFilter::~Filter() { 538eb5cd610700661bc46c660640c36949033247d2dCraig Topper std::map<unsigned, const FilterChooser*>::iterator filterIterator; 539d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (filterIterator = FilterChooserMap.begin(); 540d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson filterIterator != FilterChooserMap.end(); 541d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson filterIterator++) { 542d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson delete filterIterator->second; 543d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 544d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 545d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 546d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Divides the decoding task into sub tasks and delegates them to the 547d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// inferior FilterChooser's. 548d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 549d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// A special case arises when there's only one entry in the filtered 550d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// instructions. In order to unambiguously decode the singleton, we need to 551d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// match the remaining undecoded encoding bits against the singleton. 552d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid Filter::recurse() { 553d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<uint64_t, std::vector<unsigned> >::const_iterator mapIterator; 554d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 555d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Starts by inheriting our parent filter chooser's filter bit values. 556f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues); 557d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 558d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (VariableInstructions.size()) { 559d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Conservatively marks each segment position as BIT_UNSET. 5608cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) 561d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_UNSET; 562d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 5637a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Delegates to an inferior filter chooser for further processing on this 564d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // group of instructions whose segment values are variable. 565eb5cd610700661bc46c660640c36949033247d2dCraig Topper FilterChooserMap.insert(std::pair<unsigned, const FilterChooser*>( 566d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson (unsigned)-1, 567d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson new FilterChooser(Owner->AllInstructions, 568d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson VariableInstructions, 569d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Owner->Operands, 570d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray, 571d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson *Owner) 572d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson )); 573d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 574d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 575d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // No need to recurse for a singleton filtered instruction. 576fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // See also Filter::emit*(). 577d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (getNumFiltered() == 1) { 578d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson //Owner->SingletonExists(LastOpcFiltered); 579d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(FilterChooserMap.size() == 1); 580d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 581d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 582d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 583d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Otherwise, create sub choosers. 584d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (mapIterator = FilteredInstructions.begin(); 585d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson mapIterator != FilteredInstructions.end(); 586d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson mapIterator++) { 587d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 588d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Marks all the segment positions with either BIT_TRUE or BIT_FALSE. 5898cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) { 590d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (mapIterator->first & (1ULL << bitIndex)) 591d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_TRUE; 592d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 593d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_FALSE; 594d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 595d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 5967a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Delegates to an inferior filter chooser for further processing on this 597d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // category of instructions. 598eb5cd610700661bc46c660640c36949033247d2dCraig Topper FilterChooserMap.insert(std::pair<unsigned, const FilterChooser*>( 599d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson mapIterator->first, 600d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson new FilterChooser(Owner->AllInstructions, 601d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson mapIterator->second, 602d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Owner->Operands, 603d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray, 604d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson *Owner) 605d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson )); 606d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 607d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 608d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 609fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstatic void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups, 610fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t DestIdx) { 611fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Any NumToSkip fixups in the current scope can resolve to the 612fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // current location. 613fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (FixupList::const_reverse_iterator I = Fixups.rbegin(), 614fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach E = Fixups.rend(); 615fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach I != E; ++I) { 616fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Calculate the distance from the byte following the fixup entry byte 617fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // to the destination. The Target is calculated from after the 16-bit 618fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // NumToSkip entry itself, so subtract two from the displacement here 619fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // to account for that. 620fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t FixupIdx = *I; 621fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t Delta = DestIdx - FixupIdx - 2; 622fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Our NumToSkip entries are 16-bits. Make sure our table isn't too 623fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // big. 624fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(Delta < 65536U && "disassembler decoding table too large!"); 625fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table[FixupIdx] = (uint8_t)Delta; 626fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table[FixupIdx + 1] = (uint8_t)(Delta >> 8); 627fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 628fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 629d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 630fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emit table entries to decode instructions given a segment or segments 631fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// of bits. 632fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid Filter::emitTableEntry(DecoderTableInfo &TableInfo) const { 633fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_ExtractField); 634fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(StartBit); 635fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(NumBits); 636d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 637fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // A new filter entry begins a new scope for fixup resolution. 638fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.push_back(FixupList()); 639d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 640eb5cd610700661bc46c660640c36949033247d2dCraig Topper std::map<unsigned, const FilterChooser*>::const_iterator filterIterator; 641d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 642fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable &Table = TableInfo.Table; 643fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 644fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach size_t PrevFilter = 0; 645fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach bool HasFallthrough = false; 646d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (filterIterator = FilterChooserMap.begin(); 647d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson filterIterator != FilterChooserMap.end(); 648d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson filterIterator++) { 649d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Field value -1 implies a non-empty set of variable instructions. 650d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // See also recurse(). 651d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterIterator->first == (unsigned)-1) { 652fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach HasFallthrough = true; 653fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 654fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Each scope should always have at least one filter value to check 655fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // for. 656fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(PrevFilter != 0 && "empty filter set!"); 657fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FixupList &CurScope = TableInfo.FixupStack.back(); 658fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Resolve any NumToSkip fixups in the current scope. 659fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach resolveTableFixups(Table, CurScope, Table.size()); 660fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach CurScope.clear(); 661fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PrevFilter = 0; // Don't re-process the filter's fallthrough. 662fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } else { 663fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table.push_back(MCD::OPC_FilterValue); 664fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Encode and emit the value to filter against. 665fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8]; 666fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Len = encodeULEB128(filterIterator->first, Buffer); 667fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table.insert(Table.end(), Buffer, Buffer + Len); 668fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Reserve space for the NumToSkip entry. We'll backpatch the value 669fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // later. 670fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PrevFilter = Table.size(); 671fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table.push_back(0); 672fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table.push_back(0); 673fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 674d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 675d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We arrive at a category of instructions with the same segment value. 676d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Now delegate to the sub filter chooser for further decodings. 677d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The case may fallthrough, which happens if the remaining well-known 678d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // encoding bits do not match exactly. 679fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach filterIterator->second->emitTableEntries(TableInfo); 680fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 681fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Now that we've emitted the body of the handler, update the NumToSkip 682fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // of the filter itself to be able to skip forward when false. Subtract 683fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // two as to account for the width of the NumToSkip field itself. 684fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (PrevFilter) { 685fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t NumToSkip = Table.size() - PrevFilter - 2; 686fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(NumToSkip < 65536U && "disassembler decoding table too large!"); 687fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table[PrevFilter] = (uint8_t)NumToSkip; 688fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8); 689fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 690d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 691d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 692fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Any remaining unresolved fixups bubble up to the parent fixup scope. 693fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!"); 694fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1; 695fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FixupScopeList::iterator Dest = Source - 1; 696fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Dest->insert(Dest->end(), Source->begin(), Source->end()); 697fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.pop_back(); 698fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 699fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // If there is no fallthrough, then the final filter should get fixed 700fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // up according to the enclosing scope rather than the current position. 701fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!HasFallthrough) 702fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.back().push_back(PrevFilter); 703d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 704d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 705d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns the number of fanout produced by the filter. More fanout implies 706d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// the filter distinguishes more categories of instructions. 707d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonunsigned Filter::usefulness() const { 708d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (VariableInstructions.size()) 709d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return FilteredInstructions.size(); 710d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 711d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return FilteredInstructions.size() + 1; 712d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 713d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 714d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson////////////////////////////////// 715d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 716d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Filterchooser Implementation // 717d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 718d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson////////////////////////////////// 719d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 720fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emit the decoder state machine table. 721fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 722fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable &Table, 723fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation, 724fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned BitWidth, 725fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach StringRef Namespace) const { 726fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace 727fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << BitWidth << "[] = {\n"; 728fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 729fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation += 2; 730fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 731fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // FIXME: We may be able to use the NumToSkip values to recover 732fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // appropriate indentation levels. 733fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable::const_iterator I = Table.begin(); 734fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable::const_iterator E = Table.end(); 735fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach while (I != E) { 736fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert (I < E && "incomplete decode table entry!"); 737fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 738fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint64_t Pos = I - Table.begin(); 739fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "/* " << Pos << " */"; 740fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.PadToColumn(12); 741fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 742fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach switch (*I) { 743fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach default: 744fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach throw "invalid decode table opcode"; 745fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_ExtractField: { 746fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 747fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Start = *I++; 748fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Len = *I++; 749fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", " 750fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << Len << ", // Inst{"; 751fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Len > 1) 752fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << (Start + Len - 1) << "-"; 753fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << Start << "} ...\n"; 754fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 755fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 756fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_FilterValue: { 757fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 758fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_FilterValue, "; 759fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The filter value is ULEB128 encoded. 760fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach while (*I >= 128) 761fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 762fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 763fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 764fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // 16-bit numtoskip value. 765fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Byte = *I++; 766fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t NumToSkip = Byte; 767fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 768fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Byte = *I++; 769fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 770fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumToSkip |= Byte << 8; 771fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 772fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 773fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 774fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_CheckField: { 775fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 776fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Start = *I++; 777fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Len = *I++; 778fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", " 779fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << Len << ", ";// << Val << ", " << NumToSkip << ",\n"; 780fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // ULEB128 encoded field value. 781fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (; *I >= 128; ++I) 782fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I) << ", "; 783fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 784fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // 16-bit numtoskip value. 785fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Byte = *I++; 786fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t NumToSkip = Byte; 787fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 788fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Byte = *I++; 789fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 790fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumToSkip |= Byte << 8; 791fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 792fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 793fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 794fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_CheckPredicate: { 795fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 796fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_CheckPredicate, "; 797fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (; *I >= 128; ++I) 798fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I) << ", "; 799fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 800fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 801fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // 16-bit numtoskip value. 802fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Byte = *I++; 803fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t NumToSkip = Byte; 804fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 805fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Byte = *I++; 806fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 807fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumToSkip |= Byte << 8; 808fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 809fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 810fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 811fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_Decode: { 812fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 813fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Extract the ULEB128 encoded Opcode to a buffer. 814fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8], *p = Buffer; 815fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach while ((*p++ = *I++) >= 128) 816fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert((p - Buffer) <= (ptrdiff_t)sizeof(Buffer) 817fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach && "ULEB128 value too large!"); 818fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Decode the Opcode value. 819fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc = decodeULEB128(Buffer); 820fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_Decode, "; 821fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (p = Buffer; *p >= 128; ++p) 822fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*p) << ", "; 823fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*p) << ", "; 824fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 825fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Decoder index. 826fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (; *I >= 128; ++I) 827fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I) << ", "; 828fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 829fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 830fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Opcode: " 831fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << NumberedInstructions->at(Opc)->TheDef->getName() << "\n"; 832fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 833fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 834fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_SoftFail: { 835fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 836fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_SoftFail"; 837fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Positive mask 838fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint64_t Value = 0; 839fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Shift = 0; 840fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach do { 841fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << ", " << utostr(*I); 842fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Value += (*I & 0x7f) << Shift; 843fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Shift += 7; 844fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } while (*I++ >= 128); 845fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Value > 127) 846fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << " /* 0x" << utohexstr(Value) << " */"; 847fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Negative mask 848fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Value = 0; 849fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Shift = 0; 850fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach do { 851fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << ", " << utostr(*I); 852fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Value += (*I & 0x7f) << Shift; 853fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Shift += 7; 854fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } while (*I++ >= 128); 855fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Value > 127) 856fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << " /* 0x" << utohexstr(Value) << " */"; 857fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << ",\n"; 858fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 859fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 860fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_Fail: { 861fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 862fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_Fail,\n"; 863fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 864fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 865fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 866fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 867fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "0\n"; 868fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 869fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation -= 2; 870fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 871fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "};\n\n"; 872fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 873fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 874fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FixedLenDecoderEmitter:: 875fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim GrosbachemitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, 876fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const { 877fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The predicate function is just a big switch statement based on the 878fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // input predicate index. 879fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, " 880fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "uint64_t Bits) {\n"; 881fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation += 2; 882fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "switch (Idx) {\n"; 883fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; 884fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Index = 0; 885fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (PredicateSet::const_iterator I = Predicates.begin(), E = Predicates.end(); 886fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach I != E; ++I, ++Index) { 887fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "case " << Index << ":\n"; 888fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation+2) << "return (" << *I << ");\n"; 889fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 890fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n"; 891fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation -= 2; 892fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n\n"; 893fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 894fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 895fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FixedLenDecoderEmitter:: 896fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim GrosbachemitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, 897fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const { 898fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The decoder function is just a big switch statement based on the 899fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // input decoder index. 900fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "template<typename InsnType>\n"; 901fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S," 902fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Idx, InsnType insn, MCInst &MI,\n"; 903fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << " uint64_t " 90495d235ddb62805923f2f64edd71b15b904ee4a16Benjamin Kramer << "Address, const void *Decoder) {\n"; 905fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation += 2; 906fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "InsnType tmp;\n"; 907fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "switch (Idx) {\n"; 908fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; 909fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Index = 0; 910fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (DecoderSet::const_iterator I = Decoders.begin(), E = Decoders.end(); 911fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach I != E; ++I, ++Index) { 912fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "case " << Index << ":\n"; 913c056483fc6cfab4307559afb0538323781b28d53Craig Topper OS << *I; 914fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation+2) << "return S;\n"; 915fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 916fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n"; 917fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation -= 2; 918fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n\n"; 919d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 920d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 921d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Populates the field of the insn given the start position and the number of 922d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// consecutive bits to scan for. 923d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 924d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns false if and on the first uninitialized bit value encountered. 925d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns true, otherwise. 926d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn, 927eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned StartBit, unsigned NumBits) const { 928d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Field = 0; 929d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 930d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < NumBits; ++i) { 931d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Insn[StartBit + i] == BIT_UNSET) 932d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 933d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 934d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Insn[StartBit + i] == BIT_TRUE) 935d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Field = Field | (1ULL << i); 936d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 937d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 938d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 939d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 940d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 941d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpFilterArray - dumpFilterArray prints out debugging info for the given 942d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// filter array as a series of chars. 943d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::dumpFilterArray(raw_ostream &o, 944eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::vector<bit_value_t> &filter) const { 9458cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) { 946d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (filter[bitIndex - 1]) { 947d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNFILTERED: 948d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "."; 949d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 950d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNSET: 951d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "_"; 952d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 953d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_TRUE: 954d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "1"; 955d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 956d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_FALSE: 957d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "0"; 958d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 959d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 960d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 961d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 962d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 963d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpStack - dumpStack traverses the filter chooser chain and calls 964d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpFilterArray on each filter chooser up to the top level one. 965eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const { 966eb5cd610700661bc46c660640c36949033247d2dCraig Topper const FilterChooser *current = this; 967d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 968d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson while (current) { 969d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << prefix; 970d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpFilterArray(o, current->FilterBitValues); 971d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << '\n'; 972d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson current = current->Parent; 973d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 974d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 975d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 976d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Called from Filter::recurse() when singleton exists. For debug purpose. 977eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::SingletonExists(unsigned Opc) const { 978d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn0; 979d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn0, Opc); 980d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 981d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "Singleton exists: " << nameWithID(Opc) 982d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson << " with its decoding dominating "; 983d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); ++i) { 984d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Opcodes[i] == Opc) continue; 985d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << nameWithID(Opcodes[i]) << ' '; 986d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 987d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 988d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 989d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpStack(errs(), "\t\t"); 990d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper for (unsigned i = 0; i < Opcodes.size(); ++i) { 991d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &Name = nameWithID(Opcodes[i]); 992d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 993d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\t' << Name << " "; 994d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), 995d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 996d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 997d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 998d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 999d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1000d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Calculates the island(s) needed to decode the instruction. 1001d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// This returns a list of undecoded bits of an instructions, for example, 1002d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 1003d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// decoded bits in order to verify that the instruction matches the Opcode. 1004d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonunsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits, 1005d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::vector<unsigned> &EndBits, 1006d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::vector<uint64_t> &FieldVals, 1007eb5cd610700661bc46c660640c36949033247d2dCraig Topper const insn_t &Insn) const { 1008d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Num, BitNo; 1009d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Num = BitNo = 0; 1010d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1011d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson uint64_t FieldVal = 0; 1012d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1013d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 0: Init 1014d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1: Water (the bit value does not affect decoding) 1015d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 2: Island (well-known bit value needed for decoding) 1016d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int State = 0; 1017d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int Val = -1; 1018d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1019f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (unsigned i = 0; i < BitWidth; ++i) { 1020d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Val = Value(Insn[i]); 1021d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool Filtered = PositionFiltered(i); 1022d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (State) { 1023655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper default: llvm_unreachable("Unreachable code!"); 1024d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 0: 1025d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 1: 1026d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Filtered || Val == -1) 1027d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 1; // Still in Water 1028d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else { 1029d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 2; // Into the Island 1030d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitNo = 0; 1031d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBits.push_back(i); 1032d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVal = Val; 1033d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1034d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1035d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 2: 1036d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Filtered || Val == -1) { 1037d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 1; // Into the Water 1038d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson EndBits.push_back(i - 1); 1039d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.push_back(FieldVal); 1040d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Num; 1041d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } else { 1042d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 2; // Still in Island 1043d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++BitNo; 1044d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVal = FieldVal | Val << BitNo; 1045d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1046d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1047d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1048d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1049d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we are still in Island after the loop, do some housekeeping. 1050d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (State == 2) { 1051f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson EndBits.push_back(BitWidth - 1); 1052d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.push_back(FieldVal); 1053d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Num; 1054d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1055d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1056d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(StartBits.size() == Num && EndBits.size() == Num && 1057d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.size() == Num); 1058d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return Num; 1059d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1060d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1061d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Andersonvoid FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, 1062eb5cd610700661bc46c660640c36949033247d2dCraig Topper const OperandInfo &OpInfo) const { 1063eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::string &Decoder = OpInfo.Decoder; 1064d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1065d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (OpInfo.numFields() == 1) { 1066eb5cd610700661bc46c660640c36949033247d2dCraig Topper OperandInfo::const_iterator OI = OpInfo.begin(); 1067c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "tmp = fieldFromInstruction" 1068fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "(insn, " << OI->Base << ", " << OI->Width 1069fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << ");\n"; 1070d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } else { 1071c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "tmp = 0;\n"; 1072eb5cd610700661bc46c660640c36949033247d2dCraig Topper for (OperandInfo::const_iterator OI = OpInfo.begin(), OE = OpInfo.end(); 1073d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OI != OE; ++OI) { 1074c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "tmp |= (fieldFromInstruction" 1075ed968a9a045cb6fecb80abfb7e938954fed54927Andrew Trick << "(insn, " << OI->Base << ", " << OI->Width 1076d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson << ") << " << OI->Offset << ");\n"; 1077d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1078d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1079d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1080d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Decoder != "") 1081c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << Emitter->GuardPrefix << Decoder 10829c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach << "(MI, tmp, Address, Decoder)" 10839c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach << Emitter->GuardPostfix << "\n"; 1084d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson else 1085c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "MI.addOperand(MCOperand::CreateImm(tmp));\n"; 1086d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1087d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson} 1088d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1089fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation, 1090fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1091fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach std::map<unsigned, std::vector<OperandInfo> >::const_iterator OpIter = 1092fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Operands.find(Opc); 1093fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const std::vector<OperandInfo>& InsnOperands = OpIter->second; 1094fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (std::vector<OperandInfo>::const_iterator 1095fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) { 1096fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // If a custom instruction decoder was specified, use that. 1097fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (I->numFields() == 0 && I->Decoder.size()) { 1098c056483fc6cfab4307559afb0538323781b28d53Craig Topper OS.indent(Indentation) << Emitter->GuardPrefix << I->Decoder 1099fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "(MI, insn, Address, Decoder)" 1100fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << Emitter->GuardPostfix << "\n"; 1101fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 1102fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1103fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1104fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitBinaryParser(OS, Indentation, *I); 1105fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1106fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1107fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1108fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachunsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, 1109fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1110fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Build up the predicate string. 1111fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<256> Decoder; 1112fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // FIXME: emitDecoder() function can take a buffer directly rather than 1113fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // a stream. 1114fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(Decoder); 1115c056483fc6cfab4307559afb0538323781b28d53Craig Topper unsigned I = 4; 1116fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecoder(S, I, Opc); 1117fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1118fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1119fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Using the full decoder string as the key value here is a bit 1120fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // heavyweight, but is effective. If the string comparisons become a 1121fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // performance concern, we can implement a mangling of the predicate 1122fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // data easilly enough with a map back to the actual string. That's 1123fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // overkill for now, though. 1124fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1125fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Make sure the predicate is in the table. 1126fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Decoders.insert(Decoder.str()); 1127fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Now figure out the index for when we write out the table. 1128fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderSet::const_iterator P = std::find(Decoders.begin(), 1129fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Decoders.end(), 1130fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Decoder.str()); 1131fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return (unsigned)(P - Decoders.begin()); 1132fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1133fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1134a5d585685493d85d5cb72b831a68ec747ae55a86James Molloystatic void emitSinglePredicateMatch(raw_ostream &o, StringRef str, 1135eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::string &PredicateNamespace) { 113622b4c819d463da7eadb20162d049ee89de746bceAndrew Trick if (str[0] == '!') 113722b4c819d463da7eadb20162d049ee89de746bceAndrew Trick o << "!(Bits & " << PredicateNamespace << "::" 113822b4c819d463da7eadb20162d049ee89de746bceAndrew Trick << str.slice(1,str.size()) << ")"; 1139a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy else 114022b4c819d463da7eadb20162d049ee89de746bceAndrew Trick o << "(Bits & " << PredicateNamespace << "::" << str << ")"; 1141a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy} 1142a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1143a5d585685493d85d5cb72b831a68ec747ae55a86James Molloybool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 1144eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned Opc) const { 11459c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach ListInit *Predicates = 11469c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); 1147a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy for (unsigned i = 0; i < Predicates->getSize(); ++i) { 1148a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy Record *Pred = Predicates->getElementAsRecord(i); 1149a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (!Pred->getValue("AssemblerMatcherPredicate")) 1150a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy continue; 1151a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1152a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::string P = Pred->getValueAsString("AssemblerCondString"); 1153a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1154a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (!P.length()) 1155a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy continue; 1156a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1157a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (i != 0) 1158a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 1159a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1160a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy StringRef SR(P); 1161a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::pair<StringRef, StringRef> pairs = SR.split(','); 1162a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy while (pairs.second.size()) { 1163a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); 1164a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 1165a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy pairs = pairs.second.split(','); 1166a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 1167a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); 1168a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 1169a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy return Predicates->getSize() > 0; 1170ed968a9a045cb6fecb80abfb7e938954fed54927Andrew Trick} 1171a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1172fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachbool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const { 1173fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ListInit *Predicates = 1174fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); 1175fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (unsigned i = 0; i < Predicates->getSize(); ++i) { 1176fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Record *Pred = Predicates->getElementAsRecord(i); 1177fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!Pred->getValue("AssemblerMatcherPredicate")) 1178fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach continue; 1179fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1180fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach std::string P = Pred->getValueAsString("AssemblerCondString"); 1181fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1182fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!P.length()) 1183fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach continue; 1184fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1185fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return true; 1186fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1187fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return false; 1188fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1189fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1190fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachunsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo, 1191fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach StringRef Predicate) const { 1192fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Using the full predicate string as the key value here is a bit 1193fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // heavyweight, but is effective. If the string comparisons become a 1194fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // performance concern, we can implement a mangling of the predicate 1195fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // data easilly enough with a map back to the actual string. That's 1196fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // overkill for now, though. 1197fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1198fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Make sure the predicate is in the table. 1199fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Predicates.insert(Predicate.str()); 1200fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Now figure out the index for when we write out the table. 1201fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PredicateSet::const_iterator P = std::find(TableInfo.Predicates.begin(), 1202fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Predicates.end(), 1203fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Predicate.str()); 1204fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return (unsigned)(P - TableInfo.Predicates.begin()); 1205fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1206fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1207fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo, 1208fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1209fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!doesOpcodeNeedPredicate(Opc)) 1210fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1211fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1212fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Build up the predicate string. 1213fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<256> Predicate; 1214fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // FIXME: emitPredicateMatch() functions can take a buffer directly rather 1215fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // than a stream. 1216fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream PS(Predicate); 1217fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned I = 0; 1218fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateMatch(PS, I, Opc); 1219fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1220fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Figure out the index into the predicate table for the predicate just 1221fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // computed. 1222fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned PIdx = getPredicateIndex(TableInfo, PS.str()); 1223fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> PBytes; 1224fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(PBytes); 1225fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(PIdx, S); 1226fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1227fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1228fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_CheckPredicate); 1229fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Predicate index 12308cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = PBytes.size(); i != e; ++i) 1231fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(PBytes[i]); 1232fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Push location for NumToSkip backpatching. 1233fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 1234fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1235fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1236fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1237fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1238fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo, 1239fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 12409c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach BitsInit *SFBits = 12419c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach AllInstructions[Opc]->TheDef->getValueAsBitsInit("SoftFail"); 12423015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (!SFBits) return; 12433015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy BitsInit *InstBits = AllInstructions[Opc]->TheDef->getValueAsBitsInit("Inst"); 12443015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12453015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy APInt PositiveMask(BitWidth, 0ULL); 12463015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy APInt NegativeMask(BitWidth, 0ULL); 12473015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy for (unsigned i = 0; i < BitWidth; ++i) { 12483015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bit_value_t B = bitFromBits(*SFBits, i); 12493015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bit_value_t IB = bitFromBits(*InstBits, i); 12503015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12513015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (B != BIT_TRUE) continue; 12523015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12533015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy switch (IB) { 12543015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy case BIT_FALSE: 12553015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is meant to be false, so emit a check to see if it is true. 12563015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy PositiveMask.setBit(i); 12573015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy break; 12583015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy case BIT_TRUE: 12593015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is meant to be true, so emit a check to see if it is false. 12603015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy NegativeMask.setBit(i); 12613015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy break; 12623015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy default: 12633015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is not set; this must be an error! 12643015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy StringRef Name = AllInstructions[Opc]->TheDef->getName(); 1265fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in " << Name 1266fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " is set but Inst{" << i << "} is unset!\n" 12673015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy << " - You can only mark a bit as SoftFail if it is fully defined" 12683015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy << " (1/0 - not '?') in Inst\n"; 1269fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 12703015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy } 12713015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy } 12723015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12733015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bool NeedPositiveMask = PositiveMask.getBoolValue(); 12743015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bool NeedNegativeMask = NegativeMask.getBoolValue(); 12753015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12763015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (!NeedPositiveMask && !NeedNegativeMask) 12773015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy return; 12783015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 1279fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_SoftFail); 1280fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1281fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> MaskBytes; 1282fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(MaskBytes); 1283fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (NeedPositiveMask) { 1284fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(PositiveMask.getZExtValue(), S); 1285fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 12868cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i) 1287fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MaskBytes[i]); 1288fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } else 1289fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1290fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (NeedNegativeMask) { 1291fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach MaskBytes.clear(); 1292fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.resync(); 1293fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(NegativeMask.getZExtValue(), S); 1294fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 12958cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i) 1296fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MaskBytes[i]); 1297fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } else 1298fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 12993015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy} 13003015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 1301fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emits table entries to decode the singleton. 1302fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo, 1303fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1304d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> StartBits; 1305d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> EndBits; 1306d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<uint64_t> FieldVals; 1307d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 1308d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn, Opc); 1309d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1310d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Look for islands of undecoded bits of the singleton. 1311d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getIslands(StartBits, EndBits, FieldVals, Insn); 1312d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1313d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Size = StartBits.size(); 1314d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1315fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the predicate table entry if one is needed. 1316fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateTableEntry(TableInfo, Opc); 1317d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1318fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Check any additional encoding fields needed. 13198cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned I = Size; I != 0; --I) { 13208cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper unsigned NumBits = EndBits[I-1] - StartBits[I-1] + 1; 1321fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_CheckField); 1322fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(StartBits[I-1]); 1323fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(NumBits); 1324fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8], *p; 1325fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(FieldVals[I-1], Buffer); 1326fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (p = Buffer; *p >= 128 ; ++p) 1327fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1328fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1329fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Push location for NumToSkip backpatching. 1330fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 1331fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The fixup is always 16-bits, so go ahead and allocate the space 1332fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // in the table so all our relative position calculations work OK even 1333fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // before we fully resolve the real value here. 1334fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1335fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1336d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1337d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1338fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Check for soft failure of the match. 1339fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSoftFailTableEntry(TableInfo, Opc); 1340fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1341fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_Decode); 1342fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8], *p; 1343fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(Opc, Buffer); 1344fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (p = Buffer; *p >= 128 ; ++p) 1345fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1346fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1347fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1348fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned DIdx = getDecoderIndex(TableInfo.Decoders, Opc); 1349fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> Bytes; 1350fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(Bytes); 1351fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(DIdx, S); 1352fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1353fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1354fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Decoder index 13558cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = Bytes.size(); i != e; ++i) 1356fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(Bytes[i]); 1357d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1358d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1359fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emits table entries to decode the singleton, and then to decode the rest. 1360fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo, 1361fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const Filter &Best) const { 1362d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Opc = Best.getSingletonOpc(); 1363d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1364fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // complex singletons need predicate checks from the first singleton 1365fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // to refer forward to the variable filterchooser that follows. 1366fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.push_back(FixupList()); 1367d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1368fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Opc); 1369d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1370fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(), 1371fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.size()); 1372fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.pop_back(); 1373fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1374fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Best.getVariableFC().emitTableEntries(TableInfo); 1375d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1376d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1377fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1378d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Assign a single filter and run with it. Top level API client can initialize 1379d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// with a single filter to start the filtering process. 1380eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit, 1381eb5cd610700661bc46c660640c36949033247d2dCraig Topper bool mixed) { 1382d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.clear(); 1383d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter F(*this, startBit, numBit, true); 1384d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(F); 1385d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = 0; // Sole Filter instance to choose from. 1386d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().recurse(); 1387d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1388d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1389d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// reportRegion is a helper function for filterProcessor to mark a region as 1390d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// eligible for use as a filter region. 1391d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit, 1392d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper unsigned BitIndex, bool AllowMixed) { 1393d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (RA == ATTR_MIXED && AllowMixed) 1394d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, true)); 1395d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else if (RA == ATTR_ALL_SET && !AllowMixed) 1396d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, false)); 1397d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1398d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1399d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// FilterProcessor scans the well-known encoding bits of the instructions and 1400d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// builds up a list of candidate filters. It chooses the best filter and 1401d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// recursively descends down the decoding tree. 1402d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) { 1403d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.clear(); 1404d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = -1; 1405d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned numInstructions = Opcodes.size(); 1406d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1407d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(numInstructions && "Filter created with no instructions"); 1408d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1409d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // No further filtering is necessary. 1410d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (numInstructions == 1) 1411d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1412d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1413d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Heuristics. See also doFilter()'s "Heuristics" comment when num of 1414d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instructions is 3. 1415d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (AllowMixed && !Greedy) { 1416d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(numInstructions == 3); 1417d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1418d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); ++i) { 1419d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> StartBits; 1420d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> EndBits; 1421d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<uint64_t> FieldVals; 1422d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 1423d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1424d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn, Opcodes[i]); 1425d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1426d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Look for islands of undecoded bits of any instruction. 1427d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) { 1428d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Found an instruction with island(s). Now just assign a filter. 1429eb5cd610700661bc46c660640c36949033247d2dCraig Topper runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true); 1430d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1431d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1432d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1433d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1434d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 14358cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper unsigned BitIndex; 1436d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1437d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We maintain BIT_WIDTH copies of the bitAttrs automaton. 1438d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The automaton consumes the corresponding bit from each 1439d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instruction. 1440d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1441d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Input symbols: 0, 1, and _ (unset). 1442d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED. 1443d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Initial state: NONE. 1444d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1445d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ------- [01] -> (ALL_SET) 1446d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ------- _ ----> (ALL_UNSET) 1447d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) ---- [01] -> (ALL_SET) 1448d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) ---- _ ----> (MIXED) 1449d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_UNSET) -- [01] -> (MIXED) 1450d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_UNSET) -- _ ----> (ALL_UNSET) 1451d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ------ . ----> (MIXED) 1452d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (FILTERED)---- . ----> (FILTERED) 1453d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1454f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bitAttr_t> bitAttrs; 1455d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1456d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FILTERED bit positions provide no entropy and are not worthy of pursuing. 1457d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position. 1458f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) 1459d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (FilterBitValues[BitIndex] == BIT_TRUE || 1460d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterBitValues[BitIndex] == BIT_FALSE) 1461f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson bitAttrs.push_back(ATTR_FILTERED); 1462d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1463f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson bitAttrs.push_back(ATTR_NONE); 1464d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 14658cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) { 1466d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t insn; 1467d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1468d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(insn, Opcodes[InsnIndex]); 1469d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1470f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 1471d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttrs[BitIndex]) { 1472d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1473d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] == BIT_UNSET) 1474d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_ALL_UNSET; 1475d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1476d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_ALL_SET; 1477d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1478d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1479d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] == BIT_UNSET) 1480d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_MIXED; 1481d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1482d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1483d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] != BIT_UNSET) 1484d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_MIXED; 1485d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1486d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1487d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1488d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1489d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1490d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1491d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1492d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1493d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The regionAttr automaton consumes the bitAttrs automatons' state, 1494d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // lowest-to-highest. 1495d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1496d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed) 1497d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // States: NONE, ALL_SET, MIXED 1498d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Initial state: NONE 1499d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1500d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- F --> (NONE) 1501d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- S --> (ALL_SET) ; and set region start 1502d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- U --> (NONE) 1503d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- M --> (MIXED) ; and set region start 1504d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region 1505d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- S --> (ALL_SET) 1506d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region 1507d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region 1508d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- F --> (NONE) ; and report a MIXED region 1509d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region 1510d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- U --> (NONE) ; and report a MIXED region 1511d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- M --> (MIXED) 1512d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1513d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttr_t RA = ATTR_NONE; 1514d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned StartBit = 0; 1515d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 15168cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 1517d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttr_t bitAttr = bitAttrs[BitIndex]; 1518d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1519d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(bitAttr != ATTR_NONE && "Bit without attributes"); 1520d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1521d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (RA) { 1522d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1523d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1524d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1525d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1526d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1527d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1528d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_ALL_SET; 1529d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1530d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1531d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1532d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1533d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1534d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_MIXED; 1535d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1536d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1537655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1538d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1539d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1540d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1541d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1542d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1543d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1544d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1545d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1546d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1547d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1548d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1549d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1550d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1551d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1552d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1553d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1554d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1555d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_MIXED; 1556d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1557d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1558655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1559d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1560d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1561d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1562d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1563d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1564d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1565d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1566d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1567d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1568d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1569d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1570d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1571d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_ALL_SET; 1572d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1573d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1574d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1575d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1576d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1577d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1578d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1579d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1580655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1581d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1582d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1583d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1584655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("regionAttr state machine has no ATTR_UNSET state"); 1585d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1586655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state"); 1587d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1588d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1589d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1590d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // At the end, if we're still in ALL_SET or MIXED states, report a region 1591d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (RA) { 1592d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1593d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1594d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1595d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1596d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1597d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1598d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1599d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1600d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1601d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1602d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1603d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1604d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1605d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1606d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We have finished with the filter processings. Now it's time to choose 1607d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the best performing filter. 1608d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = 0; 1609d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool AllUseless = true; 1610d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned BestScore = 0; 1611d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1612d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = Filters.size(); i != e; ++i) { 1613d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Usefulness = Filters[i].usefulness(); 1614d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1615d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Usefulness) 1616d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson AllUseless = false; 1617d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1618d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Usefulness > BestScore) { 1619d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = i; 1620d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestScore = Usefulness; 1621d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1622d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1623d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1624d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (!AllUseless) 1625d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().recurse(); 1626d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1627d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return !AllUseless; 1628d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} // end of FilterChooser::filterProcessor(bool) 1629d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1630d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Decides on the best configuration of filter(s) to use in order to decode 1631d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// the instructions. A conflict of instructions may occur, in which case we 1632d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// dump the conflict set to the standard error. 1633d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::doFilter() { 1634d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Num = Opcodes.size(); 1635d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(Num && "FilterChooser created with no instructions"); 1636d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1637d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Try regions of consecutive known bit values first. 1638d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterProcessor(false)) 1639d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1640d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1641d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Then regions of mixed bits (both known and unitialized bit values allowed). 1642d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterProcessor(true)) 1643d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1644d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1645d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where 1646d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a 1647d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // well-known encoding pattern. In such case, we backtrack and scan for the 1648d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the very first consecutive ATTR_ALL_SET region and assign a filter to it. 1649d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Num == 3 && filterProcessor(true, false)) 1650d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1651d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1652d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we come to here, the instruction decoding has failed. 1653d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set the BestIndex to -1 to indicate so. 1654d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = -1; 1655d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1656d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1657fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitTableEntries - Emit state machine entries to decode our share of 1658fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// instructions. 1659fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const { 1660fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Opcodes.size() == 1) { 1661d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // There is only one instruction in the set, which is great! 1662d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Call emitSingletonDecoder() to see whether there are any remaining 1663d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // encodings bits. 1664fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Opcodes[0]); 1665fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1666fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1667d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1668d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Choose the best filter to do the decodings! 1669d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (BestIndex != -1) { 1670eb5cd610700661bc46c660640c36949033247d2dCraig Topper const Filter &Best = Filters[BestIndex]; 1671d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Best.getNumFiltered() == 1) 1672fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Best); 1673d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1674fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Best.emitTableEntry(TableInfo); 1675fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1676d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1677d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1678fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // We don't know how to decode these instructions! Dump the 1679fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // conflict set and bail. 1680d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1681d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Print out useful conflict information for postmortem analysis. 1682d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "Decoding Conflict:\n"; 1683d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1684d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpStack(errs(), "\t\t"); 1685d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1686d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper for (unsigned i = 0; i < Opcodes.size(); ++i) { 1687d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &Name = nameWithID(Opcodes[i]); 1688d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1689d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\t' << Name << " "; 1690d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), 1691d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 1692d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1693d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1694d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1695d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1696d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topperstatic bool populateInstruction(const CodeGenInstruction &CGI, unsigned Opc, 1697d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::map<unsigned, std::vector<OperandInfo> > &Operands){ 1698d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const Record &Def = *CGI.TheDef; 1699d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If all the bit positions are not specified; do not decode this instruction. 1700d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We are bound to fail! For proper disassembly, the well-known encoding bits 1701d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // of the instruction must be fully specified. 1702d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1703d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // This also removes pseudo instructions from considerations of disassembly, 1704d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // which is a better design and less fragile than the name matchings. 1705d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Ignore "asm parser only" instructions. 17064dd27ebcc2b218630899163504bc2641b9735466Owen Anderson if (Def.getValueAsBit("isAsmParserOnly") || 17074dd27ebcc2b218630899163504bc2641b9735466Owen Anderson Def.getValueAsBit("isCodeGenOnly")) 1708d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 1709d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 171005bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit &Bits = getBitsField(Def, "Inst"); 1711806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach if (Bits.allInComplete()) return false; 1712806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach 1713d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<OperandInfo> InsnOperands; 1714d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1715d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If the instruction has specified a custom decoding hook, use that instead 1716d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // of trying to auto-generate the decoder. 1717d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::string InstDecoder = Def.getValueAsString("DecoderMethod"); 1718d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (InstDecoder != "") { 1719d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson InsnOperands.push_back(OperandInfo(InstDecoder)); 1720d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Operands[Opc] = InsnOperands; 1721d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1722d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1723d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1724d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Generate a description of the operand of the instruction that we know 1725d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // how to decode automatically. 1726d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FIXME: We'll need to have a way to manually override this as needed. 1727d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1728d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Gather the outputs/inputs of the instruction, so we can find their 1729d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // positions in the encoding. This assumes for now that they appear in the 1730d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // MCInst in the order that they're listed. 173105bce0beee87512e52428d4b80f5a8e79a949576David Greene std::vector<std::pair<Init*, std::string> > InOutOperands; 173205bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *Out = Def.getValueAsDag("OutOperandList"); 173305bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *In = Def.getValueAsDag("InOperandList"); 1734d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Out->getNumArgs(); ++i) 1735d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson InOutOperands.push_back(std::make_pair(Out->getArg(i), Out->getArgName(i))); 1736d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < In->getNumArgs(); ++i) 1737d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson InOutOperands.push_back(std::make_pair(In->getArg(i), In->getArgName(i))); 1738d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 173900ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson // Search for tied operands, so that we can correctly instantiate 174000ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson // operands that are not explicitly represented in the encoding. 1741ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson std::map<std::string, std::string> TiedNames; 174200ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson for (unsigned i = 0; i < CGI.Operands.size(); ++i) { 174300ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson int tiedTo = CGI.Operands[i].getTiedRegister(); 1744ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson if (tiedTo != -1) { 1745ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson TiedNames[InOutOperands[i].second] = InOutOperands[tiedTo].second; 1746ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson TiedNames[InOutOperands[tiedTo].second] = InOutOperands[i].second; 1747ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson } 174800ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson } 174900ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson 1750d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // For each operand, see if we can figure out where it is encoded. 17515a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper for (std::vector<std::pair<Init*, std::string> >::const_iterator 1752d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) { 1753d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::string Decoder = ""; 1754d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1755d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // At this point, we can locate the field, but we need to know how to 1756d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // interpret it. As a first step, require the target to provide callbacks 1757d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // for decoding register classes. 1758d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // FIXME: This need to be extended to handle instructions with custom 1759d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // decoder methods, and operands with (simple) MIOperandInfo's. 176005bce0beee87512e52428d4b80f5a8e79a949576David Greene TypedInit *TI = dynamic_cast<TypedInit*>(NI->first); 1761d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType()); 1762d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Record *TypeRecord = Type->getRecord(); 1763d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson bool isReg = false; 1764d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (TypeRecord->isSubClassOf("RegisterOperand")) 1765d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson TypeRecord = TypeRecord->getValueAsDef("RegClass"); 1766d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (TypeRecord->isSubClassOf("RegisterClass")) { 1767d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; 1768d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson isReg = true; 1769d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1770d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1771d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod"); 177205bce0beee87512e52428d4b80f5a8e79a949576David Greene StringInit *String = DecoderString ? 177305bce0beee87512e52428d4b80f5a8e79a949576David Greene dynamic_cast<StringInit*>(DecoderString->getValue()) : 0; 1774d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (!isReg && String && String->getValue() != "") 1775d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Decoder = String->getValue(); 1776d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1777d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OperandInfo OpInfo(Decoder); 1778d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Base = ~0U; 1779d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Width = 0; 1780d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Offset = 0; 1781d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1782d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) { 1783cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson VarInit *Var = 0; 178405bce0beee87512e52428d4b80f5a8e79a949576David Greene VarBitInit *BI = dynamic_cast<VarBitInit*>(Bits.getBit(bi)); 1785cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson if (BI) 1786cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson Var = dynamic_cast<VarInit*>(BI->getVariable()); 1787cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson else 1788cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson Var = dynamic_cast<VarInit*>(Bits.getBit(bi)); 1789cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson 1790cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson if (!Var) { 1791d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) { 1792d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1793d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = ~0U; 1794d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 0; 1795d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Offset = 0; 1796d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1797d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson continue; 1798d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1799d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 180000ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson if (Var->getName() != NI->second && 1801ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson Var->getName() != TiedNames[NI->second]) { 1802d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) { 1803d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1804d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = ~0U; 1805d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 0; 1806d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Offset = 0; 1807d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1808d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson continue; 1809d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1810d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1811d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base == ~0U) { 1812d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = bi; 1813d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 1; 1814cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson Offset = BI ? BI->getBitNum() : 0; 1815cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson } else if (BI && BI->getBitNum() != Offset + Width) { 1816eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson OpInfo.addField(Base, Width, Offset); 1817eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Base = bi; 1818eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Width = 1; 1819eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Offset = BI->getBitNum(); 1820d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } else { 1821d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson ++Width; 1822d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1823d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1824d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1825d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) 1826d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1827d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1828d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (OpInfo.numFields() > 0) 1829d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson InsnOperands.push_back(OpInfo); 1830d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1831d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1832d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Operands[Opc] = InsnOperands; 1833d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1834d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1835d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#if 0 1836d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson DEBUG({ 1837d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Dumps the instruction encoding bits. 1838d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), Bits); 1839d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1840d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1841d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1842d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Dumps the list of operand info. 1843d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { 1844d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const CGIOperandList::OperandInfo &Info = CGI.Operands[i]; 1845d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &OperandName = Info.Name; 1846d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const Record &OperandDef = *Info.Rec; 1847d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1848d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n"; 1849d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1850d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson }); 1851d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#endif 1852d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1853d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1854d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1855d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1856fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitFieldFromInstruction - Emit the templated helper function 1857fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// fieldFromInstruction(). 1858fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstatic void emitFieldFromInstruction(formatted_raw_ostream &OS) { 1859fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Helper function for extracting fields from encoded instructions.\n" 1860fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "template<typename InsnType>\n" 1861fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "static InsnType fieldFromInstruction(InsnType insn, unsigned startBit,\n" 1862fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned numBits) {\n" 1863fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " assert(startBit + numBits <= (sizeof(InsnType)*8) &&\n" 1864fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " \"Instruction field out of bounds!\");\n" 1865fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType fieldMask;\n" 1866fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (numBits == sizeof(InsnType)*8)\n" 1867fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " fieldMask = (InsnType)(-1LL);\n" 1868fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " else\n" 1869fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " fieldMask = ((1 << numBits) - 1) << startBit;\n" 1870fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return (insn & fieldMask) >> startBit;\n" 1871fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "}\n\n"; 1872fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1873f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1874fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitDecodeInstruction - Emit the templated helper function 1875fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// decodeInstruction(). 1876fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstatic void emitDecodeInstruction(formatted_raw_ostream &OS) { 1877fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "template<typename InsnType>\n" 1878fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,\n" 1879fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType insn, uint64_t Address,\n" 1880fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const void *DisAsm,\n" 1881fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const MCSubtargetInfo &STI) {\n" 1882fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " uint64_t Bits = STI.getFeatureBits();\n" 1883fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1884fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const uint8_t *Ptr = DecodeTable;\n" 1885fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " uint32_t CurFieldValue;\n" 1886fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DecodeStatus S = MCDisassembler::Success;\n" 1887fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " for (;;) {\n" 1888fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " ptrdiff_t Loc = Ptr - DecodeTable;\n" 1889fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " switch (*Ptr) {\n" 1890fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " default:\n" 1891fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " errs() << Loc << \": Unexpected decode table opcode!\\n\";\n" 1892fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return MCDisassembler::Fail;\n" 1893fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_ExtractField: {\n" 1894fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Start = *++Ptr;\n" 1895fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len = *++Ptr;\n" 1896fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " ++Ptr;\n" 1897fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\n" 1898fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_ExtractField(\" << Start << \", \"\n" 1899fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << Len << \"): \" << CurFieldValue << \"\\n\");\n" 1900fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1901fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1902fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_FilterValue: {\n" 1903fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the field value.\n" 1904fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 1905fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType Val = decodeULEB128(++Ptr, &Len);\n" 1906fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1907fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 1908fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 1909fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 1910fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1911fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Perform the filter operation.\n" 1912fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (Val != CurFieldValue)\n" 1913fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 1914fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_FilterValue(\" << Val << \", \" << NumToSkip\n" 1915fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \"): \" << ((Val != CurFieldValue) ? \"FAIL:\" : \"PASS:\")\n" 1916fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \" continuing at \" << (Ptr - DecodeTable) << \"\\n\");\n" 1917fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1918fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1919fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1920fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_CheckField: {\n" 1921fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Start = *++Ptr;\n" 1922fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len = *++Ptr;\n" 1923fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\n" 1924fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the field value.\n" 1925fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\n" 1926fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1927fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 1928fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 1929fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 1930fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1931fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // If the actual and expected values don't match, skip.\n" 1932fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (ExpectedValue != FieldValue)\n" 1933fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 1934fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_CheckField(\" << Start << \", \"\n" 1935fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << Len << \", \" << ExpectedValue << \", \" << NumToSkip\n" 1936fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \"): FieldValue = \" << FieldValue << \", ExpectedValue = \"\n" 1937fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << ExpectedValue << \": \"\n" 1938fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << ((ExpectedValue == FieldValue) ? \"PASS\\n\" : \"FAIL\\n\"));\n" 1939fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1940fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1941fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_CheckPredicate: {\n" 1942fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 1943fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the Predicate Index value.\n" 1944fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\n" 1945fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1946fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 1947fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 1948fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 1949fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Check the predicate.\n" 1950fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " bool Pred;\n" 1951fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\n" 1952fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 1953fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " (void)Pred;\n" 1954fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_CheckPredicate(\" << PIdx << \"): \"\n" 1955fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << (Pred ? \"PASS\\n\" : \"FAIL\\n\"));\n" 1956fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1957fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1958fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1959fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_Decode: {\n" 1960fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 1961fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the Opcode value.\n" 1962fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Opc = decodeULEB128(++Ptr, &Len);\n" 1963fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1964fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n" 1965fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1966fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_Decode: opcode \" << Opc\n" 1967fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \", using decoder \" << DecodeIdx << \"\\n\" );\n" 1968fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << \"----- DECODE SUCCESSFUL -----\\n\");\n" 1969fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1970fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " MI.setOpcode(Opc);\n" 197195d235ddb62805923f2f64edd71b15b904ee4a16Benjamin Kramer << " return decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm);\n" 1972fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1973fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_SoftFail: {\n" 1974fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the mask values.\n" 1975fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 1976fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\n" 1977fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1978fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\n" 1979fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1980fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " bool Fail = (insn & PositiveMask) || (~insn & NegativeMask);\n" 1981fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (Fail)\n" 1982fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " S = MCDisassembler::SoftFail;\n" 1983fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_SoftFail: \" << (Fail ? \"FAIL\\n\":\"PASS\\n\"));\n" 1984fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1985fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1986fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_Fail: {\n" 1987fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_Fail\\n\");\n" 1988fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return MCDisassembler::Fail;\n" 1989fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1990fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1991fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1992fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " llvm_unreachable(\"bogosity detected in disassembler state machine!\");\n" 1993fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "}\n\n"; 1994d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1995d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1996d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emits disassembler code for instruction decoding. 1997d936045625ae2e101d3a9544586d7568c6dbacc0Craig Toppervoid FixedLenDecoderEmitter::run(raw_ostream &o) { 1998fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach formatted_raw_ostream OS(o); 1999fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/MC/MCInst.h\"\n"; 2000fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/Debug.h\"\n"; 2001fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/DataTypes.h\"\n"; 2002fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/LEB128.h\"\n"; 2003fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/raw_ostream.h\"\n"; 2004fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include <assert.h>\n"; 2005fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << '\n'; 2006fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "namespace llvm {\n\n"; 2007fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2008fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitFieldFromInstruction(OS); 2009d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 2010f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Parameterize the decoders based on namespace and instruction width. 2011fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumberedInstructions = &Target.getInstructionsByEnumValue(); 2012f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<std::pair<std::string, unsigned>, 2013f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<unsigned> > OpcMap; 2014f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<unsigned, std::vector<OperandInfo> > Operands; 2015f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2016fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (unsigned i = 0; i < NumberedInstructions->size(); ++i) { 2017fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const CodeGenInstruction *Inst = NumberedInstructions->at(i); 2018eb5cd610700661bc46c660640c36949033247d2dCraig Topper const Record *Def = Inst->TheDef; 2019f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned Size = Def->getValueAsInt("Size"); 2020f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (Def->getValueAsString("Namespace") == "TargetOpcode" || 2021f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isPseudo") || 2022f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isAsmParserOnly") || 2023f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isCodeGenOnly")) 2024f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson continue; 2025f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2026f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::string DecoderNamespace = Def->getValueAsString("DecoderNamespace"); 2027f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2028f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (Size) { 2029f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (populateInstruction(*Inst, i, Operands)) { 2030f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i); 2031f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2032f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2033f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2034f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2035fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTableInfo TableInfo; 2036f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::set<unsigned> Sizes; 2037f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (std::map<std::pair<std::string, unsigned>, 2038eb5cd610700661bc46c660640c36949033247d2dCraig Topper std::vector<unsigned> >::const_iterator 2039f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson I = OpcMap.begin(), E = OpcMap.end(); I != E; ++I) { 2040f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Emit the decoder for this namespace+width combination. 2041fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FilterChooser FC(*NumberedInstructions, I->second, Operands, 204283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson 8*I->first.second, this); 2043fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2044fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The decode table is cleared for each top level decoder function. The 2045fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // predicates and decoders themselves, however, are shared across all 2046fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // decoders to give more opportunities for uniqueing. 2047fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.clear(); 2048fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.clear(); 2049fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.reserve(16384); 2050fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.push_back(FixupList()); 2051fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FC.emitTableEntries(TableInfo); 2052fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Any NumToSkip fixups in the top level scope can resolve to the 2053fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // OPC_Fail at the end of the table. 2054fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!"); 2055fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Resolve any NumToSkip fixups in the current scope. 2056fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(), 2057fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.size()); 2058fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.clear(); 2059fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2060fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_Fail); 2061fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2062fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Print the table to the output stream. 2063fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), I->first.first); 2064fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.flush(); 2065f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2066d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 2067fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the predicate function. 2068fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateFunction(OS, TableInfo.Predicates, 0); 2069fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2070fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the decoder function. 2071fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecoderFunction(OS, TableInfo.Decoders, 0); 2072fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2073fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the main entry point for the decoder, decodeInstruction(). 2074fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecodeInstruction(OS); 2075fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2076fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "\n} // End llvm namespace\n"; 2077d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 20786f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 20796f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 20806f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 20816f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS, 20826f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string PredicateNamespace, 20836f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPrefix, 20846f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPostfix, 20856f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string ROK, 20866f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string RFail, 20876f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string L) { 20886f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen FixedLenDecoderEmitter(RK, PredicateNamespace, GPrefix, GPostfix, 20896f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen ROK, RFail, L).run(OS); 20906f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} 20916f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 20926f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 2093