X86RecognizableInstr.cpp revision c266600bec4b5ba0ee93ffdfeaafcab8f1295145
15b955920c1d8f2cd35aae3c85b656578286a8bc1Anders Carlsson//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===//
25d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
35d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//                     The LLVM Compiler Infrastructure
45d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
55d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This file is distributed under the University of Illinois Open Source
65d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// License. See LICENSE.TXT for details.
75d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
85d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//===----------------------------------------------------------------------===//
95d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//
105d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This file is part of the X86 Disassembler Emitter.
115d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// It contains the implementation of a single recognizable instruction.
125d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// Documentation for the disassembler emitter in general can be found in
135d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//  X86DisasemblerEmitter.h.
1464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman//
15d67ef0eed463b43980f04a444155f423114be34bDevang Patel//===----------------------------------------------------------------------===//
1656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
175d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "X86DisassemblerShared.h"
182f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "X86RecognizableInstr.h"
197e1dff7a68a4d00e71debafa7f5c259473091746John McCall#include "X86ModRMFilters.h"
205d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall#include "llvm/Support/ErrorHandling.h"
2256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
233ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel#include <string>
242f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson
255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace llvm;
265d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
275d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#define MRM_MAPPING     \
2855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck  MAP(C1, 33)           \
2934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  MAP(C2, 34)           \
3034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  MAP(C3, 35)           \
31f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  MAP(C4, 36)           \
32f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  MAP(C8, 37)           \
3355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck  MAP(C9, 38)           \
3434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  MAP(E8, 39)           \
3534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  MAP(F0, 40)           \
3634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  MAP(F8, 41)           \
37f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  MAP(F9, 42)
3834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
3934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson// A clone of X86 since we can't depend on something that is generated.
4034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlssonnamespace X86Local {
4134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  enum {
4234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    Pseudo      = 0,
4334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    RawFrm      = 1,
4434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    AddRegFrm   = 2,
4534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    MRMDestReg  = 3,
4634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    MRMDestMem  = 4,
4734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    MRMSrcReg   = 5,
4855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck    MRMSrcMem   = 6,
4934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19,
5034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
5134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
5234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
5355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck    MRMInitReg  = 32,
5434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson#define MAP(from, to) MRM_##from = to,
555d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson    MRM_MAPPING
5684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson#undef MAP
57a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson    RawFrmImm8  = 43,
58f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    RawFrmImm16 = 44,
59f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    lastMRM
60f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  };
61a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson
6255c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck  enum {
63f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    TB  = 1,
64f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    REP = 2,
6555c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck    D8 = 3, D9 = 4, DA = 5, DB = 6,
66a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson    DC = 7, DD = 8, DE = 9, DF = 10,
67a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson    XD = 11,  XS = 12,
682acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    T8 = 13,  P_TA = 14,
69a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson    P_0F_AE = 16, P_0F_01 = 17
70a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson  };
7155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck}
7284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson
7384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson// If rows are added to the opcode extension tables, then corresponding entries
748561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// must be added here.
75bff225ecf77fb891596ecb1b27196310d268365eJohn McCall//
76bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// If the row corresponds to a single byte (i.e., 8f), then add an entry for
77bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// that byte to ONE_BYTE_EXTENSION_TABLES.
78bff225ecf77fb891596ecb1b27196310d268365eJohn McCall//
79bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// If the row corresponds to two bytes where the first is 0f, add an entry for
808561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// the second byte to TWO_BYTE_EXTENSION_TABLES.
818561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson//
828561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// If the row corresponds to some other set of bytes, you will need to modify
838561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes
84bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// to the X86 TD files, except in two cases: if the first two bytes of such a
85bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// new combination are 0f 38 or 0f 3a, you just have to add maps called
86bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a
87bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line
88bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// in RecognizableInstr::emitDecodePath().
89bff225ecf77fb891596ecb1b27196310d268365eJohn McCall
905fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck#define ONE_BYTE_EXTENSION_TABLES \
91bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(80)             \
928561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson  EXTENSION_TABLE(81)             \
935fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck  EXTENSION_TABLE(82)             \
94bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(83)             \
955fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck  EXTENSION_TABLE(8f)             \
96bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(c0)             \
97bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(c1)             \
98bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(c6)             \
99bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(c7)             \
1005fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck  EXTENSION_TABLE(d0)             \
101bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(d1)             \
1025fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck  EXTENSION_TABLE(d2)             \
103bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(d3)             \
104bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(f6)             \
105bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(f7)             \
106bff225ecf77fb891596ecb1b27196310d268365eJohn McCall  EXTENSION_TABLE(fe)             \
107d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson  EXTENSION_TABLE(ff)
108bff225ecf77fb891596ecb1b27196310d268365eJohn McCall
1099dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson#define TWO_BYTE_EXTENSION_TABLES \
1107916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(00)             \
1117916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(01)             \
1127916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(18)             \
1137916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(71)             \
1147916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(72)             \
1157916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(73)             \
1167916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(ae)             \
1177916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(ba)             \
1187916c997127fe616ba255ba4cade10e5de0c8812John McCall  EXTENSION_TABLE(c7)
1197916c997127fe616ba255ba4cade10e5de0c8812John McCall
1207916c997127fe616ba255ba4cade10e5de0c8812John McCallusing namespace X86Disassembler;
1217916c997127fe616ba255ba4cade10e5de0c8812John McCall
1227916c997127fe616ba255ba4cade10e5de0c8812John McCall/// needsModRMForDecode - Indicates whether a particular instruction requires a
1237916c997127fe616ba255ba4cade10e5de0c8812John McCall///   ModR/M byte for the instruction to be properly decoded.  For example, a
1247916c997127fe616ba255ba4cade10e5de0c8812John McCall///   MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to
1257916c997127fe616ba255ba4cade10e5de0c8812John McCall///   0b11.
1267916c997127fe616ba255ba4cade10e5de0c8812John McCall///
1279dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson/// @param form - The form of the instruction.
1289dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson/// @return     - true if the form implies that a ModR/M byte is required, false
1297916c997127fe616ba255ba4cade10e5de0c8812John McCall///               otherwise.
1307916c997127fe616ba255ba4cade10e5de0c8812John McCallstatic bool needsModRMForDecode(uint8_t form) {
1317916c997127fe616ba255ba4cade10e5de0c8812John McCall  if (form == X86Local::MRMDestReg    ||
1329dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson     form == X86Local::MRMDestMem    ||
1339dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson     form == X86Local::MRMSrcReg     ||
1345d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson     form == X86Local::MRMSrcMem     ||
13534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson     (form >= X86Local::MRM0r && form <= X86Local::MRM7r) ||
1368561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson     (form >= X86Local::MRM0m && form <= X86Local::MRM7m))
137f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    return true;
138f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall  else
13934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    return false;
140f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall}
14134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
142f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall/// isRegFormat - Indicates whether a particular form requires the Mod field of
14334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson///   the ModR/M byte to be 0b11.
14434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson///
1457916c997127fe616ba255ba4cade10e5de0c8812John McCall/// @param form - The form of the instruction.
1467916c997127fe616ba255ba4cade10e5de0c8812John McCall/// @return     - true if the form implies that Mod must be 0b11, false
1477916c997127fe616ba255ba4cade10e5de0c8812John McCall///               otherwise.
1487916c997127fe616ba255ba4cade10e5de0c8812John McCallstatic bool isRegFormat(uint8_t form) {
14934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  if (form == X86Local::MRMDestReg ||
15034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson     form == X86Local::MRMSrcReg  ||
15134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson     (form >= X86Local::MRM0r && form <= X86Local::MRM7r))
15234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson    return true;
15334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  else
1547916c997127fe616ba255ba4cade10e5de0c8812John McCall    return false;
1557916c997127fe616ba255ba4cade10e5de0c8812John McCall}
1567916c997127fe616ba255ba4cade10e5de0c8812John McCall
1577916c997127fe616ba255ba4cade10e5de0c8812John McCall/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
15855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck///   Useful for switch statements and the like.
1598561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson///
160f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall/// @param init - A reference to the BitsInit to be decoded.
16134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson/// @return     - The field, with the first bit in the BitsInit as the lowest
1627916c997127fe616ba255ba4cade10e5de0c8812John McCall///               order bit.
1637916c997127fe616ba255ba4cade10e5de0c8812John McCallstatic uint8_t byteFromBitsInit(BitsInit &init) {
1647916c997127fe616ba255ba4cade10e5de0c8812John McCall  int width = init.getNumBits();
1657916c997127fe616ba255ba4cade10e5de0c8812John McCall
1667916c997127fe616ba255ba4cade10e5de0c8812John McCall  assert(width <= 8 && "Field is too large for uint8_t!");
1677916c997127fe616ba255ba4cade10e5de0c8812John McCall
1687916c997127fe616ba255ba4cade10e5de0c8812John McCall  int     index;
1697916c997127fe616ba255ba4cade10e5de0c8812John McCall  uint8_t mask = 0x01;
1707916c997127fe616ba255ba4cade10e5de0c8812John McCall
1717916c997127fe616ba255ba4cade10e5de0c8812John McCall  uint8_t ret = 0;
17234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
1732acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  for (index = 0; index < width; index++) {
174f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall    if (static_cast<BitInit*>(init.getBit(index))->getValue())
1757916c997127fe616ba255ba4cade10e5de0c8812John McCall      ret |= mask;
1767916c997127fe616ba255ba4cade10e5de0c8812John McCall
1777916c997127fe616ba255ba4cade10e5de0c8812John McCall    mask <<= 1;
17855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck  }
17934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
18034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  return ret;
1817916c997127fe616ba255ba4cade10e5de0c8812John McCall}
1827916c997127fe616ba255ba4cade10e5de0c8812John McCall
1837916c997127fe616ba255ba4cade10e5de0c8812John McCall/// byteFromRec - Extract a value at most 8 bits in with from a Record given the
18434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson///   name of the field.
1857916c997127fe616ba255ba4cade10e5de0c8812John McCall///
1867916c997127fe616ba255ba4cade10e5de0c8812John McCall/// @param rec  - The record from which to extract the value.
18734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson/// @param name - The name of the field in the record.
1887916c997127fe616ba255ba4cade10e5de0c8812John McCall/// @return     - The field, as translated by byteFromBitsInit().
1897916c997127fe616ba255ba4cade10e5de0c8812John McCallstatic uint8_t byteFromRec(const Record* rec, const std::string &name) {
1907916c997127fe616ba255ba4cade10e5de0c8812John McCall  BitsInit* bits = rec->getValueAsBitsInit(name);
19134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  return byteFromBitsInit(*bits);
1927916c997127fe616ba255ba4cade10e5de0c8812John McCall}
1937916c997127fe616ba255ba4cade10e5de0c8812John McCall
1947916c997127fe616ba255ba4cade10e5de0c8812John McCallRecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
19534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson                                     const CodeGenInstruction &insn,
19634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson                                     InstrUID uid) {
1977916c997127fe616ba255ba4cade10e5de0c8812John McCall  UID = uid;
19834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
199336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson  Rec = insn.TheDef;
2007916c997127fe616ba255ba4cade10e5de0c8812John McCall  Name = Rec->getName();
201336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson  Spec = &tables.specForUID(UID);
20234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
2037916c997127fe616ba255ba4cade10e5de0c8812John McCall  if (!Rec->isSubClassOf("X86Inst")) {
20455c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck    ShouldBeEmitted = false;
2059a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck    return;
20634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  }
20734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
2087916c997127fe616ba255ba4cade10e5de0c8812John McCall  Prefix   = byteFromRec(Rec, "Prefix");
20934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  Opcode   = byteFromRec(Rec, "Opcode");
2107916c997127fe616ba255ba4cade10e5de0c8812John McCall  Form     = byteFromRec(Rec, "FormBits");
2117916c997127fe616ba255ba4cade10e5de0c8812John McCall  SegOvr   = byteFromRec(Rec, "SegOvrBits");
21234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
2137916c997127fe616ba255ba4cade10e5de0c8812John McCall  HasOpSizePrefix  = Rec->getValueAsBit("hasOpSizePrefix");
2147916c997127fe616ba255ba4cade10e5de0c8812John McCall  HasREX_WPrefix   = Rec->getValueAsBit("hasREX_WPrefix");
2157916c997127fe616ba255ba4cade10e5de0c8812John McCall  HasVEX_4VPrefix  = Rec->getValueAsBit("hasVEX_4VPrefix");
21634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  HasLockPrefix    = Rec->getValueAsBit("hasLockPrefix");
2177916c997127fe616ba255ba4cade10e5de0c8812John McCall  IsCodeGenOnly    = Rec->getValueAsBit("isCodeGenOnly");
2187916c997127fe616ba255ba4cade10e5de0c8812John McCall
2197916c997127fe616ba255ba4cade10e5de0c8812John McCall  Name      = Rec->getName();
22034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  AsmString = Rec->getValueAsString("AsmString");
22134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
22234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  Operands = &insn.Operands.OperandList;
22334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
22434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  IsSSE            = HasOpSizePrefix && (Name.find("16") == Name.npos);
22534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson  HasFROperands    = false;
22634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson
227a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  ShouldBeEmitted  = true;
2288561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson}
229f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
230f871d0cc377a1367b519a6cce26be74607566ebaJohn McCallvoid RecognizableInstr::processInstr(DisassemblerTables &tables,
231a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson                                   const CodeGenInstruction &insn,
232f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall                                   InstrUID uid)
233a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson{
234a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  // Ignore "asm parser only" instructions.
2358561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson  if (insn.TheDef->getValueAsBit("isAsmParserOnly"))
2362acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    return;
237c764830bdb6de82baed068889096bd3e52d4cbdaRichard Smith
238a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  RecognizableInstr recogInstr(tables, insn, uid);
239f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall
240a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  recogInstr.emitInstructionSpecifier(tables);
241a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson
242a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  if (recogInstr.shouldBeEmitted())
243a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    recogInstr.emitDecodePath(tables);
244a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson}
245a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson
246a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonInstructionContext RecognizableInstr::insnContext() const {
247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  InstructionContext insnContext;
248a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
249a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  if (Name.find("64") != Name.npos || HasREX_WPrefix) {
250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    if (HasREX_WPrefix && HasOpSizePrefix)
251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      insnContext = IC_64BIT_REXW_OPSIZE;
252a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    else if (HasOpSizePrefix)
253a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      insnContext = IC_64BIT_OPSIZE;
254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    else if (HasREX_WPrefix && Prefix == X86Local::XS)
255b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson      insnContext = IC_64BIT_REXW_XS;
256a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    else if (HasREX_WPrefix && Prefix == X86Local::XD)
257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      insnContext = IC_64BIT_REXW_XD;
258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    else if (Prefix == X86Local::XD)
259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      insnContext = IC_64BIT_XD;
260a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    else if (Prefix == X86Local::XS)
261c5685438df6105052b02c9e02f01c34489606308Eli Friedman      insnContext = IC_64BIT_XS;
262c5685438df6105052b02c9e02f01c34489606308Eli Friedman    else if (HasREX_WPrefix)
263c5685438df6105052b02c9e02f01c34489606308Eli Friedman      insnContext = IC_64BIT_REXW;
264a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson    else
265a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson      insnContext = IC_64BIT;
266a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson  } else {
267a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    if (HasOpSizePrefix)
268a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      insnContext = IC_OPSIZE;
269a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    else if (Prefix == X86Local::XD)
270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      insnContext = IC_XD;
271a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    else if (Prefix == X86Local::XS)
272a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson      insnContext = IC_XS;
273a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson    else
274bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad      insnContext = IC;
275a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  }
276a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson
27732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson  return insnContext;
278a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson}
27932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson
2805d58a1d50e2644668122b8efb6b603a706ecfd6bAnders CarlssonRecognizableInstr::filter_ret RecognizableInstr::filter() const {
281a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson  // Filter out intrinsics
2825d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson
28321c9ad9d29d08a287292c670e7c52bc522c7f8bbAnders Carlsson  if (!Rec->isSubClassOf("X86Inst"))
284c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    return FILTER_STRONG;
285c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
286314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson  if (Form == X86Local::Pseudo ||
287378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor      IsCodeGenOnly)
288378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor    return FILTER_STRONG;
289af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson
290c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  if (Form == X86Local::MRMInitReg)
291c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    return FILTER_STRONG;
292c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
293c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
294c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  // Filter out instructions with a LOCK prefix;
295c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  //   prefer forms that do not have the prefix
2963b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall  if (HasLockPrefix)
297c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    return FILTER_WEAK;
298c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson
2993b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall  // Filter out artificial instructions
3003b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall
301378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor  if (Name.find("TAILJMP") != Name.npos    ||
302378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor     Name.find("_Int") != Name.npos       ||
303378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor     Name.find("_int") != Name.npos       ||
304378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor     Name.find("Int_") != Name.npos       ||
305378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor     Name.find("_NOREX") != Name.npos     ||
306378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor     Name.find("_TC") != Name.npos     ||
307af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson     Name.find("EH_RETURN") != Name.npos  ||
3083b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall     Name.find("V_SET") != Name.npos      ||
309314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson     Name.find("LOCK_") != Name.npos      ||
3103b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall     Name.find("WIN") != Name.npos)
3113b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall    return FILTER_STRONG;
312c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson
313c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson  // Special cases.
3144230d529a8797bbeef2328b60abeae333f7e143fKen Dyck
3154230d529a8797bbeef2328b60abeae333f7e143fKen Dyck  if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI")
3164230d529a8797bbeef2328b60abeae333f7e143fKen Dyck    return FILTER_WEAK;
317c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson  if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI")
318c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson    return FILTER_WEAK;
319c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson
3203b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall  if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos)
3213b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall    return FILTER_WEAK;
322c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos)
323af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson    return FILTER_WEAK;
324c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  if (Name.find("Fs") != Name.npos)
325c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson    return FILTER_WEAK;
326c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson  if (Name == "MOVLPDrr"          ||
327c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      Name == "MOVLPSrr"          ||
328c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      Name == "PUSHFQ"            ||
3291cbce125b91cad81c8be3f8bbae8df917211176cAnders Carlsson      Name == "BSF16rr"           ||
330c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      Name == "BSF16rm"           ||
331c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      Name == "BSR16rr"           ||
332c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      Name == "BSR16rm"           ||
333c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      Name == "MOVSX16rm8"        ||
334c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      Name == "MOVSX16rr8"        ||
335c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson      Name == "MOVZX16rm8"        ||
336182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall      Name == "MOVZX16rr8"        ||
33750da2cadcc6da86abff6772de65280ace2cabc94John McCall      Name == "PUSH32i16"         ||
3381f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall      Name == "PUSH64i16"         ||
33950da2cadcc6da86abff6772de65280ace2cabc94John McCall      Name == "MOVPQI2QImr"       ||
34050da2cadcc6da86abff6772de65280ace2cabc94John McCall      Name == "MOVSDmr"           ||
34150da2cadcc6da86abff6772de65280ace2cabc94John McCall      Name == "MOVSDrm"           ||
34250da2cadcc6da86abff6772de65280ace2cabc94John McCall      Name == "MOVSSmr"           ||
343182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall      Name == "MOVSSrm"           ||
344ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall      Name == "MMX_MOVD64rrv164"  ||
34550da2cadcc6da86abff6772de65280ace2cabc94John McCall      Name == "CRC32m16"          ||
34650da2cadcc6da86abff6772de65280ace2cabc94John McCall      Name == "MOV64ri64i32"      ||
34750da2cadcc6da86abff6772de65280ace2cabc94John McCall      Name == "CRC32r16")
34850da2cadcc6da86abff6772de65280ace2cabc94John McCall    return FILTER_WEAK;
34950da2cadcc6da86abff6772de65280ace2cabc94John McCall
35050da2cadcc6da86abff6772de65280ace2cabc94John McCall  // Filter out instructions with segment override prefixes.
35150da2cadcc6da86abff6772de65280ace2cabc94John McCall  // They're too messy to handle now and we'll special case them if needed.
35250da2cadcc6da86abff6772de65280ace2cabc94John McCall
353378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor  if (SegOvr)
354378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor    return FILTER_STRONG;
355182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall
356182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall  // Filter out instructions that can't be printed.
3577e1dff7a68a4d00e71debafa7f5c259473091746John McCall
3587e1dff7a68a4d00e71debafa7f5c259473091746John McCall  if (AsmString.size() == 0)
3597e1dff7a68a4d00e71debafa7f5c259473091746John McCall    return FILTER_STRONG;
3607e1dff7a68a4d00e71debafa7f5c259473091746John McCall
3617e1dff7a68a4d00e71debafa7f5c259473091746John McCall  // Filter out instructions with subreg operands.
3627e1dff7a68a4d00e71debafa7f5c259473091746John McCall
3637e1dff7a68a4d00e71debafa7f5c259473091746John McCall  if (AsmString.find("subreg") != AsmString.npos)
3647e1dff7a68a4d00e71debafa7f5c259473091746John McCall    return FILTER_STRONG;
3657e1dff7a68a4d00e71debafa7f5c259473091746John McCall
3667e1dff7a68a4d00e71debafa7f5c259473091746John McCall  if (HasFROperands && Name.find("MOV") != Name.npos &&
3677e1dff7a68a4d00e71debafa7f5c259473091746John McCall     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
3687e1dff7a68a4d00e71debafa7f5c259473091746John McCall      (Name.find("to") != Name.npos)))
3697e1dff7a68a4d00e71debafa7f5c259473091746John McCall    return FILTER_WEAK;
3707e1dff7a68a4d00e71debafa7f5c259473091746John McCall
3717e1dff7a68a4d00e71debafa7f5c259473091746John McCall  return FILTER_NORMAL;
3727e1dff7a68a4d00e71debafa7f5c259473091746John McCall}
3737e1dff7a68a4d00e71debafa7f5c259473091746John McCall
3747e1dff7a68a4d00e71debafa7f5c259473091746John McCallvoid RecognizableInstr::handleOperand(
3757e1dff7a68a4d00e71debafa7f5c259473091746John McCall  bool optional,
3767e1dff7a68a4d00e71debafa7f5c259473091746John McCall  unsigned &operandIndex,
3777e1dff7a68a4d00e71debafa7f5c259473091746John McCall  unsigned &physicalOperandIndex,
3787e1dff7a68a4d00e71debafa7f5c259473091746John McCall  unsigned &numPhysicalOperands,
3797e1dff7a68a4d00e71debafa7f5c259473091746John McCall  unsigned *operandMapping,
380182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall  OperandEncoding (*encodingFromString)(const std::string&, bool hasOpSizePrefix)) {
381182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall  if (optional) {
382607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (physicalOperandIndex >= numPhysicalOperands)
383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      return;
384cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  } else {
385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    assert(physicalOperandIndex < numPhysicalOperands);
386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  while (operandMapping[operandIndex] != operandIndex) {
389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Spec->operands[operandIndex].encoding = ENCODING_DUP;
390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    Spec->operands[operandIndex].type =
391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);
392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    ++operandIndex;
393607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  }
394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
39580638c5e6395344c1e6096542b0ff3b8bfb2139eAnders Carlsson  const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
396607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
397607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Spec->operands[operandIndex].encoding = encodingFromString(typeName,
398607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                              HasOpSizePrefix);
399607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  Spec->operands[operandIndex].type = typeFromString(typeName,
400607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson                                                      IsSSE,
4017e1dff7a68a4d00e71debafa7f5c259473091746John McCall                                                      HasREX_WPrefix,
4027e1dff7a68a4d00e71debafa7f5c259473091746John McCall                                                      HasOpSizePrefix);
4037e1dff7a68a4d00e71debafa7f5c259473091746John McCall
4047e1dff7a68a4d00e71debafa7f5c259473091746John McCall  ++operandIndex;
4057e1dff7a68a4d00e71debafa7f5c259473091746John McCall  ++physicalOperandIndex;
4067e1dff7a68a4d00e71debafa7f5c259473091746John McCall}
407bff225ecf77fb891596ecb1b27196310d268365eJohn McCall
408bff225ecf77fb891596ecb1b27196310d268365eJohn McCallvoid RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
4098561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson  Spec->name       = Name;
4108561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson
41150da2cadcc6da86abff6772de65280ace2cabc94John McCall  if (!Rec->isSubClassOf("X86Inst"))
41250da2cadcc6da86abff6772de65280ace2cabc94John McCall    return;
413d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman
4147c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall  switch (filter()) {
415f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman  case FILTER_WEAK:
4167c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall    Spec->filtered = true;
417410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall    break;
418649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier  case FILTER_STRONG:
419558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    ShouldBeEmitted = false;
420558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    return;
421594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson  case FILTER_NORMAL:
4224e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    break;
423c1cfdf8647a499b6b3024f4bd14a236cddb23988Anders Carlsson  }
4241f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall
4251f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall  Spec->insnContext = insnContext();
426607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson
427607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
428fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor
429fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  unsigned operandIndex;
4300bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  unsigned numOperands = OperandList.size();
431fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  unsigned numPhysicalOperands = 0;
432fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor
4330bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  // operandMapping maps from operands in OperandList to their originals.
434fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  // If operandMapping[i] != i, then the entry is a duplicate.
4350bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  unsigned operandMapping[X86_MAX_OPERANDS];
436f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman
437924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl  bool hasFROperands = false;
438924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl
439924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl  assert(numOperands < X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough");
440924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl
441924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl  for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
442924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl    if (OperandList[operandIndex].Constraints.size()) {
443924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl      const CGIOperandList::ConstraintInfo &Constraint =
444924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl        OperandList[operandIndex].Constraints[0];
445924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl      if (Constraint.isTied()) {
446924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl        operandMapping[operandIndex] = Constraint.getTiedOperand();
447924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl      } else {
448924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl        ++numPhysicalOperands;
449924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl        operandMapping[operandIndex] = operandIndex;
450924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl      }
451924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl    } else {
452924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl      ++numPhysicalOperands;
453924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl      operandMapping[operandIndex] = operandIndex;
454924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl    }
455924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl
456924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl    const std::string &recName = OperandList[operandIndex].Rec->getName();
457924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl
458924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl    if (recName.find("FR") != recName.npos)
459924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl      hasFROperands = true;
460924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl  }
461924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl
462924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl  if (hasFROperands && Name.find("MOV") != Name.npos &&
463924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
464924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl      (Name.find("to") != Name.npos)))
465924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl    ShouldBeEmitted = false;
466649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier
467924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl  if (!ShouldBeEmitted)
468924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl    return;
469924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl
470fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor#define HANDLE_OPERAND(class)               \
471558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall  handleOperand(false,                      \
472924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl                operandIndex,               \
473924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl                physicalOperandIndex,       \
474972edf0534d8a50f87fac1d0ff34eb22f593df11Sebastian Redl                numPhysicalOperands,        \
475924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl                operandMapping,             \
476fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor                class##EncodingFromString);
477fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor
478fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor#define HANDLE_OPTIONAL(class)              \
479fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  handleOperand(true,                       \
480fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor                operandIndex,               \
481fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor                physicalOperandIndex,       \
4820bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman                numPhysicalOperands,        \
483fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor                operandMapping,             \
484fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor                class##EncodingFromString);
485fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor
486fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  // operandIndex should always be < numOperands
487fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  operandIndex = 0;
488fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  // physicalOperandIndex should always be < numPhysicalOperands
489fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  unsigned physicalOperandIndex = 0;
490fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor
491fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  switch (Form) {
492fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  case X86Local::RawFrm:
493fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 1 (optional) is an address or immediate.
494fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 2 (optional) is an immediate.
495fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    assert(numPhysicalOperands <= 2 &&
496fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor           "Unexpected number of operands for RawFrm");
497fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPTIONAL(relocation)
498fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPTIONAL(immediate)
499fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    break;
500fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  case X86Local::AddRegFrm:
501fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 1 is added to the opcode.
502985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner    // Operand 2 (optional) is an address.
503985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
504fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor           "Unexpected number of operands for AddRegFrm");
505fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPERAND(opcodeModifier)
506fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPTIONAL(relocation)
507fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    break;
508fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  case X86Local::MRMDestReg:
509fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 1 is a register operand in the R/M field.
510fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 2 is a register operand in the Reg/Opcode field.
511fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 3 (optional) is an immediate.
512fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
513fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor           "Unexpected number of operands for MRMDestRegFrm");
514f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    HANDLE_OPERAND(rmRegister)
515fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPERAND(roRegister)
516fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPTIONAL(immediate)
517fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    break;
5180bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  case X86Local::MRMDestMem:
5190bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // Operand 1 is a memory operand (possibly SIB-extended)
520fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 2 is a register operand in the Reg/Opcode field.
521fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 3 (optional) is an immediate.
522fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
523fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor           "Unexpected number of operands for MRMDestMemFrm");
524fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPERAND(memory)
525fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPERAND(roRegister)
526fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPTIONAL(immediate)
527fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    break;
528fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  case X86Local::MRMSrcReg:
529fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 1 is a register operand in the Reg/Opcode field.
530fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 2 is a register operand in the R/M field.
531fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    // Operand 3 (optional) is an immediate.
532fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
533fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor           "Unexpected number of operands for MRMSrcRegFrm");
534fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPERAND(roRegister)
535fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    HANDLE_OPERAND(rmRegister)
536182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall
537607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    if (HasVEX_4VPrefix)
538607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      // FIXME: In AVX, the register below becomes the one encoded
539cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt      // in ModRMVEX and the one above the one in the VEX.VVVV field
540fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor      HANDLE_OPTIONAL(rmRegister)
541fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    else
54200eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet      HANDLE_OPTIONAL(immediate)
543607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    break;
5447a614d8380297fcd2bc23986241905d97222948cRichard Smith  case X86Local::MRMSrcMem:
545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Operand 1 is a register operand in the Reg/Opcode field.
546607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    // Operand 2 is a memory operand (possibly SIB-extended)
54700eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet    // Operand 3 (optional) is an immediate.
5480bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
549607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson           "Unexpected number of operands for MRMSrcMemFrm");
550607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson    HANDLE_OPERAND(roRegister)
551377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman
552859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman    if (HasVEX_4VPrefix)
553377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman      // FIXME: In AVX, the register below becomes the one encoded
55400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet      // in ModRMVEX and the one above the one in the VEX.VVVV field
555859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman      HANDLE_OPTIONAL(rmRegister)
556859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman
557859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman    HANDLE_OPERAND(memory)
558859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman    HANDLE_OPTIONAL(immediate)
559859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman    break;
560859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman  case X86Local::MRM0r:
561859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman  case X86Local::MRM1r:
56200eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet  case X86Local::MRM2r:
563a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall  case X86Local::MRM3r:
564859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman  case X86Local::MRM4r:
565607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  case X86Local::MRM5r:
566607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  case X86Local::MRM6r:
5670bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  case X86Local::MRM7r:
5680bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // Operand 1 is a register operand in the R/M field.
5690bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // Operand 2 (optional) is an immediate or relocation.
5700bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    assert(numPhysicalOperands <= 2 &&
5710bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman           "Unexpected number of operands for MRMnRFrm");
5720bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    HANDLE_OPTIONAL(rmRegister)
5730bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    HANDLE_OPTIONAL(relocation)
5740bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    break;
5750bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  case X86Local::MRM0m:
5760bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  case X86Local::MRM1m:
577e9385363069388d8e3536052a138f17332e00620Richard Smith  case X86Local::MRM2m:
5780bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  case X86Local::MRM3m:
579e9385363069388d8e3536052a138f17332e00620Richard Smith  case X86Local::MRM4m:
580e9385363069388d8e3536052a138f17332e00620Richard Smith  case X86Local::MRM5m:
581e9385363069388d8e3536052a138f17332e00620Richard Smith  case X86Local::MRM6m:
5820bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  case X86Local::MRM7m:
5830bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // Operand 1 is a memory operand (possibly SIB-extended)
5840bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // Operand 2 (optional) is an immediate or relocation.
585377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
586377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman           "Unexpected number of operands for MRMnMFrm");
5870bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    HANDLE_OPERAND(memory)
5880bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    HANDLE_OPTIONAL(relocation)
5890bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    break;
590649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier  case X86Local::RawFrmImm8:
5910bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // operand 1 is a 16-bit immediate
5920bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // operand 2 is an 8-bit immediate
5930bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    assert(numPhysicalOperands == 2 &&
5940bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman           "Unexpected number of operands for X86Local::RawFrmImm8");
5950bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    HANDLE_OPERAND(immediate)
5960bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    HANDLE_OPERAND(immediate)
5970bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    break;
598b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  case X86Local::RawFrmImm16:
5990bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // operand 1 is a 16-bit immediate
6000bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    // operand 2 is a 16-bit immediate
601b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman    HANDLE_OPERAND(immediate)
602b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman    HANDLE_OPERAND(immediate)
603b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman    break;
6040bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman  case X86Local::MRMInitReg:
605b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman    // Ignored.
606f85e193739c953358c865005855253af4f68a497John McCall    break;
607b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  }
608f85e193739c953358c865005855253af4f68a497John McCall
609b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  #undef HANDLE_OPERAND
610b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  #undef HANDLE_OPTIONAL
611f85e193739c953358c865005855253af4f68a497John McCall}
6120bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman
613b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedmanvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
614607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson  // Special cases where the LLVM tables are not complete
615fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor
6160bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman#define MAP(from, to)                     \
617b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  case X86Local::MRM_##from:              \
618fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    filter = new ExactFilter(0x##from);   \
619fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    break;
620fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor
621b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  OpcodeType    opcodeType  = (OpcodeType)-1;
622b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman
623fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  ModRMFilter*  filter      = NULL;
624b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  uint8_t       opcodeToSet = 0;
625b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman
626b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  switch (Prefix) {
627fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f
628fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  case X86Local::XD:
629fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor  case X86Local::XS:
630b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman  case X86Local::TB:
631fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    opcodeType = TWOBYTE;
632b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman
633fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    switch (Opcode) {
634fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor    default:
635fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor      if (needsModRMForDecode(Form))
6360bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman        filter = new ModFilter(isRegFormat(Form));
637b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman      else
638fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor        filter = new DumbFilter();
639fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor      break;
640b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman#define EXTENSION_TABLE(n) case 0x##n:
6410bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman    TWO_BYTE_EXTENSION_TABLES
642607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson#undef EXTENSION_TABLE
643074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall      switch (Form) {
644074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall      default:
645074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall        llvm_unreachable("Unhandled two-byte extended opcode");
646074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall      case X86Local::MRM0r:
647074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall      case X86Local::MRM1r:
648074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall      case X86Local::MRM2r:
649607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      case X86Local::MRM3r:
650607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson      case X86Local::MRM4r:
651c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM5r:
652c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM6r:
653c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM7r:
654c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
655c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall        break;
656c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM0m:
657c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM1m:
658c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM2m:
659c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM3m:
660c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM4m:
661c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM5m:
662c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM6m:
663c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM7m:
664c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
665c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall        break;
666c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      MRM_MAPPING
667c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      } // switch (Form)
668c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      break;
669c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    } // switch (Opcode)
670c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    opcodeToSet = Opcode;
671c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    break;
672c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  case X86Local::T8:
673c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    opcodeType = THREEBYTE_38;
674c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    if (needsModRMForDecode(Form))
675c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      filter = new ModFilter(isRegFormat(Form));
676c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    else
677c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      filter = new DumbFilter();
678c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    opcodeToSet = Opcode;
679c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    break;
680c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  case X86Local::P_TA:
681c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    opcodeType = THREEBYTE_3A;
682c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    if (needsModRMForDecode(Form))
683c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      filter = new ModFilter(isRegFormat(Form));
684c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    else
685c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      filter = new DumbFilter();
686c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    opcodeToSet = Opcode;
687c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    break;
688c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  case X86Local::D8:
689c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  case X86Local::D9:
690c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  case X86Local::DA:
691c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall  case X86Local::DB:
692059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt  case X86Local::DC:
693059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt  case X86Local::DD:
694059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt  case X86Local::DE:
695059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt  case X86Local::DF:
696c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
697c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    opcodeType = ONEBYTE;
698c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    if (Form == X86Local::AddRegFrm) {
6999fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      Spec->modifierType = MODIFIER_MODRM;
7009fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      Spec->modifierBase = Opcode;
7019fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      filter = new AddRegEscapeFilter(Opcode);
7029fc6a7774643a810c8501dae2323e863fefb623eJohn McCall    } else {
7039fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      filter = new EscapeFilter(true, Opcode);
704c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    }
705c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
7068560791791e7b33249feb0ffafeca427076b37b4Timur Iskhodzhanov    break;
707b8b2c9da87e7d70a1679db026f40548b3192b705John McCall  default:
708d67ef0eed463b43980f04a444155f423114be34bDevang Patel    opcodeType = ONEBYTE;
70973fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher    switch (Opcode) {
710c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall#define EXTENSION_TABLE(n) case 0x##n:
711c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    ONE_BYTE_EXTENSION_TABLES
712c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall#undef EXTENSION_TABLE
713c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      switch (Form) {
7149fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      default:
7159fc6a7774643a810c8501dae2323e863fefb623eJohn McCall        llvm_unreachable("Fell through the cracks of a single-byte "
716c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall                         "extended opcode");
717c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM0r:
718c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM1r:
719c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM2r:
72059a7000a79118e4c140885ccbb2ac6a686a73092John McCall      case X86Local::MRM3r:
7219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      case X86Local::MRM4r:
722f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      case X86Local::MRM5r:
7239fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      case X86Local::MRM6r:
72456ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall      case X86Local::MRM7r:
72556ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
72656ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall        break;
727c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM0m:
728c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM1m:
729fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor      case X86Local::MRM2m:
7309fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      case X86Local::MRM3m:
7319fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      case X86Local::MRM4m:
732c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall      case X86Local::MRM5m:
7339fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      case X86Local::MRM6m:
7349fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      case X86Local::MRM7m:
7359fc6a7774643a810c8501dae2323e863fefb623eJohn McCall        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
7369fc6a7774643a810c8501dae2323e863fefb623eJohn McCall        break;
7379fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      MRM_MAPPING
7389fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      } // switch (Form)
7399fc6a7774643a810c8501dae2323e863fefb623eJohn McCall      break;
7409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall    case 0xd8:
741f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case 0xd9:
7429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall    case 0xda:
743c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall    case 0xdb:
74459a7000a79118e4c140885ccbb2ac6a686a73092John McCall    case 0xdc:
7459fc6a7774643a810c8501dae2323e863fefb623eJohn McCall    case 0xdd:
7469fc6a7774643a810c8501dae2323e863fefb623eJohn McCall    case 0xde:
74756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    case 0xdf:
74856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      filter = new EscapeFilter(false, Form - X86Local::MRM0m);
74956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      break;
75056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    default:
75156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      if (needsModRMForDecode(Form))
75256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames        filter = new ModFilter(isRegFormat(Form));
75356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      else
75456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames        filter = new DumbFilter();
75556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      break;
75656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    } // switch (Opcode)
75756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    opcodeToSet = Opcode;
75856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  } // switch (Prefix)
75956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
76056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  assert(opcodeType != (OpcodeType)-1 &&
76156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames         "Opcode type not set");
76256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  assert(filter && "Filter not set");
76356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
76456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  if (Form == X86Local::AddRegFrm) {
76556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    if(Spec->modifierType != MODIFIER_MODRM) {
76656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      assert(opcodeToSet < 0xf9 &&
76756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames             "Not enough room for all ADDREG_FRM operands");
76856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
76956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      uint8_t currentOpcode;
77056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
77156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      for (currentOpcode = opcodeToSet;
77256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames           currentOpcode < opcodeToSet + 8;
77356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames           ++currentOpcode)
77456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames        tables.setTableFields(opcodeType,
77556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                              insnContext(),
77656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                              currentOpcode,
77756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                              *filter,
77856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                              UID);
77956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
78056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      Spec->modifierType = MODIFIER_OPCODE;
78156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      Spec->modifierBase = opcodeToSet;
78256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    } else {
78356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      // modifierBase was set where MODIFIER_MODRM was set
78456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames      tables.setTableFields(opcodeType,
78556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                            insnContext(),
78656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                            opcodeToSet,
78756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                            *filter,
78856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                            UID);
78956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    }
79056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  } else {
7915e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames    tables.setTableFields(opcodeType,
79256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                          insnContext(),
79356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                          opcodeToSet,
79456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                          *filter,
79556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                          UID);
79656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
7975e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames    Spec->modifierType = MODIFIER_NONE;
7985e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames    Spec->modifierBase = opcodeToSet;
7995e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames  }
8005e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames
8015e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames  delete filter;
8025e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames
8035e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames#undef MAP
8045e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames}
8055e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames
80656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#define TYPE(str, type) if (s == str) return type;
80756c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandType RecognizableInstr::typeFromString(const std::string &s,
80856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                                              bool isSSE,
80956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                                              bool hasREX_WPrefix,
81056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames                                              bool hasOpSizePrefix) {
81156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  if (isSSE) {
81256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // For SSE instructions, we ignore the OpSize prefix and force operand
81356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // sizes.
81456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    TYPE("GR16",              TYPE_R16)
81556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    TYPE("GR32",              TYPE_R32)
81656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    TYPE("GR64",              TYPE_R64)
81756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  }
81856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  if(hasREX_WPrefix) {
81956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // For instructions with a REX_W prefix, a declared 32-bit register encoding
82056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // is special.
82156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    TYPE("GR32",              TYPE_R32)
82256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  }
82356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  if(!hasOpSizePrefix) {
82456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // For instructions without an OpSize prefix, a declared 16-bit register or
82556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // immediate encoding is special.
82656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    TYPE("GR16",              TYPE_R16)
82756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    TYPE("i16imm",            TYPE_IMM16)
82856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  }
82956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i16mem",              TYPE_Mv)
83056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i16imm",              TYPE_IMMv)
83156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i16i8imm",            TYPE_IMMv)
83256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("GR16",                TYPE_Rv)
83356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i32mem",              TYPE_Mv)
83456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i32imm",              TYPE_IMMv)
83556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i32i8imm",            TYPE_IMM32)
83656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("GR32",                TYPE_Rv)
83756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i64mem",              TYPE_Mv)
83856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i64i32imm",           TYPE_IMM64)
83956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i64i8imm",            TYPE_IMM64)
84056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("GR64",                TYPE_R64)
84156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i8mem",               TYPE_M8)
84256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i8imm",               TYPE_IMM8)
84356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("GR8",                 TYPE_R8)
84456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("VR128",               TYPE_XMM128)
84556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("f128mem",             TYPE_M128)
84656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("f256mem",             TYPE_M256)
84756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("FR64",                TYPE_XMM64)
84856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("f64mem",              TYPE_M64FP)
84956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("sdmem",               TYPE_M64FP)
85056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("FR32",                TYPE_XMM32)
85156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("f32mem",              TYPE_M32FP)
85256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("ssmem",               TYPE_M32FP)
85356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("RST",                 TYPE_ST)
85456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i128mem",             TYPE_M128)
85556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i64i32imm_pcrel",     TYPE_REL64)
85656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i16imm_pcrel",        TYPE_REL16)
85756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i32imm_pcrel",        TYPE_REL32)
85856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("SSECC",               TYPE_IMM3)
85956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("brtarget",            TYPE_RELv)
86056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("uncondbrtarget",      TYPE_RELv)
86156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("brtarget8",           TYPE_REL8)
86256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("f80mem",              TYPE_M80FP)
86356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("lea32mem",            TYPE_LEA)
86456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("lea64_32mem",         TYPE_LEA)
86556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("lea64mem",            TYPE_LEA)
86656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("VR64",                TYPE_MM64)
86756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("i64imm",              TYPE_IMMv)
86856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("opaque32mem",         TYPE_M1616)
86956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("opaque48mem",         TYPE_M1632)
87056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("opaque80mem",         TYPE_M1664)
87156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("opaque512mem",        TYPE_M512)
87256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("SEGMENT_REG",         TYPE_SEGMENTREG)
87356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("DEBUG_REG",           TYPE_DEBUGREG)
87456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("CONTROL_REG",         TYPE_CONTROLREG)
87556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("offset8",             TYPE_MOFFS8)
87656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("offset16",            TYPE_MOFFS16)
87756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("offset32",            TYPE_MOFFS32)
87856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  TYPE("offset64",            TYPE_MOFFS64)
87956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  errs() << "Unhandled type string " << s << "\n";
88056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  llvm_unreachable("Unhandled type string");
88156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames}
88256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#undef TYPE
88356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
88456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#define ENCODING(str, encoding) if (s == str) return encoding;
88556c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::immediateEncodingFromString
88656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  (const std::string &s,
88756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames   bool hasOpSizePrefix) {
88856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  if(!hasOpSizePrefix) {
88956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // For instructions without an OpSize prefix, a declared 16-bit register or
89056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // immediate encoding is special.
89156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    ENCODING("i16imm",        ENCODING_IW)
89256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  }
89356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i32i8imm",        ENCODING_IB)
89456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("SSECC",           ENCODING_IB)
89556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i16imm",          ENCODING_Iv)
89656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i16i8imm",        ENCODING_IB)
89756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i32imm",          ENCODING_Iv)
89856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i64i32imm",       ENCODING_ID)
89956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i64i8imm",        ENCODING_IB)
90056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i8imm",           ENCODING_IB)
90156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  errs() << "Unhandled immediate encoding " << s << "\n";
90256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  llvm_unreachable("Unhandled immediate encoding");
90356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames}
90456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
90556c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::rmRegisterEncodingFromString
90656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  (const std::string &s,
90756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames   bool hasOpSizePrefix) {
90856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR16",            ENCODING_RM)
90956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR32",            ENCODING_RM)
91056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR64",            ENCODING_RM)
91156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR8",             ENCODING_RM)
91256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("VR128",           ENCODING_RM)
91356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("FR64",            ENCODING_RM)
91456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("FR32",            ENCODING_RM)
91556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("VR64",            ENCODING_RM)
91656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  errs() << "Unhandled R/M register encoding " << s << "\n";
91756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  llvm_unreachable("Unhandled R/M register encoding");
91856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames}
91956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
92056c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::roRegisterEncodingFromString
92156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  (const std::string &s,
92256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames   bool hasOpSizePrefix) {
92356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR16",            ENCODING_REG)
92456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR32",            ENCODING_REG)
92556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR64",            ENCODING_REG)
92656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR8",             ENCODING_REG)
92756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("VR128",           ENCODING_REG)
92856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("FR64",            ENCODING_REG)
92956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("FR32",            ENCODING_REG)
93056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("VR64",            ENCODING_REG)
93156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("SEGMENT_REG",     ENCODING_REG)
93256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("DEBUG_REG",       ENCODING_REG)
93356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("CONTROL_REG",     ENCODING_REG)
93456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  errs() << "Unhandled reg/opcode register encoding " << s << "\n";
93556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  llvm_unreachable("Unhandled reg/opcode register encoding");
93656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames}
93756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
93856c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::memoryEncodingFromString
93956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  (const std::string &s,
94056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames   bool hasOpSizePrefix) {
94156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i16mem",          ENCODING_RM)
94256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i32mem",          ENCODING_RM)
94356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i64mem",          ENCODING_RM)
94456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i8mem",           ENCODING_RM)
94556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("ssmem",           ENCODING_RM)
94656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("sdmem",           ENCODING_RM)
94756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("f128mem",         ENCODING_RM)
94856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("f256mem",         ENCODING_RM)
94956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("f64mem",          ENCODING_RM)
95056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("f32mem",          ENCODING_RM)
95156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i128mem",         ENCODING_RM)
95256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("f80mem",          ENCODING_RM)
95356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("lea32mem",        ENCODING_RM)
95456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("lea64_32mem",     ENCODING_RM)
95556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("lea64mem",        ENCODING_RM)
95656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("opaque32mem",     ENCODING_RM)
95756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("opaque48mem",     ENCODING_RM)
95856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("opaque80mem",     ENCODING_RM)
95956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("opaque512mem",    ENCODING_RM)
96056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  errs() << "Unhandled memory encoding " << s << "\n";
96156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  llvm_unreachable("Unhandled memory encoding");
96256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames}
96356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
96456c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::relocationEncodingFromString
96556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  (const std::string &s,
96656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames   bool hasOpSizePrefix) {
96756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  if(!hasOpSizePrefix) {
96856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // For instructions without an OpSize prefix, a declared 16-bit register or
96956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    // immediate encoding is special.
97056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames    ENCODING("i16imm",        ENCODING_IW)
97156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  }
97256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i16imm",          ENCODING_Iv)
97356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i16i8imm",        ENCODING_IB)
97456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i32imm",          ENCODING_Iv)
97556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i32i8imm",        ENCODING_IB)
97656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i64i32imm",       ENCODING_ID)
97756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i64i8imm",        ENCODING_IB)
97856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i8imm",           ENCODING_IB)
97956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i64i32imm_pcrel", ENCODING_ID)
98056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i16imm_pcrel",    ENCODING_IW)
98156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i32imm_pcrel",    ENCODING_ID)
98256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("brtarget",        ENCODING_Iv)
98356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("brtarget8",       ENCODING_IB)
98456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("i64imm",          ENCODING_IO)
98556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("offset8",         ENCODING_Ia)
98656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("offset16",        ENCODING_Ia)
98756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("offset32",        ENCODING_Ia)
98856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("offset64",        ENCODING_Ia)
98956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  errs() << "Unhandled relocation encoding " << s << "\n";
99056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  llvm_unreachable("Unhandled relocation encoding");
99156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames}
99256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames
99356c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
99456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  (const std::string &s,
99556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames   bool hasOpSizePrefix) {
99656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("RST",             ENCODING_I)
99756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR32",            ENCODING_Rv)
99856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR64",            ENCODING_RO)
99956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR16",            ENCODING_Rv)
100056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  ENCODING("GR8",             ENCODING_RB)
100156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  errs() << "Unhandled opcode modifier encoding " << s << "\n";
100256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames  llvm_unreachable("Unhandled opcode modifier encoding");
100356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames}
100456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#undef ENCODING
100556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames