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#include "CodeGenTarget.h" 163015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy#include "llvm/ADT/APInt.h" 17fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/SmallString.h" 18d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/ADT/StringExtras.h" 19fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/StringRef.h" 20fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/ADT/Twine.h" 21fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/MC/MCFixedLenDisassembler.h" 226f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/Support/DataTypes.h" 23d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/Support/Debug.h" 24fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/Support/FormattedStream.h" 25fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/Support/LEB128.h" 26d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/Support/raw_ostream.h" 274ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/TableGen/Error.h" 284ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/TableGen/Record.h" 29d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <map> 30d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <string> 314ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include <vector> 32d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 33d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonusing namespace llvm; 34d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "decoder-emitter" 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenstruct EncodingField { 396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned Base, Width, Offset; 406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen EncodingField(unsigned B, unsigned W, unsigned O) 416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen : Base(B), Width(W), Offset(O) { } 426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenstruct OperandInfo { 456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<EncodingField> Fields; 466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string Decoder; 476f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 486f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen OperandInfo(std::string D) 496f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen : Decoder(D) { } 506f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 516f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void addField(unsigned Base, unsigned Width, unsigned Offset) { 526f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen Fields.push_back(EncodingField(Base, Width, Offset)); 536f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen } 546f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 556f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned numFields() const { return Fields.size(); } 566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen typedef std::vector<EncodingField>::const_iterator const_iterator; 586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen const_iterator begin() const { return Fields.begin(); } 606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen const_iterator end() const { return Fields.end(); } 616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 62fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 63fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef std::vector<uint8_t> DecoderTable; 64fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef uint32_t DecoderFixup; 65fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef std::vector<DecoderFixup> FixupList; 66fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef std::vector<FixupList> FixupScopeList; 67fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef SetVector<std::string> PredicateSet; 68fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachtypedef SetVector<std::string> DecoderSet; 69fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstruct DecoderTableInfo { 70fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable Table; 71fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FixupScopeList FixupStack; 72fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PredicateSet Predicates; 73fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderSet Decoders; 74fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach}; 75fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 766f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 776f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 786f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 796f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass FixedLenDecoderEmitter { 80fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const std::vector<const CodeGenInstruction*> *NumberedInstructions; 816f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 826f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 836f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen // Defaults preserved here for documentation, even though they aren't 846f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen // strictly necessary given the way that this is currently being called. 856f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen FixedLenDecoderEmitter(RecordKeeper &R, 866f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string PredicateNamespace, 876f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPrefix = "if (", 886f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPostfix = " == MCDisassembler::Fail)" 896f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen " return MCDisassembler::Fail;", 906f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string ROK = "MCDisassembler::Success", 916f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string RFail = "MCDisassembler::Fail", 926f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string L = "") : 936f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen Target(R), 946f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen PredicateNamespace(PredicateNamespace), 956f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen GuardPrefix(GPrefix), GuardPostfix(GPostfix), 966f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen ReturnOK(ROK), ReturnFail(RFail), Locals(L) {} 976f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 98fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the decoder state machine table. 99fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitTable(formatted_raw_ostream &o, DecoderTable &Table, 100fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation, unsigned BitWidth, 101fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach StringRef Namespace) const; 102fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitPredicateFunction(formatted_raw_ostream &OS, 103fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PredicateSet &Predicates, 104fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const; 105fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitDecoderFunction(formatted_raw_ostream &OS, 106fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderSet &Decoders, 107fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const; 108fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1096f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen // run - Output the code emitter 1106f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void run(raw_ostream &o); 1116f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 1126f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenprivate: 1136f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CodeGenTarget Target; 1146f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 1156f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string PredicateNamespace; 1166f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GuardPrefix, GuardPostfix; 1176f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string ReturnOK, ReturnFail; 1186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string Locals; 1196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 1206f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 1216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 122d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system 123d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// for a bit value. 124d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 125d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// BIT_UNFILTERED is used as the init value for a filter position. It is used 126d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// only for filter processings. 127d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersontypedef enum { 128d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_TRUE, // '1' 129d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_FALSE, // '0' 130d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_UNSET, // '?' 131d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_UNFILTERED // unfiltered 132d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} bit_value_t; 133d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 134d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic bool ValueSet(bit_value_t V) { 135d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return (V == BIT_TRUE || V == BIT_FALSE); 136d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 137d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic bool ValueNotSet(bit_value_t V) { 138d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return (V == BIT_UNSET); 139d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 140d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic int Value(bit_value_t V) { 141d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1); 142d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 143eb5cd610700661bc46c660640c36949033247d2dCraig Topperstatic bit_value_t bitFromBits(const BitsInit &bits, unsigned index) { 1446cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva if (BitInit *bit = dyn_cast<BitInit>(bits.getBit(index))) 145d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return bit->getValue() ? BIT_TRUE : BIT_FALSE; 146d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 147d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The bit is uninitialized. 148d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return BIT_UNSET; 149d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 150d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Prints the bit value for each position. 151eb5cd610700661bc46c660640c36949033247d2dCraig Topperstatic void dumpBits(raw_ostream &o, const BitsInit &bits) { 1528cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned index = bits.getNumBits(); index > 0; --index) { 153d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitFromBits(bits, index - 1)) { 154d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_TRUE: 155d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "1"; 156d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 157d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_FALSE: 158d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "0"; 159d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 160d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNSET: 161d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "_"; 162d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 163d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 164655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("unexpected return value from bitFromBits"); 165d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 166d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 167d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 168d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 16905bce0beee87512e52428d4b80f5a8e79a949576David Greenestatic BitsInit &getBitsField(const Record &def, const char *str) { 17005bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit *bits = def.getValueAsBitsInit(str); 171d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return *bits; 172d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 173d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 174d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Forward declaration. 1756f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 176d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass FilterChooser; 1776f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 178d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 179d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Representation of the instruction to work on. 180f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Andersontypedef std::vector<bit_value_t> insn_t; 181d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 182d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Filter - Filter works with FilterChooser to produce the decoding tree for 183d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the ISA. 184d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 185d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// It is useful to think of a Filter as governing the switch stmts of the 186d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoding tree in a certain level. Each case stmt delegates to an inferior 187d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser to decide what further decoding logic to employ, or in another 188d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// words, what other remaining bits to look at. The FilterChooser eventually 189d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// chooses a best Filter to do its job. 190d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 191d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// This recursive scheme ends when the number of Opcodes assigned to the 192d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser becomes 1 or if there is a conflict. A conflict happens when 193d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the Filter/FilterChooser combo does not know how to distinguish among the 194d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Opcodes assigned. 195d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 196d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// An example of a conflict is 197d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 198d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Conflict: 199d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 111101000.00........00010000.... 200d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 111101000.00........0001........ 201d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010...00........0001........ 202d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010...00.................... 203d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010......................... 204d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111............................ 205d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// ................................ 206d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8a 111101000_00________00010000____ 207d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8b 111101000_00________00010000____ 208d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 209d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// The Debug output shows the path that the decoding tree follows to reach the 210d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced 211d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// even registers, while VST4q8b is a vst4 to double-spaced odd regsisters. 212d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 213d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// The encoding info in the .td files does not specify this meta information, 214d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// which could have been used by the decoder to resolve the conflict. The 215d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoder could try to decode the even/odd register numbering and assign to 216d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a" 217d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// version and return the Opcode since the two have the same Asm format string. 2186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 219d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass Filter { 220d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 2215a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const FilterChooser *Owner;// points to the FilterChooser who owns this filter 222d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned StartBit; // the starting bit position 223d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned NumBits; // number of bits to filter 224d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool Mixed; // a mixed region contains both set and unset bits 225d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 226d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Map of well-known segment value to the set of uid's with that value. 227d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<uint64_t, std::vector<unsigned> > FilteredInstructions; 228d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 229d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set of uid's with non-constant segment values. 230d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> VariableInstructions; 231d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 232d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Map of well-known segment value to its delegate. 23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::map<unsigned, std::unique_ptr<const FilterChooser>> FilterChooserMap; 234d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 235d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Number of instructions which fall under FilteredInstructions category. 236d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned NumFiltered; 237d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 238d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Keeps track of the last opcode in the filtered bucket. 239d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned LastOpcFiltered; 240d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 241d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonpublic: 242eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned getNumFiltered() const { return NumFiltered; } 243eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned getSingletonOpc() const { 244d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(NumFiltered == 1); 245d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return LastOpcFiltered; 246d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 247d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Return the filter chooser for the group of instructions without constant 248d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // segment values. 249eb5cd610700661bc46c660640c36949033247d2dCraig Topper const FilterChooser &getVariableFC() const { 250d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(NumFiltered == 1); 251d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(FilterChooserMap.size() == 1); 252d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return *(FilterChooserMap.find((unsigned)-1)->second); 253d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 254d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Filter(Filter &&f); 256d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed); 257d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 258d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ~Filter(); 259d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 260d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Divides the decoding task into sub tasks and delegates them to the 261d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // inferior FilterChooser's. 262d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 263d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // A special case arises when there's only one entry in the filtered 264d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instructions. In order to unambiguously decode the singleton, we need to 265d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // match the remaining undecoded encoding bits against the singleton. 266d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void recurse(); 267d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 268fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit table entries to decode instructions given a segment or segments of 269fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // bits. 270fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitTableEntry(DecoderTableInfo &TableInfo) const; 271d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 272d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns the number of fanout produced by the filter. More fanout implies 273d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the filter distinguishes more categories of instructions. 274d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned usefulness() const; 275d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson}; // End of class Filter 2766f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 277d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 278d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// These are states of our finite state machines used in FilterChooser's 279d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// filterProcessor() which produces the filter candidates to use. 280d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersontypedef enum { 281d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_NONE, 282d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_FILTERED, 283d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_ALL_SET, 284d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_ALL_UNSET, 285d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_MIXED 286d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} bitAttr_t; 287d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 288d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser - FilterChooser chooses the best filter among a set of Filters 289d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// in order to perform the decoding of instructions at the current level. 290d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 291d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Decoding proceeds from the top down. Based on the well-known encoding bits 292d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// of instructions available, FilterChooser builds up the possible Filters that 293d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// can further the task of decoding by distinguishing among the remaining 294d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// candidate instructions. 295d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 296d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Once a filter has been chosen, it is called upon to divide the decoding task 297d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// into sub-tasks and delegates them to its inferior FilterChoosers for further 298d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// processings. 299d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 300d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// It is useful to think of a Filter as governing the switch stmts of the 301d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoding tree. And each case is delegated to an inferior FilterChooser to 302d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decide what further remaining bits to look at. 3036f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 304d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass FilterChooser { 305d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 306d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson friend class Filter; 307d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 308d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of codegen instructions to choose our filter. 309d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<const CodeGenInstruction*> &AllInstructions; 310d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 311d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of uid's for this filter chooser to work on. 3125a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::vector<unsigned> &Opcodes; 313d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 314d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Lookup table for the operand decoding of instructions. 3155a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::map<unsigned, std::vector<OperandInfo> > &Operands; 316d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 317d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of candidate filters. 318d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<Filter> Filters; 319d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 320d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Array of bit values passed down from our parent. 321d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set to all BIT_UNFILTERED's for Parent == NULL. 322f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bit_value_t> FilterBitValues; 323d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 324d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Links to the FilterChooser above us in the decoding tree. 3255a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const FilterChooser *Parent; 326d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 327d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Index of the best filter from Filters. 328d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int BestIndex; 329d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 330f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Width of instructions 331f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned BitWidth; 332f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 33383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson // Parent emitter 33483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson const FixedLenDecoderEmitter *Emitter; 33583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson 336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FilterChooser(const FilterChooser &) = delete; 337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void operator=(const FilterChooser &) = delete; 338d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonpublic: 339d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 340d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser(const std::vector<const CodeGenInstruction*> &Insts, 341d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<unsigned> &IDs, 3425a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::map<unsigned, std::vector<OperandInfo> > &Ops, 34383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson unsigned BW, 344d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper const FixedLenDecoderEmitter *E) 345d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), Filters(), 34637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines FilterBitValues(BW, BIT_UNFILTERED), Parent(nullptr), BestIndex(-1), 34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines BitWidth(BW), Emitter(E) { 348d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson doFilter(); 349d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 350d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 351d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser(const std::vector<const CodeGenInstruction*> &Insts, 352d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<unsigned> &IDs, 3535a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::map<unsigned, std::vector<OperandInfo> > &Ops, 3545a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const std::vector<bit_value_t> &ParentFilterBitValues, 3555a4c790c06a8884b208611f63d8623da9a93b7e7Craig Topper const FilterChooser &parent) 356d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), 357f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Filters(), FilterBitValues(ParentFilterBitValues), 35883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Parent(&parent), BestIndex(-1), BitWidth(parent.BitWidth), 35983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Emitter(parent.Emitter) { 360d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson doFilter(); 361d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 362d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 363fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned getBitWidth() const { return BitWidth; } 364d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 365d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 366d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the insn given the uid. 367d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void insnWithID(insn_t &Insn, unsigned Opcode) const { 36805bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst"); 369d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 3703015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // We may have a SoftFail bitmask, which specifies a mask where an encoding 3713015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // may differ from the value in "Inst" and yet still be valid, but the 3723015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // disassembler should return SoftFail instead of Success. 3733015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // 3743015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // This is used for marking UNPREDICTABLE instructions in the ARM world. 3759c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach BitsInit *SFBits = 3769c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach AllInstructions[Opcode]->TheDef->getValueAsBitsInit("SoftFail"); 3773015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 3783015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy for (unsigned i = 0; i < BitWidth; ++i) { 3793015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE) 3803015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy Insn.push_back(BIT_UNSET); 3813015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy else 3823015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy Insn.push_back(bitFromBits(Bits, i)); 3833015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy } 384d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 385d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 386d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns the record name. 387d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &nameWithID(unsigned Opcode) const { 388d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return AllInstructions[Opcode]->TheDef->getName(); 389d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 390d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 391d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the field of the insn given the start position and the number of 392d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // consecutive bits to scan for. 393d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 394d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns false if there exists any uninitialized bit value in the range. 395d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns true, otherwise. 396d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit, 397d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper unsigned NumBits) const; 398d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 399d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpFilterArray - dumpFilterArray prints out debugging info for the given 400d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// filter array as a series of chars. 401eb5cd610700661bc46c660640c36949033247d2dCraig Topper void dumpFilterArray(raw_ostream &o, 402eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::vector<bit_value_t> & filter) const; 403d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 404d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpStack - dumpStack traverses the filter chooser chain and calls 405d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpFilterArray on each filter chooser up to the top level one. 406eb5cd610700661bc46c660640c36949033247d2dCraig Topper void dumpStack(raw_ostream &o, const char *prefix) const; 407d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 408d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter &bestFilter() { 409d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(BestIndex != -1 && "BestIndex not set"); 410d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return Filters[BestIndex]; 411d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 412d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 413d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Called from Filter::recurse() when singleton exists. For debug purpose. 414eb5cd610700661bc46c660640c36949033247d2dCraig Topper void SingletonExists(unsigned Opc) const; 415d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 416eb5cd610700661bc46c660640c36949033247d2dCraig Topper bool PositionFiltered(unsigned i) const { 417d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return ValueSet(FilterBitValues[i]); 418d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 419d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 420d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Calculates the island(s) needed to decode the instruction. 421d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // This returns a lit of undecoded bits of an instructions, for example, 422d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 423d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // decoded bits in order to verify that the instruction matches the Opcode. 424d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned getIslands(std::vector<unsigned> &StartBits, 425d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::vector<unsigned> &EndBits, 426eb5cd610700661bc46c660640c36949033247d2dCraig Topper std::vector<uint64_t> &FieldVals, 427eb5cd610700661bc46c660640c36949033247d2dCraig Topper const insn_t &Insn) const; 428d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 429a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy // Emits code to check the Predicates member of an instruction are true. 430a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy // Returns true if predicate matches were emitted, false otherwise. 431eb5cd610700661bc46c660640c36949033247d2dCraig Topper bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 432eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned Opc) const; 433a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 434fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach bool doesOpcodeNeedPredicate(unsigned Opc) const; 435fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const; 436fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitPredicateTableEntry(DecoderTableInfo &TableInfo, 437fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const; 438fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 439fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitSoftFailTableEntry(DecoderTableInfo &TableInfo, 440fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const; 4413015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 442fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emits table entries to decode the singleton. 443fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitSingletonTableEntry(DecoderTableInfo &TableInfo, 444fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const; 445d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 446d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emits code to decode the singleton, and then to decode the rest. 447fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitSingletonTableEntry(DecoderTableInfo &TableInfo, 448fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const Filter &Best) const; 449d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 450fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitBinaryParser(raw_ostream &o, unsigned &Indentation, 451eb5cd610700661bc46c660640c36949033247d2dCraig Topper const OperandInfo &OpInfo) const; 452d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 453fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitDecoder(raw_ostream &OS, unsigned Indentation, unsigned Opc) const; 454fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned getDecoderIndex(DecoderSet &Decoders, unsigned Opc) const; 455fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 456d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Assign a single filter and run with it. 457eb5cd610700661bc46c660640c36949033247d2dCraig Topper void runSingleFilter(unsigned startBit, unsigned numBit, bool mixed); 458d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 459d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // reportRegion is a helper function for filterProcessor to mark a region as 460d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // eligible for use as a filter region. 461d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex, 462d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper bool AllowMixed); 463d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 464d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FilterProcessor scans the well-known encoding bits of the instructions and 465d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // builds up a list of candidate filters. It chooses the best filter and 466d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // recursively descends down the decoding tree. 467d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool filterProcessor(bool AllowMixed, bool Greedy = true); 468d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 469d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Decides on the best configuration of filter(s) to use in order to decode 470d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the instructions. A conflict of instructions may occur, in which case we 471d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // dump the conflict set to the standard error. 472d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void doFilter(); 473d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 474fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachpublic: 475fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // emitTableEntries - Emit state machine entries to decode our share of 476fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // instructions. 477fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach void emitTableEntries(DecoderTableInfo &TableInfo) const; 478d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson}; 4796f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 480d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 481d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/////////////////////////// 482d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 483797ba55e20fa5c6b0bcaf3ab676b54c65a4666acCraig Topper// Filter Implementation // 484d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 485d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/////////////////////////// 486d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 48737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesFilter::Filter(Filter &&f) 488d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed), 48937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines FilteredInstructions(std::move(f.FilteredInstructions)), 49037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines VariableInstructions(std::move(f.VariableInstructions)), 49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines FilterChooserMap(std::move(f.FilterChooserMap)), NumFiltered(f.NumFiltered), 492d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper LastOpcFiltered(f.LastOpcFiltered) { 493d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 494d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 495d8c87888a71c4433d76b48bca6c3e03a17890648Owen AndersonFilter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, 496d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper bool mixed) 497d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) { 498f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson assert(StartBit + NumBits - 1 < Owner->BitWidth); 499d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 500d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NumFiltered = 0; 501d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson LastOpcFiltered = 0; 502d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 503d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) { 504d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 505d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 506d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the insn given the uid. 507d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Owner->insnWithID(Insn, Owner->Opcodes[i]); 508d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 509d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson uint64_t Field; 510d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Scans the segment for possibly well-specified encoding bits. 511d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits); 512d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 513d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (ok) { 514d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The encoding bits are well-known. Lets add the uid of the 515d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instruction into the bucket keyed off the constant field value. 516d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson LastOpcFiltered = Owner->Opcodes[i]; 517d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilteredInstructions[Field].push_back(LastOpcFiltered); 518d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++NumFiltered; 519d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } else { 520797ba55e20fa5c6b0bcaf3ab676b54c65a4666acCraig Topper // Some of the encoding bit(s) are unspecified. This contributes to 521d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // one additional member of "Variable" instructions. 522d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson VariableInstructions.push_back(Owner->Opcodes[i]); 523d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 524d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 525d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 526d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert((FilteredInstructions.size() + VariableInstructions.size() > 0) 527d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson && "Filter returns no instruction categories"); 528d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 529d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 530d8c87888a71c4433d76b48bca6c3e03a17890648Owen AndersonFilter::~Filter() { 531d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 532d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 533d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Divides the decoding task into sub tasks and delegates them to the 534d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// inferior FilterChooser's. 535d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 536d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// A special case arises when there's only one entry in the filtered 537d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// instructions. In order to unambiguously decode the singleton, we need to 538d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// match the remaining undecoded encoding bits against the singleton. 539d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid Filter::recurse() { 540d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Starts by inheriting our parent filter chooser's filter bit values. 541f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues); 542d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 543ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!VariableInstructions.empty()) { 544d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Conservatively marks each segment position as BIT_UNSET. 5458cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) 546d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_UNSET; 547d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 5487a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Delegates to an inferior filter chooser for further processing on this 549d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // group of instructions whose segment values are variable. 55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines FilterChooserMap.insert( 55137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::make_pair(-1U, llvm::make_unique<FilterChooser>( 55237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Owner->AllInstructions, VariableInstructions, 55337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Owner->Operands, BitValueArray, *Owner))); 554d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 555d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 556d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // No need to recurse for a singleton filtered instruction. 557fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // See also Filter::emit*(). 558d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (getNumFiltered() == 1) { 559d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson //Owner->SingletonExists(LastOpcFiltered); 560d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(FilterChooserMap.size() == 1); 561d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 562d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 563d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 564d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Otherwise, create sub choosers. 565ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &Inst : FilteredInstructions) { 566d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 567d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Marks all the segment positions with either BIT_TRUE or BIT_FALSE. 5688cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) { 569ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Inst.first & (1ULL << bitIndex)) 570d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_TRUE; 571d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 572d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_FALSE; 573d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 574d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 5757a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Delegates to an inferior filter chooser for further processing on this 576d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // category of instructions. 57737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines FilterChooserMap.insert(std::make_pair( 578ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Inst.first, llvm::make_unique<FilterChooser>( 579ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Owner->AllInstructions, Inst.second, 58037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Owner->Operands, BitValueArray, *Owner))); 581d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 582d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 583d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 584fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstatic void resolveTableFixups(DecoderTable &Table, const FixupList &Fixups, 585fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t DestIdx) { 586fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Any NumToSkip fixups in the current scope can resolve to the 587fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // current location. 588fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (FixupList::const_reverse_iterator I = Fixups.rbegin(), 589fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach E = Fixups.rend(); 590fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach I != E; ++I) { 591fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Calculate the distance from the byte following the fixup entry byte 592fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // to the destination. The Target is calculated from after the 16-bit 593fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // NumToSkip entry itself, so subtract two from the displacement here 594fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // to account for that. 595fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t FixupIdx = *I; 596fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t Delta = DestIdx - FixupIdx - 2; 597fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Our NumToSkip entries are 16-bits. Make sure our table isn't too 598fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // big. 599fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(Delta < 65536U && "disassembler decoding table too large!"); 600fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table[FixupIdx] = (uint8_t)Delta; 601fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table[FixupIdx + 1] = (uint8_t)(Delta >> 8); 602fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 603fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 604d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 605fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emit table entries to decode instructions given a segment or segments 606fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// of bits. 607fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid Filter::emitTableEntry(DecoderTableInfo &TableInfo) const { 608fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_ExtractField); 609fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(StartBit); 610fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(NumBits); 611d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 612fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // A new filter entry begins a new scope for fixup resolution. 613fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.push_back(FixupList()); 614d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 615fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable &Table = TableInfo.Table; 616fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 617fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach size_t PrevFilter = 0; 618fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach bool HasFallthrough = false; 619ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto &Filter : FilterChooserMap) { 620d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Field value -1 implies a non-empty set of variable instructions. 621d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // See also recurse(). 622ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Filter.first == (unsigned)-1) { 623fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach HasFallthrough = true; 624fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 625fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Each scope should always have at least one filter value to check 626fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // for. 627fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(PrevFilter != 0 && "empty filter set!"); 628fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FixupList &CurScope = TableInfo.FixupStack.back(); 629fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Resolve any NumToSkip fixups in the current scope. 630fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach resolveTableFixups(Table, CurScope, Table.size()); 631fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach CurScope.clear(); 632fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PrevFilter = 0; // Don't re-process the filter's fallthrough. 633fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } else { 634fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table.push_back(MCD::OPC_FilterValue); 635fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Encode and emit the value to filter against. 636fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8]; 637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Len = encodeULEB128(Filter.first, Buffer); 638fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table.insert(Table.end(), Buffer, Buffer + Len); 639fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Reserve space for the NumToSkip entry. We'll backpatch the value 640fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // later. 641fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PrevFilter = Table.size(); 642fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table.push_back(0); 643fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table.push_back(0); 644fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 645d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 646d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We arrive at a category of instructions with the same segment value. 647d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Now delegate to the sub filter chooser for further decodings. 648d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The case may fallthrough, which happens if the remaining well-known 649d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // encoding bits do not match exactly. 650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Filter.second->emitTableEntries(TableInfo); 651fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 652fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Now that we've emitted the body of the handler, update the NumToSkip 653fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // of the filter itself to be able to skip forward when false. Subtract 654fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // two as to account for the width of the NumToSkip field itself. 655fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (PrevFilter) { 656fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t NumToSkip = Table.size() - PrevFilter - 2; 657fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(NumToSkip < 65536U && "disassembler decoding table too large!"); 658fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table[PrevFilter] = (uint8_t)NumToSkip; 659fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Table[PrevFilter + 1] = (uint8_t)(NumToSkip >> 8); 660fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 661d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 662d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 663fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Any remaining unresolved fixups bubble up to the parent fixup scope. 664fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(TableInfo.FixupStack.size() > 1 && "fixup stack underflow!"); 665fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FixupScopeList::iterator Source = TableInfo.FixupStack.end() - 1; 666fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FixupScopeList::iterator Dest = Source - 1; 667fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Dest->insert(Dest->end(), Source->begin(), Source->end()); 668fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.pop_back(); 669fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 670fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // If there is no fallthrough, then the final filter should get fixed 671fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // up according to the enclosing scope rather than the current position. 672fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!HasFallthrough) 673fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.back().push_back(PrevFilter); 674d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 675d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 676d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns the number of fanout produced by the filter. More fanout implies 677d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// the filter distinguishes more categories of instructions. 678d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonunsigned Filter::usefulness() const { 679ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!VariableInstructions.empty()) 680d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return FilteredInstructions.size(); 681d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 682d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return FilteredInstructions.size() + 1; 683d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 684d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 685d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson////////////////////////////////// 686d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 687d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Filterchooser Implementation // 688d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 689d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson////////////////////////////////// 690d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 691fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emit the decoder state machine table. 692fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 693fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable &Table, 694fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation, 695fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned BitWidth, 696fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach StringRef Namespace) const { 697fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "static const uint8_t DecoderTable" << Namespace 698fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << BitWidth << "[] = {\n"; 699fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 700fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation += 2; 701fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 702fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // FIXME: We may be able to use the NumToSkip values to recover 703fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // appropriate indentation levels. 704fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable::const_iterator I = Table.begin(); 705fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTable::const_iterator E = Table.end(); 706fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach while (I != E) { 707fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert (I < E && "incomplete decode table entry!"); 708fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 709fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint64_t Pos = I - Table.begin(); 710fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "/* " << Pos << " */"; 711fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.PadToColumn(12); 712fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 713fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach switch (*I) { 714fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach default: 71561131ab15fd593a2e295d79fe2714e7bc21f2ec8Joerg Sonnenberger PrintFatalError("invalid decode table opcode"); 716fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_ExtractField: { 717fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 718fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Start = *I++; 719fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Len = *I++; 720fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", " 721fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << Len << ", // Inst{"; 722fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Len > 1) 723fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << (Start + Len - 1) << "-"; 724fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << Start << "} ...\n"; 725fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 726fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 727fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_FilterValue: { 728fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 729fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_FilterValue, "; 730fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The filter value is ULEB128 encoded. 731fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach while (*I >= 128) 732fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 733fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 734fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 735fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // 16-bit numtoskip value. 736fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Byte = *I++; 737fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t NumToSkip = Byte; 738fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 739fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Byte = *I++; 740fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 741fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumToSkip |= Byte << 8; 742fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 743fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 744fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 745fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_CheckField: { 746fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 747fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Start = *I++; 748fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Len = *I++; 749fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", " 750fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << Len << ", ";// << Val << ", " << NumToSkip << ",\n"; 751fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // ULEB128 encoded field value. 752fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (; *I >= 128; ++I) 753fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I) << ", "; 754fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 755fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // 16-bit numtoskip value. 756fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Byte = *I++; 757fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t NumToSkip = Byte; 758fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 759fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Byte = *I++; 760fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 761fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumToSkip |= Byte << 8; 762fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 763fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 764fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 765fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_CheckPredicate: { 766fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 767fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_CheckPredicate, "; 768fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (; *I >= 128; ++I) 769fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I) << ", "; 770fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 771fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 772fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // 16-bit numtoskip value. 773fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Byte = *I++; 774fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint32_t NumToSkip = Byte; 775fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 776fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Byte = *I++; 777fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(Byte) << ", "; 778fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumToSkip |= Byte << 8; 779fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n"; 780fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 781fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 782fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_Decode: { 783fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 784fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Extract the ULEB128 encoded Opcode to a buffer. 785fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8], *p = Buffer; 786fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach while ((*p++ = *I++) >= 128) 787fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert((p - Buffer) <= (ptrdiff_t)sizeof(Buffer) 788fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach && "ULEB128 value too large!"); 789fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Decode the Opcode value. 790fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc = decodeULEB128(Buffer); 791fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_Decode, "; 792fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (p = Buffer; *p >= 128; ++p) 793fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*p) << ", "; 794fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*p) << ", "; 795fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 796fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Decoder index. 797fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (; *I >= 128; ++I) 798fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I) << ", "; 799fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << utostr(*I++) << ", "; 800fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 801fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Opcode: " 802fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << NumberedInstructions->at(Opc)->TheDef->getName() << "\n"; 803fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 804fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 805fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_SoftFail: { 806fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 807fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_SoftFail"; 808fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Positive mask 809fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint64_t Value = 0; 810fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Shift = 0; 811fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach do { 812fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << ", " << utostr(*I); 813fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Value += (*I & 0x7f) << Shift; 814fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Shift += 7; 815fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } while (*I++ >= 128); 816fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Value > 127) 817fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << " /* 0x" << utohexstr(Value) << " */"; 818fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Negative mask 819fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Value = 0; 820fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Shift = 0; 821fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach do { 822fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << ", " << utostr(*I); 823fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Value += (*I & 0x7f) << Shift; 824fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Shift += 7; 825fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } while (*I++ >= 128); 826fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Value > 127) 827fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << " /* 0x" << utohexstr(Value) << " */"; 828fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << ",\n"; 829fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 830fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 831fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach case MCD::OPC_Fail: { 832fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ++I; 833fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "MCD::OPC_Fail,\n"; 834fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 835fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 836fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 837fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 838fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "0\n"; 839fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 840fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation -= 2; 841fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 842fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "};\n\n"; 843fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 844fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 845fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FixedLenDecoderEmitter:: 846fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim GrosbachemitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, 847fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const { 848fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The predicate function is just a big switch statement based on the 849fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // input predicate index. 850fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, " 851fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "uint64_t Bits) {\n"; 852fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation += 2; 85354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman if (!Predicates.empty()) { 85454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "switch (Idx) {\n"; 85554911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; 85654911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman unsigned Index = 0; 857ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &Predicate : Predicates) { 858ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OS.indent(Indentation) << "case " << Index++ << ":\n"; 859ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OS.indent(Indentation+2) << "return (" << Predicate << ");\n"; 86054911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman } 86154911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "}\n"; 86254911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman } else { 86354911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman // No case statement to emit 86454911a5303f44694c43608eedf2142e9d65d7c22Aaron Ballman OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n"; 865fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 866fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation -= 2; 867fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n\n"; 868fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 869fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 870fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FixedLenDecoderEmitter:: 871fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim GrosbachemitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, 872fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Indentation) const { 873fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The decoder function is just a big switch statement based on the 874fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // input decoder index. 875fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "template<typename InsnType>\n"; 876fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S," 877fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Idx, InsnType insn, MCInst &MI,\n"; 878fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << " uint64_t " 87995d235ddb62805923f2f64edd71b15b904ee4a16Benjamin Kramer << "Address, const void *Decoder) {\n"; 880fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation += 2; 881fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "InsnType tmp;\n"; 882fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "switch (Idx) {\n"; 883fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; 884fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Index = 0; 885ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &Decoder : Decoders) { 886ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OS.indent(Indentation) << "case " << Index++ << ":\n"; 887ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OS << Decoder; 888fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation+2) << "return S;\n"; 889fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 890fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n"; 891fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Indentation -= 2; 892fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.indent(Indentation) << "}\n\n"; 893d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 894d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 895d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Populates the field of the insn given the start position and the number of 896d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// consecutive bits to scan for. 897d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 898d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns false if and on the first uninitialized bit value encountered. 899d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns true, otherwise. 900d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn, 901eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned StartBit, unsigned NumBits) const { 902d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Field = 0; 903d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 904d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < NumBits; ++i) { 905d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Insn[StartBit + i] == BIT_UNSET) 906d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 907d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 908d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Insn[StartBit + i] == BIT_TRUE) 909d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Field = Field | (1ULL << i); 910d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 911d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 912d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 913d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 914d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 915d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpFilterArray - dumpFilterArray prints out debugging info for the given 916d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// filter array as a series of chars. 917d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::dumpFilterArray(raw_ostream &o, 918eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::vector<bit_value_t> &filter) const { 9198cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--) { 920d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (filter[bitIndex - 1]) { 921d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNFILTERED: 922d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "."; 923d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 924d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNSET: 925d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "_"; 926d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 927d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_TRUE: 928d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "1"; 929d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 930d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_FALSE: 931d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "0"; 932d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 933d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 934d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 935d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 936d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 937d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpStack - dumpStack traverses the filter chooser chain and calls 938d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpFilterArray on each filter chooser up to the top level one. 939eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::dumpStack(raw_ostream &o, const char *prefix) const { 940eb5cd610700661bc46c660640c36949033247d2dCraig Topper const FilterChooser *current = this; 941d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 942d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson while (current) { 943d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << prefix; 944d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpFilterArray(o, current->FilterBitValues); 945d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << '\n'; 946d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson current = current->Parent; 947d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 948d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 949d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 950d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Called from Filter::recurse() when singleton exists. For debug purpose. 951eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::SingletonExists(unsigned Opc) const { 952d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn0; 953d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn0, Opc); 954d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 955d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "Singleton exists: " << nameWithID(Opc) 956d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson << " with its decoding dominating "; 957d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); ++i) { 958d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Opcodes[i] == Opc) continue; 959d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << nameWithID(Opcodes[i]) << ' '; 960d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 961d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 962d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 963d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpStack(errs(), "\t\t"); 964d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper for (unsigned i = 0; i < Opcodes.size(); ++i) { 965d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &Name = nameWithID(Opcodes[i]); 966d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 967d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\t' << Name << " "; 968d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), 969d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 970d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 971d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 972d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 973d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 974d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Calculates the island(s) needed to decode the instruction. 975d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// This returns a list of undecoded bits of an instructions, for example, 976d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 977d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// decoded bits in order to verify that the instruction matches the Opcode. 978d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonunsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits, 979d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::vector<unsigned> &EndBits, 980d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::vector<uint64_t> &FieldVals, 981eb5cd610700661bc46c660640c36949033247d2dCraig Topper const insn_t &Insn) const { 982d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Num, BitNo; 983d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Num = BitNo = 0; 984d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 985d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson uint64_t FieldVal = 0; 986d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 987d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 0: Init 988d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1: Water (the bit value does not affect decoding) 989d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 2: Island (well-known bit value needed for decoding) 990d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int State = 0; 991d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int Val = -1; 992d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 993f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (unsigned i = 0; i < BitWidth; ++i) { 994d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Val = Value(Insn[i]); 995d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool Filtered = PositionFiltered(i); 996d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (State) { 997655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper default: llvm_unreachable("Unreachable code!"); 998d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 0: 999d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 1: 1000d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Filtered || Val == -1) 1001d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 1; // Still in Water 1002d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else { 1003d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 2; // Into the Island 1004d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitNo = 0; 1005d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBits.push_back(i); 1006d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVal = Val; 1007d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1008d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1009d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 2: 1010d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Filtered || Val == -1) { 1011d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 1; // Into the Water 1012d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson EndBits.push_back(i - 1); 1013d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.push_back(FieldVal); 1014d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Num; 1015d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } else { 1016d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 2; // Still in Island 1017d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++BitNo; 1018d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVal = FieldVal | Val << BitNo; 1019d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1020d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1021d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1022d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1023d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we are still in Island after the loop, do some housekeeping. 1024d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (State == 2) { 1025f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson EndBits.push_back(BitWidth - 1); 1026d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.push_back(FieldVal); 1027d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Num; 1028d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1029d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1030d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(StartBits.size() == Num && EndBits.size() == Num && 1031d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.size() == Num); 1032d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return Num; 1033d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1034d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1035d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Andersonvoid FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, 1036eb5cd610700661bc46c660640c36949033247d2dCraig Topper const OperandInfo &OpInfo) const { 1037eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::string &Decoder = OpInfo.Decoder; 1038d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 103937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (OpInfo.numFields() != 1) 1040c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "tmp = 0;\n"; 104137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 104237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const EncodingField &EF : OpInfo) { 104337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines o.indent(Indentation) << "tmp "; 104437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (OpInfo.numFields() != 1) o << '|'; 104537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines o << "= fieldFromInstruction" 104637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "(insn, " << EF.Base << ", " << EF.Width << ')'; 104737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (OpInfo.numFields() != 1 || EF.Offset != 0) 104837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines o << " << " << EF.Offset; 104937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines o << ";\n"; 1050d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1051d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1052d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Decoder != "") 1053c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << Emitter->GuardPrefix << Decoder 10549c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach << "(MI, tmp, Address, Decoder)" 10559c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach << Emitter->GuardPostfix << "\n"; 1056d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson else 1057c056483fc6cfab4307559afb0538323781b28d53Craig Topper o.indent(Indentation) << "MI.addOperand(MCOperand::CreateImm(tmp));\n"; 1058d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1059d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson} 1060d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1061fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation, 1062fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1063ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &Op : Operands.find(Opc)->second) { 1064fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // If a custom instruction decoder was specified, use that. 1065ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Op.numFields() == 0 && Op.Decoder.size()) { 1066ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OS.indent(Indentation) << Emitter->GuardPrefix << Op.Decoder 1067fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "(MI, insn, Address, Decoder)" 1068fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << Emitter->GuardPostfix << "\n"; 1069fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach break; 1070fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1071fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1072ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines emitBinaryParser(OS, Indentation, Op); 1073fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1074fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1075fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1076fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachunsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, 1077fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1078fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Build up the predicate string. 1079fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<256> Decoder; 1080fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // FIXME: emitDecoder() function can take a buffer directly rather than 1081fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // a stream. 1082fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(Decoder); 1083c056483fc6cfab4307559afb0538323781b28d53Craig Topper unsigned I = 4; 1084fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecoder(S, I, Opc); 1085fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1086fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1087fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Using the full decoder string as the key value here is a bit 1088fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // heavyweight, but is effective. If the string comparisons become a 1089fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // performance concern, we can implement a mangling of the predicate 1090fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // data easilly enough with a map back to the actual string. That's 1091fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // overkill for now, though. 1092fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1093fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Make sure the predicate is in the table. 10944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Decoders.insert(StringRef(Decoder)); 1095fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Now figure out the index for when we write out the table. 1096fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderSet::const_iterator P = std::find(Decoders.begin(), 1097fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Decoders.end(), 1098fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Decoder.str()); 1099fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return (unsigned)(P - Decoders.begin()); 1100fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1101fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1102a5d585685493d85d5cb72b831a68ec747ae55a86James Molloystatic void emitSinglePredicateMatch(raw_ostream &o, StringRef str, 1103eb5cd610700661bc46c660640c36949033247d2dCraig Topper const std::string &PredicateNamespace) { 110422b4c819d463da7eadb20162d049ee89de746bceAndrew Trick if (str[0] == '!') 110522b4c819d463da7eadb20162d049ee89de746bceAndrew Trick o << "!(Bits & " << PredicateNamespace << "::" 110622b4c819d463da7eadb20162d049ee89de746bceAndrew Trick << str.slice(1,str.size()) << ")"; 1107a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy else 110822b4c819d463da7eadb20162d049ee89de746bceAndrew Trick o << "(Bits & " << PredicateNamespace << "::" << str << ")"; 1109a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy} 1110a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1111a5d585685493d85d5cb72b831a68ec747ae55a86James Molloybool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 1112eb5cd610700661bc46c660640c36949033247d2dCraig Topper unsigned Opc) const { 11139c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach ListInit *Predicates = 11149c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); 11152c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar bool IsFirstEmission = true; 1116a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy for (unsigned i = 0; i < Predicates->getSize(); ++i) { 1117a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy Record *Pred = Predicates->getElementAsRecord(i); 1118a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (!Pred->getValue("AssemblerMatcherPredicate")) 1119a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy continue; 1120a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1121a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::string P = Pred->getValueAsString("AssemblerCondString"); 1122a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1123a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (!P.length()) 1124a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy continue; 1125a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 11262c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar if (!IsFirstEmission) 1127a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 1128a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1129a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy StringRef SR(P); 1130a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::pair<StringRef, StringRef> pairs = SR.split(','); 1131a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy while (pairs.second.size()) { 1132a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); 1133a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 1134a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy pairs = pairs.second.split(','); 1135a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 1136a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); 11372c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar IsFirstEmission = false; 1138a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 1139a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy return Predicates->getSize() > 0; 1140ed968a9a045cb6fecb80abfb7e938954fed54927Andrew Trick} 1141a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 1142fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachbool FilterChooser::doesOpcodeNeedPredicate(unsigned Opc) const { 1143fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach ListInit *Predicates = 1144fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); 1145fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (unsigned i = 0; i < Predicates->getSize(); ++i) { 1146fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Record *Pred = Predicates->getElementAsRecord(i); 1147fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!Pred->getValue("AssemblerMatcherPredicate")) 1148fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach continue; 1149fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1150fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach std::string P = Pred->getValueAsString("AssemblerCondString"); 1151fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1152fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!P.length()) 1153fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach continue; 1154fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1155fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return true; 1156fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1157fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return false; 1158fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1159fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1160fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachunsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo, 1161fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach StringRef Predicate) const { 1162fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Using the full predicate string as the key value here is a bit 1163fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // heavyweight, but is effective. If the string comparisons become a 1164fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // performance concern, we can implement a mangling of the predicate 1165fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // data easilly enough with a map back to the actual string. That's 1166fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // overkill for now, though. 1167fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1168fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Make sure the predicate is in the table. 1169fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Predicates.insert(Predicate.str()); 1170fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Now figure out the index for when we write out the table. 1171fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach PredicateSet::const_iterator P = std::find(TableInfo.Predicates.begin(), 1172fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Predicates.end(), 1173fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Predicate.str()); 1174fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return (unsigned)(P - TableInfo.Predicates.begin()); 1175fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1176fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1177fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo, 1178fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1179fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (!doesOpcodeNeedPredicate(Opc)) 1180fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1181fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1182fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Build up the predicate string. 1183fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<256> Predicate; 1184fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // FIXME: emitPredicateMatch() functions can take a buffer directly rather 1185fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // than a stream. 1186fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream PS(Predicate); 1187fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned I = 0; 1188fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateMatch(PS, I, Opc); 1189fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1190fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Figure out the index into the predicate table for the predicate just 1191fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // computed. 1192fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned PIdx = getPredicateIndex(TableInfo, PS.str()); 1193fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> PBytes; 1194fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(PBytes); 1195fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(PIdx, S); 1196fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1197fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1198fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_CheckPredicate); 1199fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Predicate index 12008cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = PBytes.size(); i != e; ++i) 1201fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(PBytes[i]); 1202fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Push location for NumToSkip backpatching. 1203fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 1204fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1205fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1206fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 1207fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1208fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo, 1209fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 12109c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach BitsInit *SFBits = 12119c826d2d3c16e31bd97d4626efe49937d2de9aaaJim Grosbach AllInstructions[Opc]->TheDef->getValueAsBitsInit("SoftFail"); 12123015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (!SFBits) return; 12133015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy BitsInit *InstBits = AllInstructions[Opc]->TheDef->getValueAsBitsInit("Inst"); 12143015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12153015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy APInt PositiveMask(BitWidth, 0ULL); 12163015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy APInt NegativeMask(BitWidth, 0ULL); 12173015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy for (unsigned i = 0; i < BitWidth; ++i) { 12183015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bit_value_t B = bitFromBits(*SFBits, i); 12193015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bit_value_t IB = bitFromBits(*InstBits, i); 12203015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12213015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (B != BIT_TRUE) continue; 12223015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12233015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy switch (IB) { 12243015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy case BIT_FALSE: 12253015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is meant to be false, so emit a check to see if it is true. 12263015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy PositiveMask.setBit(i); 12273015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy break; 12283015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy case BIT_TRUE: 12293015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is meant to be true, so emit a check to see if it is false. 12303015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy NegativeMask.setBit(i); 12313015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy break; 12323015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy default: 12333015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy // The bit is not set; this must be an error! 12343015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy StringRef Name = AllInstructions[Opc]->TheDef->getName(); 1235fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in " << Name 1236fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " is set but Inst{" << i << "} is unset!\n" 12373015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy << " - You can only mark a bit as SoftFail if it is fully defined" 12383015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy << " (1/0 - not '?') in Inst\n"; 1239fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 12403015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy } 12413015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy } 12423015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12433015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bool NeedPositiveMask = PositiveMask.getBoolValue(); 12443015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy bool NeedNegativeMask = NegativeMask.getBoolValue(); 12453015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 12463015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy if (!NeedPositiveMask && !NeedNegativeMask) 12473015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy return; 12483015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 1249fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_SoftFail); 1250fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1251fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> MaskBytes; 1252fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(MaskBytes); 1253fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (NeedPositiveMask) { 1254fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(PositiveMask.getZExtValue(), S); 1255fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 12568cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i) 1257fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MaskBytes[i]); 1258fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } else 1259fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1260fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (NeedNegativeMask) { 1261fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach MaskBytes.clear(); 1262fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.resync(); 1263fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(NegativeMask.getZExtValue(), S); 1264fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 12658cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = MaskBytes.size(); i != e; ++i) 1266fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MaskBytes[i]); 1267fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } else 1268fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 12693015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy} 12703015dfb7d739f4cc0b1408555889ecea880ffac9James Molloy 1271fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emits table entries to decode the singleton. 1272fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo, 1273fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned Opc) const { 1274d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> StartBits; 1275d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> EndBits; 1276d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<uint64_t> FieldVals; 1277d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 1278d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn, Opc); 1279d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1280d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Look for islands of undecoded bits of the singleton. 1281d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getIslands(StartBits, EndBits, FieldVals, Insn); 1282d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1283d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Size = StartBits.size(); 1284d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1285fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the predicate table entry if one is needed. 1286fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateTableEntry(TableInfo, Opc); 1287d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1288fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Check any additional encoding fields needed. 12898cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned I = Size; I != 0; --I) { 12908cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper unsigned NumBits = EndBits[I-1] - StartBits[I-1] + 1; 1291fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_CheckField); 1292fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(StartBits[I-1]); 1293fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(NumBits); 1294fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8], *p; 1295fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(FieldVals[I-1], Buffer); 1296fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (p = Buffer; *p >= 128 ; ++p) 1297fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1298fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1299fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Push location for NumToSkip backpatching. 1300fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.back().push_back(TableInfo.Table.size()); 1301fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The fixup is always 16-bits, so go ahead and allocate the space 1302fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // in the table so all our relative position calculations work OK even 1303fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // before we fully resolve the real value here. 1304fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1305fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(0); 1306d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1307d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1308fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Check for soft failure of the match. 1309fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSoftFailTableEntry(TableInfo, Opc); 1310fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1311fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_Decode); 1312fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach uint8_t Buffer[8], *p; 1313fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(Opc, Buffer); 1314fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (p = Buffer; *p >= 128 ; ++p) 1315fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1316fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(*p); 1317fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1318fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach unsigned DIdx = getDecoderIndex(TableInfo.Decoders, Opc); 1319fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach SmallString<16> Bytes; 1320fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach raw_svector_ostream S(Bytes); 1321fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach encodeULEB128(DIdx, S); 1322fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach S.flush(); 1323fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1324fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Decoder index 13258cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned i = 0, e = Bytes.size(); i != e; ++i) 1326fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(Bytes[i]); 1327d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1328d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1329fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// Emits table entries to decode the singleton, and then to decode the rest. 1330fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo, 1331fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const Filter &Best) const { 1332d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Opc = Best.getSingletonOpc(); 1333d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1334fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // complex singletons need predicate checks from the first singleton 1335fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // to refer forward to the variable filterchooser that follows. 1336fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.push_back(FixupList()); 1337d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1338fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Opc); 1339d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1340fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(), 1341fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.size()); 1342fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.pop_back(); 1343fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1344fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Best.getVariableFC().emitTableEntries(TableInfo); 1345d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1346d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1347fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 1348d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Assign a single filter and run with it. Top level API client can initialize 1349d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// with a single filter to start the filtering process. 1350eb5cd610700661bc46c660640c36949033247d2dCraig Toppervoid FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit, 1351eb5cd610700661bc46c660640c36949033247d2dCraig Topper bool mixed) { 1352d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.clear(); 135337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Filters.push_back(Filter(*this, startBit, numBit, true)); 1354d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = 0; // Sole Filter instance to choose from. 1355d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().recurse(); 1356d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1357d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1358d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// reportRegion is a helper function for filterProcessor to mark a region as 1359d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// eligible for use as a filter region. 1360d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit, 1361d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper unsigned BitIndex, bool AllowMixed) { 1362d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (RA == ATTR_MIXED && AllowMixed) 1363d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, true)); 1364d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else if (RA == ATTR_ALL_SET && !AllowMixed) 1365d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, false)); 1366d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1367d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1368d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// FilterProcessor scans the well-known encoding bits of the instructions and 1369d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// builds up a list of candidate filters. It chooses the best filter and 1370d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// recursively descends down the decoding tree. 1371d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) { 1372d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.clear(); 1373d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = -1; 1374d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned numInstructions = Opcodes.size(); 1375d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1376d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(numInstructions && "Filter created with no instructions"); 1377d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1378d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // No further filtering is necessary. 1379d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (numInstructions == 1) 1380d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1381d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1382d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Heuristics. See also doFilter()'s "Heuristics" comment when num of 1383d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instructions is 3. 1384d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (AllowMixed && !Greedy) { 1385d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(numInstructions == 3); 1386d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1387d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); ++i) { 1388d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> StartBits; 1389d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> EndBits; 1390d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<uint64_t> FieldVals; 1391d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 1392d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1393d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn, Opcodes[i]); 1394d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1395d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Look for islands of undecoded bits of any instruction. 1396d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) { 1397d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Found an instruction with island(s). Now just assign a filter. 1398eb5cd610700661bc46c660640c36949033247d2dCraig Topper runSingleFilter(StartBits[0], EndBits[0] - StartBits[0] + 1, true); 1399d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1400d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1401d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1402d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1403d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 14048cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper unsigned BitIndex; 1405d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1406d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We maintain BIT_WIDTH copies of the bitAttrs automaton. 1407d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The automaton consumes the corresponding bit from each 1408d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instruction. 1409d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1410d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Input symbols: 0, 1, and _ (unset). 1411d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED. 1412d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Initial state: NONE. 1413d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1414d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ------- [01] -> (ALL_SET) 1415d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ------- _ ----> (ALL_UNSET) 1416d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) ---- [01] -> (ALL_SET) 1417d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) ---- _ ----> (MIXED) 1418d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_UNSET) -- [01] -> (MIXED) 1419d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_UNSET) -- _ ----> (ALL_UNSET) 1420d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ------ . ----> (MIXED) 1421d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (FILTERED)---- . ----> (FILTERED) 1422d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1423f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bitAttr_t> bitAttrs; 1424d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1425d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FILTERED bit positions provide no entropy and are not worthy of pursuing. 1426d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position. 1427f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) 1428d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (FilterBitValues[BitIndex] == BIT_TRUE || 1429d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterBitValues[BitIndex] == BIT_FALSE) 1430f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson bitAttrs.push_back(ATTR_FILTERED); 1431d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1432f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson bitAttrs.push_back(ATTR_NONE); 1433d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 14348cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (unsigned InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) { 1435d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t insn; 1436d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1437d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(insn, Opcodes[InsnIndex]); 1438d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1439f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 1440d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttrs[BitIndex]) { 1441d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1442d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] == BIT_UNSET) 1443d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_ALL_UNSET; 1444d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1445d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_ALL_SET; 1446d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1447d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1448d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] == BIT_UNSET) 1449d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_MIXED; 1450d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1451d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1452d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] != BIT_UNSET) 1453d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_MIXED; 1454d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1455d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1456d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1457d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1458d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1459d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1460d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1461d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1462d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The regionAttr automaton consumes the bitAttrs automatons' state, 1463d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // lowest-to-highest. 1464d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1465d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed) 1466d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // States: NONE, ALL_SET, MIXED 1467d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Initial state: NONE 1468d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1469d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- F --> (NONE) 1470d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- S --> (ALL_SET) ; and set region start 1471d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- U --> (NONE) 1472d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- M --> (MIXED) ; and set region start 1473d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region 1474d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- S --> (ALL_SET) 1475d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region 1476d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region 1477d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- F --> (NONE) ; and report a MIXED region 1478d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region 1479d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- U --> (NONE) ; and report a MIXED region 1480d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- M --> (MIXED) 1481d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1482d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttr_t RA = ATTR_NONE; 1483d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned StartBit = 0; 1484d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 14858cd9eaef0102771b93b9336c9b99afa4e18fd45dCraig Topper for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 1486d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttr_t bitAttr = bitAttrs[BitIndex]; 1487d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1488d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(bitAttr != ATTR_NONE && "Bit without attributes"); 1489d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1490d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (RA) { 1491d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1492d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1493d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1494d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1495d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1496d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1497d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_ALL_SET; 1498d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1499d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1500d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1501d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1502d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1503d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_MIXED; 1504d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1505d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1506655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1507d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1508d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1509d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1510d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1511d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1512d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1513d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1514d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1515d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1516d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1517d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1518d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1519d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1520d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1521d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1522d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1523d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1524d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_MIXED; 1525d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1526d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1527655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1528d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1529d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1530d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1531d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1532d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1533d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1534d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1535d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1536d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1537d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1538d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1539d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1540d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_ALL_SET; 1541d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1542d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1543d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1544d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1545d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1546d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1547d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1548d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1549655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unexpected bitAttr!"); 1550d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1551d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1552d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1553655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("regionAttr state machine has no ATTR_UNSET state"); 1554d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1555655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("regionAttr state machine has no ATTR_FILTERED state"); 1556d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1557d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1558d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1559d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // At the end, if we're still in ALL_SET or MIXED states, report a region 1560d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (RA) { 1561d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1562d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1563d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1564d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1565d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1566d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1567d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1568d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1569d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1570d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1571d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1572d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1573d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1574d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1575d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We have finished with the filter processings. Now it's time to choose 1576d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the best performing filter. 1577d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = 0; 1578d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool AllUseless = true; 1579d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned BestScore = 0; 1580d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1581d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = Filters.size(); i != e; ++i) { 1582d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Usefulness = Filters[i].usefulness(); 1583d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1584d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Usefulness) 1585d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson AllUseless = false; 1586d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1587d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Usefulness > BestScore) { 1588d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = i; 1589d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestScore = Usefulness; 1590d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1591d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1592d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1593d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (!AllUseless) 1594d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().recurse(); 1595d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1596d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return !AllUseless; 1597d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} // end of FilterChooser::filterProcessor(bool) 1598d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1599d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Decides on the best configuration of filter(s) to use in order to decode 1600d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// the instructions. A conflict of instructions may occur, in which case we 1601d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// dump the conflict set to the standard error. 1602d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::doFilter() { 1603d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Num = Opcodes.size(); 1604d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(Num && "FilterChooser created with no instructions"); 1605d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1606d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Try regions of consecutive known bit values first. 1607d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterProcessor(false)) 1608d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1609d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1610d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Then regions of mixed bits (both known and unitialized bit values allowed). 1611d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterProcessor(true)) 1612d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1613d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1614d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where 1615d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a 1616d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // well-known encoding pattern. In such case, we backtrack and scan for the 1617d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the very first consecutive ATTR_ALL_SET region and assign a filter to it. 1618d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Num == 3 && filterProcessor(true, false)) 1619d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1620d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1621d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we come to here, the instruction decoding has failed. 1622d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set the BestIndex to -1 to indicate so. 1623d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = -1; 1624d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1625d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1626fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitTableEntries - Emit state machine entries to decode our share of 1627fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// instructions. 1628fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachvoid FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const { 1629fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach if (Opcodes.size() == 1) { 1630d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // There is only one instruction in the set, which is great! 1631d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Call emitSingletonDecoder() to see whether there are any remaining 1632d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // encodings bits. 1633fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Opcodes[0]); 1634fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1635fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach } 1636d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1637d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Choose the best filter to do the decodings! 1638d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (BestIndex != -1) { 1639eb5cd610700661bc46c660640c36949033247d2dCraig Topper const Filter &Best = Filters[BestIndex]; 1640d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Best.getNumFiltered() == 1) 1641fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitSingletonTableEntry(TableInfo, Best); 1642d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1643fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach Best.emitTableEntry(TableInfo); 1644fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach return; 1645d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1646d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1647fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // We don't know how to decode these instructions! Dump the 1648fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // conflict set and bail. 1649d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1650d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Print out useful conflict information for postmortem analysis. 1651d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "Decoding Conflict:\n"; 1652d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1653d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpStack(errs(), "\t\t"); 1654d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1655d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper for (unsigned i = 0; i < Opcodes.size(); ++i) { 1656d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &Name = nameWithID(Opcodes[i]); 1657d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1658d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\t' << Name << " "; 1659d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), 1660d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 1661d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1662d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1663d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1664d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 166536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool populateInstruction(CodeGenTarget &Target, 166636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const CodeGenInstruction &CGI, unsigned Opc, 1667d936045625ae2e101d3a9544586d7568c6dbacc0Craig Topper std::map<unsigned, std::vector<OperandInfo> > &Operands){ 1668d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const Record &Def = *CGI.TheDef; 1669d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If all the bit positions are not specified; do not decode this instruction. 1670d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We are bound to fail! For proper disassembly, the well-known encoding bits 1671d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // of the instruction must be fully specified. 1672d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 167305bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit &Bits = getBitsField(Def, "Inst"); 1674806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach if (Bits.allInComplete()) return false; 1675806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach 1676d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<OperandInfo> InsnOperands; 1677d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1678d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If the instruction has specified a custom decoding hook, use that instead 1679d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // of trying to auto-generate the decoder. 1680d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::string InstDecoder = Def.getValueAsString("DecoderMethod"); 1681d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (InstDecoder != "") { 1682d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson InsnOperands.push_back(OperandInfo(InstDecoder)); 1683d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Operands[Opc] = InsnOperands; 1684d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1685d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1686d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1687d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Generate a description of the operand of the instruction that we know 1688d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // how to decode automatically. 1689d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FIXME: We'll need to have a way to manually override this as needed. 1690d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1691d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Gather the outputs/inputs of the instruction, so we can find their 1692d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // positions in the encoding. This assumes for now that they appear in the 1693d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // MCInst in the order that they're listed. 169405bce0beee87512e52428d4b80f5a8e79a949576David Greene std::vector<std::pair<Init*, std::string> > InOutOperands; 169505bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *Out = Def.getValueAsDag("OutOperandList"); 169605bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *In = Def.getValueAsDag("InOperandList"); 1697d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Out->getNumArgs(); ++i) 1698d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson InOutOperands.push_back(std::make_pair(Out->getArg(i), Out->getArgName(i))); 1699d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < In->getNumArgs(); ++i) 1700d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson InOutOperands.push_back(std::make_pair(In->getArg(i), In->getArgName(i))); 1701d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 170200ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson // Search for tied operands, so that we can correctly instantiate 170300ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson // operands that are not explicitly represented in the encoding. 1704ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson std::map<std::string, std::string> TiedNames; 170500ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson for (unsigned i = 0; i < CGI.Operands.size(); ++i) { 170600ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson int tiedTo = CGI.Operands[i].getTiedRegister(); 1707ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson if (tiedTo != -1) { 170836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::pair<unsigned, unsigned> SO = 170936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands.getSubOperandNumber(tiedTo); 171036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TiedNames[InOutOperands[i].second] = InOutOperands[SO.first].second; 171136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TiedNames[InOutOperands[SO.first].second] = InOutOperands[i].second; 171236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 171336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 171436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 171536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::map<std::string, std::vector<OperandInfo> > NumberedInsnOperands; 171636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::set<std::string> NumberedInsnOperandsNoTie; 171736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Target.getInstructionSet()-> 171836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getValueAsBit("decodePositionallyEncodedOperands")) { 171936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const std::vector<RecordVal> &Vals = Def.getValues(); 172036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned NumberedOp = 0; 172136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 172236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::set<unsigned> NamedOpIndices; 172336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Target.getInstructionSet()-> 172436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getValueAsBit("noNamedPositionallyEncodedOperands")) 172536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Collect the set of operand indices that might correspond to named 172636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // operand, and skip these when assigning operands based on position. 172736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 172836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned OpIdx; 172936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx)) 173036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 173136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 173236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NamedOpIndices.insert(OpIdx); 173336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 173436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 173536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 173636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Ignore fixed fields in the record, we're looking for values like: 173736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // bits<5> RST = { ?, ?, ?, ?, ? }; 173836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete()) 173936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 174036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 174136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Determine if Vals[i] actually contributes to the Inst encoding. 174236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned bi = 0; 174336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (; bi < Bits.getNumBits(); ++bi) { 1744dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines VarInit *Var = nullptr; 174536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi)); 174636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BI) 174736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Var = dyn_cast<VarInit>(BI->getBitVar()); 174836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 174936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Var = dyn_cast<VarInit>(Bits.getBit(bi)); 175036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 175136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Var && Var->getName() == Vals[i].getName()) 175236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 175336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 175436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 175536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (bi == Bits.getNumBits()) 175636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 175736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 175836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Skip variables that correspond to explicitly-named operands. 175936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned OpIdx; 176036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx)) 176136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 176236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 176336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get the bit range for this operand: 176436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned bitStart = bi++, bitWidth = 1; 176536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (; bi < Bits.getNumBits(); ++bi) { 1766dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines VarInit *Var = nullptr; 176736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi)); 176836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BI) 176936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Var = dyn_cast<VarInit>(BI->getBitVar()); 177036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 177136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Var = dyn_cast<VarInit>(Bits.getBit(bi)); 177236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 177336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Var) 177436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 177536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 177636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Var->getName() != Vals[i].getName()) 177736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 177836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 177936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++bitWidth; 178036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 178136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 178236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned NumberOps = CGI.Operands.size(); 178336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (NumberedOp < NumberOps && 178436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) || 1785ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (!NamedOpIndices.empty() && NamedOpIndices.count( 178636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands.getSubOperandNumber(NumberedOp).first)))) 178736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++NumberedOp; 178836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 178936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OpIdx = NumberedOp++; 179036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 179136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // OpIdx now holds the ordered operand number of Vals[i]. 179236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::pair<unsigned, unsigned> SO = 179336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands.getSubOperandNumber(OpIdx); 179436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const std::string &Name = CGI.Operands[SO.first].Name; 179536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 179636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Numbered operand mapping for " << Def.getName() << ": " << 179736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Name << "(" << SO.first << ", " << SO.second << ") => " << 179836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Vals[i].getName() << "\n"); 179936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 180036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string Decoder = ""; 180136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Record *TypeRecord = CGI.Operands[SO.first].Rec; 180236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 180336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod"); 180436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringInit *String = DecoderString ? 1805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines dyn_cast<StringInit>(DecoderString->getValue()) : nullptr; 180636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (String && String->getValue() != "") 180736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Decoder = String->getValue(); 180836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 180936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Decoder == "" && 181036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands[SO.first].MIOperandInfo && 181136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands[SO.first].MIOperandInfo->getNumArgs()) { 181236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Init *Arg = CGI.Operands[SO.first].MIOperandInfo-> 181336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getArg(SO.second); 181436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TypedInit *TI = cast<TypedInit>(Arg)) { 181536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RecordRecTy *Type = cast<RecordRecTy>(TI->getType()); 181636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TypeRecord = Type->getRecord(); 181736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 181836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 181936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 182036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isReg = false; 182136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TypeRecord->isSubClassOf("RegisterOperand")) 182236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TypeRecord = TypeRecord->getValueAsDef("RegClass"); 182336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TypeRecord->isSubClassOf("RegisterClass")) { 182436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; 182536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines isReg = true; 182636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (TypeRecord->isSubClassOf("PointerLikeRegClass")) { 182736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Decoder = "DecodePointerLikeRegClass" + 182836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines utostr(TypeRecord->getValueAsInt("RegClassKind")); 182936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines isReg = true; 183036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 183136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 183236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DecoderString = TypeRecord->getValue("DecoderMethod"); 183336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines String = DecoderString ? 1834dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines dyn_cast<StringInit>(DecoderString->getValue()) : nullptr; 183536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!isReg && String && String->getValue() != "") 183636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Decoder = String->getValue(); 183736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 183836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OperandInfo OpInfo(Decoder); 183936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OpInfo.addField(bitStart, bitWidth, 0); 184036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 184136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumberedInsnOperands[Name].push_back(OpInfo); 184236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 184336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FIXME: For complex operands with custom decoders we can't handle tied 184436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // sub-operands automatically. Skip those here and assume that this is 184536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // fixed up elsewhere. 184636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CGI.Operands[SO.first].MIOperandInfo && 184736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands[SO.first].MIOperandInfo->getNumArgs() > 1 && 184836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines String && String->getValue() != "") 184936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NumberedInsnOperandsNoTie.insert(Name); 1850ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson } 185100ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson } 185200ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson 1853d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // For each operand, see if we can figure out where it is encoded. 1854ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &Op : InOutOperands) { 1855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!NumberedInsnOperands[Op.second].empty()) { 185636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InsnOperands.insert(InsnOperands.end(), 1857ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NumberedInsnOperands[Op.second].begin(), 1858ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NumberedInsnOperands[Op.second].end()); 185936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 1860ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1861ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!NumberedInsnOperands[TiedNames[Op.second]].empty()) { 1862ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!NumberedInsnOperandsNoTie.count(TiedNames[Op.second])) { 186336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Figure out to which (sub)operand we're tied. 1864ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned i = CGI.Operands.getOperandNamed(TiedNames[Op.second]); 186536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int tiedTo = CGI.Operands[i].getTiedRegister(); 186636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (tiedTo == -1) { 1867ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines i = CGI.Operands.getOperandNamed(Op.second); 186836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines tiedTo = CGI.Operands[i].getTiedRegister(); 186936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 187036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 187136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (tiedTo != -1) { 187236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::pair<unsigned, unsigned> SO = 187336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CGI.Operands.getSubOperandNumber(tiedTo); 187436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1875ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InsnOperands.push_back(NumberedInsnOperands[TiedNames[Op.second]] 187636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines [SO.second]); 187736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 187836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 187936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 188036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 188136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1882d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::string Decoder = ""; 1883d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1884d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // At this point, we can locate the field, but we need to know how to 1885d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // interpret it. As a first step, require the target to provide callbacks 1886d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // for decoding register classes. 1887d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // FIXME: This need to be extended to handle instructions with custom 1888d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // decoder methods, and operands with (simple) MIOperandInfo's. 1889ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TypedInit *TI = cast<TypedInit>(Op.first); 18903f7b7f8ce0b050fc6a0100839d9c5a84198b2aedSean Silva RecordRecTy *Type = cast<RecordRecTy>(TI->getType()); 1891d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Record *TypeRecord = Type->getRecord(); 1892d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson bool isReg = false; 1893d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (TypeRecord->isSubClassOf("RegisterOperand")) 1894d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson TypeRecord = TypeRecord->getValueAsDef("RegClass"); 1895d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (TypeRecord->isSubClassOf("RegisterClass")) { 1896d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; 1897d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson isReg = true; 189836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (TypeRecord->isSubClassOf("PointerLikeRegClass")) { 189936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Decoder = "DecodePointerLikeRegClass" + 190036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines utostr(TypeRecord->getValueAsInt("RegClassKind")); 190136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines isReg = true; 1902d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1903d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1904d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod"); 190505bce0beee87512e52428d4b80f5a8e79a949576David Greene StringInit *String = DecoderString ? 1906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines dyn_cast<StringInit>(DecoderString->getValue()) : nullptr; 1907d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (!isReg && String && String->getValue() != "") 1908d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Decoder = String->getValue(); 1909d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1910d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OperandInfo OpInfo(Decoder); 1911d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Base = ~0U; 1912d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Width = 0; 1913d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Offset = 0; 1914d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1915d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) { 1916dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines VarInit *Var = nullptr; 19176cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva VarBitInit *BI = dyn_cast<VarBitInit>(Bits.getBit(bi)); 1918cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson if (BI) 19196cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva Var = dyn_cast<VarInit>(BI->getBitVar()); 1920cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson else 19216cfc806a6b82b60a3e923b6b89f2b4da62cdb50bSean Silva Var = dyn_cast<VarInit>(Bits.getBit(bi)); 1922cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson 1923cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson if (!Var) { 1924d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) { 1925d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1926d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = ~0U; 1927d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 0; 1928d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Offset = 0; 1929d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1930d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson continue; 1931d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1932d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1933ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Var->getName() != Op.second && 1934ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Var->getName() != TiedNames[Op.second]) { 1935d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) { 1936d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1937d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = ~0U; 1938d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 0; 1939d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Offset = 0; 1940d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1941d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson continue; 1942d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1943d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1944d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base == ~0U) { 1945d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = bi; 1946d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 1; 1947cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson Offset = BI ? BI->getBitNum() : 0; 1948cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson } else if (BI && BI->getBitNum() != Offset + Width) { 1949eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson OpInfo.addField(Base, Width, Offset); 1950eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Base = bi; 1951eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Width = 1; 1952eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Offset = BI->getBitNum(); 1953d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } else { 1954d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson ++Width; 1955d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1956d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1957d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1958d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) 1959d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1960d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1961d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (OpInfo.numFields() > 0) 1962d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson InsnOperands.push_back(OpInfo); 1963d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1964d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1965d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Operands[Opc] = InsnOperands; 1966d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1967d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1968d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#if 0 1969d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson DEBUG({ 1970d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Dumps the instruction encoding bits. 1971d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), Bits); 1972d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1973d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1974d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1975d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Dumps the list of operand info. 1976d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { 1977d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const CGIOperandList::OperandInfo &Info = CGI.Operands[i]; 1978d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &OperandName = Info.Name; 1979d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const Record &OperandDef = *Info.Rec; 1980d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1981d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n"; 1982d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1983d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson }); 1984d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#endif 1985d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1986d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1987d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1988d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1989fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitFieldFromInstruction - Emit the templated helper function 1990fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// fieldFromInstruction(). 1991fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstatic void emitFieldFromInstruction(formatted_raw_ostream &OS) { 1992fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "// Helper function for extracting fields from encoded instructions.\n" 1993fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "template<typename InsnType>\n" 1994fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "static InsnType fieldFromInstruction(InsnType insn, unsigned startBit,\n" 1995fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned numBits) {\n" 1996fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " assert(startBit + numBits <= (sizeof(InsnType)*8) &&\n" 1997fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " \"Instruction field out of bounds!\");\n" 1998fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType fieldMask;\n" 1999fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (numBits == sizeof(InsnType)*8)\n" 2000fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " fieldMask = (InsnType)(-1LL);\n" 2001fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " else\n" 2002fc093def2d892a2ea068d3b9e6d5839c187cc942NAKAMURA Takumi << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n" 2003fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return (insn & fieldMask) >> startBit;\n" 2004fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "}\n\n"; 2005fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach} 2006f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2007fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// emitDecodeInstruction - Emit the templated helper function 2008fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach// decodeInstruction(). 2009fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbachstatic void emitDecodeInstruction(formatted_raw_ostream &OS) { 2010fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "template<typename InsnType>\n" 2011fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,\n" 2012fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType insn, uint64_t Address,\n" 2013fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const void *DisAsm,\n" 2014fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const MCSubtargetInfo &STI) {\n" 2015fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " uint64_t Bits = STI.getFeatureBits();\n" 2016fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 2017fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " const uint8_t *Ptr = DecodeTable;\n" 20189bb938c5401db90817d16b32fa078066fb586551Jim Grosbach << " uint32_t CurFieldValue = 0;\n" 2019fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DecodeStatus S = MCDisassembler::Success;\n" 2020fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " for (;;) {\n" 2021fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " ptrdiff_t Loc = Ptr - DecodeTable;\n" 2022fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " switch (*Ptr) {\n" 2023fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " default:\n" 2024fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " errs() << Loc << \": Unexpected decode table opcode!\\n\";\n" 2025fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return MCDisassembler::Fail;\n" 2026fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_ExtractField: {\n" 2027fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Start = *++Ptr;\n" 2028fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len = *++Ptr;\n" 2029fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " ++Ptr;\n" 2030fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\n" 2031fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_ExtractField(\" << Start << \", \"\n" 2032fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << Len << \"): \" << CurFieldValue << \"\\n\");\n" 2033fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 2034fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2035fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_FilterValue: {\n" 2036fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the field value.\n" 2037fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 2038fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType Val = decodeULEB128(++Ptr, &Len);\n" 2039fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 2040fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 2041fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 2042fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 2043fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 2044fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Perform the filter operation.\n" 2045fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (Val != CurFieldValue)\n" 2046fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 2047fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_FilterValue(\" << Val << \", \" << NumToSkip\n" 2048fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \"): \" << ((Val != CurFieldValue) ? \"FAIL:\" : \"PASS:\")\n" 2049fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \" continuing at \" << (Ptr - DecodeTable) << \"\\n\");\n" 2050fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 2051fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 2052fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2053fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_CheckField: {\n" 2054fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Start = *++Ptr;\n" 2055fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len = *++Ptr;\n" 2056fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\n" 2057fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the field value.\n" 2058fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\n" 2059fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 2060fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 2061fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 2062fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 2063fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 2064fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // If the actual and expected values don't match, skip.\n" 2065fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (ExpectedValue != FieldValue)\n" 2066fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 2067fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_CheckField(\" << Start << \", \"\n" 2068fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << Len << \", \" << ExpectedValue << \", \" << NumToSkip\n" 2069fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \"): FieldValue = \" << FieldValue << \", ExpectedValue = \"\n" 2070fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << ExpectedValue << \": \"\n" 2071fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << ((ExpectedValue == FieldValue) ? \"PASS\\n\" : \"FAIL\\n\"));\n" 2072fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 2073fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2074fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_CheckPredicate: {\n" 2075fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 2076fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the Predicate Index value.\n" 2077fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\n" 2078fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 2079fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // NumToSkip is a plain 16-bit integer.\n" 2080fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned NumToSkip = *Ptr++;\n" 2081fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " NumToSkip |= (*Ptr++) << 8;\n" 2082fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Check the predicate.\n" 2083fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " bool Pred;\n" 2084fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\n" 2085fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += NumToSkip;\n" 2086fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " (void)Pred;\n" 2087fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_CheckPredicate(\" << PIdx << \"): \"\n" 2088fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << (Pred ? \"PASS\\n\" : \"FAIL\\n\"));\n" 2089fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 2090fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 2091fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2092fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_Decode: {\n" 2093fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 2094fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the Opcode value.\n" 2095fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Opc = decodeULEB128(++Ptr, &Len);\n" 2096fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 2097fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\n" 2098fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 2099fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_Decode: opcode \" << Opc\n" 2100fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " << \", using decoder \" << DecodeIdx << \"\\n\" );\n" 2101fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << \"----- DECODE SUCCESSFUL -----\\n\");\n" 2102fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "\n" 2103fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " MI.setOpcode(Opc);\n" 210495d235ddb62805923f2f64edd71b15b904ee4a16Benjamin Kramer << " return decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm);\n" 2105fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2106fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_SoftFail: {\n" 2107fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " // Decode the mask values.\n" 2108fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " unsigned Len;\n" 2109fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\n" 2110fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 2111fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\n" 2112fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " Ptr += Len;\n" 2113fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " bool Fail = (insn & PositiveMask) || (~insn & NegativeMask);\n" 2114fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " if (Fail)\n" 2115fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " S = MCDisassembler::SoftFail;\n" 2116fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_SoftFail: \" << (Fail ? \"FAIL\\n\":\"PASS\\n\"));\n" 2117fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " break;\n" 2118fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2119fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " case MCD::OPC_Fail: {\n" 2120fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " DEBUG(dbgs() << Loc << \": OPC_Fail\\n\");\n" 2121fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " return MCDisassembler::Fail;\n" 2122fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2123fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2124fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " }\n" 2125fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << " llvm_unreachable(\"bogosity detected in disassembler state machine!\");\n" 2126fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach << "}\n\n"; 2127d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 2128d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 2129d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emits disassembler code for instruction decoding. 2130d936045625ae2e101d3a9544586d7568c6dbacc0Craig Toppervoid FixedLenDecoderEmitter::run(raw_ostream &o) { 2131fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach formatted_raw_ostream OS(o); 2132fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/MC/MCInst.h\"\n"; 2133fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/Debug.h\"\n"; 2134fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/DataTypes.h\"\n"; 2135fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/LEB128.h\"\n"; 2136fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include \"llvm/Support/raw_ostream.h\"\n"; 2137fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "#include <assert.h>\n"; 2138fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << '\n'; 2139fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "namespace llvm {\n\n"; 2140fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2141fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitFieldFromInstruction(OS); 2142d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 214336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Target.reverseBitsForLittleEndianEncoding(); 214436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2145f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Parameterize the decoders based on namespace and instruction width. 2146fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach NumberedInstructions = &Target.getInstructionsByEnumValue(); 2147f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<std::pair<std::string, unsigned>, 2148f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<unsigned> > OpcMap; 2149f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<unsigned, std::vector<OperandInfo> > Operands; 2150f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2151fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach for (unsigned i = 0; i < NumberedInstructions->size(); ++i) { 2152fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach const CodeGenInstruction *Inst = NumberedInstructions->at(i); 2153eb5cd610700661bc46c660640c36949033247d2dCraig Topper const Record *Def = Inst->TheDef; 2154f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned Size = Def->getValueAsInt("Size"); 2155f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (Def->getValueAsString("Namespace") == "TargetOpcode" || 2156f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isPseudo") || 2157f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isAsmParserOnly") || 2158f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isCodeGenOnly")) 2159f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson continue; 2160f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2161f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::string DecoderNamespace = Def->getValueAsString("DecoderNamespace"); 2162f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2163f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (Size) { 216436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (populateInstruction(Target, *Inst, i, Operands)) { 2165f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i); 2166f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2167f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2168f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2169f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 2170fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach DecoderTableInfo TableInfo; 2171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (const auto &Opc : OpcMap) { 2172f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Emit the decoder for this namespace+width combination. 2173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FilterChooser FC(*NumberedInstructions, Opc.second, Operands, 2174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 8*Opc.first.second, this); 2175fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2176fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // The decode table is cleared for each top level decoder function. The 2177fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // predicates and decoders themselves, however, are shared across all 2178fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // decoders to give more opportunities for uniqueing. 2179fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.clear(); 2180fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.clear(); 2181fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.reserve(16384); 2182fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.push_back(FixupList()); 2183fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach FC.emitTableEntries(TableInfo); 2184fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Any NumToSkip fixups in the top level scope can resolve to the 2185fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // OPC_Fail at the end of the table. 2186fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach assert(TableInfo.FixupStack.size() == 1 && "fixup stack phasing error!"); 2187fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Resolve any NumToSkip fixups in the current scope. 2188fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach resolveTableFixups(TableInfo.Table, TableInfo.FixupStack.back(), 2189fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.size()); 2190fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.FixupStack.clear(); 2191fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2192fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach TableInfo.Table.push_back(MCD::OPC_Fail); 2193fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2194fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Print the table to the output stream. 2195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first); 2196fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS.flush(); 2197f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 2198d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 2199fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the predicate function. 2200fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitPredicateFunction(OS, TableInfo.Predicates, 0); 2201fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2202fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the decoder function. 2203fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecoderFunction(OS, TableInfo.Decoders, 0); 2204fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2205fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach // Emit the main entry point for the decoder, decodeInstruction(). 2206fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach emitDecodeInstruction(OS); 2207fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach 2208fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach OS << "\n} // End llvm namespace\n"; 2209d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 22106f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 22116f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 22126f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 22136f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS, 22146f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string PredicateNamespace, 22156f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPrefix, 22166f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string GPostfix, 22176f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string ROK, 22186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string RFail, 22196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string L) { 22206f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen FixedLenDecoderEmitter(RK, PredicateNamespace, GPrefix, GPostfix, 22216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen ROK, RFail, L).run(OS); 22226f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} 22236f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 22246f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 2225