FixedLenDecoderEmitter.cpp revision ed968a9a045cb6fecb80abfb7e938954fed54927
1d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson//===------------ FixedLenDecoderEmitter.cpp - Decoder Generator ----------===// 2d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 3d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// The LLVM Compiler Infrastructure 4d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 5d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// This file is distributed under the University of Illinois Open Source 6d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// License. See LICENSE.TXT for details. 7d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 8d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson//===----------------------------------------------------------------------===// 9d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 10d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// It contains the tablegen backend that emits the decoder functions for 11d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// targets with fixed length instruction set. 12d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 13d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson//===----------------------------------------------------------------------===// 14d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 15d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#define DEBUG_TYPE "decoder-emitter" 16d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 17d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "FixedLenDecoderEmitter.h" 18d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "CodeGenTarget.h" 19d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "Record.h" 20d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/ADT/StringExtras.h" 21d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/Support/Debug.h" 22d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include "llvm/Support/raw_ostream.h" 23d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 24d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <vector> 25d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <map> 26d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#include <string> 27d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 28d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonusing namespace llvm; 29d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 30d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system 31d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// for a bit value. 32d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 33d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// BIT_UNFILTERED is used as the init value for a filter position. It is used 34d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// only for filter processings. 35d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersontypedef enum { 36d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_TRUE, // '1' 37d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_FALSE, // '0' 38d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_UNSET, // '?' 39d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BIT_UNFILTERED // unfiltered 40d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} bit_value_t; 41d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 42d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic bool ValueSet(bit_value_t V) { 43d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return (V == BIT_TRUE || V == BIT_FALSE); 44d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 45d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic bool ValueNotSet(bit_value_t V) { 46d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return (V == BIT_UNSET); 47d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 48d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonstatic int Value(bit_value_t V) { 49d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1); 50d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 5105bce0beee87512e52428d4b80f5a8e79a949576David Greenestatic bit_value_t bitFromBits(BitsInit &bits, unsigned index) { 5205bce0beee87512e52428d4b80f5a8e79a949576David Greene if (BitInit *bit = dynamic_cast<BitInit*>(bits.getBit(index))) 53d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return bit->getValue() ? BIT_TRUE : BIT_FALSE; 54d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 55d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The bit is uninitialized. 56d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return BIT_UNSET; 57d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 58d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Prints the bit value for each position. 5905bce0beee87512e52428d4b80f5a8e79a949576David Greenestatic void dumpBits(raw_ostream &o, BitsInit &bits) { 60d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned index; 61d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 62d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (index = bits.getNumBits(); index > 0; index--) { 63d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitFromBits(bits, index - 1)) { 64d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_TRUE: 65d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "1"; 66d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 67d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_FALSE: 68d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "0"; 69d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 70d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNSET: 71d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "_"; 72d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 73d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 74d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(0 && "unexpected return value from bitFromBits"); 75d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 76d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 77d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 78d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 7905bce0beee87512e52428d4b80f5a8e79a949576David Greenestatic BitsInit &getBitsField(const Record &def, const char *str) { 8005bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit *bits = def.getValueAsBitsInit(str); 81d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return *bits; 82d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 83d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 84d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Forward declaration. 85d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass FilterChooser; 86d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 87d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Representation of the instruction to work on. 88f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Andersontypedef std::vector<bit_value_t> insn_t; 89d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 90d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Filter - Filter works with FilterChooser to produce the decoding tree for 91d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the ISA. 92d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 93d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// It is useful to think of a Filter as governing the switch stmts of the 94d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoding tree in a certain level. Each case stmt delegates to an inferior 95d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser to decide what further decoding logic to employ, or in another 96d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// words, what other remaining bits to look at. The FilterChooser eventually 97d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// chooses a best Filter to do its job. 98d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 99d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// This recursive scheme ends when the number of Opcodes assigned to the 100d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser becomes 1 or if there is a conflict. A conflict happens when 101d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the Filter/FilterChooser combo does not know how to distinguish among the 102d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Opcodes assigned. 103d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 104d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// An example of a conflict is 105d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 106d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Conflict: 107d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 111101000.00........00010000.... 108d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 111101000.00........0001........ 109d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010...00........0001........ 110d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010...00.................... 111d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111010......................... 112d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 1111............................ 113d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// ................................ 114d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8a 111101000_00________00010000____ 115d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8b 111101000_00________00010000____ 116d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 117d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// The Debug output shows the path that the decoding tree follows to reach the 118d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced 119d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// even registers, while VST4q8b is a vst4 to double-spaced odd regsisters. 120d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 121d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// The encoding info in the .td files does not specify this meta information, 122d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// which could have been used by the decoder to resolve the conflict. The 123d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoder could try to decode the even/odd register numbering and assign to 124d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a" 125d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// version and return the Opcode since the two have the same Asm format string. 126d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass Filter { 127d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 128d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser *Owner; // points to the FilterChooser who owns this filter 129d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned StartBit; // the starting bit position 130d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned NumBits; // number of bits to filter 131d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool Mixed; // a mixed region contains both set and unset bits 132d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 133d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Map of well-known segment value to the set of uid's with that value. 134d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<uint64_t, std::vector<unsigned> > FilteredInstructions; 135d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 136d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set of uid's with non-constant segment values. 137d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> VariableInstructions; 138d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 139d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Map of well-known segment value to its delegate. 140d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<unsigned, FilterChooser*> FilterChooserMap; 141d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 142d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Number of instructions which fall under FilteredInstructions category. 143d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned NumFiltered; 144d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 145d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Keeps track of the last opcode in the filtered bucket. 146d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned LastOpcFiltered; 147d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 148d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Number of instructions which fall under VariableInstructions category. 149d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned NumVariable; 150d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 151d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonpublic: 152d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned getNumFiltered() { return NumFiltered; } 153d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned getNumVariable() { return NumVariable; } 154d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned getSingletonOpc() { 155d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(NumFiltered == 1); 156d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return LastOpcFiltered; 157d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 158d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Return the filter chooser for the group of instructions without constant 159d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // segment values. 160d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser &getVariableFC() { 161d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(NumFiltered == 1); 162d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(FilterChooserMap.size() == 1); 163d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return *(FilterChooserMap.find((unsigned)-1)->second); 164d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 165d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 166d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter(const Filter &f); 167d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed); 168d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 169d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ~Filter(); 170d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 171d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Divides the decoding task into sub tasks and delegates them to the 172d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // inferior FilterChooser's. 173d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 174d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // A special case arises when there's only one entry in the filtered 175d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instructions. In order to unambiguously decode the singleton, we need to 176d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // match the remaining undecoded encoding bits against the singleton. 177d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void recurse(); 178d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 179d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emit code to decode instructions given a segment or segments of bits. 180d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void emit(raw_ostream &o, unsigned &Indentation); 181d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 182d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns the number of fanout produced by the filter. More fanout implies 183d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the filter distinguishes more categories of instructions. 184d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned usefulness() const; 185d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson}; // End of class Filter 186d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 187d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// These are states of our finite state machines used in FilterChooser's 188d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// filterProcessor() which produces the filter candidates to use. 189d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersontypedef enum { 190d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_NONE, 191d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_FILTERED, 192d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_ALL_SET, 193d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_ALL_UNSET, 194d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ATTR_MIXED 195d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} bitAttr_t; 196d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 197d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// FilterChooser - FilterChooser chooses the best filter among a set of Filters 198d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// in order to perform the decoding of instructions at the current level. 199d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 200d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Decoding proceeds from the top down. Based on the well-known encoding bits 201d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// of instructions available, FilterChooser builds up the possible Filters that 202d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// can further the task of decoding by distinguishing among the remaining 203d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// candidate instructions. 204d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 205d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// Once a filter has been chosen, it is called upon to divide the decoding task 206d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// into sub-tasks and delegates them to its inferior FilterChoosers for further 207d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// processings. 208d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// 209d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// It is useful to think of a Filter as governing the switch stmts of the 210d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decoding tree. And each case is delegated to an inferior FilterChooser to 211d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// decide what further remaining bits to look at. 212d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonclass FilterChooser { 213d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 214d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson friend class Filter; 215d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 216d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of codegen instructions to choose our filter. 217d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<const CodeGenInstruction*> &AllInstructions; 218d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 219d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of uid's for this filter chooser to work on. 220d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<unsigned> Opcodes; 221d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 222d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Lookup table for the operand decoding of instructions. 223d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<unsigned, std::vector<OperandInfo> > &Operands; 224d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 225d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Vector of candidate filters. 226d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<Filter> Filters; 227d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 228d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Array of bit values passed down from our parent. 229d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set to all BIT_UNFILTERED's for Parent == NULL. 230f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bit_value_t> FilterBitValues; 231d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 232d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Links to the FilterChooser above us in the decoding tree. 233d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser *Parent; 234d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 235d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Index of the best filter from Filters. 236d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int BestIndex; 237d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 238f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Width of instructions 239f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned BitWidth; 240f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 24183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson // Parent emitter 24283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson const FixedLenDecoderEmitter *Emitter; 24383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson 244d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonpublic: 245d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser(const FilterChooser &FC) : 246d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson AllInstructions(FC.AllInstructions), Opcodes(FC.Opcodes), 247f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Operands(FC.Operands), Filters(FC.Filters), 248f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson FilterBitValues(FC.FilterBitValues), Parent(FC.Parent), 24983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson BestIndex(FC.BestIndex), BitWidth(FC.BitWidth), 25083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Emitter(FC.Emitter) { } 251d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 252d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser(const std::vector<const CodeGenInstruction*> &Insts, 253d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<unsigned> &IDs, 254f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<unsigned, std::vector<OperandInfo> > &Ops, 25583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson unsigned BW, 25683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson const FixedLenDecoderEmitter *E) : 257d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson AllInstructions(Insts), Opcodes(IDs), Operands(Ops), Filters(), 25883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Parent(NULL), BestIndex(-1), BitWidth(BW), Emitter(E) { 259f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (unsigned i = 0; i < BitWidth; ++i) 260f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson FilterBitValues.push_back(BIT_UNFILTERED); 261d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 262d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson doFilter(); 263d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 264d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 265d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser(const std::vector<const CodeGenInstruction*> &Insts, 266d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::vector<unsigned> &IDs, 267d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<unsigned, std::vector<OperandInfo> > &Ops, 268f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bit_value_t> &ParentFilterBitValues, 269d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser &parent) : 270d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson AllInstructions(Insts), Opcodes(IDs), Operands(Ops), 271f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Filters(), FilterBitValues(ParentFilterBitValues), 27283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Parent(&parent), BestIndex(-1), BitWidth(parent.BitWidth), 27383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson Emitter(parent.Emitter) { 274d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson doFilter(); 275d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 276d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 277d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The top level filter chooser has NULL as its parent. 278d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool isTopLevel() { return Parent == NULL; } 279d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 280d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emit the top level typedef and decodeInstruction() function. 281f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson void emitTop(raw_ostream &o, unsigned Indentation, std::string Namespace); 282d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 283d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonprotected: 284d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the insn given the uid. 285d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void insnWithID(insn_t &Insn, unsigned Opcode) const { 28605bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst"); 287d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 288f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (unsigned i = 0; i < BitWidth; ++i) 289f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Insn.push_back(bitFromBits(Bits, i)); 290d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 291d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 292d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns the record name. 293d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &nameWithID(unsigned Opcode) const { 294d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return AllInstructions[Opcode]->TheDef->getName(); 295d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 296d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 297d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the field of the insn given the start position and the number of 298d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // consecutive bits to scan for. 299d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 300d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns false if there exists any uninitialized bit value in the range. 301d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Returns true, otherwise. 302d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit, 303d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned NumBits) const; 304d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 305d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpFilterArray - dumpFilterArray prints out debugging info for the given 306d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// filter array as a series of chars. 307f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson void dumpFilterArray(raw_ostream &o, std::vector<bit_value_t> & filter); 308d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 309d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpStack - dumpStack traverses the filter chooser chain and calls 310d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson /// dumpFilterArray on each filter chooser up to the top level one. 311d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void dumpStack(raw_ostream &o, const char *prefix); 312d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 313d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter &bestFilter() { 314d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(BestIndex != -1 && "BestIndex not set"); 315d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return Filters[BestIndex]; 316d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 317d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 318d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Called from Filter::recurse() when singleton exists. For debug purpose. 319d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void SingletonExists(unsigned Opc); 320d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 321d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool PositionFiltered(unsigned i) { 322d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return ValueSet(FilterBitValues[i]); 323d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 324d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 325d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Calculates the island(s) needed to decode the instruction. 326d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // This returns a lit of undecoded bits of an instructions, for example, 327d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 328d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // decoded bits in order to verify that the instruction matches the Opcode. 329d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned getIslands(std::vector<unsigned> &StartBits, 330d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals, 331d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t &Insn); 332d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 333a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy // Emits code to check the Predicates member of an instruction are true. 334a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy // Returns true if predicate matches were emitted, false otherwise. 335a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,unsigned Opc); 336a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 337d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emits code to decode the singleton. Return true if we have matched all the 338d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // well-known bits. 339d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc); 340d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 341d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emits code to decode the singleton, and then to decode the rest. 342d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,Filter &Best); 343d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 344d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson void emitBinaryParser(raw_ostream &o , unsigned &Indentation, 345d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OperandInfo &OpInfo); 346d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 347d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Assign a single filter and run with it. 348d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void runSingleFilter(FilterChooser &owner, unsigned startBit, unsigned numBit, 349d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool mixed); 350d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 351d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // reportRegion is a helper function for filterProcessor to mark a region as 352d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // eligible for use as a filter region. 353d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex, 354d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool AllowMixed); 355d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 356d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FilterProcessor scans the well-known encoding bits of the instructions and 357d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // builds up a list of candidate filters. It chooses the best filter and 358d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // recursively descends down the decoding tree. 359d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool filterProcessor(bool AllowMixed, bool Greedy = true); 360d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 361d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Decides on the best configuration of filter(s) to use in order to decode 362d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the instructions. A conflict of instructions may occur, in which case we 363d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // dump the conflict set to the standard error. 364d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson void doFilter(); 365d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 366d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emits code to decode our share of instructions. Returns true if the 367d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // emitted code causes a return, which occurs if we know how to decode 368d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the instruction at this level or the instruction is not decodeable. 369d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool emit(raw_ostream &o, unsigned &Indentation); 370d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson}; 371d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 372d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/////////////////////////// 373d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 374d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Filter Implmenetation // 375d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 376d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/////////////////////////// 377d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 378d8c87888a71c4433d76b48bca6c3e03a17890648Owen AndersonFilter::Filter(const Filter &f) : 379d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed), 380d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilteredInstructions(f.FilteredInstructions), 381d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson VariableInstructions(f.VariableInstructions), 382d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooserMap(f.FilterChooserMap), NumFiltered(f.NumFiltered), 383d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson LastOpcFiltered(f.LastOpcFiltered), NumVariable(f.NumVariable) { 384d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 385d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 386d8c87888a71c4433d76b48bca6c3e03a17890648Owen AndersonFilter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, 387d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool mixed) : Owner(&owner), StartBit(startBit), NumBits(numBits), 388d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Mixed(mixed) { 389f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson assert(StartBit + NumBits - 1 < Owner->BitWidth); 390d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 391d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NumFiltered = 0; 392d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson LastOpcFiltered = 0; 393d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NumVariable = 0; 394d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 395d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) { 396d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 397d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 398d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Populates the insn given the uid. 399d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Owner->insnWithID(Insn, Owner->Opcodes[i]); 400d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 401d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson uint64_t Field; 402d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Scans the segment for possibly well-specified encoding bits. 403d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits); 404d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 405d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (ok) { 406d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The encoding bits are well-known. Lets add the uid of the 407d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instruction into the bucket keyed off the constant field value. 408d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson LastOpcFiltered = Owner->Opcodes[i]; 409d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilteredInstructions[Field].push_back(LastOpcFiltered); 410d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++NumFiltered; 411d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } else { 412d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Some of the encoding bit(s) are unspecfied. This contributes to 413d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // one additional member of "Variable" instructions. 414d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson VariableInstructions.push_back(Owner->Opcodes[i]); 415d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++NumVariable; 416d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 417d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 418d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 419d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert((FilteredInstructions.size() + VariableInstructions.size() > 0) 420d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson && "Filter returns no instruction categories"); 421d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 422d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 423d8c87888a71c4433d76b48bca6c3e03a17890648Owen AndersonFilter::~Filter() { 424d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<unsigned, FilterChooser*>::iterator filterIterator; 425d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (filterIterator = FilterChooserMap.begin(); 426d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson filterIterator != FilterChooserMap.end(); 427d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson filterIterator++) { 428d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson delete filterIterator->second; 429d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 430d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 431d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 432d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Divides the decoding task into sub tasks and delegates them to the 433d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// inferior FilterChooser's. 434d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 435d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// A special case arises when there's only one entry in the filtered 436d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// instructions. In order to unambiguously decode the singleton, we need to 437d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// match the remaining undecoded encoding bits against the singleton. 438d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid Filter::recurse() { 439d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<uint64_t, std::vector<unsigned> >::const_iterator mapIterator; 440d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 441d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Starts by inheriting our parent filter chooser's filter bit values. 442f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues); 443d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 444d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned bitIndex; 445d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 446d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (VariableInstructions.size()) { 447d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Conservatively marks each segment position as BIT_UNSET. 448d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (bitIndex = 0; bitIndex < NumBits; bitIndex++) 449d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_UNSET; 450d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 4517a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Delegates to an inferior filter chooser for further processing on this 452d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // group of instructions whose segment values are variable. 453d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooserMap.insert(std::pair<unsigned, FilterChooser*>( 454d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson (unsigned)-1, 455d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson new FilterChooser(Owner->AllInstructions, 456d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson VariableInstructions, 457d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Owner->Operands, 458d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray, 459d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson *Owner) 460d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson )); 461d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 462d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 463d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // No need to recurse for a singleton filtered instruction. 464d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // See also Filter::emit(). 465d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (getNumFiltered() == 1) { 466d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson //Owner->SingletonExists(LastOpcFiltered); 467d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(FilterChooserMap.size() == 1); 468d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 469d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 470d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 471d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Otherwise, create sub choosers. 472d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (mapIterator = FilteredInstructions.begin(); 473d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson mapIterator != FilteredInstructions.end(); 474d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson mapIterator++) { 475d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 476d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Marks all the segment positions with either BIT_TRUE or BIT_FALSE. 477d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (bitIndex = 0; bitIndex < NumBits; bitIndex++) { 478d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (mapIterator->first & (1ULL << bitIndex)) 479d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_TRUE; 480d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 481d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray[StartBit + bitIndex] = BIT_FALSE; 482d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 483d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 4847a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Delegates to an inferior filter chooser for further processing on this 485d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // category of instructions. 486d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooserMap.insert(std::pair<unsigned, FilterChooser*>( 487d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson mapIterator->first, 488d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson new FilterChooser(Owner->AllInstructions, 489d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson mapIterator->second, 490d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Owner->Operands, 491d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitValueArray, 492d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson *Owner) 493d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson )); 494d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 495d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 496d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 497d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emit code to decode instructions given a segment or segments of bits. 498d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid Filter::emit(raw_ostream &o, unsigned &Indentation) { 499d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "// Check Inst{"; 500d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 501d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (NumBits > 1) 502d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << (StartBit + NumBits - 1) << '-'; 503d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 504d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << StartBit << "} ...\n"; 505d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 506f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "switch (fieldFromInstruction" << Owner->BitWidth 507f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson << "(insn, " << StartBit << ", " 508f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson << NumBits << ")) {\n"; 509d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 510d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::map<unsigned, FilterChooser*>::iterator filterIterator; 511d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 512d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool DefaultCase = false; 513d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (filterIterator = FilterChooserMap.begin(); 514d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson filterIterator != FilterChooserMap.end(); 515d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson filterIterator++) { 516d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 517d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Field value -1 implies a non-empty set of variable instructions. 518d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // See also recurse(). 519d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterIterator->first == (unsigned)-1) { 520d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson DefaultCase = true; 521d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 522d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "default:\n"; 523d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << " break; // fallthrough\n"; 524d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 525d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Closing curly brace for the switch statement. 526d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // This is unconventional because we want the default processing to be 527d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // performed for the fallthrough cases as well, i.e., when the "cases" 528d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // did not prove a decoded instruction. 529d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "}\n"; 530d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 531d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } else 532d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "case " << filterIterator->first << ":\n"; 533d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 534d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We arrive at a category of instructions with the same segment value. 535d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Now delegate to the sub filter chooser for further decodings. 536d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The case may fallthrough, which happens if the remaining well-known 537d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // encoding bits do not match exactly. 538d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (!DefaultCase) { ++Indentation; ++Indentation; } 539d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 540d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool finished = filterIterator->second->emit(o, Indentation); 541d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // For top level default case, there's no need for a break statement. 542d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Owner->isTopLevel() && DefaultCase) 543d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 544d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (!finished) 545d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "break;\n"; 546d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 547d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (!DefaultCase) { --Indentation; --Indentation; } 548d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 549d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 550d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If there is no default case, we still need to supply a closing brace. 551d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (!DefaultCase) { 552d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Closing curly brace for the switch statement. 553d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "}\n"; 554d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 555d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 556d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 557d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns the number of fanout produced by the filter. More fanout implies 558d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// the filter distinguishes more categories of instructions. 559d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonunsigned Filter::usefulness() const { 560d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (VariableInstructions.size()) 561d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return FilteredInstructions.size(); 562d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 563d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return FilteredInstructions.size() + 1; 564d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 565d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 566d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson////////////////////////////////// 567d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 568d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Filterchooser Implementation // 569d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// // 570d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson////////////////////////////////// 571d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 572d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emit the top level typedef and decodeInstruction() function. 573f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Andersonvoid FilterChooser::emitTop(raw_ostream &o, unsigned Indentation, 574f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::string Namespace) { 575d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << 57683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson "static MCDisassembler::DecodeStatus decode" << Namespace << "Instruction" << BitWidth 577f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson << "(MCInst &MI, uint" << BitWidth << "_t insn, uint64_t Address, " 578a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy << "const void *Decoder, const MCSubtargetInfo &STI) {\n"; 57983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson o.indent(Indentation) << " unsigned tmp = 0;\n (void)tmp;\n" << Emitter->Locals << "\n"; 580a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o.indent(Indentation) << " unsigned Bits = STI.getFeatureBits();\n"; 581d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 582d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Indentation; ++Indentation; 583d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emits code to decode the instructions. 584d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson emit(o, Indentation); 585d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 586d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << '\n'; 58783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson o.indent(Indentation) << "return " << Emitter->ReturnFail << ";\n"; 588d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson --Indentation; --Indentation; 589d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 590d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "}\n"; 591d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 592d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << '\n'; 593d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 594d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 595d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Populates the field of the insn given the start position and the number of 596d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// consecutive bits to scan for. 597d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// 598d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns false if and on the first uninitialized bit value encountered. 599d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Returns true, otherwise. 600d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn, 601d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned StartBit, unsigned NumBits) const { 602d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Field = 0; 603d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 604d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < NumBits; ++i) { 605d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Insn[StartBit + i] == BIT_UNSET) 606d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 607d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 608d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Insn[StartBit + i] == BIT_TRUE) 609d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Field = Field | (1ULL << i); 610d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 611d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 612d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 613d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 614d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 615d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpFilterArray - dumpFilterArray prints out debugging info for the given 616d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// filter array as a series of chars. 617d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::dumpFilterArray(raw_ostream &o, 618f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bit_value_t> &filter) { 619d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned bitIndex; 620d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 621f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (bitIndex = BitWidth; bitIndex > 0; bitIndex--) { 622d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (filter[bitIndex - 1]) { 623d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNFILTERED: 624d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "."; 625d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 626d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_UNSET: 627d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "_"; 628d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 629d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_TRUE: 630d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "1"; 631d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 632d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case BIT_FALSE: 633d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "0"; 634d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 635d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 636d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 637d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 638d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 639d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpStack - dumpStack traverses the filter chooser chain and calls 640d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson/// dumpFilterArray on each filter chooser up to the top level one. 641d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::dumpStack(raw_ostream &o, const char *prefix) { 642d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterChooser *current = this; 643d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 644d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson while (current) { 645d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << prefix; 646d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpFilterArray(o, current->FilterBitValues); 647d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << '\n'; 648d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson current = current->Parent; 649d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 650d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 651d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 652d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Called from Filter::recurse() when singleton exists. For debug purpose. 653d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::SingletonExists(unsigned Opc) { 654d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn0; 655d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn0, Opc); 656d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 657d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "Singleton exists: " << nameWithID(Opc) 658d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson << " with its decoding dominating "; 659d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); ++i) { 660d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Opcodes[i] == Opc) continue; 661d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << nameWithID(Opcodes[i]) << ' '; 662d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 663d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 664d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 665d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpStack(errs(), "\t\t"); 666d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); i++) { 667d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &Name = nameWithID(Opcodes[i]); 668d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 669d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\t' << Name << " "; 670d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), 671d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 672d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 673d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 674d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 675d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 676d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Calculates the island(s) needed to decode the instruction. 677d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// This returns a list of undecoded bits of an instructions, for example, 678d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 679d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// decoded bits in order to verify that the instruction matches the Opcode. 680d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonunsigned FilterChooser::getIslands(std::vector<unsigned> &StartBits, 681d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals, 682d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t &Insn) { 683d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Num, BitNo; 684d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Num = BitNo = 0; 685d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 686d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson uint64_t FieldVal = 0; 687d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 688d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 0: Init 689d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1: Water (the bit value does not affect decoding) 690d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 2: Island (well-known bit value needed for decoding) 691d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int State = 0; 692d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson int Val = -1; 693d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 694f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (unsigned i = 0; i < BitWidth; ++i) { 695d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Val = Value(Insn[i]); 696d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool Filtered = PositionFiltered(i); 697d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (State) { 698d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 699d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(0 && "Unreachable code!"); 700d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 701d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 0: 702d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 1: 703d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Filtered || Val == -1) 704d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 1; // Still in Water 705d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else { 706d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 2; // Into the Island 707d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BitNo = 0; 708d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBits.push_back(i); 709d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVal = Val; 710d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 711d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 712d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case 2: 713d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Filtered || Val == -1) { 714d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 1; // Into the Water 715d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson EndBits.push_back(i - 1); 716d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.push_back(FieldVal); 717d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Num; 718d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } else { 719d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson State = 2; // Still in Island 720d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++BitNo; 721d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVal = FieldVal | Val << BitNo; 722d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 723d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 724d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 725d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 726d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we are still in Island after the loop, do some housekeeping. 727d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (State == 2) { 728f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson EndBits.push_back(BitWidth - 1); 729d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.push_back(FieldVal); 730d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson ++Num; 731d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 732d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 733d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(StartBits.size() == Num && EndBits.size() == Num && 734d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FieldVals.size() == Num); 735d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return Num; 736d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 737d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 738d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Andersonvoid FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, 739d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OperandInfo &OpInfo) { 740d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson std::string &Decoder = OpInfo.Decoder; 741d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 742d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (OpInfo.numFields() == 1) { 743d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OperandInfo::iterator OI = OpInfo.begin(); 744d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson o.indent(Indentation) << " tmp = fieldFromInstruction" << BitWidth 745d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson << "(insn, " << OI->Base << ", " << OI->Width 746d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson << ");\n"; 747d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } else { 748d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson o.indent(Indentation) << " tmp = 0;\n"; 749d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson for (OperandInfo::iterator OI = OpInfo.begin(), OE = OpInfo.end(); 750d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OI != OE; ++OI) { 751d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson o.indent(Indentation) << " tmp |= (fieldFromInstruction" << BitWidth 752ed968a9a045cb6fecb80abfb7e938954fed54927Andrew Trick << "(insn, " << OI->Base << ", " << OI->Width 753d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson << ") << " << OI->Offset << ");\n"; 754d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 755d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 756d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 757d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Decoder != "") 75883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson o.indent(Indentation) << " " << Emitter->GuardPrefix << Decoder 75983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson << "(MI, tmp, Address, Decoder)" << Emitter->GuardPostfix << "\n"; 760d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson else 761d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson o.indent(Indentation) << " MI.addOperand(MCOperand::CreateImm(tmp));\n"; 762d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 763d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson} 764d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 765a5d585685493d85d5cb72b831a68ec747ae55a86James Molloystatic void emitSinglePredicateMatch(raw_ostream &o, StringRef str, 766a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::string PredicateNamespace) { 767a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy const char *X = str.str().c_str(); 768a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (X[0] == '!') 769a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << "!(Bits & " << PredicateNamespace << "::" << &X[1] << ")"; 770a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy else 771a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << "(Bits & " << PredicateNamespace << "::" << X << ")"; 772a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy} 773a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 774a5d585685493d85d5cb72b831a68ec747ae55a86James Molloybool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 775a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy unsigned Opc) { 776a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy ListInit *Predicates = AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); 777a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy for (unsigned i = 0; i < Predicates->getSize(); ++i) { 778a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy Record *Pred = Predicates->getElementAsRecord(i); 779a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (!Pred->getValue("AssemblerMatcherPredicate")) 780a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy continue; 781a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 782a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::string P = Pred->getValueAsString("AssemblerCondString"); 783a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 784a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (!P.length()) 785a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy continue; 786a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 787a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (i != 0) 788a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 789a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 790a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy StringRef SR(P); 791a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy std::pair<StringRef, StringRef> pairs = SR.split(','); 792a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy while (pairs.second.size()) { 793a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); 794a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 795a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy pairs = pairs.second.split(','); 796a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 797a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); 798a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 799a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy return Predicates->getSize() > 0; 800ed968a9a045cb6fecb80abfb7e938954fed54927Andrew Trick} 801a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy 802d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emits code to decode the singleton. Return true if we have matched all the 803d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// well-known bits. 804d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, 805d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Opc) { 806d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> StartBits; 807d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> EndBits; 808d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<uint64_t> FieldVals; 809d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 810d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn, Opc); 811d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 812d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Look for islands of undecoded bits of the singleton. 813d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getIslands(StartBits, EndBits, FieldVals, Insn); 814d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 815d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Size = StartBits.size(); 816d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned I, NumBits; 817d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 818d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we have matched all the well-known bits, just issue a return. 819d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Size == 0) { 820a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o.indent(Indentation) << "if ("; 821a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy emitPredicateMatch(o, Indentation, Opc); 822a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << ") {\n"; 823d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << " MI.setOpcode(" << Opc << ");\n"; 824d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<OperandInfo>& InsnOperands = Operands[Opc]; 825d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (std::vector<OperandInfo>::iterator 826d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) { 827d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If a custom instruction decoder was specified, use that. 828d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (I->numFields() == 0 && I->Decoder.size()) { 82983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson o.indent(Indentation) << " " << Emitter->GuardPrefix << I->Decoder 83083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << "\n"; 831d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 832d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 833d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 834d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson emitBinaryParser(o, Indentation, *I); 835d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 836d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 83783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson o.indent(Indentation) << " return " << Emitter->ReturnOK << "; // " << nameWithID(Opc) 838d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson << '\n'; 839a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o.indent(Indentation) << "}\n"; // Closing predicate block. 840d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 841d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 842d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 843d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Otherwise, there are more decodings to be done! 844d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 845d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emit code to match the island(s) for the singleton. 846d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "// Check "; 847d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 848d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (I = Size; I != 0; --I) { 849d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "Inst{" << EndBits[I-1] << '-' << StartBits[I-1] << "} "; 850d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (I > 1) 851a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " && "; 852d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 853d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "for singleton decoding...\n"; 854d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 855d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 856d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "if ("; 857a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy if (emitPredicateMatch(o, Indentation, Opc) > 0) { 858a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o << " &&\n"; 859a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy o.indent(Indentation+4); 860a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy } 861d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 862d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (I = Size; I != 0; --I) { 863d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NumBits = EndBits[I-1] - StartBits[I-1] + 1; 864f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o << "fieldFromInstruction" << BitWidth << "(insn, " 865f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson << StartBits[I-1] << ", " << NumBits 866d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson << ") == " << FieldVals[I-1]; 867d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (I > 1) 868d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << " && "; 869d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 870d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << ") {\n"; 871d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 872d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << " MI.setOpcode(" << Opc << ");\n"; 873d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<OperandInfo>& InsnOperands = Operands[Opc]; 874d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (std::vector<OperandInfo>::iterator 875d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) { 876d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If a custom instruction decoder was specified, use that. 877d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (I->numFields() == 0 && I->Decoder.size()) { 87883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson o.indent(Indentation) << " " << Emitter->GuardPrefix << I->Decoder 87983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << "\n"; 880d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 881d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 882d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 883d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson emitBinaryParser(o, Indentation, *I); 884d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 88583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson o.indent(Indentation) << " return " << Emitter->ReturnOK << "; // " << nameWithID(Opc) 886d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson << '\n'; 887d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "}\n"; 888d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 889d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 890d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 891d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 892d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emits code to decode the singleton, and then to decode the rest. 893d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, 894d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter &Best) { 895d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 896d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Opc = Best.getSingletonOpc(); 897d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 898d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson emitSingletonDecoder(o, Indentation, Opc); 899d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 900d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Emit code for the rest. 901d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "else\n"; 902d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 903d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Indentation += 2; 904d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Best.getVariableFC().emit(o, Indentation); 905d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Indentation -= 2; 906d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 907d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 908d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Assign a single filter and run with it. Top level API client can initialize 909d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// with a single filter to start the filtering process. 910d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::runSingleFilter(FilterChooser &owner, unsigned startBit, 911d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned numBit, bool mixed) { 912d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.clear(); 913d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter F(*this, startBit, numBit, true); 914d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(F); 915d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = 0; // Sole Filter instance to choose from. 916d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().recurse(); 917d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 918d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 919d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// reportRegion is a helper function for filterProcessor to mark a region as 920d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// eligible for use as a filter region. 921d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit, 922d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned BitIndex, bool AllowMixed) { 923d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (RA == ATTR_MIXED && AllowMixed) 924d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, true)); 925d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else if (RA == ATTR_ALL_SET && !AllowMixed) 926d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.push_back(Filter(*this, StartBit, BitIndex - StartBit, false)); 927d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 928d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 929d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// FilterProcessor scans the well-known encoding bits of the instructions and 930d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// builds up a list of candidate filters. It chooses the best filter and 931d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// recursively descends down the decoding tree. 932d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) { 933d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filters.clear(); 934d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = -1; 935d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned numInstructions = Opcodes.size(); 936d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 937d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(numInstructions && "Filter created with no instructions"); 938d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 939d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // No further filtering is necessary. 940d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (numInstructions == 1) 941d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 942d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 943d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Heuristics. See also doFilter()'s "Heuristics" comment when num of 944d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instructions is 3. 945d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (AllowMixed && !Greedy) { 946d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(numInstructions == 3); 947d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 948d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); ++i) { 949d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> StartBits; 950d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<unsigned> EndBits; 951d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<uint64_t> FieldVals; 952d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t Insn; 953d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 954d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(Insn, Opcodes[i]); 955d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 956d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Look for islands of undecoded bits of any instruction. 957d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) { 958d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Found an instruction with island(s). Now just assign a filter. 959d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson runSingleFilter(*this, StartBits[0], EndBits[0] - StartBits[0] + 1, 960d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson true); 961d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 962d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 963d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 964d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 965d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 966d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned BitIndex, InsnIndex; 967d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 968d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We maintain BIT_WIDTH copies of the bitAttrs automaton. 969d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The automaton consumes the corresponding bit from each 970d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // instruction. 971d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 972d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Input symbols: 0, 1, and _ (unset). 973d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED. 974d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Initial state: NONE. 975d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 976d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ------- [01] -> (ALL_SET) 977d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ------- _ ----> (ALL_UNSET) 978d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) ---- [01] -> (ALL_SET) 979d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) ---- _ ----> (MIXED) 980d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_UNSET) -- [01] -> (MIXED) 981d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_UNSET) -- _ ----> (ALL_UNSET) 982d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ------ . ----> (MIXED) 983d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (FILTERED)---- . ----> (FILTERED) 984d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 985f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<bitAttr_t> bitAttrs; 986d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 987d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FILTERED bit positions provide no entropy and are not worthy of pursuing. 988d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position. 989f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) 990d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (FilterBitValues[BitIndex] == BIT_TRUE || 991d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson FilterBitValues[BitIndex] == BIT_FALSE) 992f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson bitAttrs.push_back(ATTR_FILTERED); 993d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 994f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson bitAttrs.push_back(ATTR_NONE); 995d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 996d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) { 997d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insn_t insn; 998d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 999d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson insnWithID(insn, Opcodes[InsnIndex]); 1000d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1001f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { 1002d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttrs[BitIndex]) { 1003d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1004d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] == BIT_UNSET) 1005d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_ALL_UNSET; 1006d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1007d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_ALL_SET; 1008d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1009d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1010d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] == BIT_UNSET) 1011d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_MIXED; 1012d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1013d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1014d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (insn[BitIndex] != BIT_UNSET) 1015d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttrs[BitIndex] = ATTR_MIXED; 1016d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1017d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1018d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1019d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1020d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1021d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1022d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1023d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1024d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // The regionAttr automaton consumes the bitAttrs automatons' state, 1025d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // lowest-to-highest. 1026d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1027d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed) 1028d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // States: NONE, ALL_SET, MIXED 1029d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Initial state: NONE 1030d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1031d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- F --> (NONE) 1032d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- S --> (ALL_SET) ; and set region start 1033d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- U --> (NONE) 1034d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (NONE) ----- M --> (MIXED) ; and set region start 1035d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region 1036d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- S --> (ALL_SET) 1037d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region 1038d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region 1039d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- F --> (NONE) ; and report a MIXED region 1040d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region 1041d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- U --> (NONE) ; and report a MIXED region 1042d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // (MIXED) ---- M --> (MIXED) 1043d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1044d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttr_t RA = ATTR_NONE; 1045d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned StartBit = 0; 1046d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1047f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (BitIndex = 0; BitIndex < BitWidth; BitIndex++) { 1048d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bitAttr_t bitAttr = bitAttrs[BitIndex]; 1049d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1050d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(bitAttr != ATTR_NONE && "Bit without attributes"); 1051d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1052d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (RA) { 1053d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1054d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1055d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1056d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1057d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1058d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1059d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_ALL_SET; 1060d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1061d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1062d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1063d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1064d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1065d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_MIXED; 1066d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1067d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1068d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(0 && "Unexpected bitAttr!"); 1069d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1070d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1071d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1072d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1073d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1074d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1075d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1076d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1077d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1078d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1079d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1080d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1081d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1082d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1083d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1084d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1085d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1086d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_MIXED; 1087d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1088d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1089d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(0 && "Unexpected bitAttr!"); 1090d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1091d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1092d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1093d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (bitAttr) { 1094d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1095d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1096d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1097d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1098d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1099d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1100d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1101d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson StartBit = BitIndex; 1102d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_ALL_SET; 1103d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1104d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1105d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1106d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson RA = ATTR_NONE; 1107d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1108d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1109d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1110d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson default: 1111d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(0 && "Unexpected bitAttr!"); 1112d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1113d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1114d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1115d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(0 && "regionAttr state machine has no ATTR_UNSET state"); 1116d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1117d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(0 && "regionAttr state machine has no ATTR_FILTERED state"); 1118d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1119d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1120d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1121d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // At the end, if we're still in ALL_SET or MIXED states, report a region 1122d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson switch (RA) { 1123d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_NONE: 1124d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1125d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_FILTERED: 1126d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1127d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_SET: 1128d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1129d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1130d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_ALL_UNSET: 1131d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1132d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson case ATTR_MIXED: 1133d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson reportRegion(RA, StartBit, BitIndex, AllowMixed); 1134d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson break; 1135d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1136d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1137d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We have finished with the filter processings. Now it's time to choose 1138d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the best performing filter. 1139d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = 0; 1140d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bool AllUseless = true; 1141d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned BestScore = 0; 1142d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1143d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = Filters.size(); i != e; ++i) { 1144d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Usefulness = Filters[i].usefulness(); 1145d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1146d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Usefulness) 1147d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson AllUseless = false; 1148d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1149d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Usefulness > BestScore) { 1150d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = i; 1151d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestScore = Usefulness; 1152d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1153d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1154d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1155d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (!AllUseless) 1156d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().recurse(); 1157d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1158d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return !AllUseless; 1159d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} // end of FilterChooser::filterProcessor(bool) 1160d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1161d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Decides on the best configuration of filter(s) to use in order to decode 1162d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// the instructions. A conflict of instructions may occur, in which case we 1163d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// dump the conflict set to the standard error. 1164d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FilterChooser::doFilter() { 1165d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson unsigned Num = Opcodes.size(); 1166d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson assert(Num && "FilterChooser created with no instructions"); 1167d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1168d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Try regions of consecutive known bit values first. 1169d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterProcessor(false)) 1170d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1171d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1172d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Then regions of mixed bits (both known and unitialized bit values allowed). 1173d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (filterProcessor(true)) 1174d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1175d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1176d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where 1177d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a 1178d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // well-known encoding pattern. In such case, we backtrack and scan for the 1179d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // the very first consecutive ATTR_ALL_SET region and assign a filter to it. 1180d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Num == 3 && filterProcessor(true, false)) 1181d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return; 1182d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1183d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If we come to here, the instruction decoding has failed. 1184d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Set the BestIndex to -1 to indicate so. 1185d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson BestIndex = -1; 1186d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1187d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1188d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emits code to decode our share of instructions. Returns true if the 1189d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// emitted code causes a return, which occurs if we know how to decode 1190d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// the instruction at this level or the instruction is not decodeable. 1191d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonbool FilterChooser::emit(raw_ostream &o, unsigned &Indentation) { 1192d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Opcodes.size() == 1) 1193d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // There is only one instruction in the set, which is great! 1194d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Call emitSingletonDecoder() to see whether there are any remaining 1195d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // encodings bits. 1196d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return emitSingletonDecoder(o, Indentation, Opcodes[0]); 1197d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1198d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Choose the best filter to do the decodings! 1199d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (BestIndex != -1) { 1200d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Filter &Best = bestFilter(); 1201d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (Best.getNumFiltered() == 1) 1202d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson emitSingletonDecoder(o, Indentation, Best); 1203d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1204d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson bestFilter().emit(o, Indentation); 1205d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 1206d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1207d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1208d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We don't know how to decode these instructions! Return 0 and dump the 1209d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // conflict set! 1210d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o.indent(Indentation) << "return 0;" << " // Conflict set: "; 1211d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (int i = 0, N = Opcodes.size(); i < N; ++i) { 1212d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << nameWithID(Opcodes[i]); 1213d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (i < (N - 1)) 1214d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << ", "; 1215d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson else 1216d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << '\n'; 1217d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1218d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1219d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Print out useful conflict information for postmortem analysis. 1220d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "Decoding Conflict:\n"; 1221d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1222d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpStack(errs(), "\t\t"); 1223d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1224d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Opcodes.size(); i++) { 1225d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &Name = nameWithID(Opcodes[i]); 1226d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1227d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\t' << Name << " "; 1228d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), 1229d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 1230d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1231d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1232d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1233d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1234d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1235d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1236f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Andersonstatic bool populateInstruction(const CodeGenInstruction &CGI, 1237f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned Opc, 1238f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<unsigned, std::vector<OperandInfo> >& Operands){ 1239d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const Record &Def = *CGI.TheDef; 1240d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If all the bit positions are not specified; do not decode this instruction. 1241d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // We are bound to fail! For proper disassembly, the well-known encoding bits 1242d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // of the instruction must be fully specified. 1243d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // 1244d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // This also removes pseudo instructions from considerations of disassembly, 1245d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // which is a better design and less fragile than the name matchings. 1246d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Ignore "asm parser only" instructions. 12474dd27ebcc2b218630899163504bc2641b9735466Owen Anderson if (Def.getValueAsBit("isAsmParserOnly") || 12484dd27ebcc2b218630899163504bc2641b9735466Owen Anderson Def.getValueAsBit("isCodeGenOnly")) 1249d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return false; 1250d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 125105bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit &Bits = getBitsField(Def, "Inst"); 1252806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach if (Bits.allInComplete()) return false; 1253806fcc040e0bc7962891f12d6e09fc86f0bc2184Jim Grosbach 1254d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::vector<OperandInfo> InsnOperands; 1255d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1256d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // If the instruction has specified a custom decoding hook, use that instead 1257d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // of trying to auto-generate the decoder. 1258d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::string InstDecoder = Def.getValueAsString("DecoderMethod"); 1259d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson if (InstDecoder != "") { 1260d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson InsnOperands.push_back(OperandInfo(InstDecoder)); 1261d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Operands[Opc] = InsnOperands; 1262d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1263d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1264d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1265d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Generate a description of the operand of the instruction that we know 1266d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // how to decode automatically. 1267d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // FIXME: We'll need to have a way to manually override this as needed. 1268d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1269d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Gather the outputs/inputs of the instruction, so we can find their 1270d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // positions in the encoding. This assumes for now that they appear in the 1271d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // MCInst in the order that they're listed. 127205bce0beee87512e52428d4b80f5a8e79a949576David Greene std::vector<std::pair<Init*, std::string> > InOutOperands; 127305bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *Out = Def.getValueAsDag("OutOperandList"); 127405bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *In = Def.getValueAsDag("InOperandList"); 1275d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < Out->getNumArgs(); ++i) 1276d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson InOutOperands.push_back(std::make_pair(Out->getArg(i), Out->getArgName(i))); 1277d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0; i < In->getNumArgs(); ++i) 1278d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson InOutOperands.push_back(std::make_pair(In->getArg(i), In->getArgName(i))); 1279d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 128000ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson // Search for tied operands, so that we can correctly instantiate 128100ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson // operands that are not explicitly represented in the encoding. 1282ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson std::map<std::string, std::string> TiedNames; 128300ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson for (unsigned i = 0; i < CGI.Operands.size(); ++i) { 128400ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson int tiedTo = CGI.Operands[i].getTiedRegister(); 1285ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson if (tiedTo != -1) { 1286ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson TiedNames[InOutOperands[i].second] = InOutOperands[tiedTo].second; 1287ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson TiedNames[InOutOperands[tiedTo].second] = InOutOperands[i].second; 1288ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson } 128900ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson } 129000ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson 1291d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // For each operand, see if we can figure out where it is encoded. 129205bce0beee87512e52428d4b80f5a8e79a949576David Greene for (std::vector<std::pair<Init*, std::string> >::iterator 1293d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) { 1294d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson std::string Decoder = ""; 1295d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1296d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // At this point, we can locate the field, but we need to know how to 1297d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // interpret it. As a first step, require the target to provide callbacks 1298d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // for decoding register classes. 1299d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // FIXME: This need to be extended to handle instructions with custom 1300d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson // decoder methods, and operands with (simple) MIOperandInfo's. 130105bce0beee87512e52428d4b80f5a8e79a949576David Greene TypedInit *TI = dynamic_cast<TypedInit*>(NI->first); 1302d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType()); 1303d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Record *TypeRecord = Type->getRecord(); 1304d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson bool isReg = false; 1305d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (TypeRecord->isSubClassOf("RegisterOperand")) 1306d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson TypeRecord = TypeRecord->getValueAsDef("RegClass"); 1307d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (TypeRecord->isSubClassOf("RegisterClass")) { 1308d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; 1309d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson isReg = true; 1310d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1311d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1312d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod"); 131305bce0beee87512e52428d4b80f5a8e79a949576David Greene StringInit *String = DecoderString ? 131405bce0beee87512e52428d4b80f5a8e79a949576David Greene dynamic_cast<StringInit*>(DecoderString->getValue()) : 0; 1315d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (!isReg && String && String->getValue() != "") 1316d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Decoder = String->getValue(); 1317d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1318d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OperandInfo OpInfo(Decoder); 1319d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Base = ~0U; 1320d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Width = 0; 1321d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson unsigned Offset = 0; 1322d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1323d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) { 1324cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson VarInit *Var = 0; 132505bce0beee87512e52428d4b80f5a8e79a949576David Greene VarBitInit *BI = dynamic_cast<VarBitInit*>(Bits.getBit(bi)); 1326cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson if (BI) 1327cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson Var = dynamic_cast<VarInit*>(BI->getVariable()); 1328cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson else 1329cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson Var = dynamic_cast<VarInit*>(Bits.getBit(bi)); 1330cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson 1331cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson if (!Var) { 1332d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) { 1333d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1334d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = ~0U; 1335d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 0; 1336d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Offset = 0; 1337d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1338d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson continue; 1339d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1340d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 134100ef6e3a30a6b80ff995d3ee718db6349f93d732Owen Anderson if (Var->getName() != NI->second && 1342ea2429896a9f4cf3176bf69e83d107f214630ec1Owen Anderson Var->getName() != TiedNames[NI->second]) { 1343d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) { 1344d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1345d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = ~0U; 1346d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 0; 1347d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Offset = 0; 1348d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } 1349d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson continue; 1350d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1351d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1352d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base == ~0U) { 1353d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Base = bi; 1354d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson Width = 1; 1355cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson Offset = BI ? BI->getBitNum() : 0; 1356cf6039548bd7ee4ad960da0a480b399869f6fc6fOwen Anderson } else if (BI && BI->getBitNum() != Offset + Width) { 1357eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson OpInfo.addField(Base, Width, Offset); 1358eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Base = bi; 1359eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Width = 1; 1360eb809f562e13603459182a5d1c7b0d0704770e6fOwen Anderson Offset = BI->getBitNum(); 1361d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson } else { 1362d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson ++Width; 1363d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1364d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1365d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1366d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (Base != ~0U) 1367d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson OpInfo.addField(Base, Width, Offset); 1368d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson 1369d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson if (OpInfo.numFields() > 0) 1370d1e38dfb8d53df048b15e5f2ae70d4e1c9ce61bfOwen Anderson InsnOperands.push_back(OpInfo); 1371d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1372d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1373d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson Operands[Opc] = InsnOperands; 1374d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1375d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1376d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#if 0 1377d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson DEBUG({ 1378d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Dumps the instruction encoding bits. 1379d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson dumpBits(errs(), Bits); 1380d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1381d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << '\n'; 1382d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1383d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson // Dumps the list of operand info. 1384d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { 1385d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const CGIOperandList::OperandInfo &Info = CGI.Operands[i]; 1386d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const std::string &OperandName = Info.Name; 1387d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson const Record &OperandDef = *Info.Rec; 1388d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1389d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n"; 1390d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson } 1391d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson }); 1392d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson#endif 1393d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1394d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson return true; 1395d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1396d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1397f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Andersonstatic void emitHelper(llvm::raw_ostream &o, unsigned BitWidth) { 1398f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned Indentation = 0; 1399f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::string WidthStr = "uint" + utostr(BitWidth) + "_t"; 1400d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1401f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o << '\n'; 1402f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1403f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "static " << WidthStr << 1404f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson " fieldFromInstruction" << BitWidth << 1405f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson "(" << WidthStr <<" insn, unsigned startBit, unsigned numBits)\n"; 1406f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1407f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "{\n"; 1408f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1409f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson ++Indentation; ++Indentation; 1410f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "assert(startBit + numBits <= " << BitWidth 1411f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson << " && \"Instruction field out of bounds!\");\n"; 1412f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o << '\n'; 1413f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << WidthStr << " fieldMask;\n"; 1414f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o << '\n'; 1415f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "if (numBits == " << BitWidth << ")\n"; 1416f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1417f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson ++Indentation; ++Indentation; 1418f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "fieldMask = (" << WidthStr << ")-1;\n"; 1419f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson --Indentation; --Indentation; 1420f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1421f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "else\n"; 1422f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1423f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson ++Indentation; ++Indentation; 1424f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "fieldMask = ((1 << numBits) - 1) << startBit;\n"; 1425f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson --Indentation; --Indentation; 1426f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1427f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o << '\n'; 1428f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "return (insn & fieldMask) >> startBit;\n"; 1429f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson --Indentation; --Indentation; 1430f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1431f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o.indent(Indentation) << "}\n"; 1432f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1433f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson o << '\n'; 1434d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1435d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1436d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson// Emits disassembler code for instruction decoding. 1437d8c87888a71c4433d76b48bca6c3e03a17890648Owen Andersonvoid FixedLenDecoderEmitter::run(raw_ostream &o) 1438d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson{ 1439d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "#include \"llvm/MC/MCInst.h\"\n"; 1440d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "#include \"llvm/Support/DataTypes.h\"\n"; 1441d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "#include <assert.h>\n"; 1442d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << '\n'; 1443d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "namespace llvm {\n\n"; 1444d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1445f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Parameterize the decoders based on namespace and instruction width. 1446d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson NumberedInstructions = Target.getInstructionsByEnumValue(); 1447f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<std::pair<std::string, unsigned>, 1448f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<unsigned> > OpcMap; 1449f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::map<unsigned, std::vector<OperandInfo> > Operands; 1450f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1451f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (unsigned i = 0; i < NumberedInstructions.size(); ++i) { 1452f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson const CodeGenInstruction *Inst = NumberedInstructions[i]; 1453f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Record *Def = Inst->TheDef; 1454f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson unsigned Size = Def->getValueAsInt("Size"); 1455f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (Def->getValueAsString("Namespace") == "TargetOpcode" || 1456f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isPseudo") || 1457f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isAsmParserOnly") || 1458f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Def->getValueAsBit("isCodeGenOnly")) 1459f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson continue; 1460f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1461f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::string DecoderNamespace = Def->getValueAsString("DecoderNamespace"); 1462f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1463f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (Size) { 1464f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (populateInstruction(*Inst, i, Operands)) { 1465f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i); 1466f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 1467f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 1468f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 1469f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1470f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::set<unsigned> Sizes; 1471f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson for (std::map<std::pair<std::string, unsigned>, 1472f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson std::vector<unsigned> >::iterator 1473f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson I = OpcMap.begin(), E = OpcMap.end(); I != E; ++I) { 1474f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // If we haven't visited this instruction width before, emit the 1475f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // helper method to extract fields. 1476f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson if (!Sizes.count(I->first.second)) { 1477f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson emitHelper(o, 8*I->first.second); 1478f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson Sizes.insert(I->first.second); 1479f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 1480f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson 1481f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson // Emit the decoder for this namespace+width combination. 1482f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson FilterChooser FC(NumberedInstructions, I->second, Operands, 148383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson 8*I->first.second, this); 1484f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson FC.emitTop(o, 0, I->first.first); 1485f1a009007374d8ae1c1565f34d9cea3b83665e5fOwen Anderson } 1486d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson 1487d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson o << "\n} // End llvm namespace \n"; 1488d8c87888a71c4433d76b48bca6c3e03a17890648Owen Anderson} 1489