1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===------------ ARMDecoderEmitter.cpp - Decoder Generator ---------------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is part of the ARM Disassembler. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// It contains the tablegen backend that emits the decoder functions for ARM and 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Thumb. The disassembler core includes the auto-generated file, invokes the 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// decoder functions, and builds up the MCInst based on the decoded Opcode. 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define DEBUG_TYPE "arm-decoder-emitter" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "ARMDecoderEmitter.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "CodeGenTarget.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/StringExtras.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/TableGen/Record.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <vector> 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <map> 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <string> 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///////////////////////////////////////////////////// 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Enums and Utilities for ARM Instruction Format // 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///////////////////////////////////////////////////// 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define ARM_FORMATS \ 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_PSEUDO, 0) \ 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_MULFRM, 1) \ 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_BRFRM, 2) \ 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_BRMISCFRM, 3) \ 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_DPFRM, 4) \ 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ENTRY(ARM_FORMAT_DPSOREGREGFRM, 5) \ 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_LDFRM, 6) \ 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_STFRM, 7) \ 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_LDMISCFRM, 8) \ 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_STMISCFRM, 9) \ 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_LDSTMULFRM, 10) \ 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_LDSTEXFRM, 11) \ 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_ARITHMISCFRM, 12) \ 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_SATFRM, 13) \ 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_EXTFRM, 14) \ 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPUNARYFRM, 15) \ 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPBINARYFRM, 16) \ 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPCONV1FRM, 17) \ 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPCONV2FRM, 18) \ 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPCONV3FRM, 19) \ 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPCONV4FRM, 20) \ 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPCONV5FRM, 21) \ 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPLDSTFRM, 22) \ 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 23) \ 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_VFPMISCFRM, 24) \ 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_THUMBFRM, 25) \ 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_MISCFRM, 26) \ 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_NEONGETLNFRM, 27) \ 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_NEONSETLNFRM, 28) \ 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_NEONDUPFRM, 29) \ 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_NLdSt, 30) \ 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_N1RegModImm, 31) \ 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_N2Reg, 32) \ 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_NVCVT, 33) \ 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_NVecDupLn, 34) \ 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_N2RegVecShL, 35) \ 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_N2RegVecShR, 36) \ 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_N3Reg, 37) \ 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_N3RegVecSh, 38) \ 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_NVecExtract, 39) \ 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ENTRY(ARM_FORMAT_NVecMulScalar, 40) \ 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ENTRY(ARM_FORMAT_NVTBL, 41) \ 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ENTRY(ARM_FORMAT_DPSOREGIMMFRM, 42) 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// ARM instruction format specifies the encoding used by the instruction. 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define ENTRY(n, v) n = v, 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef enum { 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ARM_FORMATS 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ARM_FORMAT_NA 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} ARMFormat; 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#undef ENTRY 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Converts enum to const char*. 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic const char *stringForARMFormat(ARMFormat form) { 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define ENTRY(n, v) case n: return #n; 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch(form) { 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ARM_FORMATS 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ARM_FORMAT_NA: 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ""; 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#undef ENTRY 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanenum { 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IndexModeNone = 0, 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IndexModePre = 1, 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IndexModePost = 2, 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IndexModeUpd = 3 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///////////////////////// 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Utility functions // 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///////////////////////// 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// byteFromBitsInit - Return the byte value from a BitsInit. 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Called from getByteField(). 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic uint8_t byteFromBitsInit(BitsInit &init) { 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int width = init.getNumBits(); 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(width <= 8 && "Field is too large for uint8_t!"); 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int index; 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint8_t mask = 0x01; 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint8_t ret = 0; 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (index = 0; index < width; index++) { 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (static_cast<BitInit*>(init.getBit(index))->getValue()) 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ret |= mask; 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mask <<= 1; 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ret; 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic uint8_t getByteField(const Record &def, const char *str) { 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitsInit *bits = def.getValueAsBitsInit(str); 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return byteFromBitsInit(*bits); 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic BitsInit &getBitsField(const Record &def, const char *str) { 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitsInit *bits = def.getValueAsBitsInit(str); 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *bits; 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// sameStringExceptSuffix - Return true if the two strings differ only in RHS's 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// suffix. ("VST4d8", "VST4d8_UPD", "_UPD") as input returns true. 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool sameStringExceptSuffix(const StringRef LHS, const StringRef RHS, 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const StringRef Suffix) { 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RHS.startswith(LHS) && RHS.endswith(Suffix)) 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return RHS.size() == LHS.size() + Suffix.size(); 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// thumbInstruction - Determine whether we have a Thumb instruction. 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// See also ARMInstrFormats.td. 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic bool thumbInstruction(uint8_t Form) { 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Form == ARM_FORMAT_THUMBFRM; 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// for a bit value. 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// BIT_UNFILTERED is used as the init value for a filter position. It is used 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// only for filter processings. 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef enum { 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BIT_TRUE, // '1' 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BIT_FALSE, // '0' 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BIT_UNSET, // '?' 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BIT_UNFILTERED // unfiltered 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} bit_value_t; 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic bool ValueSet(bit_value_t V) { 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return (V == BIT_TRUE || V == BIT_FALSE); 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic bool ValueNotSet(bit_value_t V) { 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return (V == BIT_UNSET); 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic int Value(bit_value_t V) { 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ValueNotSet(V) ? -1 : (V == BIT_FALSE ? 0 : 1); 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic bit_value_t bitFromBits(BitsInit &bits, unsigned index) { 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BitInit *bit = dynamic_cast<BitInit*>(bits.getBit(index))) 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return bit->getValue() ? BIT_TRUE : BIT_FALSE; 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The bit is uninitialized. 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return BIT_UNSET; 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Prints the bit value for each position. 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic void dumpBits(raw_ostream &o, BitsInit &bits) { 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned index; 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (index = bits.getNumBits(); index > 0; index--) { 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (bitFromBits(bits, index - 1)) { 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BIT_TRUE: 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "1"; 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BIT_FALSE: 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "0"; 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BIT_UNSET: 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "_"; 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "unexpected return value from bitFromBits"); 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Enums for the available target names. 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef enum { 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TARGET_ARM = 0, 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TARGET_THUMB 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} TARGET_NAME_t; 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// FIXME: Possibly auto-detected? 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define BIT_WIDTH 32 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Forward declaration. 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass ARMFilterChooser; 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Representation of the instruction to work on. 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef bit_value_t insn_t[BIT_WIDTH]; 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Filter - Filter works with FilterChooser to produce the decoding tree for 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the ISA. 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// It is useful to think of a Filter as governing the switch stmts of the 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// decoding tree in a certain level. Each case stmt delegates to an inferior 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FilterChooser to decide what further decoding logic to employ, or in another 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// words, what other remaining bits to look at. The FilterChooser eventually 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// chooses a best Filter to do its job. 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// This recursive scheme ends when the number of Opcodes assigned to the 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FilterChooser becomes 1 or if there is a conflict. A conflict happens when 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the Filter/FilterChooser combo does not know how to distinguish among the 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Opcodes assigned. 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// An example of a conflict is 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Conflict: 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 111101000.00........00010000.... 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 111101000.00........0001........ 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 1111010...00........0001........ 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 1111010...00.................... 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 1111010......................... 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 1111............................ 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ................................ 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// VST4q8a 111101000_00________00010000____ 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// VST4q8b 111101000_00________00010000____ 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// The Debug output shows the path that the decoding tree follows to reach the 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// even registers, while VST4q8b is a vst4 to double-spaced odd regsisters. 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// The encoding info in the .td files does not specify this meta information, 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// which could have been used by the decoder to resolve the conflict. The 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// decoder could try to decode the even/odd register numbering and assign to 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a" 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// version and return the Opcode since the two have the same Asm format string. 26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass ARMFilter { 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprotected: 26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser *Owner; // points to the FilterChooser who owns this filter 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned StartBit; // the starting bit position 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumBits; // number of bits to filter 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool Mixed; // a mixed region contains both set and unset bits 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Map of well-known segment value to the set of uid's with that value. 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::map<uint64_t, std::vector<unsigned> > FilteredInstructions; 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set of uid's with non-constant segment values. 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> VariableInstructions; 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Map of well-known segment value to its delegate. 28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::map<unsigned, ARMFilterChooser*> FilterChooserMap; 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Number of instructions which fall under FilteredInstructions category. 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumFiltered; 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Keeps track of the last opcode in the filtered bucket. 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned LastOpcFiltered; 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Number of instructions which fall under VariableInstructions category. 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumVariable; 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned getNumFiltered() { return NumFiltered; } 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned getNumVariable() { return NumVariable; } 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned getSingletonOpc() { 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NumFiltered == 1); 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return LastOpcFiltered; 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Return the filter chooser for the group of instructions without constant 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // segment values. 30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser &getVariableFC() { 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NumFiltered == 1); 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FilterChooserMap.size() == 1); 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *(FilterChooserMap.find((unsigned)-1)->second); 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilter(const ARMFilter &f); 30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilter(ARMFilterChooser &owner, unsigned startBit, unsigned numBits, 30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool mixed); 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ~ARMFilter(); 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Divides the decoding task into sub tasks and delegates them to the 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // inferior FilterChooser's. 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // A special case arises when there's only one entry in the filtered 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // instructions. In order to unambiguously decode the singleton, we need to 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // match the remaining undecoded encoding bits against the singleton. 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void recurse(); 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit code to decode instructions given a segment or segments of bits. 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void emit(raw_ostream &o, unsigned &Indentation); 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Returns the number of fanout produced by the filter. More fanout implies 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the filter distinguishes more categories of instructions. 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned usefulness() const; 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; // End of class Filter 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// These are states of our finite state machines used in FilterChooser's 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// filterProcessor() which produces the filter candidates to use. 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantypedef enum { 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ATTR_NONE, 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ATTR_FILTERED, 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ATTR_ALL_SET, 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ATTR_ALL_UNSET, 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ATTR_MIXED 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} bitAttr_t; 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ARMFilterChooser - FilterChooser chooses the best filter among a set of Filters 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// in order to perform the decoding of instructions at the current level. 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Decoding proceeds from the top down. Based on the well-known encoding bits 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// of instructions available, FilterChooser builds up the possible Filters that 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// can further the task of decoding by distinguishing among the remaining 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// candidate instructions. 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Once a filter has been chosen, it is called upon to divide the decoding task 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// into sub-tasks and delegates them to its inferior FilterChoosers for further 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// processings. 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// It is useful to think of a Filter as governing the switch stmts of the 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// decoding tree. And each case is delegated to an inferior FilterChooser to 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// decide what further remaining bits to look at. 35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass ARMFilterChooser { 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static TARGET_NAME_t TargetName; 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprotected: 35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman friend class ARMFilter; 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Vector of codegen instructions to choose our filter. 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<const CodeGenInstruction*> &AllInstructions; 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Vector of uid's for this filter chooser to work on. 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<unsigned> Opcodes; 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Vector of candidate filters. 36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<ARMFilter> Filters; 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Array of bit values passed down from our parent. 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set to all BIT_UNFILTERED's for Parent == NULL. 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bit_value_t FilterBitValues[BIT_WIDTH]; 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Links to the FilterChooser above us in the decoding tree. 37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser *Parent; 374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Index of the best filter from Filters. 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int BestIndex; 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static void setTargetName(TARGET_NAME_t tn) { TargetName = tn; } 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser(const ARMFilterChooser &FC) : 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AllInstructions(FC.AllInstructions), Opcodes(FC.Opcodes), 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Filters(FC.Filters), Parent(FC.Parent), BestIndex(FC.BestIndex) { 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman memcpy(FilterBitValues, FC.FilterBitValues, sizeof(FilterBitValues)); 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser(const std::vector<const CodeGenInstruction*> &Insts, 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::vector<unsigned> &IDs) : 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AllInstructions(Insts), Opcodes(IDs), Filters(), Parent(NULL), 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BestIndex(-1) { 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < BIT_WIDTH; ++i) 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FilterBitValues[i] = BIT_UNFILTERED; 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman doFilter(); 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser(const std::vector<const CodeGenInstruction*> &Insts, 39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<unsigned> &IDs, 39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bit_value_t (&ParentFilterBitValues)[BIT_WIDTH], 40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser &parent) : 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AllInstructions(Insts), Opcodes(IDs), Filters(), Parent(&parent), 402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BestIndex(-1) { 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < BIT_WIDTH; ++i) 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FilterBitValues[i] = ParentFilterBitValues[i]; 405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman doFilter(); 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The top level filter chooser has NULL as its parent. 410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isTopLevel() { return Parent == NULL; } 411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This provides an opportunity for target specific code emission. 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void emitTopHook(raw_ostream &o); 414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit the top level typedef and decodeInstruction() function. 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void emitTop(raw_ostream &o, unsigned &Indentation); 417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This provides an opportunity for target specific code emission after 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // emitTop(). 420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void emitBot(raw_ostream &o, unsigned &Indentation); 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprotected: 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Populates the insn given the uid. 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void insnWithID(insn_t &Insn, unsigned Opcode) const { 42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (AllInstructions[Opcode]->isPseudo) 42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst"); 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < BIT_WIDTH; ++i) 431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Insn[i] = bitFromBits(Bits, i); 432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set Inst{21} to 1 (wback) when IndexModeBits == IndexModeUpd. 43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *R = AllInstructions[Opcode]->TheDef; 43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (R->getValue("IndexModeBits") && 43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getByteField(*R, "IndexModeBits") == IndexModeUpd) 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Insn[21] = BIT_TRUE; 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Returns the record name. 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string &nameWithID(unsigned Opcode) const { 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return AllInstructions[Opcode]->TheDef->getName(); 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Populates the field of the insn given the start position and the number of 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // consecutive bits to scan for. 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Returns false if there exists any uninitialized bit value in the range. 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Returns true, otherwise. 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool fieldFromInsn(uint64_t &Field, insn_t &Insn, unsigned StartBit, 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumBits) const; 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// dumpFilterArray - dumpFilterArray prints out debugging info for the given 454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// filter array as a series of chars. 455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void dumpFilterArray(raw_ostream &o, bit_value_t (&filter)[BIT_WIDTH]); 456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// dumpStack - dumpStack traverses the filter chooser chain and calls 458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// dumpFilterArray on each filter chooser up to the top level one. 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void dumpStack(raw_ostream &o, const char *prefix); 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilter &bestFilter() { 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(BestIndex != -1 && "BestIndex not set"); 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Filters[BestIndex]; 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Called from Filter::recurse() when singleton exists. For debug purpose. 467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void SingletonExists(unsigned Opc); 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool PositionFiltered(unsigned i) { 470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ValueSet(FilterBitValues[i]); 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Calculates the island(s) needed to decode the instruction. 474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This returns a lit of undecoded bits of an instructions, for example, 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // decoded bits in order to verify that the instruction matches the Opcode. 477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned getIslands(std::vector<unsigned> &StartBits, 478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals, 479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insn_t &Insn); 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The purpose of this function is for the API client to detect possible 482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load/Store Coprocessor instructions. If the coprocessor number is of 483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the instruction is either 10 or 11, the decoder should not report the 484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // instruction as LDC/LDC2/STC/STC2, but should match against Advanced SIMD or 485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // VFP instructions. 486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool LdStCopEncoding1(unsigned Opc) { 487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string &Name = nameWithID(Opc); 488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Name == "LDC_OFFSET" || Name == "LDC_OPTION" || 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "LDC_POST" || Name == "LDC_PRE" || 490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "LDCL_OFFSET" || Name == "LDCL_OPTION" || 491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "LDCL_POST" || Name == "LDCL_PRE" || 492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "STC_OFFSET" || Name == "STC_OPTION" || 493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "STC_POST" || Name == "STC_PRE" || 494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "STCL_OFFSET" || Name == "STCL_OPTION" || 495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "STCL_POST" || Name == "STCL_PRE") 496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emits code to decode the singleton. Return true if we have matched all the 502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // well-known bits. 503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc); 504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emits code to decode the singleton, and then to decode the rest. 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, 50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilter &Best); 508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Assign a single filter and run with it. 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void runSingleFilter(ARMFilterChooser &owner, unsigned startBit, 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned numBit, bool mixed); 512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // reportRegion is a helper function for filterProcessor to mark a region as 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // eligible for use as a filter region. 515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void reportRegion(bitAttr_t RA, unsigned StartBit, unsigned BitIndex, 516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool AllowMixed); 517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FilterProcessor scans the well-known encoding bits of the instructions and 519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // builds up a list of candidate filters. It chooses the best filter and 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // recursively descends down the decoding tree. 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool filterProcessor(bool AllowMixed, bool Greedy = true); 522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Decides on the best configuration of filter(s) to use in order to decode 524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the instructions. A conflict of instructions may occur, in which case we 525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // dump the conflict set to the standard error. 526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void doFilter(); 527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emits code to decode our share of instructions. Returns true if the 529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // emitted code causes a return, which occurs if we know how to decode 530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the instruction at this level or the instruction is not decodeable. 531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool emit(raw_ostream &o, unsigned &Indentation); 532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/////////////////////////// 535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Filter Implmenetation // 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/////////////////////////// 539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanARMFilter::ARMFilter(const ARMFilter &f) : 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Owner(f.Owner), StartBit(f.StartBit), NumBits(f.NumBits), Mixed(f.Mixed), 542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FilteredInstructions(f.FilteredInstructions), 543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VariableInstructions(f.VariableInstructions), 544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FilterChooserMap(f.FilterChooserMap), NumFiltered(f.NumFiltered), 545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastOpcFiltered(f.LastOpcFiltered), NumVariable(f.NumVariable) { 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanARMFilter::ARMFilter(ARMFilterChooser &owner, unsigned startBit, unsigned numBits, 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool mixed) : Owner(&owner), StartBit(startBit), NumBits(numBits), 550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Mixed(mixed) { 551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(StartBit + NumBits - 1 < BIT_WIDTH); 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumFiltered = 0; 554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastOpcFiltered = 0; 555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumVariable = 0; 556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) { 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insn_t Insn; 559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Populates the insn given the uid. 561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Owner->insnWithID(Insn, Owner->Opcodes[i]); 562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t Field; 564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Scans the segment for possibly well-specified encoding bits. 565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool ok = Owner->fieldFromInsn(Field, Insn, StartBit, NumBits); 566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ok) { 568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The encoding bits are well-known. Lets add the uid of the 569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // instruction into the bucket keyed off the constant field value. 570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastOpcFiltered = Owner->Opcodes[i]; 571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FilteredInstructions[Field].push_back(LastOpcFiltered); 572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++NumFiltered; 573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Some of the encoding bit(s) are unspecfied. This contributes to 575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // one additional member of "Variable" instructions. 576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VariableInstructions.push_back(Owner->Opcodes[i]); 577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++NumVariable; 578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert((FilteredInstructions.size() + VariableInstructions.size() > 0) 582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && "Filter returns no instruction categories"); 583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanARMFilter::~ARMFilter() { 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::map<unsigned, ARMFilterChooser*>::iterator filterIterator; 587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (filterIterator = FilterChooserMap.begin(); 588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman filterIterator != FilterChooserMap.end(); 589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman filterIterator++) { 590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete filterIterator->second; 591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Divides the decoding task into sub tasks and delegates them to the 595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// inferior FilterChooser's. 596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// A special case arises when there's only one entry in the filtered 598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// instructions. In order to unambiguously decode the singleton, we need to 599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// match the remaining undecoded encoding bits against the singleton. 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilter::recurse() { 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::map<uint64_t, std::vector<unsigned> >::const_iterator mapIterator; 602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bit_value_t BitValueArray[BIT_WIDTH]; 604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Starts by inheriting our parent filter chooser's filter bit values. 605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman memcpy(BitValueArray, Owner->FilterBitValues, sizeof(BitValueArray)); 606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bitIndex; 608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VariableInstructions.size()) { 610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Conservatively marks each segment position as BIT_UNSET. 611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (bitIndex = 0; bitIndex < NumBits; bitIndex++) 612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitValueArray[StartBit + bitIndex] = BIT_UNSET; 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Delegates to an inferior filter chooser for further processing on this 615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // group of instructions whose segment values are variable. 61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FilterChooserMap.insert(std::pair<unsigned, ARMFilterChooser*>( 617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (unsigned)-1, 61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman new ARMFilterChooser(Owner->AllInstructions, 61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VariableInstructions, 62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BitValueArray, 62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *Owner) 622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman )); 623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // No need to recurse for a singleton filtered instruction. 626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // See also Filter::emit(). 627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (getNumFiltered() == 1) { 628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //Owner->SingletonExists(LastOpcFiltered); 629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FilterChooserMap.size() == 1); 630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, create sub choosers. 634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (mapIterator = FilteredInstructions.begin(); 635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mapIterator != FilteredInstructions.end(); 636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mapIterator++) { 637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Marks all the segment positions with either BIT_TRUE or BIT_FALSE. 639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (bitIndex = 0; bitIndex < NumBits; bitIndex++) { 640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (mapIterator->first & (1ULL << bitIndex)) 641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitValueArray[StartBit + bitIndex] = BIT_TRUE; 642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitValueArray[StartBit + bitIndex] = BIT_FALSE; 644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Delegates to an inferior filter chooser for further processing on this 647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // category of instructions. 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FilterChooserMap.insert(std::pair<unsigned, ARMFilterChooser*>( 649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman mapIterator->first, 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman new ARMFilterChooser(Owner->AllInstructions, 65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman mapIterator->second, 65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BitValueArray, 65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *Owner) 654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman )); 655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emit code to decode instructions given a segment or segments of bits. 65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilter::emit(raw_ostream &o, unsigned &Indentation) { 660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "// Check Inst{"; 661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NumBits > 1) 663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << (StartBit + NumBits - 1) << '-'; 664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << StartBit << "} ...\n"; 666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "switch (fieldFromInstruction(insn, " 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << StartBit << ", " << NumBits << ")) {\n"; 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::map<unsigned, ARMFilterChooser*>::iterator filterIterator; 671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool DefaultCase = false; 673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (filterIterator = FilterChooserMap.begin(); 674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman filterIterator != FilterChooserMap.end(); 675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman filterIterator++) { 676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Field value -1 implies a non-empty set of variable instructions. 678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // See also recurse(). 679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (filterIterator->first == (unsigned)-1) { 680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DefaultCase = true; 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "default:\n"; 683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << " break; // fallthrough\n"; 684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Closing curly brace for the switch statement. 686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This is unconventional because we want the default processing to be 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // performed for the fallthrough cases as well, i.e., when the "cases" 688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // did not prove a decoded instruction. 689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "}\n"; 690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else 692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "case " << filterIterator->first << ":\n"; 693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We arrive at a category of instructions with the same segment value. 695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Now delegate to the sub filter chooser for further decodings. 696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The case may fallthrough, which happens if the remaining well-known 697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // encoding bits do not match exactly. 698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!DefaultCase) { ++Indentation; ++Indentation; } 699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool finished = filterIterator->second->emit(o, Indentation); 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For top level default case, there's no need for a break statement. 702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Owner->isTopLevel() && DefaultCase) 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!finished) 705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "break;\n"; 706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!DefaultCase) { --Indentation; --Indentation; } 708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If there is no default case, we still need to supply a closing brace. 711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!DefaultCase) { 712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Closing curly brace for the switch statement. 713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "}\n"; 714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Returns the number of fanout produced by the filter. More fanout implies 718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// the filter distinguishes more categories of instructions. 71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned ARMFilter::usefulness() const { 720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VariableInstructions.size()) 721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FilteredInstructions.size(); 722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FilteredInstructions.size() + 1; 724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman////////////////////////////////// 727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Filterchooser Implementation // 729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman////////////////////////////////// 731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Define the symbol here. 73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanTARGET_NAME_t ARMFilterChooser::TargetName; 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This provides an opportunity for target specific code emission. 73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::emitTopHook(raw_ostream &o) { 737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TargetName == TARGET_ARM) { 738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit code that references the ARMFormat data type. 739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "static const ARMFormat ARMFormats[] = {\n"; 740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = AllInstructions.size(); i != e; ++i) { 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Record &Def = *(AllInstructions[i]->TheDef); 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string &Name = Def.getName(); 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Def.isSubClassOf("InstARM") || Def.isSubClassOf("InstThumb")) 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(2) << 745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman stringForARMFormat((ARMFormat)getByteField(Def, "Form")); 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << " ARM_FORMAT_NA"; 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << ",\t// Inst #" << i << " = " << Name << '\n'; 750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << " ARM_FORMAT_NA\t// Unreachable.\n"; 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "};\n\n"; 753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emit the top level typedef and decodeInstruction() function. 75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::emitTop(raw_ostream &o, unsigned &Indentation) { 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Run the target specific emit hook. 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitTopHook(o); 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (BIT_WIDTH) { 762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 8: 763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "typedef uint8_t field_t;\n"; 764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 16: 766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "typedef uint16_t field_t;\n"; 767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 32: 769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "typedef uint32_t field_t;\n"; 770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 64: 772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "typedef uint64_t field_t;\n"; 773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Unexpected instruction size!"); 776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "static field_t " << 781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "fieldFromInstruction(field_t insn, unsigned startBit, unsigned numBits)\n"; 782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "{\n"; 784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "assert(startBit + numBits <= " << BIT_WIDTH 787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << " && \"Instruction field out of bounds!\");\n"; 788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "field_t fieldMask;\n"; 790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "if (numBits == " << BIT_WIDTH << ")\n"; 792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "fieldMask = (field_t)-1;\n"; 795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "else\n"; 798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "fieldMask = ((1 << numBits) - 1) << startBit;\n"; 801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "return (insn & fieldMask) >> startBit;\n"; 805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "}\n"; 808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman o.indent(Indentation) <<"static uint16_t decodeInstruction(field_t insn) {\n"; 812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emits code to decode the instructions. 815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emit(o, Indentation); 816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "return 0;\n"; 819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "}\n"; 822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This provides an opportunity for target specific code emission after 827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// emitTop(). 82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::emitBot(raw_ostream &o, unsigned &Indentation) { 829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TargetName != TARGET_THUMB) return; 830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit code that decodes the Thumb ISA. 832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) 833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "static uint16_t decodeThumbInstruction(field_t insn) {\n"; 834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emits code to decode the instructions. 838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emit(o, Indentation); 839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "return 0;\n"; 842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "}\n"; 846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Populates the field of the insn given the start position and the number of 849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// consecutive bits to scan for. 850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Returns false if and on the first uninitialized bit value encountered. 852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Returns true, otherwise. 85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ARMFilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn, 854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned StartBit, unsigned NumBits) const { 855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Field = 0; 856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < NumBits; ++i) { 858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Insn[StartBit + i] == BIT_UNSET) 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Insn[StartBit + i] == BIT_TRUE) 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Field = Field | (1ULL << i); 863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// dumpFilterArray - dumpFilterArray prints out debugging info for the given 869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// filter array as a series of chars. 87019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::dumpFilterArray(raw_ostream &o, 871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bit_value_t (&filter)[BIT_WIDTH]) { 872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned bitIndex; 873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (bitIndex = BIT_WIDTH; bitIndex > 0; bitIndex--) { 875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (filter[bitIndex - 1]) { 876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BIT_UNFILTERED: 877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "."; 878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BIT_UNSET: 880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "_"; 881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BIT_TRUE: 883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "1"; 884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case BIT_FALSE: 886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "0"; 887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// dumpStack - dumpStack traverses the filter chooser chain and calls 893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// dumpFilterArray on each filter chooser up to the top level one. 89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::dumpStack(raw_ostream &o, const char *prefix) { 89519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser *current = this; 896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (current) { 898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << prefix; 899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dumpFilterArray(o, current->FilterBitValues); 900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman current = current->Parent; 902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Called from Filter::recurse() when singleton exists. For debug purpose. 90619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::SingletonExists(unsigned Opc) { 907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insn_t Insn0; 908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insnWithID(Insn0, Opc); 909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "Singleton exists: " << nameWithID(Opc) 911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << " with its decoding dominating "; 912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < Opcodes.size(); ++i) { 913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Opcodes[i] == Opc) continue; 914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << nameWithID(Opcodes[i]) << ' '; 915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << '\n'; 917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dumpStack(errs(), "\t\t"); 919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < Opcodes.size(); i++) { 920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string &Name = nameWithID(Opcodes[i]); 921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << '\t' << Name << " "; 923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dumpBits(errs(), 924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << '\n'; 926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Calculates the island(s) needed to decode the instruction. 930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This returns a list of undecoded bits of an instructions, for example, 931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Inst{20} = 1 && Inst{3-0} == 0b1111 represents two islands of yet-to-be 932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// decoded bits in order to verify that the instruction matches the Opcode. 93319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned ARMFilterChooser::getIslands(std::vector<unsigned> &StartBits, 934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals, 935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insn_t &Insn) { 936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Num, BitNo; 937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Num = BitNo = 0; 938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t FieldVal = 0; 940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 0: Init 942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1: Water (the bit value does not affect decoding) 943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 2: Island (well-known bit value needed for decoding) 944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int State = 0; 945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int Val = -1; 946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < BIT_WIDTH; ++i) { 948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Val = Value(Insn[i]); 949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool Filtered = PositionFiltered(i); 950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (State) { 951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Unreachable code!"); 953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 0: 955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 1: 956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Filtered || Val == -1) 957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman State = 1; // Still in Water 958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else { 959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman State = 2; // Into the Island 960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitNo = 0; 961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StartBits.push_back(i); 962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FieldVal = Val; 963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case 2: 966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Filtered || Val == -1) { 967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman State = 1; // Into the Water 968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EndBits.push_back(i - 1); 969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FieldVals.push_back(FieldVal); 970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Num; 971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman State = 2; // Still in Island 973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++BitNo; 974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FieldVal = FieldVal | Val << BitNo; 975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we are still in Island after the loop, do some housekeeping. 980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (State == 2) { 981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EndBits.push_back(BIT_WIDTH - 1); 982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FieldVals.push_back(FieldVal); 983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Num; 984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(StartBits.size() == Num && EndBits.size() == Num && 987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FieldVals.size() == Num); 988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Num; 989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emits code to decode the singleton. Return true if we have matched all the 992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// well-known bits. 99319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ARMFilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, 994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc) { 995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> StartBits; 996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> EndBits; 997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<uint64_t> FieldVals; 998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insn_t Insn; 999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insnWithID(Insn, Opc); 1000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This provides a good opportunity to check for possible Ld/St Coprocessor 1002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Opcode and escapes if the coproc # is either 10 or 11. It is a NEON/VFP 1003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // instruction is disguise. 1004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TargetName == TARGET_ARM && LdStCopEncoding1(Opc)) { 1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation); 1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // A8.6.51 & A8.6.188 1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If coproc = 0b101?, i.e, slice(insn, 11, 8) = 10 or 11, escape. 1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "if (fieldFromInstruction(insn, 9, 3) == 5) break; // fallthrough\n"; 1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Look for islands of undecoded bits of the singleton. 1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getIslands(StartBits, EndBits, FieldVals, Insn); 1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Size = StartBits.size(); 1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned I, NumBits; 1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have matched all the well-known bits, just issue a return. 1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Size == 0) { 1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "return " << Opc << "; // " << nameWithID(Opc) 1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << '\n'; 1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, there are more decodings to be done! 1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit code to match the island(s) for the singleton. 1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "// Check "; 1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (I = Size; I != 0; --I) { 1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "Inst{" << EndBits[I-1] << '-' << StartBits[I-1] << "} "; 1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I > 1) 1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "&& "; 1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "for singleton decoding...\n"; 1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "if ("; 1038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (I = Size; I != 0; --I) { 1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumBits = EndBits[I-1] - StartBits[I-1] + 1; 1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "fieldFromInstruction(insn, " << StartBits[I-1] << ", " << NumBits 1042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << ") == " << FieldVals[I-1]; 1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I > 1) 1044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << " && "; 1045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << ")\n"; 1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << " return " << Opc << "; // " << nameWithID(Opc) 1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << '\n'; 1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emits code to decode the singleton, and then to decode the rest. 105619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::emitSingletonDecoder(raw_ostream &o, 105719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned &Indentation, 105819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilter &Best) { 1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = Best.getSingletonOpc(); 1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitSingletonDecoder(o, Indentation, Opc); 1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit code for the rest. 1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "else\n"; 1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Indentation += 2; 1068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Best.getVariableFC().emit(o, Indentation); 1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Indentation -= 2; 1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Assign a single filter and run with it. Top level API client can initialize 1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// with a single filter to start the filtering process. 107419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::runSingleFilter(ARMFilterChooser &owner, 107519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned startBit, 107619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned numBit, bool mixed) { 1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Filters.clear(); 107819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilter F(*this, startBit, numBit, true); 1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Filters.push_back(F); 1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BestIndex = 0; // Sole Filter instance to choose from. 1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bestFilter().recurse(); 1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// reportRegion is a helper function for filterProcessor to mark a region as 1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// eligible for use as a filter region. 108619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit, 108719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned BitIndex, bool AllowMixed) { 1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RA == ATTR_MIXED && AllowMixed) 108919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Filters.push_back(ARMFilter(*this, StartBit, BitIndex - StartBit, true)); 1090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (RA == ATTR_ALL_SET && !AllowMixed) 109119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Filters.push_back(ARMFilter(*this, StartBit, BitIndex - StartBit, false)); 1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// FilterProcessor scans the well-known encoding bits of the instructions and 1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// builds up a list of candidate filters. It chooses the best filter and 1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// recursively descends down the decoding tree. 109719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ARMFilterChooser::filterProcessor(bool AllowMixed, bool Greedy) { 1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Filters.clear(); 1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BestIndex = -1; 1100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned numInstructions = Opcodes.size(); 1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(numInstructions && "Filter created with no instructions"); 1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // No further filtering is necessary. 1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (numInstructions == 1) 1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Heuristics. See also doFilter()'s "Heuristics" comment when num of 1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // instructions is 3. 1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AllowMixed && !Greedy) { 1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(numInstructions == 3); 1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < Opcodes.size(); ++i) { 1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> StartBits; 1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> EndBits; 1116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<uint64_t> FieldVals; 1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insn_t Insn; 1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insnWithID(Insn, Opcodes[i]); 1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Look for islands of undecoded bits of any instruction. 1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) { 1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Found an instruction with island(s). Now just assign a filter. 1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman runSingleFilter(*this, StartBits[0], EndBits[0] - StartBits[0] + 1, 1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman true); 1126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned BitIndex, InsnIndex; 1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We maintain BIT_WIDTH copies of the bitAttrs automaton. 1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The automaton consumes the corresponding bit from each 1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // instruction. 1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Input symbols: 0, 1, and _ (unset). 1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED. 1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Initial state: NONE. 1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (NONE) ------- [01] -> (ALL_SET) 1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (NONE) ------- _ ----> (ALL_UNSET) 1143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (ALL_SET) ---- [01] -> (ALL_SET) 1144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (ALL_SET) ---- _ ----> (MIXED) 1145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (ALL_UNSET) -- [01] -> (MIXED) 1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (ALL_UNSET) -- _ ----> (ALL_UNSET) 1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (MIXED) ------ . ----> (MIXED) 1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (FILTERED)---- . ----> (FILTERED) 1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttr_t bitAttrs[BIT_WIDTH]; 1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FILTERED bit positions provide no entropy and are not worthy of pursuing. 1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position. 1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (BitIndex = 0; BitIndex < BIT_WIDTH; ++BitIndex) 1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FilterBitValues[BitIndex] == BIT_TRUE || 1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FilterBitValues[BitIndex] == BIT_FALSE) 1157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttrs[BitIndex] = ATTR_FILTERED; 1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttrs[BitIndex] = ATTR_NONE; 1160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) { 1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insn_t insn; 1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman insnWithID(insn, Opcodes[InsnIndex]); 1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (BitIndex = 0; BitIndex < BIT_WIDTH; ++BitIndex) { 1167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (bitAttrs[BitIndex]) { 1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_NONE: 1169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (insn[BitIndex] == BIT_UNSET) 1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttrs[BitIndex] = ATTR_ALL_UNSET; 1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttrs[BitIndex] = ATTR_ALL_SET; 1173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_SET: 1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (insn[BitIndex] == BIT_UNSET) 1176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttrs[BitIndex] = ATTR_MIXED; 1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_UNSET: 1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (insn[BitIndex] != BIT_UNSET) 1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttrs[BitIndex] = ATTR_MIXED; 1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_MIXED: 1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_FILTERED: 1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The regionAttr automaton consumes the bitAttrs automatons' state, 1190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // lowest-to-highest. 1191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Input symbols: F(iltered), (all_)S(et), (all_)U(nset), M(ixed) 1193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // States: NONE, ALL_SET, MIXED 1194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Initial state: NONE 1195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (NONE) ----- F --> (NONE) 1197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (NONE) ----- S --> (ALL_SET) ; and set region start 1198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (NONE) ----- U --> (NONE) 1199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (NONE) ----- M --> (MIXED) ; and set region start 1200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (ALL_SET) -- F --> (NONE) ; and report an ALL_SET region 1201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (ALL_SET) -- S --> (ALL_SET) 1202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (ALL_SET) -- U --> (NONE) ; and report an ALL_SET region 1203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (ALL_SET) -- M --> (MIXED) ; and report an ALL_SET region 1204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (MIXED) ---- F --> (NONE) ; and report a MIXED region 1205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (MIXED) ---- S --> (ALL_SET) ; and report a MIXED region 1206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (MIXED) ---- U --> (NONE) ; and report a MIXED region 1207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (MIXED) ---- M --> (MIXED) 1208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttr_t RA = ATTR_NONE; 1210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned StartBit = 0; 1211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (BitIndex = 0; BitIndex < BIT_WIDTH; BitIndex++) { 1213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitAttr_t bitAttr = bitAttrs[BitIndex]; 1214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(bitAttr != ATTR_NONE && "Bit without attributes"); 1216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (RA) { 1218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_NONE: 1219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (bitAttr) { 1220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_FILTERED: 1221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_SET: 1223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StartBit = BitIndex; 1224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RA = ATTR_ALL_SET; 1225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_UNSET: 1227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_MIXED: 1229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StartBit = BitIndex; 1230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RA = ATTR_MIXED; 1231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Unexpected bitAttr!"); 1234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_SET: 1237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (bitAttr) { 1238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_FILTERED: 1239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman reportRegion(RA, StartBit, BitIndex, AllowMixed); 1240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RA = ATTR_NONE; 1241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_SET: 1243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_UNSET: 1245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman reportRegion(RA, StartBit, BitIndex, AllowMixed); 1246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RA = ATTR_NONE; 1247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_MIXED: 1249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman reportRegion(RA, StartBit, BitIndex, AllowMixed); 1250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StartBit = BitIndex; 1251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RA = ATTR_MIXED; 1252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Unexpected bitAttr!"); 1255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_MIXED: 1258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (bitAttr) { 1259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_FILTERED: 1260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman reportRegion(RA, StartBit, BitIndex, AllowMixed); 1261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StartBit = BitIndex; 1262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RA = ATTR_NONE; 1263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_SET: 1265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman reportRegion(RA, StartBit, BitIndex, AllowMixed); 1266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StartBit = BitIndex; 1267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RA = ATTR_ALL_SET; 1268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_UNSET: 1270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman reportRegion(RA, StartBit, BitIndex, AllowMixed); 1271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RA = ATTR_NONE; 1272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_MIXED: 1274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Unexpected bitAttr!"); 1277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_UNSET: 1280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "regionAttr state machine has no ATTR_UNSET state"); 1281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_FILTERED: 1282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "regionAttr state machine has no ATTR_FILTERED state"); 1283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // At the end, if we're still in ALL_SET or MIXED states, report a region 1287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (RA) { 1288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_NONE: 1289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_FILTERED: 1291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_SET: 1293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman reportRegion(RA, StartBit, BitIndex, AllowMixed); 1294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_ALL_UNSET: 1296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ATTR_MIXED: 1298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman reportRegion(RA, StartBit, BitIndex, AllowMixed); 1299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We have finished with the filter processings. Now it's time to choose 1303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the best performing filter. 1304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BestIndex = 0; 1305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool AllUseless = true; 1306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned BestScore = 0; 1307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Filters.size(); i != e; ++i) { 1309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Usefulness = Filters[i].usefulness(); 1310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Usefulness) 1312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AllUseless = false; 1313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Usefulness > BestScore) { 1315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BestIndex = i; 1316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BestScore = Usefulness; 1317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!AllUseless) 1321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bestFilter().recurse(); 1322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return !AllUseless; 1324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // end of FilterChooser::filterProcessor(bool) 1325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Decides on the best configuration of filter(s) to use in order to decode 1327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// the instructions. A conflict of instructions may occur, in which case we 1328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// dump the conflict set to the standard error. 132919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ARMFilterChooser::doFilter() { 1330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Num = Opcodes.size(); 1331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Num && "FilterChooser created with no instructions"); 1332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Heuristics: Use Inst{31-28} as the top level filter for ARM ISA. 1334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TargetName == TARGET_ARM && Parent == NULL) { 1335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman runSingleFilter(*this, 28, 4, false); 1336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Try regions of consecutive known bit values first. 1340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (filterProcessor(false)) 1341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Then regions of mixed bits (both known and unitialized bit values allowed). 1344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (filterProcessor(true)) 1345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where 1348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a 1349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // well-known encoding pattern. In such case, we backtrack and scan for the 1350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the very first consecutive ATTR_ALL_SET region and assign a filter to it. 1351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Num == 3 && filterProcessor(true, false)) 1352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we come to here, the instruction decoding has failed. 1355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Set the BestIndex to -1 to indicate so. 1356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BestIndex = -1; 1357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emits code to decode our share of instructions. Returns true if the 1360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// emitted code causes a return, which occurs if we know how to decode 1361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// the instruction at this level or the instruction is not decodeable. 136219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ARMFilterChooser::emit(raw_ostream &o, unsigned &Indentation) { 1363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Opcodes.size() == 1) 1364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // There is only one instruction in the set, which is great! 1365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Call emitSingletonDecoder() to see whether there are any remaining 1366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // encodings bits. 1367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return emitSingletonDecoder(o, Indentation, Opcodes[0]); 1368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Choose the best filter to do the decodings! 1370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BestIndex != -1) { 137119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilter &Best = bestFilter(); 1372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Best.getNumFiltered() == 1) 1373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman emitSingletonDecoder(o, Indentation, Best); 1374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bestFilter().emit(o, Indentation); 1376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we reach here, there is a conflict in decoding. Let's resolve the known 1380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // conflicts! 1381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((TargetName == TARGET_ARM || TargetName == TARGET_THUMB) && 1382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Opcodes.size() == 2) { 1383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Resolve the known conflict sets: 1384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1. source registers are identical => VMOVDneon; otherwise => VORRd 1386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 2. source registers are identical => VMOVQ; otherwise => VORRq 1387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 3. LDR, LDRcp => return LDR for now. 1388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: How can we distinguish between LDR and LDRcp? Do we need to? 138919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 4. tLDMIA, tLDMIA_UPD => Rn = Inst{10-8}, reglist = Inst{7-0}, 1390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // wback = registers<Rn> = 0 1391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: (tLDM, tLDM_UPD) resolution must come before Advanced SIMD 1392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // addressing mode resolution!!! 1393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 5. VLD[234]LN*/VST[234]LN* vs. VLD[234]LN*_UPD/VST[234]LN*_UPD conflicts 1394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // are resolved returning the non-UPD versions of the instructions if the 1395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Rm field, i.e., Inst{3-0} is 0b1111. This is specified in A7.7.1 1396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Advanced SIMD addressing mode. 1397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string &name1 = nameWithID(Opcodes[0]); 1398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string &name2 = nameWithID(Opcodes[1]); 1399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((name1 == "VMOVDneon" && name2 == "VORRd") || 1400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (name1 == "VMOVQ" && name2 == "VORRq")) { 1401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Inserting the opening curly brace for this case block. 1402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 1403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "{\n"; 1404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 1405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) 1407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "field_t N = fieldFromInstruction(insn, 7, 1), " 1408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "M = fieldFromInstruction(insn, 5, 1);\n"; 1409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) 1410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "field_t Vn = fieldFromInstruction(insn, 16, 4), " 1411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "Vm = fieldFromInstruction(insn, 0, 4);\n"; 1412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) 1413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "return (N == M && Vn == Vm) ? " 1414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << Opcodes[0] << " /* " << name1 << " */ : " 1415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << Opcodes[1] << " /* " << name2 << " */ ;\n"; 1416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Inserting the closing curly brace for this case block. 1418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 1419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "}\n"; 1420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 1421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (name1 == "LDR" && name2 == "LDRcp") { 1425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) 1426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "return " << Opcodes[0] 1427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "; // Returning LDR for {LDR, LDRcp}\n"; 1428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 143019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (name1 == "tLDMIA" && name2 == "tLDMIA_UPD") { 1431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Inserting the opening curly brace for this case block. 1432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 1433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "{\n"; 1434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 1435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) 1437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "unsigned Rn = fieldFromInstruction(insn, 8, 3), " 1438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "list = fieldFromInstruction(insn, 0, 8);\n"; 1439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) 1440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "return ((list >> Rn) & 1) == 0 ? " 1441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << Opcodes[1] << " /* " << name2 << " */ : " 1442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << Opcodes[0] << " /* " << name1 << " */ ;\n"; 1443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Inserting the closing curly brace for this case block. 1445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --Indentation; --Indentation; 1446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "}\n"; 1447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ++Indentation; ++Indentation; 1448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (sameStringExceptSuffix(name1, name2, "_UPD")) { 1452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) 1453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << "return fieldFromInstruction(insn, 0, 4) == 15 ? " << Opcodes[0] 1454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << " /* " << name1 << " */ : " << Opcodes[1] << "/* " << name2 1455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman << " */ ; // Advanced SIMD addressing mode\n"; 1456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, it does not belong to the known conflict sets. 1460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We don't know how to decode these instructions! Return 0 and dump the 1463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // conflict set! 1464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o.indent(Indentation) << "return 0;" << " // Conflict set: "; 1465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = 0, N = Opcodes.size(); i < N; ++i) { 1466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << nameWithID(Opcodes[i]); 1467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (i < (N - 1)) 1468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << ", "; 1469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 1471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Print out useful conflict information for postmortem analysis. 1474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "Decoding Conflict:\n"; 1475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dumpStack(errs(), "\t\t"); 1477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < Opcodes.size(); i++) { 1479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string &Name = nameWithID(Opcodes[i]); 1480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << '\t' << Name << " "; 1482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dumpBits(errs(), 1483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getBitsField(*AllInstructions[Opcodes[i]]->TheDef, "Inst")); 1484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << '\n'; 1485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//////////////////////////////////////////// 1492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 1493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// ARMDEBackend // 1494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// (Helper class for ARMDecoderEmitter) // 1495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// // 1496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//////////////////////////////////////////// 1497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass ARMDecoderEmitter::ARMDEBackend { 1499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 150019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMDEBackend(ARMDecoderEmitter &frontend, RecordKeeper &Records) : 1501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumberedInstructions(), 1502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Opcodes(), 1503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Frontend(frontend), 150419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Target(Records), 1505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FC(NULL) 1506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Target.getName() == "ARM") 1508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetName = TARGET_ARM; 1509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else { 1510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "Target name " << Target.getName() << " not recognized\n"; 1511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Unknown target"); 1512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Populate the instructions for our TargetName. 1515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman populateInstructions(); 1516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ~ARMDEBackend() { 1519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FC) { 1520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete FC; 1521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FC = NULL; 1522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> 1526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &NumberedInstructions) { 1527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We must emit the PHI opcode first... 1528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string Namespace = Target.getInstNamespace(); 1529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!Namespace.empty() && "No instructions defined."); 1530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumberedInstructions = Target.getInstructionsByEnumValue(); 1532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool populateInstruction(const CodeGenInstruction &CGI, TARGET_NAME_t TN); 1535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void populateInstructions(); 1537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emits disassembler code for instruction decoding. This delegates to the 1539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FilterChooser instance to do the heavy lifting. 1540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void emit(raw_ostream &o); 1541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprotected: 1543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<const CodeGenInstruction*> NumberedInstructions; 1544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> Opcodes; 1545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Special case for the ARM chip, which supports ARM and Thumb ISAs. 1546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Opcodes2 will be populated with the Thumb opcodes. 1547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<unsigned> Opcodes2; 1548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ARMDecoderEmitter &Frontend; 1549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CodeGenTarget Target; 155019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser *FC; 1551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TARGET_NAME_t TargetName; 1553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 1554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 155519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ARMDecoderEmitter:: 155619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, 155719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TARGET_NAME_t TN) { 1558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Record &Def = *CGI.TheDef; 1559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const StringRef Name = Def.getName(); 1560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint8_t Form = getByteField(Def, "Form"); 1561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitsInit &Bits = getBitsField(Def, "Inst"); 1563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If all the bit positions are not specified; do not decode this instruction. 1565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We are bound to fail! For proper disassembly, the well-known encoding bits 1566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // of the instruction must be fully specified. 1567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This also removes pseudo instructions from considerations of disassembly, 1569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // which is a better design and less fragile than the name matchings. 1570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Bits.allInComplete()) return false; 1571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 157219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Ignore "asm parser only" instructions. 157319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Def.getValueAsBit("isAsmParserOnly")) 157419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return false; 157519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TN == TARGET_ARM) { 157719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Form == ARM_FORMAT_PSEUDO) 1578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (thumbInstruction(Form)) 1580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Tail calls are other patterns that generate existing instructions. 1583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Name == "TCRETURNdi" || Name == "TCRETURNdiND" || 1584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "TCRETURNri" || Name == "TCRETURNriND" || 1585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "TAILJMPd" || Name == "TAILJMPdt" || 1586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "TAILJMPdND" || Name == "TAILJMPdNDt" || 1587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "TAILJMPr" || Name == "TAILJMPrND" || 1588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "MOVr_TC") 1589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 159119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Delegate ADR disassembly to the more generic ADDri/SUBri instructions. 159219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Name == "ADR") 1593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The following special cases are for conflict resolutions. 1597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // A8-598: VEXT 1600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Vector Extract extracts elements from the bottom end of the second 1601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // operand vector and the top end of the first, concatenates them and 1602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // places the result in the destination vector. The elements of the 1603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // vectors are treated as being 8-bit bitfields. There is no distinction 1604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // between data types. The size of the operation can be specified in 1605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // assembler as vext.size. If the value is 16, 32, or 64, the syntax is 1606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // a pseudo-instruction for a VEXT instruction specifying the equivalent 1607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // number of bytes. 1608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Variants VEXTd16, VEXTd32, VEXTd8, and VEXTdf are reduced to VEXTd8; 1610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // variants VEXTq16, VEXTq32, VEXTq8, and VEXTqf are reduced to VEXTq8. 1611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Name == "VEXTd16" || Name == "VEXTd32" || Name == "VEXTdf" || 1612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Name == "VEXTq16" || Name == "VEXTq32" || Name == "VEXTqf") 1613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (TN == TARGET_THUMB) { 1615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!thumbInstruction(Form)) 1616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 161819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // A8.6.25 BX. Use the generic tBX_Rm, ignore tBX_RET and tBX_RET_vararg. 161919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Name == "tBX_RET" || Name == "tBX_RET_vararg") 1620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 162219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Ignore tADR, prefer tADDrPCi. 162319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Name == "tADR") 1624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 162619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Delegate t2ADR disassembly to the more generic t2ADDri12/t2SUBri12 162719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // instructions. 162819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Name == "t2ADR") 1629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ignore tADDrSP, tADDspr, and tPICADD, prefer the generic tADDhirr. 1632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ignore t2SUBrSPs, prefer the t2SUB[S]r[r|s]. 1633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ignore t2ADDrSPs, prefer the t2ADD[S]r[r|s]. 1634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Name == "tADDrSP" || Name == "tADDspr" || Name == "tPICADD" || 163519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Name == "t2SUBrSPs" || Name == "t2ADDrSPs") 1636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 163819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: Use ldr.n to work around a Darwin assembler bug. 163919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Introduce a workaround with tLDRpciDIS opcode. 164019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Name == "tLDRpci") 1641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 164319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Ignore t2LDRDpci, prefer the generic t2LDRDi8, t2LDRD_PRE, t2LDRD_POST. 164419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Name == "t2LDRDpci") 1645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Resolve conflicts: 1648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 164919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // t2LDMIA_RET conflict with t2LDM (ditto) 1650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // tMOVCCi conflicts with tMOVi8 1651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // tMOVCCr conflicts with tMOVgpr2gpr 1652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // tLDRcp conflicts with tLDRspi 165319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // t2MOVCCi16 conflicts with tMOVi16 165419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Name == "t2LDMIA_RET" || 165519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Name == "tMOVCCi" || Name == "tMOVCCr" || 165619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Name == "tLDRcp" || 165719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Name == "t2MOVCCi16") 1658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG({ 166219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Dumps the instruction encoding format. 166319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (TargetName) { 166419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TARGET_ARM: 166519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TARGET_THUMB: 166619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman errs() << Name << " " << stringForARMFormat((ARMFormat)Form); 166719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 166819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 166919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << " "; 1671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Dumps the instruction encoding bits. 1673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dumpBits(errs(), Bits); 1674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << '\n'; 1676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Dumps the list of operand info. 167819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { 167919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CGIOperandList::OperandInfo &Info = CGI.Operands[i]; 1680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const std::string &OperandName = Info.Name; 1681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Record &OperandDef = *Info.Rec; 1682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n"; 1684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }); 1686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid ARMDecoderEmitter::ARMDEBackend::populateInstructions() { 1691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getInstructionsByEnumValue(NumberedInstructions); 1692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 169319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned numUIDs = NumberedInstructions.size(); 169419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TargetName == TARGET_ARM) { 169519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned uid = 0; uid < numUIDs; uid++) { 169619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // filter out intrinsics 169719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!NumberedInstructions[uid]->TheDef->isSubClassOf("InstARM")) 169819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 1699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 170019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (populateInstruction(*NumberedInstructions[uid], TargetName)) 170119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Opcodes.push_back(uid); 170219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 170419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Special handling for the ARM chip, which supports two modes of execution. 170519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This branch handles the Thumb opcodes. 170619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned uid = 0; uid < numUIDs; uid++) { 1707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // filter out intrinsics 1708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!NumberedInstructions[uid]->TheDef->isSubClassOf("InstARM") 1709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman && !NumberedInstructions[uid]->TheDef->isSubClassOf("InstThumb")) 1710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 1711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (populateInstruction(*NumberedInstructions[uid], TARGET_THUMB)) 1713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Opcodes2.push_back(uid); 1714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 171519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 171619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 171719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 171819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 171919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // For other targets. 172019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned uid = 0; uid < numUIDs; uid++) { 172119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *R = NumberedInstructions[uid]->TheDef; 172219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (R->getValueAsString("Namespace") == "TargetOpcode") 172319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 172419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 172519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (populateInstruction(*NumberedInstructions[uid], TargetName)) 172619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Opcodes.push_back(uid); 1727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Emits disassembler code for instruction decoding. This delegates to the 1731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// FilterChooser instance to do the heavy lifting. 1732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid ARMDecoderEmitter::ARMDEBackend::emit(raw_ostream &o) { 1733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (TargetName) { 1734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TARGET_ARM: 1735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Frontend.EmitSourceFileHeader("ARM/Thumb Decoders", o); 1736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Unreachable code!"); 1739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 174119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman o << "#include \"llvm/Support/DataTypes.h\"\n"; 1742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "#include <assert.h>\n"; 1743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << '\n'; 1744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "namespace llvm {\n\n"; 1745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 174619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser::setTargetName(TargetName); 1747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (TargetName) { 1749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TARGET_ARM: { 1750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit common utility and ARM ISA decoder. 175119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FC = new ARMFilterChooser(NumberedInstructions, Opcodes); 1752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Reset indentation level. 1753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Indentation = 0; 1754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FC->emitTop(o, Indentation); 1755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete FC; 1756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit Thumb ISA decoder as well. 175819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ARMFilterChooser::setTargetName(TARGET_THUMB); 175919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FC = new ARMFilterChooser(NumberedInstructions, Opcodes2); 1760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Reset indentation level. 1761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Indentation = 0; 1762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FC->emitBot(o, Indentation); 1763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Unreachable code!"); 1767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman o << "\n} // End llvm namespace \n"; 1770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///////////////////////// 1773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Backend interface // 1774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman///////////////////////// 1775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid ARMDecoderEmitter::initBackend() 1777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 177819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Backend = new ARMDEBackend(*this, Records); 1779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid ARMDecoderEmitter::run(raw_ostream &o) 1782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 1783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Backend->emit(o); 1784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid ARMDecoderEmitter::shutdownBackend() 1787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 1788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete Backend; 1789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Backend = NULL; 1790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1791