X86RecognizableInstr.cpp revision 276479
1201360Srdivacky//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===//
2201360Srdivacky//
3201360Srdivacky//                     The LLVM Compiler Infrastructure
4201360Srdivacky//
5201360Srdivacky// This file is distributed under the University of Illinois Open Source
6201360Srdivacky// License. See LICENSE.TXT for details.
7201360Srdivacky//
8201360Srdivacky//===----------------------------------------------------------------------===//
9201360Srdivacky//
10201360Srdivacky// This file is part of the X86 Disassembler Emitter.
11201360Srdivacky// It contains the implementation of a single recognizable instruction.
12201360Srdivacky// Documentation for the disassembler emitter in general can be found in
13201360Srdivacky//  X86DisasemblerEmitter.h.
14201360Srdivacky//
15201360Srdivacky//===----------------------------------------------------------------------===//
16201360Srdivacky
17249423Sdim#include "X86RecognizableInstr.h"
18201360Srdivacky#include "X86DisassemblerShared.h"
19201360Srdivacky#include "X86ModRMFilters.h"
20201360Srdivacky#include "llvm/Support/ErrorHandling.h"
21201360Srdivacky#include <string>
22201360Srdivacky
23201360Srdivackyusing namespace llvm;
24201360Srdivacky
25203954Srdivacky#define MRM_MAPPING     \
26276479Sdim  MAP(C0, 32)           \
27203954Srdivacky  MAP(C1, 33)           \
28203954Srdivacky  MAP(C2, 34)           \
29203954Srdivacky  MAP(C3, 35)           \
30203954Srdivacky  MAP(C4, 36)           \
31203954Srdivacky  MAP(C8, 37)           \
32203954Srdivacky  MAP(C9, 38)           \
33251662Sdim  MAP(CA, 39)           \
34251662Sdim  MAP(CB, 40)           \
35276479Sdim  MAP(D0, 41)           \
36276479Sdim  MAP(D1, 42)           \
37276479Sdim  MAP(D4, 43)           \
38276479Sdim  MAP(D5, 44)           \
39276479Sdim  MAP(D6, 45)           \
40276479Sdim  MAP(D8, 46)           \
41276479Sdim  MAP(D9, 47)           \
42276479Sdim  MAP(DA, 48)           \
43276479Sdim  MAP(DB, 49)           \
44276479Sdim  MAP(DC, 50)           \
45276479Sdim  MAP(DD, 51)           \
46276479Sdim  MAP(DE, 52)           \
47276479Sdim  MAP(DF, 53)           \
48276479Sdim  MAP(E0, 54)           \
49276479Sdim  MAP(E1, 55)           \
50276479Sdim  MAP(E2, 56)           \
51276479Sdim  MAP(E3, 57)           \
52276479Sdim  MAP(E4, 58)           \
53276479Sdim  MAP(E5, 59)           \
54276479Sdim  MAP(E8, 60)           \
55276479Sdim  MAP(E9, 61)           \
56276479Sdim  MAP(EA, 62)           \
57276479Sdim  MAP(EB, 63)           \
58276479Sdim  MAP(EC, 64)           \
59276479Sdim  MAP(ED, 65)           \
60276479Sdim  MAP(EE, 66)           \
61276479Sdim  MAP(F0, 67)           \
62276479Sdim  MAP(F1, 68)           \
63276479Sdim  MAP(F2, 69)           \
64276479Sdim  MAP(F3, 70)           \
65276479Sdim  MAP(F4, 71)           \
66276479Sdim  MAP(F5, 72)           \
67276479Sdim  MAP(F6, 73)           \
68276479Sdim  MAP(F7, 74)           \
69276479Sdim  MAP(F8, 75)           \
70276479Sdim  MAP(F9, 76)           \
71276479Sdim  MAP(FA, 77)           \
72276479Sdim  MAP(FB, 78)           \
73276479Sdim  MAP(FC, 79)           \
74276479Sdim  MAP(FD, 80)           \
75276479Sdim  MAP(FE, 81)           \
76276479Sdim  MAP(FF, 82)
77203954Srdivacky
78201360Srdivacky// A clone of X86 since we can't depend on something that is generated.
79201360Srdivackynamespace X86Local {
80201360Srdivacky  enum {
81201360Srdivacky    Pseudo      = 0,
82201360Srdivacky    RawFrm      = 1,
83201360Srdivacky    AddRegFrm   = 2,
84201360Srdivacky    MRMDestReg  = 3,
85201360Srdivacky    MRMDestMem  = 4,
86201360Srdivacky    MRMSrcReg   = 5,
87201360Srdivacky    MRMSrcMem   = 6,
88276479Sdim    RawFrmMemOffs = 7,
89276479Sdim    RawFrmSrc   = 8,
90276479Sdim    RawFrmDst   = 9,
91276479Sdim    RawFrmDstSrc = 10,
92276479Sdim    RawFrmImm8  = 11,
93276479Sdim    RawFrmImm16 = 12,
94276479Sdim    MRMXr = 14, MRMXm = 15,
95239462Sdim    MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19,
96201360Srdivacky    MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
97201360Srdivacky    MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
98201360Srdivacky    MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
99203954Srdivacky#define MAP(from, to) MRM_##from = to,
100203954Srdivacky    MRM_MAPPING
101203954Srdivacky#undef MAP
102203954Srdivacky    lastMRM
103201360Srdivacky  };
104239462Sdim
105201360Srdivacky  enum {
106276479Sdim    OB = 0, TB = 1, T8 = 2, TA = 3, XOP8 = 4, XOP9 = 5, XOPA = 6
107201360Srdivacky  };
108203954Srdivacky
109276479Sdim  enum {
110276479Sdim    PS = 1, PD = 2, XS = 3, XD = 4
111276479Sdim  };
112203954Srdivacky
113276479Sdim  enum {
114276479Sdim    VEX = 1, XOP = 2, EVEX = 3
115276479Sdim  };
116239462Sdim
117276479Sdim  enum {
118276479Sdim    OpSize16 = 1, OpSize32 = 2
119276479Sdim  };
120276479Sdim}
121201360Srdivacky
122201360Srdivackyusing namespace X86Disassembler;
123201360Srdivacky
124201360Srdivacky/// isRegFormat - Indicates whether a particular form requires the Mod field of
125201360Srdivacky///   the ModR/M byte to be 0b11.
126201360Srdivacky///
127201360Srdivacky/// @param form - The form of the instruction.
128201360Srdivacky/// @return     - true if the form implies that Mod must be 0b11, false
129201360Srdivacky///               otherwise.
130201360Srdivackystatic bool isRegFormat(uint8_t form) {
131276479Sdim  return (form == X86Local::MRMDestReg ||
132276479Sdim          form == X86Local::MRMSrcReg  ||
133276479Sdim          form == X86Local::MRMXr ||
134276479Sdim          (form >= X86Local::MRM0r && form <= X86Local::MRM7r));
135201360Srdivacky}
136201360Srdivacky
137201360Srdivacky/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
138201360Srdivacky///   Useful for switch statements and the like.
139201360Srdivacky///
140201360Srdivacky/// @param init - A reference to the BitsInit to be decoded.
141201360Srdivacky/// @return     - The field, with the first bit in the BitsInit as the lowest
142201360Srdivacky///               order bit.
143201360Srdivackystatic uint8_t byteFromBitsInit(BitsInit &init) {
144201360Srdivacky  int width = init.getNumBits();
145201360Srdivacky
146201360Srdivacky  assert(width <= 8 && "Field is too large for uint8_t!");
147201360Srdivacky
148201360Srdivacky  int     index;
149201360Srdivacky  uint8_t mask = 0x01;
150201360Srdivacky
151201360Srdivacky  uint8_t ret = 0;
152201360Srdivacky
153201360Srdivacky  for (index = 0; index < width; index++) {
154201360Srdivacky    if (static_cast<BitInit*>(init.getBit(index))->getValue())
155201360Srdivacky      ret |= mask;
156201360Srdivacky
157201360Srdivacky    mask <<= 1;
158201360Srdivacky  }
159201360Srdivacky
160201360Srdivacky  return ret;
161201360Srdivacky}
162201360Srdivacky
163201360Srdivacky/// byteFromRec - Extract a value at most 8 bits in with from a Record given the
164201360Srdivacky///   name of the field.
165201360Srdivacky///
166201360Srdivacky/// @param rec  - The record from which to extract the value.
167201360Srdivacky/// @param name - The name of the field in the record.
168201360Srdivacky/// @return     - The field, as translated by byteFromBitsInit().
169201360Srdivackystatic uint8_t byteFromRec(const Record* rec, const std::string &name) {
170201360Srdivacky  BitsInit* bits = rec->getValueAsBitsInit(name);
171201360Srdivacky  return byteFromBitsInit(*bits);
172201360Srdivacky}
173201360Srdivacky
174201360SrdivackyRecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
175201360Srdivacky                                     const CodeGenInstruction &insn,
176201360Srdivacky                                     InstrUID uid) {
177201360Srdivacky  UID = uid;
178201360Srdivacky
179201360Srdivacky  Rec = insn.TheDef;
180201360Srdivacky  Name = Rec->getName();
181201360Srdivacky  Spec = &tables.specForUID(UID);
182239462Sdim
183201360Srdivacky  if (!Rec->isSubClassOf("X86Inst")) {
184201360Srdivacky    ShouldBeEmitted = false;
185201360Srdivacky    return;
186201360Srdivacky  }
187239462Sdim
188276479Sdim  OpPrefix = byteFromRec(Rec, "OpPrefixBits");
189276479Sdim  OpMap    = byteFromRec(Rec, "OpMapBits");
190201360Srdivacky  Opcode   = byteFromRec(Rec, "Opcode");
191201360Srdivacky  Form     = byteFromRec(Rec, "FormBits");
192276479Sdim  Encoding = byteFromRec(Rec, "OpEncBits");
193239462Sdim
194276479Sdim  OpSize           = byteFromRec(Rec, "OpSizeBits");
195234353Sdim  HasAdSizePrefix  = Rec->getValueAsBit("hasAdSizePrefix");
196201360Srdivacky  HasREX_WPrefix   = Rec->getValueAsBit("hasREX_WPrefix");
197276479Sdim  HasVEX_4V        = Rec->getValueAsBit("hasVEX_4V");
198276479Sdim  HasVEX_4VOp3     = Rec->getValueAsBit("hasVEX_4VOp3");
199221345Sdim  HasVEX_WPrefix   = Rec->getValueAsBit("hasVEX_WPrefix");
200234353Sdim  HasMemOp4Prefix  = Rec->getValueAsBit("hasMemOp4Prefix");
201226633Sdim  IgnoresVEX_L     = Rec->getValueAsBit("ignoresVEX_L");
202261991Sdim  HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2");
203261991Sdim  HasEVEX_K        = Rec->getValueAsBit("hasEVEX_K");
204261991Sdim  HasEVEX_KZ       = Rec->getValueAsBit("hasEVEX_Z");
205261991Sdim  HasEVEX_B        = Rec->getValueAsBit("hasEVEX_B");
206201360Srdivacky  IsCodeGenOnly    = Rec->getValueAsBit("isCodeGenOnly");
207276479Sdim  ForceDisassemble = Rec->getValueAsBit("ForceDisassemble");
208276479Sdim  CD8_Scale        = byteFromRec(Rec, "CD8_Scale");
209239462Sdim
210201360Srdivacky  Name      = Rec->getName();
211201360Srdivacky  AsmString = Rec->getValueAsString("AsmString");
212239462Sdim
213218893Sdim  Operands = &insn.Operands.OperandList;
214239462Sdim
215243830Sdim  HasVEX_LPrefix   = Rec->getValueAsBit("hasVEX_L");
216234353Sdim
217224145Sdim  // Check for 64-bit inst which does not require REX
218226633Sdim  Is32Bit = false;
219224145Sdim  Is64Bit = false;
220224145Sdim  // FIXME: Is there some better way to check for In64BitMode?
221224145Sdim  std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates");
222224145Sdim  for (unsigned i = 0, e = Predicates.size(); i != e; ++i) {
223276479Sdim    if (Predicates[i]->getName().find("Not64Bit") != Name.npos ||
224276479Sdim	Predicates[i]->getName().find("In32Bit") != Name.npos) {
225226633Sdim      Is32Bit = true;
226226633Sdim      break;
227226633Sdim    }
228276479Sdim    if (Predicates[i]->getName().find("In64Bit") != Name.npos) {
229224145Sdim      Is64Bit = true;
230224145Sdim      break;
231224145Sdim    }
232224145Sdim  }
233224145Sdim
234276479Sdim  if (Form == X86Local::Pseudo || (IsCodeGenOnly && !ForceDisassemble)) {
235276479Sdim    ShouldBeEmitted = false;
236276479Sdim    return;
237276479Sdim  }
238276479Sdim
239276479Sdim  // Special case since there is no attribute class for 64-bit and VEX
240276479Sdim  if (Name == "VMASKMOVDQU64") {
241276479Sdim    ShouldBeEmitted = false;
242276479Sdim    return;
243276479Sdim  }
244276479Sdim
245201360Srdivacky  ShouldBeEmitted  = true;
246201360Srdivacky}
247239462Sdim
248201360Srdivackyvoid RecognizableInstr::processInstr(DisassemblerTables &tables,
249239462Sdim                                     const CodeGenInstruction &insn,
250239462Sdim                                     InstrUID uid)
251201360Srdivacky{
252208599Srdivacky  // Ignore "asm parser only" instructions.
253208599Srdivacky  if (insn.TheDef->getValueAsBit("isAsmParserOnly"))
254208599Srdivacky    return;
255239462Sdim
256201360Srdivacky  RecognizableInstr recogInstr(tables, insn, uid);
257239462Sdim
258276479Sdim  if (recogInstr.shouldBeEmitted()) {
259276479Sdim    recogInstr.emitInstructionSpecifier();
260201360Srdivacky    recogInstr.emitDecodePath(tables);
261276479Sdim  }
262201360Srdivacky}
263201360Srdivacky
264261991Sdim#define EVEX_KB(n) (HasEVEX_KZ && HasEVEX_B ? n##_KZ_B : \
265261991Sdim                    (HasEVEX_K && HasEVEX_B ? n##_K_B : \
266261991Sdim                    (HasEVEX_KZ ? n##_KZ : \
267261991Sdim                    (HasEVEX_K? n##_K : (HasEVEX_B ? n##_B : n)))))
268261991Sdim
269201360SrdivackyInstructionContext RecognizableInstr::insnContext() const {
270201360Srdivacky  InstructionContext insnContext;
271201360Srdivacky
272276479Sdim  if (Encoding == X86Local::EVEX) {
273261991Sdim    if (HasVEX_LPrefix && HasEVEX_L2Prefix) {
274261991Sdim      errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n";
275261991Sdim      llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
276261991Sdim    }
277261991Sdim    // VEX_L & VEX_W
278234353Sdim    if (HasVEX_LPrefix && HasVEX_WPrefix) {
279276479Sdim      if (OpPrefix == X86Local::PD)
280261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
281276479Sdim      else if (OpPrefix == X86Local::XS)
282261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_W_XS);
283276479Sdim      else if (OpPrefix == X86Local::XD)
284261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_W_XD);
285276479Sdim      else if (OpPrefix == X86Local::PS)
286261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_W);
287276479Sdim      else {
288276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
289276479Sdim        llvm_unreachable("Invalid prefix");
290276479Sdim      }
291261991Sdim    } else if (HasVEX_LPrefix) {
292261991Sdim      // VEX_L
293276479Sdim      if (OpPrefix == X86Local::PD)
294261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_OPSIZE);
295276479Sdim      else if (OpPrefix == X86Local::XS)
296261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_XS);
297276479Sdim      else if (OpPrefix == X86Local::XD)
298261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_XD);
299276479Sdim      else if (OpPrefix == X86Local::PS)
300261991Sdim        insnContext = EVEX_KB(IC_EVEX_L);
301276479Sdim      else {
302276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
303276479Sdim        llvm_unreachable("Invalid prefix");
304276479Sdim      }
305261991Sdim    }
306261991Sdim    else if (HasEVEX_L2Prefix && HasVEX_WPrefix) {
307261991Sdim      // EVEX_L2 & VEX_W
308276479Sdim      if (OpPrefix == X86Local::PD)
309261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
310276479Sdim      else if (OpPrefix == X86Local::XS)
311261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_W_XS);
312276479Sdim      else if (OpPrefix == X86Local::XD)
313261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_W_XD);
314276479Sdim      else if (OpPrefix == X86Local::PS)
315261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_W);
316276479Sdim      else {
317276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
318276479Sdim        llvm_unreachable("Invalid prefix");
319276479Sdim      }
320261991Sdim    } else if (HasEVEX_L2Prefix) {
321261991Sdim      // EVEX_L2
322276479Sdim      if (OpPrefix == X86Local::PD)
323261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE);
324276479Sdim      else if (OpPrefix == X86Local::XD)
325261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_XD);
326276479Sdim      else if (OpPrefix == X86Local::XS)
327261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_XS);
328276479Sdim      else if (OpPrefix == X86Local::PS)
329261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2);
330276479Sdim      else {
331276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
332276479Sdim        llvm_unreachable("Invalid prefix");
333276479Sdim      }
334261991Sdim    }
335261991Sdim    else if (HasVEX_WPrefix) {
336261991Sdim      // VEX_W
337276479Sdim      if (OpPrefix == X86Local::PD)
338261991Sdim        insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
339276479Sdim      else if (OpPrefix == X86Local::XS)
340261991Sdim        insnContext = EVEX_KB(IC_EVEX_W_XS);
341276479Sdim      else if (OpPrefix == X86Local::XD)
342261991Sdim        insnContext = EVEX_KB(IC_EVEX_W_XD);
343276479Sdim      else if (OpPrefix == X86Local::PS)
344261991Sdim        insnContext = EVEX_KB(IC_EVEX_W);
345276479Sdim      else {
346276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
347276479Sdim        llvm_unreachable("Invalid prefix");
348276479Sdim      }
349261991Sdim    }
350261991Sdim    // No L, no W
351276479Sdim    else if (OpPrefix == X86Local::PD)
352261991Sdim      insnContext = EVEX_KB(IC_EVEX_OPSIZE);
353276479Sdim    else if (OpPrefix == X86Local::XD)
354261991Sdim      insnContext = EVEX_KB(IC_EVEX_XD);
355276479Sdim    else if (OpPrefix == X86Local::XS)
356261991Sdim      insnContext = EVEX_KB(IC_EVEX_XS);
357261991Sdim    else
358261991Sdim      insnContext = EVEX_KB(IC_EVEX);
359261991Sdim    /// eof EVEX
360276479Sdim  } else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {
361261991Sdim    if (HasVEX_LPrefix && HasVEX_WPrefix) {
362276479Sdim      if (OpPrefix == X86Local::PD)
363234353Sdim        insnContext = IC_VEX_L_W_OPSIZE;
364276479Sdim      else if (OpPrefix == X86Local::XS)
365261991Sdim        insnContext = IC_VEX_L_W_XS;
366276479Sdim      else if (OpPrefix == X86Local::XD)
367261991Sdim        insnContext = IC_VEX_L_W_XD;
368276479Sdim      else if (OpPrefix == X86Local::PS)
369261991Sdim        insnContext = IC_VEX_L_W;
370276479Sdim      else {
371276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
372276479Sdim        llvm_unreachable("Invalid prefix");
373276479Sdim      }
374276479Sdim    } else if (OpPrefix == X86Local::PD && HasVEX_LPrefix)
375221345Sdim      insnContext = IC_VEX_L_OPSIZE;
376276479Sdim    else if (OpPrefix == X86Local::PD && HasVEX_WPrefix)
377221345Sdim      insnContext = IC_VEX_W_OPSIZE;
378276479Sdim    else if (OpPrefix == X86Local::PD)
379221345Sdim      insnContext = IC_VEX_OPSIZE;
380276479Sdim    else if (HasVEX_LPrefix && OpPrefix == X86Local::XS)
381221345Sdim      insnContext = IC_VEX_L_XS;
382276479Sdim    else if (HasVEX_LPrefix && OpPrefix == X86Local::XD)
383221345Sdim      insnContext = IC_VEX_L_XD;
384276479Sdim    else if (HasVEX_WPrefix && OpPrefix == X86Local::XS)
385221345Sdim      insnContext = IC_VEX_W_XS;
386276479Sdim    else if (HasVEX_WPrefix && OpPrefix == X86Local::XD)
387221345Sdim      insnContext = IC_VEX_W_XD;
388276479Sdim    else if (HasVEX_WPrefix && OpPrefix == X86Local::PS)
389221345Sdim      insnContext = IC_VEX_W;
390276479Sdim    else if (HasVEX_LPrefix && OpPrefix == X86Local::PS)
391221345Sdim      insnContext = IC_VEX_L;
392276479Sdim    else if (OpPrefix == X86Local::XD)
393221345Sdim      insnContext = IC_VEX_XD;
394276479Sdim    else if (OpPrefix == X86Local::XS)
395221345Sdim      insnContext = IC_VEX_XS;
396276479Sdim    else if (OpPrefix == X86Local::PS)
397221345Sdim      insnContext = IC_VEX;
398276479Sdim    else {
399276479Sdim      errs() << "Instruction does not use a prefix: " << Name << "\n";
400276479Sdim      llvm_unreachable("Invalid prefix");
401276479Sdim    }
402224145Sdim  } else if (Is64Bit || HasREX_WPrefix) {
403276479Sdim    if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD))
404201360Srdivacky      insnContext = IC_64BIT_REXW_OPSIZE;
405276479Sdim    else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
406234353Sdim      insnContext = IC_64BIT_XD_OPSIZE;
407276479Sdim    else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
408226633Sdim      insnContext = IC_64BIT_XS_OPSIZE;
409276479Sdim    else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
410201360Srdivacky      insnContext = IC_64BIT_OPSIZE;
411234353Sdim    else if (HasAdSizePrefix)
412234353Sdim      insnContext = IC_64BIT_ADSIZE;
413276479Sdim    else if (HasREX_WPrefix && OpPrefix == X86Local::XS)
414201360Srdivacky      insnContext = IC_64BIT_REXW_XS;
415276479Sdim    else if (HasREX_WPrefix && OpPrefix == X86Local::XD)
416201360Srdivacky      insnContext = IC_64BIT_REXW_XD;
417276479Sdim    else if (OpPrefix == X86Local::XD)
418201360Srdivacky      insnContext = IC_64BIT_XD;
419276479Sdim    else if (OpPrefix == X86Local::XS)
420201360Srdivacky      insnContext = IC_64BIT_XS;
421201360Srdivacky    else if (HasREX_WPrefix)
422201360Srdivacky      insnContext = IC_64BIT_REXW;
423201360Srdivacky    else
424201360Srdivacky      insnContext = IC_64BIT;
425201360Srdivacky  } else {
426276479Sdim    if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
427226633Sdim      insnContext = IC_XD_OPSIZE;
428276479Sdim    else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
429226633Sdim      insnContext = IC_XS_OPSIZE;
430276479Sdim    else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
431201360Srdivacky      insnContext = IC_OPSIZE;
432234353Sdim    else if (HasAdSizePrefix)
433234353Sdim      insnContext = IC_ADSIZE;
434276479Sdim    else if (OpPrefix == X86Local::XD)
435201360Srdivacky      insnContext = IC_XD;
436276479Sdim    else if (OpPrefix == X86Local::XS)
437201360Srdivacky      insnContext = IC_XS;
438201360Srdivacky    else
439201360Srdivacky      insnContext = IC;
440201360Srdivacky  }
441201360Srdivacky
442201360Srdivacky  return insnContext;
443201360Srdivacky}
444239462Sdim
445276479Sdimvoid RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) {
446276479Sdim  // The scaling factor for AVX512 compressed displacement encoding is an
447276479Sdim  // instruction attribute.  Adjust the ModRM encoding type to include the
448276479Sdim  // scale for compressed displacement.
449276479Sdim  if (encoding != ENCODING_RM || CD8_Scale == 0)
450276479Sdim    return;
451276479Sdim  encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale));
452276479Sdim  assert(encoding <= ENCODING_RM_CD64 && "Invalid CDisp scaling");
453201360Srdivacky}
454221345Sdim
455239462Sdimvoid RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
456239462Sdim                                      unsigned &physicalOperandIndex,
457239462Sdim                                      unsigned &numPhysicalOperands,
458239462Sdim                                      const unsigned *operandMapping,
459239462Sdim                                      OperandEncoding (*encodingFromString)
460239462Sdim                                        (const std::string&,
461276479Sdim                                         uint8_t OpSize)) {
462201360Srdivacky  if (optional) {
463201360Srdivacky    if (physicalOperandIndex >= numPhysicalOperands)
464201360Srdivacky      return;
465201360Srdivacky  } else {
466201360Srdivacky    assert(physicalOperandIndex < numPhysicalOperands);
467201360Srdivacky  }
468239462Sdim
469201360Srdivacky  while (operandMapping[operandIndex] != operandIndex) {
470201360Srdivacky    Spec->operands[operandIndex].encoding = ENCODING_DUP;
471201360Srdivacky    Spec->operands[operandIndex].type =
472201360Srdivacky      (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);
473201360Srdivacky    ++operandIndex;
474201360Srdivacky  }
475239462Sdim
476201360Srdivacky  const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
477221345Sdim
478276479Sdim  OperandEncoding encoding = encodingFromString(typeName, OpSize);
479276479Sdim  // Adjust the encoding type for an operand based on the instruction.
480276479Sdim  adjustOperandEncoding(encoding);
481276479Sdim  Spec->operands[operandIndex].encoding = encoding;
482239462Sdim  Spec->operands[operandIndex].type = typeFromString(typeName,
483276479Sdim                                                     HasREX_WPrefix, OpSize);
484239462Sdim
485201360Srdivacky  ++operandIndex;
486201360Srdivacky  ++physicalOperandIndex;
487201360Srdivacky}
488201360Srdivacky
489276479Sdimvoid RecognizableInstr::emitInstructionSpecifier() {
490201360Srdivacky  Spec->name       = Name;
491239462Sdim
492201360Srdivacky  Spec->insnContext = insnContext();
493239462Sdim
494218893Sdim  const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
495239462Sdim
496201360Srdivacky  unsigned numOperands = OperandList.size();
497201360Srdivacky  unsigned numPhysicalOperands = 0;
498239462Sdim
499201360Srdivacky  // operandMapping maps from operands in OperandList to their originals.
500201360Srdivacky  // If operandMapping[i] != i, then the entry is a duplicate.
501201360Srdivacky  unsigned operandMapping[X86_MAX_OPERANDS];
502234353Sdim  assert(numOperands <= X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough");
503239462Sdim
504239462Sdim  for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
505201360Srdivacky    if (OperandList[operandIndex].Constraints.size()) {
506218893Sdim      const CGIOperandList::ConstraintInfo &Constraint =
507203954Srdivacky        OperandList[operandIndex].Constraints[0];
508203954Srdivacky      if (Constraint.isTied()) {
509239462Sdim        operandMapping[operandIndex] = operandIndex;
510239462Sdim        operandMapping[Constraint.getTiedOperand()] = operandIndex;
511201360Srdivacky      } else {
512201360Srdivacky        ++numPhysicalOperands;
513201360Srdivacky        operandMapping[operandIndex] = operandIndex;
514201360Srdivacky      }
515201360Srdivacky    } else {
516201360Srdivacky      ++numPhysicalOperands;
517201360Srdivacky      operandMapping[operandIndex] = operandIndex;
518201360Srdivacky    }
519201360Srdivacky  }
520201360Srdivacky
521201360Srdivacky#define HANDLE_OPERAND(class)               \
522201360Srdivacky  handleOperand(false,                      \
523201360Srdivacky                operandIndex,               \
524201360Srdivacky                physicalOperandIndex,       \
525201360Srdivacky                numPhysicalOperands,        \
526201360Srdivacky                operandMapping,             \
527201360Srdivacky                class##EncodingFromString);
528239462Sdim
529201360Srdivacky#define HANDLE_OPTIONAL(class)              \
530201360Srdivacky  handleOperand(true,                       \
531201360Srdivacky                operandIndex,               \
532201360Srdivacky                physicalOperandIndex,       \
533201360Srdivacky                numPhysicalOperands,        \
534201360Srdivacky                operandMapping,             \
535201360Srdivacky                class##EncodingFromString);
536239462Sdim
537201360Srdivacky  // operandIndex should always be < numOperands
538239462Sdim  unsigned operandIndex = 0;
539201360Srdivacky  // physicalOperandIndex should always be < numPhysicalOperands
540201360Srdivacky  unsigned physicalOperandIndex = 0;
541239462Sdim
542201360Srdivacky  switch (Form) {
543276479Sdim  default: llvm_unreachable("Unhandled form");
544276479Sdim  case X86Local::RawFrmSrc:
545276479Sdim    HANDLE_OPERAND(relocation);
546276479Sdim    return;
547276479Sdim  case X86Local::RawFrmDst:
548276479Sdim    HANDLE_OPERAND(relocation);
549276479Sdim    return;
550276479Sdim  case X86Local::RawFrmDstSrc:
551276479Sdim    HANDLE_OPERAND(relocation);
552276479Sdim    HANDLE_OPERAND(relocation);
553276479Sdim    return;
554201360Srdivacky  case X86Local::RawFrm:
555201360Srdivacky    // Operand 1 (optional) is an address or immediate.
556201360Srdivacky    // Operand 2 (optional) is an immediate.
557239462Sdim    assert(numPhysicalOperands <= 2 &&
558201360Srdivacky           "Unexpected number of operands for RawFrm");
559201360Srdivacky    HANDLE_OPTIONAL(relocation)
560201360Srdivacky    HANDLE_OPTIONAL(immediate)
561201360Srdivacky    break;
562276479Sdim  case X86Local::RawFrmMemOffs:
563276479Sdim    // Operand 1 is an address.
564276479Sdim    HANDLE_OPERAND(relocation);
565276479Sdim    break;
566201360Srdivacky  case X86Local::AddRegFrm:
567201360Srdivacky    // Operand 1 is added to the opcode.
568201360Srdivacky    // Operand 2 (optional) is an address.
569201360Srdivacky    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
570201360Srdivacky           "Unexpected number of operands for AddRegFrm");
571201360Srdivacky    HANDLE_OPERAND(opcodeModifier)
572201360Srdivacky    HANDLE_OPTIONAL(relocation)
573201360Srdivacky    break;
574201360Srdivacky  case X86Local::MRMDestReg:
575201360Srdivacky    // Operand 1 is a register operand in the R/M field.
576201360Srdivacky    // Operand 2 is a register operand in the Reg/Opcode field.
577226633Sdim    // - In AVX, there is a register operand in the VEX.vvvv field here -
578201360Srdivacky    // Operand 3 (optional) is an immediate.
579276479Sdim    if (HasVEX_4V)
580226633Sdim      assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&
581226633Sdim             "Unexpected number of operands for MRMDestRegFrm with VEX_4V");
582226633Sdim    else
583226633Sdim      assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
584226633Sdim             "Unexpected number of operands for MRMDestRegFrm");
585239462Sdim
586201360Srdivacky    HANDLE_OPERAND(rmRegister)
587226633Sdim
588276479Sdim    if (HasVEX_4V)
589226633Sdim      // FIXME: In AVX, the register below becomes the one encoded
590226633Sdim      // in ModRMVEX and the one above the one in the VEX.VVVV field
591226633Sdim      HANDLE_OPERAND(vvvvRegister)
592239462Sdim
593201360Srdivacky    HANDLE_OPERAND(roRegister)
594201360Srdivacky    HANDLE_OPTIONAL(immediate)
595201360Srdivacky    break;
596201360Srdivacky  case X86Local::MRMDestMem:
597201360Srdivacky    // Operand 1 is a memory operand (possibly SIB-extended)
598201360Srdivacky    // Operand 2 is a register operand in the Reg/Opcode field.
599226633Sdim    // - In AVX, there is a register operand in the VEX.vvvv field here -
600201360Srdivacky    // Operand 3 (optional) is an immediate.
601276479Sdim    if (HasVEX_4V)
602226633Sdim      assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&
603226633Sdim             "Unexpected number of operands for MRMDestMemFrm with VEX_4V");
604226633Sdim    else
605226633Sdim      assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
606226633Sdim             "Unexpected number of operands for MRMDestMemFrm");
607201360Srdivacky    HANDLE_OPERAND(memory)
608226633Sdim
609261991Sdim    if (HasEVEX_K)
610261991Sdim      HANDLE_OPERAND(writemaskRegister)
611261991Sdim
612276479Sdim    if (HasVEX_4V)
613226633Sdim      // FIXME: In AVX, the register below becomes the one encoded
614226633Sdim      // in ModRMVEX and the one above the one in the VEX.VVVV field
615226633Sdim      HANDLE_OPERAND(vvvvRegister)
616239462Sdim
617201360Srdivacky    HANDLE_OPERAND(roRegister)
618201360Srdivacky    HANDLE_OPTIONAL(immediate)
619201360Srdivacky    break;
620201360Srdivacky  case X86Local::MRMSrcReg:
621201360Srdivacky    // Operand 1 is a register operand in the Reg/Opcode field.
622201360Srdivacky    // Operand 2 is a register operand in the R/M field.
623221345Sdim    // - In AVX, there is a register operand in the VEX.vvvv field here -
624201360Srdivacky    // Operand 3 (optional) is an immediate.
625239462Sdim    // Operand 4 (optional) is an immediate.
626210299Sed
627276479Sdim    if (HasVEX_4V || HasVEX_4VOp3)
628234353Sdim      assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 &&
629239462Sdim             "Unexpected number of operands for MRMSrcRegFrm with VEX_4V");
630221345Sdim    else
631239462Sdim      assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 4 &&
632221345Sdim             "Unexpected number of operands for MRMSrcRegFrm");
633239462Sdim
634221345Sdim    HANDLE_OPERAND(roRegister)
635234353Sdim
636261991Sdim    if (HasEVEX_K)
637261991Sdim      HANDLE_OPERAND(writemaskRegister)
638261991Sdim
639276479Sdim    if (HasVEX_4V)
640210299Sed      // FIXME: In AVX, the register below becomes the one encoded
641210299Sed      // in ModRMVEX and the one above the one in the VEX.VVVV field
642221345Sdim      HANDLE_OPERAND(vvvvRegister)
643234353Sdim
644234353Sdim    if (HasMemOp4Prefix)
645234353Sdim      HANDLE_OPERAND(immediate)
646234353Sdim
647221345Sdim    HANDLE_OPERAND(rmRegister)
648234353Sdim
649276479Sdim    if (HasVEX_4VOp3)
650234353Sdim      HANDLE_OPERAND(vvvvRegister)
651234353Sdim
652234353Sdim    if (!HasMemOp4Prefix)
653234353Sdim      HANDLE_OPTIONAL(immediate)
654234353Sdim    HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
655239462Sdim    HANDLE_OPTIONAL(immediate)
656201360Srdivacky    break;
657201360Srdivacky  case X86Local::MRMSrcMem:
658201360Srdivacky    // Operand 1 is a register operand in the Reg/Opcode field.
659201360Srdivacky    // Operand 2 is a memory operand (possibly SIB-extended)
660221345Sdim    // - In AVX, there is a register operand in the VEX.vvvv field here -
661201360Srdivacky    // Operand 3 (optional) is an immediate.
662234353Sdim
663276479Sdim    if (HasVEX_4V || HasVEX_4VOp3)
664234353Sdim      assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 &&
665239462Sdim             "Unexpected number of operands for MRMSrcMemFrm with VEX_4V");
666221345Sdim    else
667221345Sdim      assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
668221345Sdim             "Unexpected number of operands for MRMSrcMemFrm");
669239462Sdim
670201360Srdivacky    HANDLE_OPERAND(roRegister)
671210299Sed
672261991Sdim    if (HasEVEX_K)
673261991Sdim      HANDLE_OPERAND(writemaskRegister)
674261991Sdim
675276479Sdim    if (HasVEX_4V)
676210299Sed      // FIXME: In AVX, the register below becomes the one encoded
677210299Sed      // in ModRMVEX and the one above the one in the VEX.VVVV field
678221345Sdim      HANDLE_OPERAND(vvvvRegister)
679210299Sed
680234353Sdim    if (HasMemOp4Prefix)
681234353Sdim      HANDLE_OPERAND(immediate)
682234353Sdim
683201360Srdivacky    HANDLE_OPERAND(memory)
684234353Sdim
685276479Sdim    if (HasVEX_4VOp3)
686234353Sdim      HANDLE_OPERAND(vvvvRegister)
687234353Sdim
688234353Sdim    if (!HasMemOp4Prefix)
689234353Sdim      HANDLE_OPTIONAL(immediate)
690234353Sdim    HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
691201360Srdivacky    break;
692276479Sdim  case X86Local::MRMXr:
693201360Srdivacky  case X86Local::MRM0r:
694201360Srdivacky  case X86Local::MRM1r:
695201360Srdivacky  case X86Local::MRM2r:
696201360Srdivacky  case X86Local::MRM3r:
697201360Srdivacky  case X86Local::MRM4r:
698201360Srdivacky  case X86Local::MRM5r:
699201360Srdivacky  case X86Local::MRM6r:
700201360Srdivacky  case X86Local::MRM7r:
701261991Sdim    {
702261991Sdim      // Operand 1 is a register operand in the R/M field.
703261991Sdim      // Operand 2 (optional) is an immediate or relocation.
704261991Sdim      // Operand 3 (optional) is an immediate.
705261991Sdim      unsigned kOp = (HasEVEX_K) ? 1:0;
706276479Sdim      unsigned Op4v = (HasVEX_4V) ? 1:0;
707261991Sdim      if (numPhysicalOperands > 3 + kOp + Op4v)
708261991Sdim        llvm_unreachable("Unexpected number of operands for MRMnr");
709261991Sdim    }
710276479Sdim    if (HasVEX_4V)
711234353Sdim      HANDLE_OPERAND(vvvvRegister)
712261991Sdim
713261991Sdim    if (HasEVEX_K)
714261991Sdim      HANDLE_OPERAND(writemaskRegister)
715201360Srdivacky    HANDLE_OPTIONAL(rmRegister)
716201360Srdivacky    HANDLE_OPTIONAL(relocation)
717239462Sdim    HANDLE_OPTIONAL(immediate)
718201360Srdivacky    break;
719276479Sdim  case X86Local::MRMXm:
720201360Srdivacky  case X86Local::MRM0m:
721201360Srdivacky  case X86Local::MRM1m:
722201360Srdivacky  case X86Local::MRM2m:
723201360Srdivacky  case X86Local::MRM3m:
724201360Srdivacky  case X86Local::MRM4m:
725201360Srdivacky  case X86Local::MRM5m:
726201360Srdivacky  case X86Local::MRM6m:
727201360Srdivacky  case X86Local::MRM7m:
728261991Sdim    {
729261991Sdim      // Operand 1 is a memory operand (possibly SIB-extended)
730261991Sdim      // Operand 2 (optional) is an immediate or relocation.
731261991Sdim      unsigned kOp = (HasEVEX_K) ? 1:0;
732276479Sdim      unsigned Op4v = (HasVEX_4V) ? 1:0;
733261991Sdim      if (numPhysicalOperands < 1 + kOp + Op4v ||
734261991Sdim          numPhysicalOperands > 2 + kOp + Op4v)
735261991Sdim        llvm_unreachable("Unexpected number of operands for MRMnm");
736261991Sdim    }
737276479Sdim    if (HasVEX_4V)
738234353Sdim      HANDLE_OPERAND(vvvvRegister)
739261991Sdim    if (HasEVEX_K)
740261991Sdim      HANDLE_OPERAND(writemaskRegister)
741201360Srdivacky    HANDLE_OPERAND(memory)
742201360Srdivacky    HANDLE_OPTIONAL(relocation)
743201360Srdivacky    break;
744218893Sdim  case X86Local::RawFrmImm8:
745218893Sdim    // operand 1 is a 16-bit immediate
746218893Sdim    // operand 2 is an 8-bit immediate
747218893Sdim    assert(numPhysicalOperands == 2 &&
748218893Sdim           "Unexpected number of operands for X86Local::RawFrmImm8");
749218893Sdim    HANDLE_OPERAND(immediate)
750218893Sdim    HANDLE_OPERAND(immediate)
751218893Sdim    break;
752218893Sdim  case X86Local::RawFrmImm16:
753218893Sdim    // operand 1 is a 16-bit immediate
754218893Sdim    // operand 2 is a 16-bit immediate
755218893Sdim    HANDLE_OPERAND(immediate)
756218893Sdim    HANDLE_OPERAND(immediate)
757218893Sdim    break;
758249423Sdim  case X86Local::MRM_F8:
759249423Sdim    if (Opcode == 0xc6) {
760249423Sdim      assert(numPhysicalOperands == 1 &&
761249423Sdim             "Unexpected number of operands for X86Local::MRM_F8");
762249423Sdim      HANDLE_OPERAND(immediate)
763249423Sdim    } else if (Opcode == 0xc7) {
764249423Sdim      assert(numPhysicalOperands == 1 &&
765249423Sdim             "Unexpected number of operands for X86Local::MRM_F8");
766249423Sdim      HANDLE_OPERAND(relocation)
767249423Sdim    }
768249423Sdim    break;
769276479Sdim  case X86Local::MRM_C0: case X86Local::MRM_C1: case X86Local::MRM_C2:
770276479Sdim  case X86Local::MRM_C3: case X86Local::MRM_C4: case X86Local::MRM_C8:
771276479Sdim  case X86Local::MRM_C9: case X86Local::MRM_CA: case X86Local::MRM_CB:
772276479Sdim  case X86Local::MRM_D0: case X86Local::MRM_D1: case X86Local::MRM_D4:
773276479Sdim  case X86Local::MRM_D5: case X86Local::MRM_D6: case X86Local::MRM_D8:
774276479Sdim  case X86Local::MRM_D9: case X86Local::MRM_DA: case X86Local::MRM_DB:
775276479Sdim  case X86Local::MRM_DC: case X86Local::MRM_DD: case X86Local::MRM_DE:
776276479Sdim  case X86Local::MRM_DF: case X86Local::MRM_E0: case X86Local::MRM_E1:
777276479Sdim  case X86Local::MRM_E2: case X86Local::MRM_E3: case X86Local::MRM_E4:
778276479Sdim  case X86Local::MRM_E5: case X86Local::MRM_E8: case X86Local::MRM_E9:
779276479Sdim  case X86Local::MRM_EA: case X86Local::MRM_EB: case X86Local::MRM_EC:
780276479Sdim  case X86Local::MRM_ED: case X86Local::MRM_EE: case X86Local::MRM_F0:
781276479Sdim  case X86Local::MRM_F1: case X86Local::MRM_F2: case X86Local::MRM_F3:
782276479Sdim  case X86Local::MRM_F4: case X86Local::MRM_F5: case X86Local::MRM_F6:
783276479Sdim  case X86Local::MRM_F7: case X86Local::MRM_F9: case X86Local::MRM_FA:
784276479Sdim  case X86Local::MRM_FB: case X86Local::MRM_FC: case X86Local::MRM_FD:
785276479Sdim  case X86Local::MRM_FE: case X86Local::MRM_FF:
786201360Srdivacky    // Ignored.
787201360Srdivacky    break;
788201360Srdivacky  }
789239462Sdim
790201360Srdivacky  #undef HANDLE_OPERAND
791201360Srdivacky  #undef HANDLE_OPTIONAL
792201360Srdivacky}
793201360Srdivacky
794201360Srdivackyvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
795201360Srdivacky  // Special cases where the LLVM tables are not complete
796201360Srdivacky
797203954Srdivacky#define MAP(from, to)                     \
798203954Srdivacky  case X86Local::MRM_##from:              \
799203954Srdivacky    filter = new ExactFilter(0x##from);   \
800203954Srdivacky    break;
801201360Srdivacky
802201360Srdivacky  OpcodeType    opcodeType  = (OpcodeType)-1;
803239462Sdim
804276479Sdim  ModRMFilter*  filter      = nullptr;
805201360Srdivacky  uint8_t       opcodeToSet = 0;
806201360Srdivacky
807276479Sdim  switch (OpMap) {
808276479Sdim  default: llvm_unreachable("Invalid map!");
809276479Sdim  case X86Local::OB:
810201360Srdivacky  case X86Local::TB:
811201360Srdivacky  case X86Local::T8:
812276479Sdim  case X86Local::TA:
813261991Sdim  case X86Local::XOP8:
814261991Sdim  case X86Local::XOP9:
815276479Sdim  case X86Local::XOPA:
816276479Sdim    switch (OpMap) {
817276479Sdim    default: llvm_unreachable("Unexpected map!");
818276479Sdim    case X86Local::OB:   opcodeType = ONEBYTE;      break;
819276479Sdim    case X86Local::TB:   opcodeType = TWOBYTE;      break;
820276479Sdim    case X86Local::T8:   opcodeType = THREEBYTE_38; break;
821276479Sdim    case X86Local::TA:   opcodeType = THREEBYTE_3A; break;
822276479Sdim    case X86Local::XOP8: opcodeType = XOP8_MAP;     break;
823276479Sdim    case X86Local::XOP9: opcodeType = XOP9_MAP;     break;
824276479Sdim    case X86Local::XOPA: opcodeType = XOPA_MAP;     break;
825276479Sdim    }
826276479Sdim
827276479Sdim    switch (Form) {
828261991Sdim    default:
829276479Sdim      filter = new DumbFilter();
830261991Sdim      break;
831276479Sdim    case X86Local::MRMDestReg: case X86Local::MRMDestMem:
832276479Sdim    case X86Local::MRMSrcReg:  case X86Local::MRMSrcMem:
833276479Sdim    case X86Local::MRMXr:      case X86Local::MRMXm:
834261991Sdim      filter = new ModFilter(isRegFormat(Form));
835201360Srdivacky      break;
836276479Sdim    case X86Local::MRM0r:      case X86Local::MRM1r:
837276479Sdim    case X86Local::MRM2r:      case X86Local::MRM3r:
838276479Sdim    case X86Local::MRM4r:      case X86Local::MRM5r:
839276479Sdim    case X86Local::MRM6r:      case X86Local::MRM7r:
840276479Sdim      filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
841201360Srdivacky      break;
842276479Sdim    case X86Local::MRM0m:      case X86Local::MRM1m:
843276479Sdim    case X86Local::MRM2m:      case X86Local::MRM3m:
844276479Sdim    case X86Local::MRM4m:      case X86Local::MRM5m:
845276479Sdim    case X86Local::MRM6m:      case X86Local::MRM7m:
846276479Sdim      filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
847201360Srdivacky      break;
848276479Sdim    MRM_MAPPING
849276479Sdim    } // switch (Form)
850276479Sdim
851201360Srdivacky    opcodeToSet = Opcode;
852276479Sdim    break;
853276479Sdim  } // switch (OpMap)
854201360Srdivacky
855201360Srdivacky  assert(opcodeType != (OpcodeType)-1 &&
856201360Srdivacky         "Opcode type not set");
857201360Srdivacky  assert(filter && "Filter not set");
858201360Srdivacky
859201360Srdivacky  if (Form == X86Local::AddRegFrm) {
860276479Sdim    assert(((opcodeToSet & 7) == 0) &&
861276479Sdim           "ADDREG_FRM opcode not aligned");
862239462Sdim
863276479Sdim    uint8_t currentOpcode;
864201360Srdivacky
865276479Sdim    for (currentOpcode = opcodeToSet;
866276479Sdim         currentOpcode < opcodeToSet + 8;
867276479Sdim         ++currentOpcode)
868239462Sdim      tables.setTableFields(opcodeType,
869239462Sdim                            insnContext(),
870276479Sdim                            currentOpcode,
871239462Sdim                            *filter,
872226633Sdim                            UID, Is32Bit, IgnoresVEX_L);
873201360Srdivacky  } else {
874201360Srdivacky    tables.setTableFields(opcodeType,
875201360Srdivacky                          insnContext(),
876201360Srdivacky                          opcodeToSet,
877201360Srdivacky                          *filter,
878226633Sdim                          UID, Is32Bit, IgnoresVEX_L);
879201360Srdivacky  }
880239462Sdim
881201360Srdivacky  delete filter;
882239462Sdim
883203954Srdivacky#undef MAP
884201360Srdivacky}
885201360Srdivacky
886201360Srdivacky#define TYPE(str, type) if (s == str) return type;
887201360SrdivackyOperandType RecognizableInstr::typeFromString(const std::string &s,
888201360Srdivacky                                              bool hasREX_WPrefix,
889276479Sdim                                              uint8_t OpSize) {
890201360Srdivacky  if(hasREX_WPrefix) {
891201360Srdivacky    // For instructions with a REX_W prefix, a declared 32-bit register encoding
892201360Srdivacky    // is special.
893201360Srdivacky    TYPE("GR32",              TYPE_R32)
894201360Srdivacky  }
895276479Sdim  if(OpSize == X86Local::OpSize16) {
896276479Sdim    // For OpSize16 instructions, a declared 16-bit register or
897201360Srdivacky    // immediate encoding is special.
898276479Sdim    TYPE("GR16",              TYPE_Rv)
899276479Sdim    TYPE("i16imm",            TYPE_IMMv)
900276479Sdim  } else if(OpSize == X86Local::OpSize32) {
901276479Sdim    // For OpSize32 instructions, a declared 32-bit register or
902276479Sdim    // immediate encoding is special.
903276479Sdim    TYPE("GR32",              TYPE_Rv)
904201360Srdivacky  }
905201360Srdivacky  TYPE("i16mem",              TYPE_Mv)
906276479Sdim  TYPE("i16imm",              TYPE_IMM16)
907201360Srdivacky  TYPE("i16i8imm",            TYPE_IMMv)
908276479Sdim  TYPE("GR16",                TYPE_R16)
909201360Srdivacky  TYPE("i32mem",              TYPE_Mv)
910201360Srdivacky  TYPE("i32imm",              TYPE_IMMv)
911201360Srdivacky  TYPE("i32i8imm",            TYPE_IMM32)
912226633Sdim  TYPE("u32u8imm",            TYPE_IMM32)
913276479Sdim  TYPE("GR32",                TYPE_R32)
914261991Sdim  TYPE("GR32orGR64",          TYPE_R32)
915201360Srdivacky  TYPE("i64mem",              TYPE_Mv)
916201360Srdivacky  TYPE("i64i32imm",           TYPE_IMM64)
917201360Srdivacky  TYPE("i64i8imm",            TYPE_IMM64)
918201360Srdivacky  TYPE("GR64",                TYPE_R64)
919201360Srdivacky  TYPE("i8mem",               TYPE_M8)
920201360Srdivacky  TYPE("i8imm",               TYPE_IMM8)
921201360Srdivacky  TYPE("GR8",                 TYPE_R8)
922201360Srdivacky  TYPE("VR128",               TYPE_XMM128)
923261991Sdim  TYPE("VR128X",              TYPE_XMM128)
924201360Srdivacky  TYPE("f128mem",             TYPE_M128)
925218893Sdim  TYPE("f256mem",             TYPE_M256)
926261991Sdim  TYPE("f512mem",             TYPE_M512)
927201360Srdivacky  TYPE("FR64",                TYPE_XMM64)
928261991Sdim  TYPE("FR64X",               TYPE_XMM64)
929201360Srdivacky  TYPE("f64mem",              TYPE_M64FP)
930218893Sdim  TYPE("sdmem",               TYPE_M64FP)
931201360Srdivacky  TYPE("FR32",                TYPE_XMM32)
932261991Sdim  TYPE("FR32X",               TYPE_XMM32)
933201360Srdivacky  TYPE("f32mem",              TYPE_M32FP)
934218893Sdim  TYPE("ssmem",               TYPE_M32FP)
935201360Srdivacky  TYPE("RST",                 TYPE_ST)
936201360Srdivacky  TYPE("i128mem",             TYPE_M128)
937221345Sdim  TYPE("i256mem",             TYPE_M256)
938261991Sdim  TYPE("i512mem",             TYPE_M512)
939201360Srdivacky  TYPE("i64i32imm_pcrel",     TYPE_REL64)
940210299Sed  TYPE("i16imm_pcrel",        TYPE_REL16)
941201360Srdivacky  TYPE("i32imm_pcrel",        TYPE_REL32)
942207618Srdivacky  TYPE("SSECC",               TYPE_IMM3)
943234353Sdim  TYPE("AVXCC",               TYPE_IMM5)
944276479Sdim  TYPE("AVX512RC",            TYPE_IMM32)
945201360Srdivacky  TYPE("brtarget",            TYPE_RELv)
946218893Sdim  TYPE("uncondbrtarget",      TYPE_RELv)
947201360Srdivacky  TYPE("brtarget8",           TYPE_REL8)
948201360Srdivacky  TYPE("f80mem",              TYPE_M80FP)
949201360Srdivacky  TYPE("lea32mem",            TYPE_LEA)
950201360Srdivacky  TYPE("lea64_32mem",         TYPE_LEA)
951201360Srdivacky  TYPE("lea64mem",            TYPE_LEA)
952201360Srdivacky  TYPE("VR64",                TYPE_MM64)
953201360Srdivacky  TYPE("i64imm",              TYPE_IMMv)
954201360Srdivacky  TYPE("opaque32mem",         TYPE_M1616)
955201360Srdivacky  TYPE("opaque48mem",         TYPE_M1632)
956201360Srdivacky  TYPE("opaque80mem",         TYPE_M1664)
957201360Srdivacky  TYPE("opaque512mem",        TYPE_M512)
958201360Srdivacky  TYPE("SEGMENT_REG",         TYPE_SEGMENTREG)
959201360Srdivacky  TYPE("DEBUG_REG",           TYPE_DEBUGREG)
960208599Srdivacky  TYPE("CONTROL_REG",         TYPE_CONTROLREG)
961276479Sdim  TYPE("srcidx8",             TYPE_SRCIDX8)
962276479Sdim  TYPE("srcidx16",            TYPE_SRCIDX16)
963276479Sdim  TYPE("srcidx32",            TYPE_SRCIDX32)
964276479Sdim  TYPE("srcidx64",            TYPE_SRCIDX64)
965276479Sdim  TYPE("dstidx8",             TYPE_DSTIDX8)
966276479Sdim  TYPE("dstidx16",            TYPE_DSTIDX16)
967276479Sdim  TYPE("dstidx32",            TYPE_DSTIDX32)
968276479Sdim  TYPE("dstidx64",            TYPE_DSTIDX64)
969201360Srdivacky  TYPE("offset8",             TYPE_MOFFS8)
970201360Srdivacky  TYPE("offset16",            TYPE_MOFFS16)
971201360Srdivacky  TYPE("offset32",            TYPE_MOFFS32)
972201360Srdivacky  TYPE("offset64",            TYPE_MOFFS64)
973221345Sdim  TYPE("VR256",               TYPE_XMM256)
974261991Sdim  TYPE("VR256X",              TYPE_XMM256)
975261991Sdim  TYPE("VR512",               TYPE_XMM512)
976276479Sdim  TYPE("VK1",                 TYPE_VK1)
977276479Sdim  TYPE("VK1WM",               TYPE_VK1)
978276479Sdim  TYPE("VK2",                 TYPE_VK2)
979276479Sdim  TYPE("VK2WM",               TYPE_VK2)
980276479Sdim  TYPE("VK4",                 TYPE_VK4)
981276479Sdim  TYPE("VK4WM",               TYPE_VK4)
982261991Sdim  TYPE("VK8",                 TYPE_VK8)
983261991Sdim  TYPE("VK8WM",               TYPE_VK8)
984261991Sdim  TYPE("VK16",                TYPE_VK16)
985261991Sdim  TYPE("VK16WM",              TYPE_VK16)
986276479Sdim  TYPE("VK32",                TYPE_VK32)
987276479Sdim  TYPE("VK32WM",              TYPE_VK32)
988276479Sdim  TYPE("VK64",                TYPE_VK64)
989276479Sdim  TYPE("VK64WM",              TYPE_VK64)
990226633Sdim  TYPE("GR16_NOAX",           TYPE_Rv)
991226633Sdim  TYPE("GR32_NOAX",           TYPE_Rv)
992226633Sdim  TYPE("GR64_NOAX",           TYPE_R64)
993239462Sdim  TYPE("vx32mem",             TYPE_M32)
994239462Sdim  TYPE("vy32mem",             TYPE_M32)
995261991Sdim  TYPE("vz32mem",             TYPE_M32)
996239462Sdim  TYPE("vx64mem",             TYPE_M64)
997239462Sdim  TYPE("vy64mem",             TYPE_M64)
998261991Sdim  TYPE("vy64xmem",            TYPE_M64)
999261991Sdim  TYPE("vz64mem",             TYPE_M64)
1000201360Srdivacky  errs() << "Unhandled type string " << s << "\n";
1001201360Srdivacky  llvm_unreachable("Unhandled type string");
1002201360Srdivacky}
1003201360Srdivacky#undef TYPE
1004201360Srdivacky
1005201360Srdivacky#define ENCODING(str, encoding) if (s == str) return encoding;
1006276479SdimOperandEncoding
1007276479SdimRecognizableInstr::immediateEncodingFromString(const std::string &s,
1008276479Sdim                                               uint8_t OpSize) {
1009276479Sdim  if(OpSize != X86Local::OpSize16) {
1010201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
1011201360Srdivacky    // immediate encoding is special.
1012201360Srdivacky    ENCODING("i16imm",        ENCODING_IW)
1013201360Srdivacky  }
1014201360Srdivacky  ENCODING("i32i8imm",        ENCODING_IB)
1015226633Sdim  ENCODING("u32u8imm",        ENCODING_IB)
1016201360Srdivacky  ENCODING("SSECC",           ENCODING_IB)
1017234353Sdim  ENCODING("AVXCC",           ENCODING_IB)
1018276479Sdim  ENCODING("AVX512RC",        ENCODING_IB)
1019201360Srdivacky  ENCODING("i16imm",          ENCODING_Iv)
1020201360Srdivacky  ENCODING("i16i8imm",        ENCODING_IB)
1021201360Srdivacky  ENCODING("i32imm",          ENCODING_Iv)
1022201360Srdivacky  ENCODING("i64i32imm",       ENCODING_ID)
1023201360Srdivacky  ENCODING("i64i8imm",        ENCODING_IB)
1024201360Srdivacky  ENCODING("i8imm",           ENCODING_IB)
1025221345Sdim  // This is not a typo.  Instructions like BLENDVPD put
1026221345Sdim  // register IDs in 8-bit immediates nowadays.
1027243830Sdim  ENCODING("FR32",            ENCODING_IB)
1028243830Sdim  ENCODING("FR64",            ENCODING_IB)
1029261991Sdim  ENCODING("VR128",           ENCODING_IB)
1030261991Sdim  ENCODING("VR256",           ENCODING_IB)
1031261991Sdim  ENCODING("FR32X",           ENCODING_IB)
1032261991Sdim  ENCODING("FR64X",           ENCODING_IB)
1033261991Sdim  ENCODING("VR128X",          ENCODING_IB)
1034261991Sdim  ENCODING("VR256X",          ENCODING_IB)
1035261991Sdim  ENCODING("VR512",           ENCODING_IB)
1036201360Srdivacky  errs() << "Unhandled immediate encoding " << s << "\n";
1037201360Srdivacky  llvm_unreachable("Unhandled immediate encoding");
1038201360Srdivacky}
1039201360Srdivacky
1040276479SdimOperandEncoding
1041276479SdimRecognizableInstr::rmRegisterEncodingFromString(const std::string &s,
1042276479Sdim                                                uint8_t OpSize) {
1043276479Sdim  ENCODING("RST",             ENCODING_FP)
1044201360Srdivacky  ENCODING("GR16",            ENCODING_RM)
1045201360Srdivacky  ENCODING("GR32",            ENCODING_RM)
1046261991Sdim  ENCODING("GR32orGR64",      ENCODING_RM)
1047201360Srdivacky  ENCODING("GR64",            ENCODING_RM)
1048201360Srdivacky  ENCODING("GR8",             ENCODING_RM)
1049201360Srdivacky  ENCODING("VR128",           ENCODING_RM)
1050261991Sdim  ENCODING("VR128X",          ENCODING_RM)
1051201360Srdivacky  ENCODING("FR64",            ENCODING_RM)
1052201360Srdivacky  ENCODING("FR32",            ENCODING_RM)
1053261991Sdim  ENCODING("FR64X",           ENCODING_RM)
1054261991Sdim  ENCODING("FR32X",           ENCODING_RM)
1055201360Srdivacky  ENCODING("VR64",            ENCODING_RM)
1056221345Sdim  ENCODING("VR256",           ENCODING_RM)
1057261991Sdim  ENCODING("VR256X",          ENCODING_RM)
1058261991Sdim  ENCODING("VR512",           ENCODING_RM)
1059276479Sdim  ENCODING("VK1",             ENCODING_RM)
1060261991Sdim  ENCODING("VK8",             ENCODING_RM)
1061261991Sdim  ENCODING("VK16",            ENCODING_RM)
1062201360Srdivacky  errs() << "Unhandled R/M register encoding " << s << "\n";
1063201360Srdivacky  llvm_unreachable("Unhandled R/M register encoding");
1064201360Srdivacky}
1065201360Srdivacky
1066276479SdimOperandEncoding
1067276479SdimRecognizableInstr::roRegisterEncodingFromString(const std::string &s,
1068276479Sdim                                                uint8_t OpSize) {
1069201360Srdivacky  ENCODING("GR16",            ENCODING_REG)
1070201360Srdivacky  ENCODING("GR32",            ENCODING_REG)
1071261991Sdim  ENCODING("GR32orGR64",      ENCODING_REG)
1072201360Srdivacky  ENCODING("GR64",            ENCODING_REG)
1073201360Srdivacky  ENCODING("GR8",             ENCODING_REG)
1074201360Srdivacky  ENCODING("VR128",           ENCODING_REG)
1075201360Srdivacky  ENCODING("FR64",            ENCODING_REG)
1076201360Srdivacky  ENCODING("FR32",            ENCODING_REG)
1077201360Srdivacky  ENCODING("VR64",            ENCODING_REG)
1078201360Srdivacky  ENCODING("SEGMENT_REG",     ENCODING_REG)
1079201360Srdivacky  ENCODING("DEBUG_REG",       ENCODING_REG)
1080208599Srdivacky  ENCODING("CONTROL_REG",     ENCODING_REG)
1081221345Sdim  ENCODING("VR256",           ENCODING_REG)
1082261991Sdim  ENCODING("VR256X",          ENCODING_REG)
1083261991Sdim  ENCODING("VR128X",          ENCODING_REG)
1084261991Sdim  ENCODING("FR64X",           ENCODING_REG)
1085261991Sdim  ENCODING("FR32X",           ENCODING_REG)
1086261991Sdim  ENCODING("VR512",           ENCODING_REG)
1087276479Sdim  ENCODING("VK1",             ENCODING_REG)
1088261991Sdim  ENCODING("VK8",             ENCODING_REG)
1089261991Sdim  ENCODING("VK16",            ENCODING_REG)
1090276479Sdim  ENCODING("VK1WM",           ENCODING_REG)
1091261991Sdim  ENCODING("VK8WM",           ENCODING_REG)
1092261991Sdim  ENCODING("VK16WM",          ENCODING_REG)
1093201360Srdivacky  errs() << "Unhandled reg/opcode register encoding " << s << "\n";
1094201360Srdivacky  llvm_unreachable("Unhandled reg/opcode register encoding");
1095201360Srdivacky}
1096201360Srdivacky
1097276479SdimOperandEncoding
1098276479SdimRecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s,
1099276479Sdim                                                  uint8_t OpSize) {
1100226633Sdim  ENCODING("GR32",            ENCODING_VVVV)
1101226633Sdim  ENCODING("GR64",            ENCODING_VVVV)
1102221345Sdim  ENCODING("FR32",            ENCODING_VVVV)
1103221345Sdim  ENCODING("FR64",            ENCODING_VVVV)
1104221345Sdim  ENCODING("VR128",           ENCODING_VVVV)
1105221345Sdim  ENCODING("VR256",           ENCODING_VVVV)
1106261991Sdim  ENCODING("FR32X",           ENCODING_VVVV)
1107261991Sdim  ENCODING("FR64X",           ENCODING_VVVV)
1108261991Sdim  ENCODING("VR128X",          ENCODING_VVVV)
1109261991Sdim  ENCODING("VR256X",          ENCODING_VVVV)
1110261991Sdim  ENCODING("VR512",           ENCODING_VVVV)
1111276479Sdim  ENCODING("VK1",             ENCODING_VVVV)
1112276479Sdim  ENCODING("VK2",             ENCODING_VVVV)
1113276479Sdim  ENCODING("VK4",             ENCODING_VVVV)
1114261991Sdim  ENCODING("VK8",             ENCODING_VVVV)
1115261991Sdim  ENCODING("VK16",            ENCODING_VVVV)
1116221345Sdim  errs() << "Unhandled VEX.vvvv register encoding " << s << "\n";
1117221345Sdim  llvm_unreachable("Unhandled VEX.vvvv register encoding");
1118221345Sdim}
1119221345Sdim
1120276479SdimOperandEncoding
1121276479SdimRecognizableInstr::writemaskRegisterEncodingFromString(const std::string &s,
1122276479Sdim                                                       uint8_t OpSize) {
1123276479Sdim  ENCODING("VK1WM",           ENCODING_WRITEMASK)
1124276479Sdim  ENCODING("VK2WM",           ENCODING_WRITEMASK)
1125276479Sdim  ENCODING("VK4WM",           ENCODING_WRITEMASK)
1126261991Sdim  ENCODING("VK8WM",           ENCODING_WRITEMASK)
1127261991Sdim  ENCODING("VK16WM",          ENCODING_WRITEMASK)
1128276479Sdim  ENCODING("VK32WM",          ENCODING_WRITEMASK)
1129276479Sdim  ENCODING("VK64WM",          ENCODING_WRITEMASK)
1130261991Sdim  errs() << "Unhandled mask register encoding " << s << "\n";
1131261991Sdim  llvm_unreachable("Unhandled mask register encoding");
1132261991Sdim}
1133261991Sdim
1134276479SdimOperandEncoding
1135276479SdimRecognizableInstr::memoryEncodingFromString(const std::string &s,
1136276479Sdim                                            uint8_t OpSize) {
1137201360Srdivacky  ENCODING("i16mem",          ENCODING_RM)
1138201360Srdivacky  ENCODING("i32mem",          ENCODING_RM)
1139201360Srdivacky  ENCODING("i64mem",          ENCODING_RM)
1140201360Srdivacky  ENCODING("i8mem",           ENCODING_RM)
1141218893Sdim  ENCODING("ssmem",           ENCODING_RM)
1142218893Sdim  ENCODING("sdmem",           ENCODING_RM)
1143201360Srdivacky  ENCODING("f128mem",         ENCODING_RM)
1144218893Sdim  ENCODING("f256mem",         ENCODING_RM)
1145261991Sdim  ENCODING("f512mem",         ENCODING_RM)
1146201360Srdivacky  ENCODING("f64mem",          ENCODING_RM)
1147201360Srdivacky  ENCODING("f32mem",          ENCODING_RM)
1148201360Srdivacky  ENCODING("i128mem",         ENCODING_RM)
1149221345Sdim  ENCODING("i256mem",         ENCODING_RM)
1150261991Sdim  ENCODING("i512mem",         ENCODING_RM)
1151201360Srdivacky  ENCODING("f80mem",          ENCODING_RM)
1152201360Srdivacky  ENCODING("lea32mem",        ENCODING_RM)
1153201360Srdivacky  ENCODING("lea64_32mem",     ENCODING_RM)
1154201360Srdivacky  ENCODING("lea64mem",        ENCODING_RM)
1155201360Srdivacky  ENCODING("opaque32mem",     ENCODING_RM)
1156201360Srdivacky  ENCODING("opaque48mem",     ENCODING_RM)
1157201360Srdivacky  ENCODING("opaque80mem",     ENCODING_RM)
1158201360Srdivacky  ENCODING("opaque512mem",    ENCODING_RM)
1159239462Sdim  ENCODING("vx32mem",         ENCODING_RM)
1160239462Sdim  ENCODING("vy32mem",         ENCODING_RM)
1161261991Sdim  ENCODING("vz32mem",         ENCODING_RM)
1162239462Sdim  ENCODING("vx64mem",         ENCODING_RM)
1163239462Sdim  ENCODING("vy64mem",         ENCODING_RM)
1164261991Sdim  ENCODING("vy64xmem",        ENCODING_RM)
1165261991Sdim  ENCODING("vz64mem",         ENCODING_RM)
1166201360Srdivacky  errs() << "Unhandled memory encoding " << s << "\n";
1167201360Srdivacky  llvm_unreachable("Unhandled memory encoding");
1168201360Srdivacky}
1169201360Srdivacky
1170276479SdimOperandEncoding
1171276479SdimRecognizableInstr::relocationEncodingFromString(const std::string &s,
1172276479Sdim                                                uint8_t OpSize) {
1173276479Sdim  if(OpSize != X86Local::OpSize16) {
1174201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
1175201360Srdivacky    // immediate encoding is special.
1176201360Srdivacky    ENCODING("i16imm",        ENCODING_IW)
1177201360Srdivacky  }
1178201360Srdivacky  ENCODING("i16imm",          ENCODING_Iv)
1179201360Srdivacky  ENCODING("i16i8imm",        ENCODING_IB)
1180201360Srdivacky  ENCODING("i32imm",          ENCODING_Iv)
1181201360Srdivacky  ENCODING("i32i8imm",        ENCODING_IB)
1182201360Srdivacky  ENCODING("i64i32imm",       ENCODING_ID)
1183201360Srdivacky  ENCODING("i64i8imm",        ENCODING_IB)
1184201360Srdivacky  ENCODING("i8imm",           ENCODING_IB)
1185201360Srdivacky  ENCODING("i64i32imm_pcrel", ENCODING_ID)
1186210299Sed  ENCODING("i16imm_pcrel",    ENCODING_IW)
1187201360Srdivacky  ENCODING("i32imm_pcrel",    ENCODING_ID)
1188201360Srdivacky  ENCODING("brtarget",        ENCODING_Iv)
1189201360Srdivacky  ENCODING("brtarget8",       ENCODING_IB)
1190201360Srdivacky  ENCODING("i64imm",          ENCODING_IO)
1191201360Srdivacky  ENCODING("offset8",         ENCODING_Ia)
1192201360Srdivacky  ENCODING("offset16",        ENCODING_Ia)
1193201360Srdivacky  ENCODING("offset32",        ENCODING_Ia)
1194201360Srdivacky  ENCODING("offset64",        ENCODING_Ia)
1195276479Sdim  ENCODING("srcidx8",         ENCODING_SI)
1196276479Sdim  ENCODING("srcidx16",        ENCODING_SI)
1197276479Sdim  ENCODING("srcidx32",        ENCODING_SI)
1198276479Sdim  ENCODING("srcidx64",        ENCODING_SI)
1199276479Sdim  ENCODING("dstidx8",         ENCODING_DI)
1200276479Sdim  ENCODING("dstidx16",        ENCODING_DI)
1201276479Sdim  ENCODING("dstidx32",        ENCODING_DI)
1202276479Sdim  ENCODING("dstidx64",        ENCODING_DI)
1203201360Srdivacky  errs() << "Unhandled relocation encoding " << s << "\n";
1204201360Srdivacky  llvm_unreachable("Unhandled relocation encoding");
1205201360Srdivacky}
1206201360Srdivacky
1207276479SdimOperandEncoding
1208276479SdimRecognizableInstr::opcodeModifierEncodingFromString(const std::string &s,
1209276479Sdim                                                    uint8_t OpSize) {
1210201360Srdivacky  ENCODING("GR32",            ENCODING_Rv)
1211201360Srdivacky  ENCODING("GR64",            ENCODING_RO)
1212201360Srdivacky  ENCODING("GR16",            ENCODING_Rv)
1213201360Srdivacky  ENCODING("GR8",             ENCODING_RB)
1214226633Sdim  ENCODING("GR16_NOAX",       ENCODING_Rv)
1215226633Sdim  ENCODING("GR32_NOAX",       ENCODING_Rv)
1216226633Sdim  ENCODING("GR64_NOAX",       ENCODING_RO)
1217201360Srdivacky  errs() << "Unhandled opcode modifier encoding " << s << "\n";
1218201360Srdivacky  llvm_unreachable("Unhandled opcode modifier encoding");
1219201360Srdivacky}
1220201360Srdivacky#undef ENCODING
1221