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" 183015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy#include "llvm/ADT/APInt.h" 19fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/SmallString.h" 20d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/ADT/StringExtras.h" 21fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/StringRef.h" 22fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/Twine.h" 23fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/MC/MCFixedLenDisassembler.h" 246f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/Support/DataTypes.h" 25d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/Support/Debug.h" 26fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/Support/FormattedStream.h" 27fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/Support/LEB128.h" 28d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/Support/raw_ostream.h" 294ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/TableGen/Error.h" 304ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/TableGen/Record.h" 316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 32d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <map> 33d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <string> 344ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include <vector> 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) { 1456cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (BitInit *bit = dyn_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: 74461131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError("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; 88254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman if (!Predicates.empty()) { 88354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "switch (Idx) {\n"; 88454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; 88554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman unsigned Index = 0; 88654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman for (PredicateSet::const_iterator I = Predicates.begin(), E = Predicates.end(); 88754911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman I != E; ++I, ++Index) { 88854911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "case " << Index << ":\n"; 88954911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation+2) << "return (" << *I << ");\n"; 89054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman } 89154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "}\n"; 89254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman } else { 89354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman // No case statement to emit 89454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n"; 895fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 896fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation -= 2; 897fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n\n"; 898fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 899fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 900fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FixedLenDecoderEmitter:: 901fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim GrosbachemitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, 902fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const { 903fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The decoder function is just a big switch statement based on the 904fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // input decoder index. 905fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "template<typename InsnType>\n"; 906fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S," 907fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Idx, InsnType insn, MCInst &MI,\n"; 908fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << " uint64_t " 90995d235ddb62805923f2f64edd71b15b904ee4a16Benjamin Kramer << "Address, const void *Decoder) {\n"; 910fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation += 2; 911fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "InsnType tmp;\n"; 912fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "switch (Idx) {\n"; 913fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; 914fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Index = 0; 915fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (DecoderSet::const_iterator I = Decoders.begin(), E = Decoders.end(); 916fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach I != E; ++I, ++Index) { 917fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "case " << Index << ":\n"; 918c056483fc6cfab4307559afb0538323781b28d53Craig Topper OS << *I; 919fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation+2) << "return S;\n"; 920fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 921fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n"; 922fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation -= 2; 923fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n\n"; 924d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 925d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 926d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Populates the field of the insn given the start position and the number of 927d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// consecutive bits to scan for. 928d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 929d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns false if and on the first uninitialized bit value encountered. 930d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns true, otherwise. 931d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn, 932eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned StartBit, unsigned NumBits) const { 933d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Field = 0; 934d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 935d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < NumBits; ++i) { 936d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Insn[StartBit + i] == BIT_UNSET) 937d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 938d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 939d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Insn[StartBit + i] == BIT_TRUE) 940d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Field = Field | (1ULL << i); 941d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 942d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 943d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 944d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 945d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 946d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpFilterArray - dumpFilterArray prints out debugging info for the given 947d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// filter array as a series of chars. 948d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::dumpFilterArray(raw_ostream &o, 949eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::vector<bit_value_t> &filter) const { 9508cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) { 951d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (filter[bitIndex - 1]) { 952d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNFILTERED: 953d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "."; 954d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 955d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNSET: 956d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "_"; 957d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 958d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_TRUE: 959d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "1"; 960d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 961d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_FALSE: 962d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "0"; 963d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 964d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 965d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 966d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 967d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 968d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpStack - dumpStack traverses the filter chooser chain and calls 969d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpFilterArray on each filter chooser up to the top level one. 970eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const { 971eb5cd610700661bc46c660640c36949033247d2dCraig Topper const FilterChooser *current = this; 972d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 973d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson while (current) { 974d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << prefix; 975d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpFilterArray(o, current->FilterBitValues); 976d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << '\n'; 977d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson current = current->Parent; 978d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 979d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 980d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 981d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Called from Filter::recurse() when singleton exists. For debug purpose. 982eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::SingletonExists(unsigned Opc) const { 983d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn0; 984d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn0, Opc); 985d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 986d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "Singleton exists: " << nameWithID(Opc) 987d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson << " with its decoding dominating "; 988d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); ++i) { 989d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Opcodes[i] == Opc) continue; 990d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << nameWithID(Opcodes[i]) << ' '; 991d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 992d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 993d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 994d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpStack(errs(), "\t\t"); 995d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper for (unsigned i = 0; i < Opcodes.size(); ++i) { 996d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &Name = nameWithID(Opcodes[i]); 997d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 998d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\t' << Name << " "; 999d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), 1000d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 1001d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1002d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1003d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1004d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1005d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Calculates the island(s) needed to decode the instruction. 1006d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// This returns a list of undecoded bits of an instructions, for example, 1007d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 1008d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// decoded bits in order to verify that the instruction matches the Opcode. 1009d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonunsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits, 1010d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::vector<unsigned> &EndBits, 1011d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::vector<uint64_t> &FieldVals, 1012eb5cd610700661bc46c660640c36949033247d2dCraig Topper const insn_t &Insn) const { 1013d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Num, BitNo; 1014d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Num = BitNo = 0; 1015d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1016d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson uint64_t FieldVal = 0; 1017d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1018d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 0: Init 1019d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1: Water (the bit value does not affect decoding) 1020d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 2: Island (well-known bit value needed for decoding) 1021d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int State = 0; 1022d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int Val = -1; 1023d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1024f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (unsigned i = 0; i < BitWidth; ++i) { 1025d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Val = Value(Insn[i]); 1026d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool Filtered = PositionFiltered(i); 1027d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (State) { 1028655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper default: llvm_unreachable("Unreachable code!"); 1029d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 0: 1030d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 1: 1031d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Filtered || Val == -1) 1032d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 1; // Still in Water 1033d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else { 1034d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 2; // Into the Island 1035d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitNo = 0; 1036d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBits.push_back(i); 1037d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVal = Val; 1038d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1039d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1040d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 2: 1041d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Filtered || Val == -1) { 1042d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 1; // Into the Water 1043d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson EndBits.push_back(i - 1); 1044d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.push_back(FieldVal); 1045d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Num; 1046d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } else { 1047d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 2; // Still in Island 1048d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++BitNo; 1049d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVal = FieldVal | Val << BitNo; 1050d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1051d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1052d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1053d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1054d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we are still in Island after the loop, do some housekeeping. 1055d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (State == 2) { 1056f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson EndBits.push_back(BitWidth - 1); 1057d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.push_back(FieldVal); 1058d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Num; 1059d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1060d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1061d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(StartBits.size() == Num && EndBits.size() == Num && 1062d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.size() == Num); 1063d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return Num; 1064d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1065d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1066d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Andersonvoid FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, 1067eb5cd610700661bc46c660640c36949033247d2dCraig Topper const OperandInfo &OpInfo) const { 1068eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::string &Decoder = OpInfo.Decoder; 1069d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1070d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (OpInfo.numFields() == 1) { 1071eb5cd610700661bc46c660640c36949033247d2dCraig Topper OperandInfo::const_iterator OI = OpInfo.begin(); 1072c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "tmp = fieldFromInstruction" 1073fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "(insn, " << OI->Base << ", " << OI->Width 1074fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << ");\n"; 1075d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } else { 1076c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "tmp = 0;\n"; 1077eb5cd610700661bc46c660640c36949033247d2dCraig Topper for (OperandInfo::const_iterator OI = OpInfo.begin(), OE = OpInfo.end(); 1078d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OI != OE; ++OI) { 1079c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "tmp |= (fieldFromInstruction" 1080ed968a9a045cb6fecb80abfb7e938954fed54927Andrew Trick << "(insn, " << OI->Base << ", " << OI->Width 1081d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson << ") << " << OI->Offset << ");\n"; 1082d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1083d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1084d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1085d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Decoder != "") 1086c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << Emitter->GuardPrefix << Decoder 10879c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach << "(MI, tmp, Address, Decoder)" 10889c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach << Emitter->GuardPostfix << "\n"; 1089d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson else 1090c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "MI.addOperand(MCOperand::CreateImm(tmp));\n"; 1091d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1092d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson} 1093d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1094fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation, 1095fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1096fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach std::map<unsigned, std::vector<OperandInfo> >::const_iterator OpIter = 1097fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Operands.find(Opc); 1098fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const std::vector<OperandInfo>& InsnOperands = OpIter->second; 1099fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (std::vector<OperandInfo>::const_iterator 1100fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) { 1101fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // If a custom instruction decoder was specified, use that. 1102fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (I->numFields() == 0 && I->Decoder.size()) { 1103c056483fc6cfab4307559afb0538323781b28d53Craig Topper OS.indent(Indentation) << Emitter->GuardPrefix << I->Decoder 1104fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "(MI, insn, Address, Decoder)" 1105fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << Emitter->GuardPostfix << "\n"; 1106fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 1107fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1108fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1109fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitBinaryParser(OS, Indentation, *I); 1110fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1111fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1112fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1113fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachunsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, 1114fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1115fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Build up the predicate string. 1116fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<256> Decoder; 1117fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // FIXME: emitDecoder() function can take a buffer directly rather than 1118fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // a stream. 1119fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(Decoder); 1120c056483fc6cfab4307559afb0538323781b28d53Craig Topper unsigned I = 4; 1121fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecoder(S, I, Opc); 1122fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1123fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1124fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Using the full decoder string as the key value here is a bit 1125fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // heavyweight, but is effective. If the string comparisons become a 1126fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // performance concern, we can implement a mangling of the predicate 1127fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // data easilly enough with a map back to the actual string. That's 1128fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // overkill for now, though. 1129fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1130fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Make sure the predicate is in the table. 1131fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Decoders.insert(Decoder.str()); 1132fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Now figure out the index for when we write out the table. 1133fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderSet::const_iterator P = std::find(Decoders.begin(), 1134fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Decoders.end(), 1135fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Decoder.str()); 1136fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return (unsigned)(P - Decoders.begin()); 1137fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1138fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1139a5d585685493d85d5cb72b831a68ec747ae55a86James Molloystatic void emitSinglePredicateMatch(raw_ostream &o, StringRef str, 1140eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::string &PredicateNamespace) { 114122b4c819d463da7eadb20162d049ee89de746bceAndrew Trick if (str[0] == '!') 114222b4c819d463da7eadb20162d049ee89de746bceAndrew Trick o << "!(Bits & " << PredicateNamespace << "::" 114322b4c819d463da7eadb20162d049ee89de746bceAndrew Trick << str.slice(1,str.size()) << ")"; 1144a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy else 114522b4c819d463da7eadb20162d049ee89de746bceAndrew Trick o << "(Bits & " << PredicateNamespace << "::" << str << ")"; 1146a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy} 1147a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1148a5d585685493d85d5cb72b831a68ec747ae55a86James Molloybool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 1149eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned Opc) const { 11509c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach ListInit *Predicates = 11519c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); 1152a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy for (unsigned i = 0; i < Predicates->getSize(); ++i) { 1153a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy Record *Pred = Predicates->getElementAsRecord(i); 1154a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (!Pred->getValue("AssemblerMatcherPredicate")) 1155a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy continue; 1156a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1157a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::string P = Pred->getValueAsString("AssemblerCondString"); 1158a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1159a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (!P.length()) 1160a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy continue; 1161a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1162a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (i != 0) 1163a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 1164a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1165a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy StringRef SR(P); 1166a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::pair<StringRef, StringRef> pairs = SR.split(','); 1167a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy while (pairs.second.size()) { 1168a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); 1169a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 1170a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy pairs = pairs.second.split(','); 1171a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 1172a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); 1173a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 1174a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy return Predicates->getSize() > 0; 1175ed968a9a045cb6fecb80abfb7e938954fed54927Andrew Trick} 1176a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1177fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachbool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const { 1178fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ListInit *Predicates = 1179fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); 1180fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (unsigned i = 0; i < Predicates->getSize(); ++i) { 1181fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Record *Pred = Predicates->getElementAsRecord(i); 1182fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!Pred->getValue("AssemblerMatcherPredicate")) 1183fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach continue; 1184fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1185fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach std::string P = Pred->getValueAsString("AssemblerCondString"); 1186fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1187fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!P.length()) 1188fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach continue; 1189fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1190fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return true; 1191fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1192fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return false; 1193fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1194fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1195fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachunsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo, 1196fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach StringRef Predicate) const { 1197fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Using the full predicate string as the key value here is a bit 1198fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // heavyweight, but is effective. If the string comparisons become a 1199fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // performance concern, we can implement a mangling of the predicate 1200fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // data easilly enough with a map back to the actual string. That's 1201fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // overkill for now, though. 1202fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1203fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Make sure the predicate is in the table. 1204fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Predicates.insert(Predicate.str()); 1205fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Now figure out the index for when we write out the table. 1206fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PredicateSet::const_iterator P = std::find(TableInfo.Predicates.begin(), 1207fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Predicates.end(), 1208fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Predicate.str()); 1209fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return (unsigned)(P - TableInfo.Predicates.begin()); 1210fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1211fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1212fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo, 1213fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1214fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!doesOpcodeNeedPredicate(Opc)) 1215fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1216fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1217fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Build up the predicate string. 1218fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<256> Predicate; 1219fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // FIXME: emitPredicateMatch() functions can take a buffer directly rather 1220fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // than a stream. 1221fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream PS(Predicate); 1222fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned I = 0; 1223fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateMatch(PS, I, Opc); 1224fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1225fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Figure out the index into the predicate table for the predicate just 1226fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // computed. 1227fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned PIdx = getPredicateIndex(TableInfo, PS.str()); 1228fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> PBytes; 1229fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(PBytes); 1230fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(PIdx, S); 1231fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1232fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1233fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_CheckPredicate); 1234fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Predicate index 12358cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = PBytes.size(); i != e; ++i) 1236fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(PBytes[i]); 1237fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Push location for NumToSkip backpatching. 1238fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 1239fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1240fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1241fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1242fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1243fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo, 1244fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 12459c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach BitsInit *SFBits = 12469c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach AllInstructions[Opc]->TheDef->getValueAsBitsInit("SoftFail"); 12473015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (!SFBits) return; 12483015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy BitsInit *InstBits = AllInstructions[Opc]->TheDef->getValueAsBitsInit("Inst"); 12493015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12503015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy APInt PositiveMask(BitWidth, 0ULL); 12513015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy APInt NegativeMask(BitWidth, 0ULL); 12523015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy for (unsigned i = 0; i < BitWidth; ++i) { 12533015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bit_value_t B = bitFromBits(*SFBits, i); 12543015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bit_value_t IB = bitFromBits(*InstBits, i); 12553015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12563015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (B != BIT_TRUE) continue; 12573015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12583015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy switch (IB) { 12593015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy case BIT_FALSE: 12603015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is meant to be false, so emit a check to see if it is true. 12613015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy PositiveMask.setBit(i); 12623015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy break; 12633015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy case BIT_TRUE: 12643015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is meant to be true, so emit a check to see if it is false. 12653015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy NegativeMask.setBit(i); 12663015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy break; 12673015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy default: 12683015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is not set; this must be an error! 12693015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy StringRef Name = AllInstructions[Opc]->TheDef->getName(); 1270fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in " << Name 1271fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " is set but Inst{" << i << "} is unset!\n" 12723015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy << " - You can only mark a bit as SoftFail if it is fully defined" 12733015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy << " (1/0 - not '?') in Inst\n"; 1274fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 12753015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy } 12763015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy } 12773015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12783015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bool NeedPositiveMask = PositiveMask.getBoolValue(); 12793015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bool NeedNegativeMask = NegativeMask.getBoolValue(); 12803015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12813015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (!NeedPositiveMask && !NeedNegativeMask) 12823015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy return; 12833015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 1284fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_SoftFail); 1285fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1286fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> MaskBytes; 1287fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(MaskBytes); 1288fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (NeedPositiveMask) { 1289fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(PositiveMask.getZExtValue(), S); 1290fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 12918cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i) 1292fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MaskBytes[i]); 1293fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } else 1294fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1295fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (NeedNegativeMask) { 1296fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach MaskBytes.clear(); 1297fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.resync(); 1298fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(NegativeMask.getZExtValue(), S); 1299fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 13008cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i) 1301fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MaskBytes[i]); 1302fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } else 1303fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 13043015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy} 13053015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 1306fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emits table entries to decode the singleton. 1307fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo, 1308fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1309d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> StartBits; 1310d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> EndBits; 1311d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<uint64_t> FieldVals; 1312d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 1313d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn, Opc); 1314d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1315d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Look for islands of undecoded bits of the singleton. 1316d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getIslands(StartBits, EndBits, FieldVals, Insn); 1317d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1318d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Size = StartBits.size(); 1319d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1320fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the predicate table entry if one is needed. 1321fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateTableEntry(TableInfo, Opc); 1322d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1323fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Check any additional encoding fields needed. 13248cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned I = Size; I != 0; --I) { 13258cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper unsigned NumBits = EndBits[I-1] - StartBits[I-1] + 1; 1326fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_CheckField); 1327fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(StartBits[I-1]); 1328fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(NumBits); 1329fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8], *p; 1330fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(FieldVals[I-1], Buffer); 1331fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (p = Buffer; *p >= 128 ; ++p) 1332fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1333fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1334fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Push location for NumToSkip backpatching. 1335fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 1336fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The fixup is always 16-bits, so go ahead and allocate the space 1337fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // in the table so all our relative position calculations work OK even 1338fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // before we fully resolve the real value here. 1339fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1340fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1341d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1342d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1343fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Check for soft failure of the match. 1344fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSoftFailTableEntry(TableInfo, Opc); 1345fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1346fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_Decode); 1347fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8], *p; 1348fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(Opc, Buffer); 1349fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (p = Buffer; *p >= 128 ; ++p) 1350fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1351fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1352fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1353fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned DIdx = getDecoderIndex(TableInfo.Decoders, Opc); 1354fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> Bytes; 1355fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(Bytes); 1356fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(DIdx, S); 1357fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1358fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1359fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Decoder index 13608cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = Bytes.size(); i != e; ++i) 1361fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(Bytes[i]); 1362d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1363d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1364fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emits table entries to decode the singleton, and then to decode the rest. 1365fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo, 1366fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const Filter &Best) const { 1367d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Opc = Best.getSingletonOpc(); 1368d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1369fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // complex singletons need predicate checks from the first singleton 1370fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // to refer forward to the variable filterchooser that follows. 1371fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.push_back(FixupList()); 1372d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1373fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Opc); 1374d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1375fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(), 1376fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.size()); 1377fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.pop_back(); 1378fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1379fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Best.getVariableFC().emitTableEntries(TableInfo); 1380d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1381d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1382fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1383d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Assign a single filter and run with it. Top level API client can initialize 1384d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// with a single filter to start the filtering process. 1385eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit, 1386eb5cd610700661bc46c660640c36949033247d2dCraig Topper bool mixed) { 1387d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.clear(); 1388d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter F(*this, startBit, numBit, true); 1389d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(F); 1390d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = 0; // Sole Filter instance to choose from. 1391d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().recurse(); 1392d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1393d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1394d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// reportRegion is a helper function for filterProcessor to mark a region as 1395d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// eligible for use as a filter region. 1396d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit, 1397d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper unsigned BitIndex, bool AllowMixed) { 1398d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (RA == ATTR_MIXED && AllowMixed) 1399d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, true)); 1400d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else if (RA == ATTR_ALL_SET && !AllowMixed) 1401d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, false)); 1402d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1403d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1404d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// FilterProcessor scans the well-known encoding bits of the instructions and 1405d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// builds up a list of candidate filters. It chooses the best filter and 1406d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// recursively descends down the decoding tree. 1407d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) { 1408d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.clear(); 1409d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = -1; 1410d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned numInstructions = Opcodes.size(); 1411d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1412d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(numInstructions && "Filter created with no instructions"); 1413d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1414d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // No further filtering is necessary. 1415d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (numInstructions == 1) 1416d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1417d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1418d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Heuristics. See also doFilter()'s "Heuristics" comment when num of 1419d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instructions is 3. 1420d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (AllowMixed && !Greedy) { 1421d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(numInstructions == 3); 1422d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1423d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); ++i) { 1424d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> StartBits; 1425d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> EndBits; 1426d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<uint64_t> FieldVals; 1427d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 1428d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1429d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn, Opcodes[i]); 1430d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1431d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Look for islands of undecoded bits of any instruction. 1432d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) { 1433d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Found an instruction with island(s). Now just assign a filter. 1434eb5cd610700661bc46c660640c36949033247d2dCraig Topper runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true); 1435d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1436d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1437d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1438d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1439d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 14408cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper unsigned BitIndex; 1441d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1442d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We maintain BIT_WIDTH copies of the bitAttrs automaton. 1443d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The automaton consumes the corresponding bit from each 1444d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instruction. 1445d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1446d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Input symbols: 0, 1, and _ (unset). 1447d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED. 1448d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Initial state: NONE. 1449d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1450d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ------- [01] -> (ALL_SET) 1451d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ------- _ ----> (ALL_UNSET) 1452d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) ---- [01] -> (ALL_SET) 1453d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) ---- _ ----> (MIXED) 1454d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_UNSET) -- [01] -> (MIXED) 1455d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_UNSET) -- _ ----> (ALL_UNSET) 1456d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ------ . ----> (MIXED) 1457d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (FILTERED)---- . ----> (FILTERED) 1458d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1459f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bitAttr_t> bitAttrs; 1460d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1461d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FILTERED bit positions provide no entropy and are not worthy of pursuing. 1462d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position. 1463f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) 1464d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (FilterBitValues[BitIndex] == BIT_TRUE || 1465d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterBitValues[BitIndex] == BIT_FALSE) 1466f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson bitAttrs.push_back(ATTR_FILTERED); 1467d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1468f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson bitAttrs.push_back(ATTR_NONE); 1469d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 14708cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) { 1471d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t insn; 1472d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1473d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(insn, Opcodes[InsnIndex]); 1474d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1475f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 1476d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttrs[BitIndex]) { 1477d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1478d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] == BIT_UNSET) 1479d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_ALL_UNSET; 1480d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1481d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_ALL_SET; 1482d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1483d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1484d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] == BIT_UNSET) 1485d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_MIXED; 1486d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1487d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1488d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] != BIT_UNSET) 1489d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_MIXED; 1490d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1491d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1492d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1493d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1494d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1495d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1496d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1497d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1498d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The regionAttr automaton consumes the bitAttrs automatons' state, 1499d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // lowest-to-highest. 1500d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1501d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed) 1502d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // States: NONE, ALL_SET, MIXED 1503d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Initial state: NONE 1504d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1505d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- F --> (NONE) 1506d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- S --> (ALL_SET) ; and set region start 1507d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- U --> (NONE) 1508d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- M --> (MIXED) ; and set region start 1509d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region 1510d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- S --> (ALL_SET) 1511d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region 1512d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region 1513d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- F --> (NONE) ; and report a MIXED region 1514d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region 1515d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- U --> (NONE) ; and report a MIXED region 1516d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- M --> (MIXED) 1517d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1518d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttr_t RA = ATTR_NONE; 1519d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned StartBit = 0; 1520d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 15218cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 1522d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttr_t bitAttr = bitAttrs[BitIndex]; 1523d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1524d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(bitAttr != ATTR_NONE && "Bit without attributes"); 1525d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1526d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (RA) { 1527d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1528d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1529d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1530d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1531d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1532d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1533d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_ALL_SET; 1534d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1535d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1536d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1537d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1538d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1539d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_MIXED; 1540d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1541d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1542655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1543d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1544d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1545d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1546d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1547d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1548d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1549d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1550d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1551d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1552d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1553d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1554d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1555d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1556d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1557d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1558d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1559d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1560d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_MIXED; 1561d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1562d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1563655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1564d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1565d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1566d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1567d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1568d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1569d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1570d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1571d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1572d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1573d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1574d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1575d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1576d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_ALL_SET; 1577d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1578d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1579d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1580d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1581d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1582d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1583d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1584d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1585655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1586d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1587d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1588d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1589655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("regionAttr state machine has no ATTR_UNSET state"); 1590d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1591655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state"); 1592d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1593d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1594d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1595d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // At the end, if we're still in ALL_SET or MIXED states, report a region 1596d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (RA) { 1597d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1598d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1599d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1600d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1601d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1602d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1603d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1604d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1605d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1606d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1607d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1608d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1609d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1610d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1611d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We have finished with the filter processings. Now it's time to choose 1612d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the best performing filter. 1613d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = 0; 1614d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool AllUseless = true; 1615d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned BestScore = 0; 1616d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1617d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = Filters.size(); i != e; ++i) { 1618d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Usefulness = Filters[i].usefulness(); 1619d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1620d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Usefulness) 1621d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson AllUseless = false; 1622d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1623d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Usefulness > BestScore) { 1624d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = i; 1625d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestScore = Usefulness; 1626d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1627d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1628d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1629d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (!AllUseless) 1630d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().recurse(); 1631d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1632d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return !AllUseless; 1633d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} // end of FilterChooser::filterProcessor(bool) 1634d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1635d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Decides on the best configuration of filter(s) to use in order to decode 1636d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// the instructions. A conflict of instructions may occur, in which case we 1637d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// dump the conflict set to the standard error. 1638d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::doFilter() { 1639d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Num = Opcodes.size(); 1640d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(Num && "FilterChooser created with no instructions"); 1641d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1642d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Try regions of consecutive known bit values first. 1643d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterProcessor(false)) 1644d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1645d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1646d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Then regions of mixed bits (both known and unitialized bit values allowed). 1647d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterProcessor(true)) 1648d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1649d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1650d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where 1651d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a 1652d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // well-known encoding pattern. In such case, we backtrack and scan for the 1653d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the very first consecutive ATTR_ALL_SET region and assign a filter to it. 1654d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Num == 3 && filterProcessor(true, false)) 1655d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1656d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1657d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we come to here, the instruction decoding has failed. 1658d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set the BestIndex to -1 to indicate so. 1659d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = -1; 1660d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1661d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1662fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitTableEntries - Emit state machine entries to decode our share of 1663fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// instructions. 1664fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const { 1665fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Opcodes.size() == 1) { 1666d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // There is only one instruction in the set, which is great! 1667d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Call emitSingletonDecoder() to see whether there are any remaining 1668d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // encodings bits. 1669fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Opcodes[0]); 1670fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1671fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1672d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1673d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Choose the best filter to do the decodings! 1674d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (BestIndex != -1) { 1675eb5cd610700661bc46c660640c36949033247d2dCraig Topper const Filter &Best = Filters[BestIndex]; 1676d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Best.getNumFiltered() == 1) 1677fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Best); 1678d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1679fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Best.emitTableEntry(TableInfo); 1680fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1681d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1682d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1683fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // We don't know how to decode these instructions! Dump the 1684fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // conflict set and bail. 1685d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1686d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Print out useful conflict information for postmortem analysis. 1687d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "Decoding Conflict:\n"; 1688d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1689d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpStack(errs(), "\t\t"); 1690d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1691d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper for (unsigned i = 0; i < Opcodes.size(); ++i) { 1692d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &Name = nameWithID(Opcodes[i]); 1693d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1694d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\t' << Name << " "; 1695d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), 1696d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 1697d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1698d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1699d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1700d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1701d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topperstatic bool populateInstruction(const CodeGenInstruction &CGI, unsigned Opc, 1702d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::map<unsigned, std::vector<OperandInfo> > &Operands){ 1703d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const Record &Def = *CGI.TheDef; 1704d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If all the bit positions are not specified; do not decode this instruction. 1705d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We are bound to fail! For proper disassembly, the well-known encoding bits 1706d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // of the instruction must be fully specified. 1707d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1708d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // This also removes pseudo instructions from considerations of disassembly, 1709d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // which is a better design and less fragile than the name matchings. 1710d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Ignore "asm parser only" instructions. 17114dd27ebcc2b218630899163504bc2641b9735466Owen Anderson if (Def.getValueAsBit("isAsmParserOnly") || 17124dd27ebcc2b218630899163504bc2641b9735466Owen Anderson Def.getValueAsBit("isCodeGenOnly")) 1713d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 1714d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 171505bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit &Bits = getBitsField(Def, "Inst"); 1716806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach if (Bits.allInComplete()) return false; 1717806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach 1718d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<OperandInfo> InsnOperands; 1719d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1720d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If the instruction has specified a custom decoding hook, use that instead 1721d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // of trying to auto-generate the decoder. 1722d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::string InstDecoder = Def.getValueAsString("DecoderMethod"); 1723d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (InstDecoder != "") { 1724d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson InsnOperands.push_back(OperandInfo(InstDecoder)); 1725d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Operands[Opc] = InsnOperands; 1726d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1727d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1728d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1729d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Generate a description of the operand of the instruction that we know 1730d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // how to decode automatically. 1731d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FIXME: We'll need to have a way to manually override this as needed. 1732d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1733d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Gather the outputs/inputs of the instruction, so we can find their 1734d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // positions in the encoding. This assumes for now that they appear in the 1735d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // MCInst in the order that they're listed. 173605bce0beee87512e52428d4b80f5a8e79a949576David Greene std::vector<std::pair<Init*, std::string> > InOutOperands; 173705bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *Out = Def.getValueAsDag("OutOperandList"); 173805bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *In = Def.getValueAsDag("InOperandList"); 1739d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Out->getNumArgs(); ++i) 1740d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson InOutOperands.push_back(std::make_pair(Out->getArg(i), Out->getArgName(i))); 1741d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < In->getNumArgs(); ++i) 1742d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson InOutOperands.push_back(std::make_pair(In->getArg(i), In->getArgName(i))); 1743d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 174400ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson // Search for tied operands, so that we can correctly instantiate 174500ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson // operands that are not explicitly represented in the encoding. 1746ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson std::map<std::string, std::string> TiedNames; 174700ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson for (unsigned i = 0; i < CGI.Operands.size(); ++i) { 174800ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson int tiedTo = CGI.Operands[i].getTiedRegister(); 1749ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson if (tiedTo != -1) { 1750ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson TiedNames[InOutOperands[i].second] = InOutOperands[tiedTo].second; 1751ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson TiedNames[InOutOperands[tiedTo].second] = InOutOperands[i].second; 1752ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson } 175300ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson } 175400ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson 1755d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // For each operand, see if we can figure out where it is encoded. 17565a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper for (std::vector<std::pair<Init*, std::string> >::const_iterator 1757d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) { 1758d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::string Decoder = ""; 1759d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1760d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // At this point, we can locate the field, but we need to know how to 1761d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // interpret it. As a first step, require the target to provide callbacks 1762d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // for decoding register classes. 1763d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // FIXME: This need to be extended to handle instructions with custom 1764d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // decoder methods, and operands with (simple) MIOperandInfo's. 17653f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva TypedInit *TI = cast<TypedInit>(NI->first); 17663f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva RecordRecTy *Type = cast<RecordRecTy>(TI->getType()); 1767d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Record *TypeRecord = Type->getRecord(); 1768d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson bool isReg = false; 1769d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (TypeRecord->isSubClassOf("RegisterOperand")) 1770d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson TypeRecord = TypeRecord->getValueAsDef("RegClass"); 1771d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (TypeRecord->isSubClassOf("RegisterClass")) { 1772d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; 1773d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson isReg = true; 1774d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1775d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1776d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod"); 177705bce0beee87512e52428d4b80f5a8e79a949576David Greene StringInit *String = DecoderString ? 17786cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva dyn_cast<StringInit>(DecoderString->getValue()) : 0; 1779d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (!isReg && String && String->getValue() != "") 1780d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Decoder = String->getValue(); 1781d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1782d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OperandInfo OpInfo(Decoder); 1783d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Base = ~0U; 1784d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Width = 0; 1785d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Offset = 0; 1786d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1787d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) { 1788cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson VarInit *Var = 0; 17896cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi)); 1790cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson if (BI) 17916cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva Var = dyn_cast<VarInit>(BI->getBitVar()); 1792cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson else 17936cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva Var = dyn_cast<VarInit>(Bits.getBit(bi)); 1794cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson 1795cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson if (!Var) { 1796d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) { 1797d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1798d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = ~0U; 1799d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 0; 1800d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Offset = 0; 1801d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1802d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson continue; 1803d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1804d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 180500ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson if (Var->getName() != NI->second && 1806ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson Var->getName() != TiedNames[NI->second]) { 1807d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) { 1808d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1809d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = ~0U; 1810d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 0; 1811d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Offset = 0; 1812d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1813d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson continue; 1814d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1815d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1816d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base == ~0U) { 1817d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = bi; 1818d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 1; 1819cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson Offset = BI ? BI->getBitNum() : 0; 1820cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson } else if (BI && BI->getBitNum() != Offset + Width) { 1821eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson OpInfo.addField(Base, Width, Offset); 1822eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Base = bi; 1823eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Width = 1; 1824eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Offset = BI->getBitNum(); 1825d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } else { 1826d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson ++Width; 1827d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1828d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1829d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1830d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) 1831d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1832d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1833d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (OpInfo.numFields() > 0) 1834d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson InsnOperands.push_back(OpInfo); 1835d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1836d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1837d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Operands[Opc] = InsnOperands; 1838d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1839d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1840d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#if 0 1841d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson DEBUG({ 1842d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Dumps the instruction encoding bits. 1843d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), Bits); 1844d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1845d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1846d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1847d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Dumps the list of operand info. 1848d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { 1849d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const CGIOperandList::OperandInfo &Info = CGI.Operands[i]; 1850d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &OperandName = Info.Name; 1851d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const Record &OperandDef = *Info.Rec; 1852d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1853d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n"; 1854d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1855d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson }); 1856d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#endif 1857d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1858d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1859d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1860d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1861fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitFieldFromInstruction - Emit the templated helper function 1862fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// fieldFromInstruction(). 1863fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstatic void emitFieldFromInstruction(formatted_raw_ostream &OS) { 1864fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Helper function for extracting fields from encoded instructions.\n" 1865fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "template<typename InsnType>\n" 1866fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "static InsnType fieldFromInstruction(InsnType insn, unsigned startBit,\n" 1867fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned numBits) {\n" 1868fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " assert(startBit + numBits <= (sizeof(InsnType)*8) &&\n" 1869fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " \"Instruction field out of bounds!\");\n" 1870fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType fieldMask;\n" 1871fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (numBits == sizeof(InsnType)*8)\n" 1872fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " fieldMask = (InsnType)(-1LL);\n" 1873fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " else\n" 1874fc093def2d892a2ea068d3b9e6d5839c187cc942NAKAMURA Takumi << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n" 1875fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return (insn & fieldMask) >> startBit;\n" 1876fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "}\n\n"; 1877fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1878f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1879fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitDecodeInstruction - Emit the templated helper function 1880fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// decodeInstruction(). 1881fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstatic void emitDecodeInstruction(formatted_raw_ostream &OS) { 1882fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "template<typename InsnType>\n" 1883fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,\n" 1884fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType insn, uint64_t Address,\n" 1885fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const void *DisAsm,\n" 1886fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const MCSubtargetInfo &STI) {\n" 1887fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " uint64_t Bits = STI.getFeatureBits();\n" 1888fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1889fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const uint8_t *Ptr = DecodeTable;\n" 18909bb938c5401db90817d16b32fa078066fb586551Jim Grosbach << " uint32_t CurFieldValue = 0;\n" 1891fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DecodeStatus S = MCDisassembler::Success;\n" 1892fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " for (;;) {\n" 1893fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " ptrdiff_t Loc = Ptr - DecodeTable;\n" 1894fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " switch (*Ptr) {\n" 1895fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " default:\n" 1896fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " errs() << Loc << \": Unexpected decode table opcode!\\n\";\n" 1897fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return MCDisassembler::Fail;\n" 1898fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_ExtractField: {\n" 1899fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Start = *++Ptr;\n" 1900fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len = *++Ptr;\n" 1901fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " ++Ptr;\n" 1902fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\n" 1903fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_ExtractField(\" << Start << \", \"\n" 1904fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << Len << \"): \" << CurFieldValue << \"\\n\");\n" 1905fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1906fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1907fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_FilterValue: {\n" 1908fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the field value.\n" 1909fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 1910fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType Val = decodeULEB128(++Ptr, &Len);\n" 1911fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1912fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 1913fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 1914fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 1915fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1916fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Perform the filter operation.\n" 1917fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (Val != CurFieldValue)\n" 1918fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 1919fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_FilterValue(\" << Val << \", \" << NumToSkip\n" 1920fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \"): \" << ((Val != CurFieldValue) ? \"FAIL:\" : \"PASS:\")\n" 1921fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \" continuing at \" << (Ptr - DecodeTable) << \"\\n\");\n" 1922fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1923fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1924fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1925fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_CheckField: {\n" 1926fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Start = *++Ptr;\n" 1927fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len = *++Ptr;\n" 1928fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\n" 1929fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the field value.\n" 1930fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\n" 1931fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1932fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 1933fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 1934fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 1935fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1936fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // If the actual and expected values don't match, skip.\n" 1937fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (ExpectedValue != FieldValue)\n" 1938fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 1939fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_CheckField(\" << Start << \", \"\n" 1940fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << Len << \", \" << ExpectedValue << \", \" << NumToSkip\n" 1941fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \"): FieldValue = \" << FieldValue << \", ExpectedValue = \"\n" 1942fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << ExpectedValue << \": \"\n" 1943fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << ((ExpectedValue == FieldValue) ? \"PASS\\n\" : \"FAIL\\n\"));\n" 1944fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1945fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1946fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_CheckPredicate: {\n" 1947fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 1948fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the Predicate Index value.\n" 1949fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\n" 1950fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1951fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 1952fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 1953fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 1954fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Check the predicate.\n" 1955fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " bool Pred;\n" 1956fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\n" 1957fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 1958fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " (void)Pred;\n" 1959fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_CheckPredicate(\" << PIdx << \"): \"\n" 1960fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << (Pred ? \"PASS\\n\" : \"FAIL\\n\"));\n" 1961fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1962fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1963fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1964fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_Decode: {\n" 1965fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 1966fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the Opcode value.\n" 1967fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Opc = decodeULEB128(++Ptr, &Len);\n" 1968fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1969fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n" 1970fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1971fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_Decode: opcode \" << Opc\n" 1972fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \", using decoder \" << DecodeIdx << \"\\n\" );\n" 1973fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << \"----- DECODE SUCCESSFUL -----\\n\");\n" 1974fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 1975fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " MI.setOpcode(Opc);\n" 197695d235ddb62805923f2f64edd71b15b904ee4a16Benjamin Kramer << " return decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm);\n" 1977fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1978fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_SoftFail: {\n" 1979fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the mask values.\n" 1980fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 1981fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\n" 1982fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1983fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\n" 1984fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 1985fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " bool Fail = (insn & PositiveMask) || (~insn & NegativeMask);\n" 1986fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (Fail)\n" 1987fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " S = MCDisassembler::SoftFail;\n" 1988fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_SoftFail: \" << (Fail ? \"FAIL\\n\":\"PASS\\n\"));\n" 1989fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 1990fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1991fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_Fail: {\n" 1992fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_Fail\\n\");\n" 1993fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return MCDisassembler::Fail;\n" 1994fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1995fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1996fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 1997fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " llvm_unreachable(\"bogosity detected in disassembler state machine!\");\n" 1998fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "}\n\n"; 1999d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 2000d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 2001d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emits disassembler code for instruction decoding. 2002d936045625ae2e101d3a9544586d7568c6dbacc0Craig Toppervoid FixedLenDecoderEmitter::run(raw_ostream &o) { 2003fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach formatted_raw_ostream OS(o); 2004fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/MC/MCInst.h\"\n"; 2005fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/Debug.h\"\n"; 2006fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/DataTypes.h\"\n"; 2007fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/LEB128.h\"\n"; 2008fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/raw_ostream.h\"\n"; 2009fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include <assert.h>\n"; 2010fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << '\n'; 2011fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "namespace llvm {\n\n"; 2012fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2013fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitFieldFromInstruction(OS); 2014d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 2015f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Parameterize the decoders based on namespace and instruction width. 2016fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumberedInstructions = &Target.getInstructionsByEnumValue(); 2017f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<std::pair<std::string, unsigned>, 2018f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<unsigned> > OpcMap; 2019f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<unsigned, std::vector<OperandInfo> > Operands; 2020f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2021fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (unsigned i = 0; i < NumberedInstructions->size(); ++i) { 2022fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const CodeGenInstruction *Inst = NumberedInstructions->at(i); 2023eb5cd610700661bc46c660640c36949033247d2dCraig Topper const Record *Def = Inst->TheDef; 2024f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned Size = Def->getValueAsInt("Size"); 2025f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (Def->getValueAsString("Namespace") == "TargetOpcode" || 2026f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isPseudo") || 2027f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isAsmParserOnly") || 2028f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isCodeGenOnly")) 2029f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson continue; 2030f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2031f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::string DecoderNamespace = Def->getValueAsString("DecoderNamespace"); 2032f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2033f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (Size) { 2034f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (populateInstruction(*Inst, i, Operands)) { 2035f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i); 2036f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2037f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2038f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2039f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2040fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTableInfo TableInfo; 2041f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::set<unsigned> Sizes; 2042f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (std::map<std::pair<std::string, unsigned>, 2043eb5cd610700661bc46c660640c36949033247d2dCraig Topper std::vector<unsigned> >::const_iterator 2044f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson I = OpcMap.begin(), E = OpcMap.end(); I != E; ++I) { 2045f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Emit the decoder for this namespace+width combination. 2046fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FilterChooser FC(*NumberedInstructions, I->second, Operands, 204783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson 8*I->first.second, this); 2048fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2049fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The decode table is cleared for each top level decoder function. The 2050fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // predicates and decoders themselves, however, are shared across all 2051fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // decoders to give more opportunities for uniqueing. 2052fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.clear(); 2053fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.clear(); 2054fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.reserve(16384); 2055fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.push_back(FixupList()); 2056fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FC.emitTableEntries(TableInfo); 2057fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Any NumToSkip fixups in the top level scope can resolve to the 2058fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // OPC_Fail at the end of the table. 2059fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!"); 2060fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Resolve any NumToSkip fixups in the current scope. 2061fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(), 2062fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.size()); 2063fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.clear(); 2064fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2065fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_Fail); 2066fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2067fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Print the table to the output stream. 2068fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), I->first.first); 2069fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.flush(); 2070f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2071d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 2072fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the predicate function. 2073fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateFunction(OS, TableInfo.Predicates, 0); 2074fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2075fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the decoder function. 2076fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecoderFunction(OS, TableInfo.Decoders, 0); 2077fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2078fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the main entry point for the decoder, decodeInstruction(). 2079fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecodeInstruction(OS); 2080fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2081fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "\n} // End llvm namespace\n"; 2082d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 20836f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 20846f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 20856f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 20866f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS, 20876f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string PredicateNamespace, 20886f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPrefix, 20896f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPostfix, 20906f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string ROK, 20916f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string RFail, 20926f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string L) { 20936f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen FixedLenDecoderEmitter(RK, PredicateNamespace, GPrefix, GPostfix, 20946f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen ROK, RFail, L).run(OS); 20956f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} 20966f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 20976f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 2098