1201360Srdivacky//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===//
2201360Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6201360Srdivacky//
7201360Srdivacky//===----------------------------------------------------------------------===//
8201360Srdivacky//
9201360Srdivacky// This file is part of the X86 Disassembler Emitter.
10201360Srdivacky// It contains the implementation of a single recognizable instruction.
11201360Srdivacky// Documentation for the disassembler emitter in general can be found in
12321369Sdim//  X86DisassemblerEmitter.h.
13201360Srdivacky//
14201360Srdivacky//===----------------------------------------------------------------------===//
15201360Srdivacky
16249423Sdim#include "X86RecognizableInstr.h"
17201360Srdivacky#include "X86DisassemblerShared.h"
18201360Srdivacky#include "X86ModRMFilters.h"
19201360Srdivacky#include "llvm/Support/ErrorHandling.h"
20201360Srdivacky#include <string>
21201360Srdivacky
22201360Srdivackyusing namespace llvm;
23201360Srdivackyusing namespace X86Disassembler;
24201360Srdivacky
25201360Srdivacky/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
26201360Srdivacky///   Useful for switch statements and the like.
27201360Srdivacky///
28201360Srdivacky/// @param init - A reference to the BitsInit to be decoded.
29201360Srdivacky/// @return     - The field, with the first bit in the BitsInit as the lowest
30201360Srdivacky///               order bit.
31201360Srdivackystatic uint8_t byteFromBitsInit(BitsInit &init) {
32201360Srdivacky  int width = init.getNumBits();
33201360Srdivacky
34201360Srdivacky  assert(width <= 8 && "Field is too large for uint8_t!");
35201360Srdivacky
36201360Srdivacky  int     index;
37201360Srdivacky  uint8_t mask = 0x01;
38201360Srdivacky
39201360Srdivacky  uint8_t ret = 0;
40201360Srdivacky
41201360Srdivacky  for (index = 0; index < width; index++) {
42341825Sdim    if (cast<BitInit>(init.getBit(index))->getValue())
43201360Srdivacky      ret |= mask;
44201360Srdivacky
45201360Srdivacky    mask <<= 1;
46201360Srdivacky  }
47201360Srdivacky
48201360Srdivacky  return ret;
49201360Srdivacky}
50201360Srdivacky
51201360Srdivacky/// byteFromRec - Extract a value at most 8 bits in with from a Record given the
52201360Srdivacky///   name of the field.
53201360Srdivacky///
54201360Srdivacky/// @param rec  - The record from which to extract the value.
55201360Srdivacky/// @param name - The name of the field in the record.
56201360Srdivacky/// @return     - The field, as translated by byteFromBitsInit().
57201360Srdivackystatic uint8_t byteFromRec(const Record* rec, const std::string &name) {
58201360Srdivacky  BitsInit* bits = rec->getValueAsBitsInit(name);
59201360Srdivacky  return byteFromBitsInit(*bits);
60201360Srdivacky}
61201360Srdivacky
62201360SrdivackyRecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
63201360Srdivacky                                     const CodeGenInstruction &insn,
64201360Srdivacky                                     InstrUID uid) {
65201360Srdivacky  UID = uid;
66201360Srdivacky
67201360Srdivacky  Rec = insn.TheDef;
68201360Srdivacky  Name = Rec->getName();
69201360Srdivacky  Spec = &tables.specForUID(UID);
70239462Sdim
71201360Srdivacky  if (!Rec->isSubClassOf("X86Inst")) {
72201360Srdivacky    ShouldBeEmitted = false;
73201360Srdivacky    return;
74201360Srdivacky  }
75239462Sdim
76276479Sdim  OpPrefix = byteFromRec(Rec, "OpPrefixBits");
77276479Sdim  OpMap    = byteFromRec(Rec, "OpMapBits");
78201360Srdivacky  Opcode   = byteFromRec(Rec, "Opcode");
79201360Srdivacky  Form     = byteFromRec(Rec, "FormBits");
80276479Sdim  Encoding = byteFromRec(Rec, "OpEncBits");
81239462Sdim
82341825Sdim  OpSize             = byteFromRec(Rec, "OpSizeBits");
83341825Sdim  AdSize             = byteFromRec(Rec, "AdSizeBits");
84341825Sdim  HasREX_WPrefix     = Rec->getValueAsBit("hasREX_WPrefix");
85341825Sdim  HasVEX_4V          = Rec->getValueAsBit("hasVEX_4V");
86353358Sdim  HasVEX_W           = Rec->getValueAsBit("HasVEX_W");
87353358Sdim  IgnoresVEX_W       = Rec->getValueAsBit("IgnoresVEX_W");
88341825Sdim  IgnoresVEX_L       = Rec->getValueAsBit("ignoresVEX_L");
89341825Sdim  HasEVEX_L2Prefix   = Rec->getValueAsBit("hasEVEX_L2");
90341825Sdim  HasEVEX_K          = Rec->getValueAsBit("hasEVEX_K");
91341825Sdim  HasEVEX_KZ         = Rec->getValueAsBit("hasEVEX_Z");
92341825Sdim  HasEVEX_B          = Rec->getValueAsBit("hasEVEX_B");
93341825Sdim  IsCodeGenOnly      = Rec->getValueAsBit("isCodeGenOnly");
94341825Sdim  ForceDisassemble   = Rec->getValueAsBit("ForceDisassemble");
95341825Sdim  CD8_Scale          = byteFromRec(Rec, "CD8_Scale");
96239462Sdim
97201360Srdivacky  Name      = Rec->getName();
98239462Sdim
99218893Sdim  Operands = &insn.Operands.OperandList;
100239462Sdim
101243830Sdim  HasVEX_LPrefix   = Rec->getValueAsBit("hasVEX_L");
102234353Sdim
103327952Sdim  EncodeRC = HasEVEX_B &&
104327952Sdim             (Form == X86Local::MRMDestReg || Form == X86Local::MRMSrcReg);
105327952Sdim
106224145Sdim  // Check for 64-bit inst which does not require REX
107226633Sdim  Is32Bit = false;
108224145Sdim  Is64Bit = false;
109224145Sdim  // FIXME: Is there some better way to check for In64BitMode?
110224145Sdim  std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates");
111224145Sdim  for (unsigned i = 0, e = Predicates.size(); i != e; ++i) {
112276479Sdim    if (Predicates[i]->getName().find("Not64Bit") != Name.npos ||
113353358Sdim        Predicates[i]->getName().find("In32Bit") != Name.npos) {
114226633Sdim      Is32Bit = true;
115226633Sdim      break;
116226633Sdim    }
117276479Sdim    if (Predicates[i]->getName().find("In64Bit") != Name.npos) {
118224145Sdim      Is64Bit = true;
119224145Sdim      break;
120224145Sdim    }
121224145Sdim  }
122224145Sdim
123276479Sdim  if (Form == X86Local::Pseudo || (IsCodeGenOnly && !ForceDisassemble)) {
124276479Sdim    ShouldBeEmitted = false;
125276479Sdim    return;
126276479Sdim  }
127276479Sdim
128276479Sdim  // Special case since there is no attribute class for 64-bit and VEX
129276479Sdim  if (Name == "VMASKMOVDQU64") {
130276479Sdim    ShouldBeEmitted = false;
131276479Sdim    return;
132276479Sdim  }
133276479Sdim
134201360Srdivacky  ShouldBeEmitted  = true;
135201360Srdivacky}
136239462Sdim
137201360Srdivackyvoid RecognizableInstr::processInstr(DisassemblerTables &tables,
138239462Sdim                                     const CodeGenInstruction &insn,
139239462Sdim                                     InstrUID uid)
140201360Srdivacky{
141208599Srdivacky  // Ignore "asm parser only" instructions.
142208599Srdivacky  if (insn.TheDef->getValueAsBit("isAsmParserOnly"))
143208599Srdivacky    return;
144239462Sdim
145201360Srdivacky  RecognizableInstr recogInstr(tables, insn, uid);
146239462Sdim
147276479Sdim  if (recogInstr.shouldBeEmitted()) {
148276479Sdim    recogInstr.emitInstructionSpecifier();
149201360Srdivacky    recogInstr.emitDecodePath(tables);
150276479Sdim  }
151201360Srdivacky}
152201360Srdivacky
153261991Sdim#define EVEX_KB(n) (HasEVEX_KZ && HasEVEX_B ? n##_KZ_B : \
154261991Sdim                    (HasEVEX_K && HasEVEX_B ? n##_K_B : \
155261991Sdim                    (HasEVEX_KZ ? n##_KZ : \
156261991Sdim                    (HasEVEX_K? n##_K : (HasEVEX_B ? n##_B : n)))))
157261991Sdim
158201360SrdivackyInstructionContext RecognizableInstr::insnContext() const {
159201360Srdivacky  InstructionContext insnContext;
160201360Srdivacky
161276479Sdim  if (Encoding == X86Local::EVEX) {
162261991Sdim    if (HasVEX_LPrefix && HasEVEX_L2Prefix) {
163261991Sdim      errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n";
164261991Sdim      llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
165261991Sdim    }
166261991Sdim    // VEX_L & VEX_W
167353358Sdim    if (!EncodeRC && HasVEX_LPrefix && HasVEX_W) {
168276479Sdim      if (OpPrefix == X86Local::PD)
169261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
170276479Sdim      else if (OpPrefix == X86Local::XS)
171261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_W_XS);
172276479Sdim      else if (OpPrefix == X86Local::XD)
173261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_W_XD);
174276479Sdim      else if (OpPrefix == X86Local::PS)
175261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_W);
176276479Sdim      else {
177276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
178276479Sdim        llvm_unreachable("Invalid prefix");
179276479Sdim      }
180327952Sdim    } else if (!EncodeRC && HasVEX_LPrefix) {
181261991Sdim      // VEX_L
182276479Sdim      if (OpPrefix == X86Local::PD)
183261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_OPSIZE);
184276479Sdim      else if (OpPrefix == X86Local::XS)
185261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_XS);
186276479Sdim      else if (OpPrefix == X86Local::XD)
187261991Sdim        insnContext = EVEX_KB(IC_EVEX_L_XD);
188276479Sdim      else if (OpPrefix == X86Local::PS)
189261991Sdim        insnContext = EVEX_KB(IC_EVEX_L);
190276479Sdim      else {
191276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
192276479Sdim        llvm_unreachable("Invalid prefix");
193276479Sdim      }
194353358Sdim    } else if (!EncodeRC && HasEVEX_L2Prefix && HasVEX_W) {
195261991Sdim      // EVEX_L2 & VEX_W
196276479Sdim      if (OpPrefix == X86Local::PD)
197261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
198276479Sdim      else if (OpPrefix == X86Local::XS)
199261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_W_XS);
200276479Sdim      else if (OpPrefix == X86Local::XD)
201261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_W_XD);
202276479Sdim      else if (OpPrefix == X86Local::PS)
203261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_W);
204276479Sdim      else {
205276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
206276479Sdim        llvm_unreachable("Invalid prefix");
207276479Sdim      }
208327952Sdim    } else if (!EncodeRC && HasEVEX_L2Prefix) {
209261991Sdim      // EVEX_L2
210276479Sdim      if (OpPrefix == X86Local::PD)
211261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE);
212276479Sdim      else if (OpPrefix == X86Local::XD)
213261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_XD);
214276479Sdim      else if (OpPrefix == X86Local::XS)
215261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2_XS);
216276479Sdim      else if (OpPrefix == X86Local::PS)
217261991Sdim        insnContext = EVEX_KB(IC_EVEX_L2);
218276479Sdim      else {
219276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
220276479Sdim        llvm_unreachable("Invalid prefix");
221276479Sdim      }
222261991Sdim    }
223353358Sdim    else if (HasVEX_W) {
224261991Sdim      // VEX_W
225276479Sdim      if (OpPrefix == X86Local::PD)
226261991Sdim        insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
227276479Sdim      else if (OpPrefix == X86Local::XS)
228261991Sdim        insnContext = EVEX_KB(IC_EVEX_W_XS);
229276479Sdim      else if (OpPrefix == X86Local::XD)
230261991Sdim        insnContext = EVEX_KB(IC_EVEX_W_XD);
231276479Sdim      else if (OpPrefix == X86Local::PS)
232261991Sdim        insnContext = EVEX_KB(IC_EVEX_W);
233276479Sdim      else {
234276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
235276479Sdim        llvm_unreachable("Invalid prefix");
236276479Sdim      }
237261991Sdim    }
238261991Sdim    // No L, no W
239276479Sdim    else if (OpPrefix == X86Local::PD)
240261991Sdim      insnContext = EVEX_KB(IC_EVEX_OPSIZE);
241276479Sdim    else if (OpPrefix == X86Local::XD)
242261991Sdim      insnContext = EVEX_KB(IC_EVEX_XD);
243276479Sdim    else if (OpPrefix == X86Local::XS)
244261991Sdim      insnContext = EVEX_KB(IC_EVEX_XS);
245341825Sdim    else if (OpPrefix == X86Local::PS)
246261991Sdim      insnContext = EVEX_KB(IC_EVEX);
247341825Sdim    else {
248341825Sdim      errs() << "Instruction does not use a prefix: " << Name << "\n";
249341825Sdim      llvm_unreachable("Invalid prefix");
250341825Sdim    }
251261991Sdim    /// eof EVEX
252276479Sdim  } else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {
253353358Sdim    if (HasVEX_LPrefix && HasVEX_W) {
254276479Sdim      if (OpPrefix == X86Local::PD)
255234353Sdim        insnContext = IC_VEX_L_W_OPSIZE;
256276479Sdim      else if (OpPrefix == X86Local::XS)
257261991Sdim        insnContext = IC_VEX_L_W_XS;
258276479Sdim      else if (OpPrefix == X86Local::XD)
259261991Sdim        insnContext = IC_VEX_L_W_XD;
260276479Sdim      else if (OpPrefix == X86Local::PS)
261261991Sdim        insnContext = IC_VEX_L_W;
262276479Sdim      else {
263276479Sdim        errs() << "Instruction does not use a prefix: " << Name << "\n";
264276479Sdim        llvm_unreachable("Invalid prefix");
265276479Sdim      }
266276479Sdim    } else if (OpPrefix == X86Local::PD && HasVEX_LPrefix)
267221345Sdim      insnContext = IC_VEX_L_OPSIZE;
268353358Sdim    else if (OpPrefix == X86Local::PD && HasVEX_W)
269221345Sdim      insnContext = IC_VEX_W_OPSIZE;
270276479Sdim    else if (OpPrefix == X86Local::PD)
271221345Sdim      insnContext = IC_VEX_OPSIZE;
272276479Sdim    else if (HasVEX_LPrefix && OpPrefix == X86Local::XS)
273221345Sdim      insnContext = IC_VEX_L_XS;
274276479Sdim    else if (HasVEX_LPrefix && OpPrefix == X86Local::XD)
275221345Sdim      insnContext = IC_VEX_L_XD;
276353358Sdim    else if (HasVEX_W && OpPrefix == X86Local::XS)
277221345Sdim      insnContext = IC_VEX_W_XS;
278353358Sdim    else if (HasVEX_W && OpPrefix == X86Local::XD)
279221345Sdim      insnContext = IC_VEX_W_XD;
280353358Sdim    else if (HasVEX_W && OpPrefix == X86Local::PS)
281221345Sdim      insnContext = IC_VEX_W;
282276479Sdim    else if (HasVEX_LPrefix && OpPrefix == X86Local::PS)
283221345Sdim      insnContext = IC_VEX_L;
284276479Sdim    else if (OpPrefix == X86Local::XD)
285221345Sdim      insnContext = IC_VEX_XD;
286276479Sdim    else if (OpPrefix == X86Local::XS)
287221345Sdim      insnContext = IC_VEX_XS;
288276479Sdim    else if (OpPrefix == X86Local::PS)
289221345Sdim      insnContext = IC_VEX;
290276479Sdim    else {
291276479Sdim      errs() << "Instruction does not use a prefix: " << Name << "\n";
292276479Sdim      llvm_unreachable("Invalid prefix");
293276479Sdim    }
294280031Sdim  } else if (Is64Bit || HasREX_WPrefix || AdSize == X86Local::AdSize64) {
295276479Sdim    if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD))
296201360Srdivacky      insnContext = IC_64BIT_REXW_OPSIZE;
297280031Sdim    else if (HasREX_WPrefix && AdSize == X86Local::AdSize32)
298280031Sdim      insnContext = IC_64BIT_REXW_ADSIZE;
299276479Sdim    else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
300234353Sdim      insnContext = IC_64BIT_XD_OPSIZE;
301276479Sdim    else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
302226633Sdim      insnContext = IC_64BIT_XS_OPSIZE;
303341825Sdim    else if (AdSize == X86Local::AdSize32 && OpPrefix == X86Local::PD)
304341825Sdim      insnContext = IC_64BIT_OPSIZE_ADSIZE;
305280031Sdim    else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize32)
306280031Sdim      insnContext = IC_64BIT_OPSIZE_ADSIZE;
307276479Sdim    else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
308201360Srdivacky      insnContext = IC_64BIT_OPSIZE;
309280031Sdim    else if (AdSize == X86Local::AdSize32)
310234353Sdim      insnContext = IC_64BIT_ADSIZE;
311276479Sdim    else if (HasREX_WPrefix && OpPrefix == X86Local::XS)
312201360Srdivacky      insnContext = IC_64BIT_REXW_XS;
313276479Sdim    else if (HasREX_WPrefix && OpPrefix == X86Local::XD)
314201360Srdivacky      insnContext = IC_64BIT_REXW_XD;
315276479Sdim    else if (OpPrefix == X86Local::XD)
316201360Srdivacky      insnContext = IC_64BIT_XD;
317276479Sdim    else if (OpPrefix == X86Local::XS)
318201360Srdivacky      insnContext = IC_64BIT_XS;
319201360Srdivacky    else if (HasREX_WPrefix)
320201360Srdivacky      insnContext = IC_64BIT_REXW;
321201360Srdivacky    else
322201360Srdivacky      insnContext = IC_64BIT;
323201360Srdivacky  } else {
324276479Sdim    if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
325226633Sdim      insnContext = IC_XD_OPSIZE;
326276479Sdim    else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
327226633Sdim      insnContext = IC_XS_OPSIZE;
328341825Sdim    else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XD)
329341825Sdim      insnContext = IC_XD_ADSIZE;
330341825Sdim    else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XS)
331341825Sdim      insnContext = IC_XS_ADSIZE;
332341825Sdim    else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::PD)
333341825Sdim      insnContext = IC_OPSIZE_ADSIZE;
334280031Sdim    else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize16)
335280031Sdim      insnContext = IC_OPSIZE_ADSIZE;
336276479Sdim    else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
337201360Srdivacky      insnContext = IC_OPSIZE;
338280031Sdim    else if (AdSize == X86Local::AdSize16)
339234353Sdim      insnContext = IC_ADSIZE;
340276479Sdim    else if (OpPrefix == X86Local::XD)
341201360Srdivacky      insnContext = IC_XD;
342276479Sdim    else if (OpPrefix == X86Local::XS)
343201360Srdivacky      insnContext = IC_XS;
344201360Srdivacky    else
345201360Srdivacky      insnContext = IC;
346201360Srdivacky  }
347201360Srdivacky
348201360Srdivacky  return insnContext;
349201360Srdivacky}
350239462Sdim
351276479Sdimvoid RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) {
352276479Sdim  // The scaling factor for AVX512 compressed displacement encoding is an
353276479Sdim  // instruction attribute.  Adjust the ModRM encoding type to include the
354276479Sdim  // scale for compressed displacement.
355321369Sdim  if ((encoding != ENCODING_RM && encoding != ENCODING_VSIB) ||CD8_Scale == 0)
356276479Sdim    return;
357276479Sdim  encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale));
358321369Sdim  assert(((encoding >= ENCODING_RM && encoding <= ENCODING_RM_CD64) ||
359321369Sdim          (encoding >= ENCODING_VSIB && encoding <= ENCODING_VSIB_CD64)) &&
360321369Sdim         "Invalid CDisp scaling");
361201360Srdivacky}
362221345Sdim
363239462Sdimvoid RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
364239462Sdim                                      unsigned &physicalOperandIndex,
365309124Sdim                                      unsigned numPhysicalOperands,
366239462Sdim                                      const unsigned *operandMapping,
367239462Sdim                                      OperandEncoding (*encodingFromString)
368239462Sdim                                        (const std::string&,
369276479Sdim                                         uint8_t OpSize)) {
370201360Srdivacky  if (optional) {
371201360Srdivacky    if (physicalOperandIndex >= numPhysicalOperands)
372201360Srdivacky      return;
373201360Srdivacky  } else {
374201360Srdivacky    assert(physicalOperandIndex < numPhysicalOperands);
375201360Srdivacky  }
376239462Sdim
377201360Srdivacky  while (operandMapping[operandIndex] != operandIndex) {
378201360Srdivacky    Spec->operands[operandIndex].encoding = ENCODING_DUP;
379201360Srdivacky    Spec->operands[operandIndex].type =
380201360Srdivacky      (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);
381201360Srdivacky    ++operandIndex;
382201360Srdivacky  }
383239462Sdim
384321369Sdim  StringRef typeName = (*Operands)[operandIndex].Rec->getName();
385221345Sdim
386276479Sdim  OperandEncoding encoding = encodingFromString(typeName, OpSize);
387276479Sdim  // Adjust the encoding type for an operand based on the instruction.
388276479Sdim  adjustOperandEncoding(encoding);
389276479Sdim  Spec->operands[operandIndex].encoding = encoding;
390239462Sdim  Spec->operands[operandIndex].type = typeFromString(typeName,
391276479Sdim                                                     HasREX_WPrefix, OpSize);
392239462Sdim
393201360Srdivacky  ++operandIndex;
394201360Srdivacky  ++physicalOperandIndex;
395201360Srdivacky}
396201360Srdivacky
397276479Sdimvoid RecognizableInstr::emitInstructionSpecifier() {
398201360Srdivacky  Spec->name       = Name;
399239462Sdim
400201360Srdivacky  Spec->insnContext = insnContext();
401239462Sdim
402218893Sdim  const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
403239462Sdim
404201360Srdivacky  unsigned numOperands = OperandList.size();
405201360Srdivacky  unsigned numPhysicalOperands = 0;
406239462Sdim
407201360Srdivacky  // operandMapping maps from operands in OperandList to their originals.
408201360Srdivacky  // If operandMapping[i] != i, then the entry is a duplicate.
409201360Srdivacky  unsigned operandMapping[X86_MAX_OPERANDS];
410234353Sdim  assert(numOperands <= X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough");
411239462Sdim
412239462Sdim  for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
413288943Sdim    if (!OperandList[operandIndex].Constraints.empty()) {
414218893Sdim      const CGIOperandList::ConstraintInfo &Constraint =
415203954Srdivacky        OperandList[operandIndex].Constraints[0];
416203954Srdivacky      if (Constraint.isTied()) {
417239462Sdim        operandMapping[operandIndex] = operandIndex;
418239462Sdim        operandMapping[Constraint.getTiedOperand()] = operandIndex;
419201360Srdivacky      } else {
420201360Srdivacky        ++numPhysicalOperands;
421201360Srdivacky        operandMapping[operandIndex] = operandIndex;
422201360Srdivacky      }
423201360Srdivacky    } else {
424201360Srdivacky      ++numPhysicalOperands;
425201360Srdivacky      operandMapping[operandIndex] = operandIndex;
426201360Srdivacky    }
427201360Srdivacky  }
428201360Srdivacky
429201360Srdivacky#define HANDLE_OPERAND(class)               \
430201360Srdivacky  handleOperand(false,                      \
431201360Srdivacky                operandIndex,               \
432201360Srdivacky                physicalOperandIndex,       \
433201360Srdivacky                numPhysicalOperands,        \
434201360Srdivacky                operandMapping,             \
435201360Srdivacky                class##EncodingFromString);
436239462Sdim
437201360Srdivacky#define HANDLE_OPTIONAL(class)              \
438201360Srdivacky  handleOperand(true,                       \
439201360Srdivacky                operandIndex,               \
440201360Srdivacky                physicalOperandIndex,       \
441201360Srdivacky                numPhysicalOperands,        \
442201360Srdivacky                operandMapping,             \
443201360Srdivacky                class##EncodingFromString);
444239462Sdim
445201360Srdivacky  // operandIndex should always be < numOperands
446239462Sdim  unsigned operandIndex = 0;
447201360Srdivacky  // physicalOperandIndex should always be < numPhysicalOperands
448201360Srdivacky  unsigned physicalOperandIndex = 0;
449239462Sdim
450309124Sdim#ifndef NDEBUG
451280031Sdim  // Given the set of prefix bits, how many additional operands does the
452280031Sdim  // instruction have?
453280031Sdim  unsigned additionalOperands = 0;
454314564Sdim  if (HasVEX_4V)
455280031Sdim    ++additionalOperands;
456280031Sdim  if (HasEVEX_K)
457280031Sdim    ++additionalOperands;
458309124Sdim#endif
459280031Sdim
460201360Srdivacky  switch (Form) {
461276479Sdim  default: llvm_unreachable("Unhandled form");
462276479Sdim  case X86Local::RawFrmSrc:
463276479Sdim    HANDLE_OPERAND(relocation);
464276479Sdim    return;
465276479Sdim  case X86Local::RawFrmDst:
466276479Sdim    HANDLE_OPERAND(relocation);
467276479Sdim    return;
468276479Sdim  case X86Local::RawFrmDstSrc:
469276479Sdim    HANDLE_OPERAND(relocation);
470276479Sdim    HANDLE_OPERAND(relocation);
471276479Sdim    return;
472201360Srdivacky  case X86Local::RawFrm:
473201360Srdivacky    // Operand 1 (optional) is an address or immediate.
474309124Sdim    assert(numPhysicalOperands <= 1 &&
475201360Srdivacky           "Unexpected number of operands for RawFrm");
476201360Srdivacky    HANDLE_OPTIONAL(relocation)
477201360Srdivacky    break;
478276479Sdim  case X86Local::RawFrmMemOffs:
479276479Sdim    // Operand 1 is an address.
480276479Sdim    HANDLE_OPERAND(relocation);
481276479Sdim    break;
482201360Srdivacky  case X86Local::AddRegFrm:
483201360Srdivacky    // Operand 1 is added to the opcode.
484201360Srdivacky    // Operand 2 (optional) is an address.
485201360Srdivacky    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
486201360Srdivacky           "Unexpected number of operands for AddRegFrm");
487201360Srdivacky    HANDLE_OPERAND(opcodeModifier)
488201360Srdivacky    HANDLE_OPTIONAL(relocation)
489201360Srdivacky    break;
490353358Sdim  case X86Local::AddCCFrm:
491353358Sdim    // Operand 1 (optional) is an address or immediate.
492353358Sdim    assert(numPhysicalOperands == 2 &&
493353358Sdim           "Unexpected number of operands for AddCCFrm");
494353358Sdim    HANDLE_OPERAND(relocation)
495353358Sdim    HANDLE_OPERAND(opcodeModifier)
496353358Sdim    break;
497201360Srdivacky  case X86Local::MRMDestReg:
498201360Srdivacky    // Operand 1 is a register operand in the R/M field.
499280031Sdim    // - In AVX512 there may be a mask operand here -
500201360Srdivacky    // Operand 2 is a register operand in the Reg/Opcode field.
501226633Sdim    // - In AVX, there is a register operand in the VEX.vvvv field here -
502201360Srdivacky    // Operand 3 (optional) is an immediate.
503280031Sdim    assert(numPhysicalOperands >= 2 + additionalOperands &&
504280031Sdim           numPhysicalOperands <= 3 + additionalOperands &&
505280031Sdim           "Unexpected number of operands for MRMDestRegFrm");
506239462Sdim
507201360Srdivacky    HANDLE_OPERAND(rmRegister)
508280031Sdim    if (HasEVEX_K)
509280031Sdim      HANDLE_OPERAND(writemaskRegister)
510226633Sdim
511276479Sdim    if (HasVEX_4V)
512226633Sdim      // FIXME: In AVX, the register below becomes the one encoded
513226633Sdim      // in ModRMVEX and the one above the one in the VEX.VVVV field
514226633Sdim      HANDLE_OPERAND(vvvvRegister)
515239462Sdim
516201360Srdivacky    HANDLE_OPERAND(roRegister)
517201360Srdivacky    HANDLE_OPTIONAL(immediate)
518201360Srdivacky    break;
519201360Srdivacky  case X86Local::MRMDestMem:
520201360Srdivacky    // Operand 1 is a memory operand (possibly SIB-extended)
521201360Srdivacky    // Operand 2 is a register operand in the Reg/Opcode field.
522226633Sdim    // - In AVX, there is a register operand in the VEX.vvvv field here -
523201360Srdivacky    // Operand 3 (optional) is an immediate.
524280031Sdim    assert(numPhysicalOperands >= 2 + additionalOperands &&
525280031Sdim           numPhysicalOperands <= 3 + additionalOperands &&
526280031Sdim           "Unexpected number of operands for MRMDestMemFrm with VEX_4V");
527280031Sdim
528201360Srdivacky    HANDLE_OPERAND(memory)
529226633Sdim
530261991Sdim    if (HasEVEX_K)
531261991Sdim      HANDLE_OPERAND(writemaskRegister)
532261991Sdim
533276479Sdim    if (HasVEX_4V)
534226633Sdim      // FIXME: In AVX, the register below becomes the one encoded
535226633Sdim      // in ModRMVEX and the one above the one in the VEX.VVVV field
536226633Sdim      HANDLE_OPERAND(vvvvRegister)
537239462Sdim
538201360Srdivacky    HANDLE_OPERAND(roRegister)
539201360Srdivacky    HANDLE_OPTIONAL(immediate)
540201360Srdivacky    break;
541201360Srdivacky  case X86Local::MRMSrcReg:
542201360Srdivacky    // Operand 1 is a register operand in the Reg/Opcode field.
543201360Srdivacky    // Operand 2 is a register operand in the R/M field.
544221345Sdim    // - In AVX, there is a register operand in the VEX.vvvv field here -
545201360Srdivacky    // Operand 3 (optional) is an immediate.
546239462Sdim    // Operand 4 (optional) is an immediate.
547210299Sed
548280031Sdim    assert(numPhysicalOperands >= 2 + additionalOperands &&
549280031Sdim           numPhysicalOperands <= 4 + additionalOperands &&
550280031Sdim           "Unexpected number of operands for MRMSrcRegFrm");
551239462Sdim
552221345Sdim    HANDLE_OPERAND(roRegister)
553234353Sdim
554261991Sdim    if (HasEVEX_K)
555261991Sdim      HANDLE_OPERAND(writemaskRegister)
556261991Sdim
557276479Sdim    if (HasVEX_4V)
558210299Sed      // FIXME: In AVX, the register below becomes the one encoded
559210299Sed      // in ModRMVEX and the one above the one in the VEX.VVVV field
560221345Sdim      HANDLE_OPERAND(vvvvRegister)
561234353Sdim
562221345Sdim    HANDLE_OPERAND(rmRegister)
563314564Sdim    HANDLE_OPTIONAL(immediate)
564234353Sdim    HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
565201360Srdivacky    break;
566314564Sdim  case X86Local::MRMSrcReg4VOp3:
567314564Sdim    assert(numPhysicalOperands == 3 &&
568321369Sdim           "Unexpected number of operands for MRMSrcReg4VOp3Frm");
569314564Sdim    HANDLE_OPERAND(roRegister)
570314564Sdim    HANDLE_OPERAND(rmRegister)
571314564Sdim    HANDLE_OPERAND(vvvvRegister)
572314564Sdim    break;
573314564Sdim  case X86Local::MRMSrcRegOp4:
574314564Sdim    assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 &&
575314564Sdim           "Unexpected number of operands for MRMSrcRegOp4Frm");
576314564Sdim    HANDLE_OPERAND(roRegister)
577314564Sdim    HANDLE_OPERAND(vvvvRegister)
578314564Sdim    HANDLE_OPERAND(immediate) // Register in imm[7:4]
579314564Sdim    HANDLE_OPERAND(rmRegister)
580314564Sdim    HANDLE_OPTIONAL(immediate)
581314564Sdim    break;
582353358Sdim  case X86Local::MRMSrcRegCC:
583353358Sdim    assert(numPhysicalOperands == 3 &&
584353358Sdim           "Unexpected number of operands for MRMSrcRegCC");
585353358Sdim    HANDLE_OPERAND(roRegister)
586353358Sdim    HANDLE_OPERAND(rmRegister)
587353358Sdim    HANDLE_OPERAND(opcodeModifier)
588353358Sdim    break;
589201360Srdivacky  case X86Local::MRMSrcMem:
590201360Srdivacky    // Operand 1 is a register operand in the Reg/Opcode field.
591201360Srdivacky    // Operand 2 is a memory operand (possibly SIB-extended)
592221345Sdim    // - In AVX, there is a register operand in the VEX.vvvv field here -
593201360Srdivacky    // Operand 3 (optional) is an immediate.
594234353Sdim
595280031Sdim    assert(numPhysicalOperands >= 2 + additionalOperands &&
596280031Sdim           numPhysicalOperands <= 4 + additionalOperands &&
597280031Sdim           "Unexpected number of operands for MRMSrcMemFrm");
598239462Sdim
599201360Srdivacky    HANDLE_OPERAND(roRegister)
600210299Sed
601261991Sdim    if (HasEVEX_K)
602261991Sdim      HANDLE_OPERAND(writemaskRegister)
603261991Sdim
604276479Sdim    if (HasVEX_4V)
605210299Sed      // FIXME: In AVX, the register below becomes the one encoded
606210299Sed      // in ModRMVEX and the one above the one in the VEX.VVVV field
607221345Sdim      HANDLE_OPERAND(vvvvRegister)
608210299Sed
609201360Srdivacky    HANDLE_OPERAND(memory)
610314564Sdim    HANDLE_OPTIONAL(immediate)
611234353Sdim    HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
612201360Srdivacky    break;
613314564Sdim  case X86Local::MRMSrcMem4VOp3:
614314564Sdim    assert(numPhysicalOperands == 3 &&
615321369Sdim           "Unexpected number of operands for MRMSrcMem4VOp3Frm");
616314564Sdim    HANDLE_OPERAND(roRegister)
617314564Sdim    HANDLE_OPERAND(memory)
618314564Sdim    HANDLE_OPERAND(vvvvRegister)
619314564Sdim    break;
620314564Sdim  case X86Local::MRMSrcMemOp4:
621314564Sdim    assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 &&
622314564Sdim           "Unexpected number of operands for MRMSrcMemOp4Frm");
623314564Sdim    HANDLE_OPERAND(roRegister)
624314564Sdim    HANDLE_OPERAND(vvvvRegister)
625314564Sdim    HANDLE_OPERAND(immediate) // Register in imm[7:4]
626314564Sdim    HANDLE_OPERAND(memory)
627314564Sdim    HANDLE_OPTIONAL(immediate)
628314564Sdim    break;
629353358Sdim  case X86Local::MRMSrcMemCC:
630353358Sdim    assert(numPhysicalOperands == 3 &&
631353358Sdim           "Unexpected number of operands for MRMSrcMemCC");
632353358Sdim    HANDLE_OPERAND(roRegister)
633353358Sdim    HANDLE_OPERAND(memory)
634353358Sdim    HANDLE_OPERAND(opcodeModifier)
635353358Sdim    break;
636353358Sdim  case X86Local::MRMXrCC:
637353358Sdim    assert(numPhysicalOperands == 2 &&
638353358Sdim           "Unexpected number of operands for MRMXrCC");
639353358Sdim    HANDLE_OPERAND(rmRegister)
640353358Sdim    HANDLE_OPERAND(opcodeModifier)
641353358Sdim    break;
642276479Sdim  case X86Local::MRMXr:
643201360Srdivacky  case X86Local::MRM0r:
644201360Srdivacky  case X86Local::MRM1r:
645201360Srdivacky  case X86Local::MRM2r:
646201360Srdivacky  case X86Local::MRM3r:
647201360Srdivacky  case X86Local::MRM4r:
648201360Srdivacky  case X86Local::MRM5r:
649201360Srdivacky  case X86Local::MRM6r:
650201360Srdivacky  case X86Local::MRM7r:
651280031Sdim    // Operand 1 is a register operand in the R/M field.
652280031Sdim    // Operand 2 (optional) is an immediate or relocation.
653280031Sdim    // Operand 3 (optional) is an immediate.
654280031Sdim    assert(numPhysicalOperands >= 0 + additionalOperands &&
655280031Sdim           numPhysicalOperands <= 3 + additionalOperands &&
656280031Sdim           "Unexpected number of operands for MRMnr");
657280031Sdim
658276479Sdim    if (HasVEX_4V)
659234353Sdim      HANDLE_OPERAND(vvvvRegister)
660261991Sdim
661261991Sdim    if (HasEVEX_K)
662261991Sdim      HANDLE_OPERAND(writemaskRegister)
663201360Srdivacky    HANDLE_OPTIONAL(rmRegister)
664201360Srdivacky    HANDLE_OPTIONAL(relocation)
665239462Sdim    HANDLE_OPTIONAL(immediate)
666201360Srdivacky    break;
667353358Sdim  case X86Local::MRMXmCC:
668353358Sdim    assert(numPhysicalOperands == 2 &&
669353358Sdim           "Unexpected number of operands for MRMXm");
670353358Sdim    HANDLE_OPERAND(memory)
671353358Sdim    HANDLE_OPERAND(opcodeModifier)
672353358Sdim    break;
673276479Sdim  case X86Local::MRMXm:
674201360Srdivacky  case X86Local::MRM0m:
675201360Srdivacky  case X86Local::MRM1m:
676201360Srdivacky  case X86Local::MRM2m:
677201360Srdivacky  case X86Local::MRM3m:
678201360Srdivacky  case X86Local::MRM4m:
679201360Srdivacky  case X86Local::MRM5m:
680201360Srdivacky  case X86Local::MRM6m:
681201360Srdivacky  case X86Local::MRM7m:
682280031Sdim    // Operand 1 is a memory operand (possibly SIB-extended)
683280031Sdim    // Operand 2 (optional) is an immediate or relocation.
684280031Sdim    assert(numPhysicalOperands >= 1 + additionalOperands &&
685280031Sdim           numPhysicalOperands <= 2 + additionalOperands &&
686280031Sdim           "Unexpected number of operands for MRMnm");
687280031Sdim
688276479Sdim    if (HasVEX_4V)
689234353Sdim      HANDLE_OPERAND(vvvvRegister)
690261991Sdim    if (HasEVEX_K)
691261991Sdim      HANDLE_OPERAND(writemaskRegister)
692201360Srdivacky    HANDLE_OPERAND(memory)
693201360Srdivacky    HANDLE_OPTIONAL(relocation)
694201360Srdivacky    break;
695218893Sdim  case X86Local::RawFrmImm8:
696218893Sdim    // operand 1 is a 16-bit immediate
697218893Sdim    // operand 2 is an 8-bit immediate
698218893Sdim    assert(numPhysicalOperands == 2 &&
699218893Sdim           "Unexpected number of operands for X86Local::RawFrmImm8");
700218893Sdim    HANDLE_OPERAND(immediate)
701218893Sdim    HANDLE_OPERAND(immediate)
702218893Sdim    break;
703218893Sdim  case X86Local::RawFrmImm16:
704218893Sdim    // operand 1 is a 16-bit immediate
705218893Sdim    // operand 2 is a 16-bit immediate
706218893Sdim    HANDLE_OPERAND(immediate)
707218893Sdim    HANDLE_OPERAND(immediate)
708218893Sdim    break;
709341825Sdim#define MAP(from, to) case X86Local::MRM_##from:
710341825Sdim  X86_INSTR_MRM_MAPPING
711341825Sdim#undef MAP
712341825Sdim    HANDLE_OPTIONAL(relocation)
713249423Sdim    break;
714201360Srdivacky  }
715239462Sdim
716341825Sdim#undef HANDLE_OPERAND
717341825Sdim#undef HANDLE_OPTIONAL
718201360Srdivacky}
719201360Srdivacky
720201360Srdivackyvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
721201360Srdivacky  // Special cases where the LLVM tables are not complete
722201360Srdivacky
723203954Srdivacky#define MAP(from, to)                     \
724288943Sdim  case X86Local::MRM_##from:
725201360Srdivacky
726327952Sdim  llvm::Optional<OpcodeType> opcodeType;
727276479Sdim  switch (OpMap) {
728276479Sdim  default: llvm_unreachable("Invalid map!");
729341825Sdim  case X86Local::OB:        opcodeType = ONEBYTE;       break;
730341825Sdim  case X86Local::TB:        opcodeType = TWOBYTE;       break;
731341825Sdim  case X86Local::T8:        opcodeType = THREEBYTE_38;  break;
732341825Sdim  case X86Local::TA:        opcodeType = THREEBYTE_3A;  break;
733341825Sdim  case X86Local::XOP8:      opcodeType = XOP8_MAP;      break;
734341825Sdim  case X86Local::XOP9:      opcodeType = XOP9_MAP;      break;
735341825Sdim  case X86Local::XOPA:      opcodeType = XOPA_MAP;      break;
736341825Sdim  case X86Local::ThreeDNow: opcodeType = THREEDNOW_MAP; break;
737341825Sdim  }
738276479Sdim
739341825Sdim  std::unique_ptr<ModRMFilter> filter;
740341825Sdim  switch (Form) {
741341825Sdim  default: llvm_unreachable("Invalid form!");
742341825Sdim  case X86Local::Pseudo: llvm_unreachable("Pseudo should not be emitted!");
743341825Sdim  case X86Local::RawFrm:
744341825Sdim  case X86Local::AddRegFrm:
745341825Sdim  case X86Local::RawFrmMemOffs:
746341825Sdim  case X86Local::RawFrmSrc:
747341825Sdim  case X86Local::RawFrmDst:
748341825Sdim  case X86Local::RawFrmDstSrc:
749341825Sdim  case X86Local::RawFrmImm8:
750341825Sdim  case X86Local::RawFrmImm16:
751353358Sdim  case X86Local::AddCCFrm:
752360784Sdim    filter = std::make_unique<DumbFilter>();
753276479Sdim    break;
754341825Sdim  case X86Local::MRMDestReg:
755341825Sdim  case X86Local::MRMSrcReg:
756341825Sdim  case X86Local::MRMSrcReg4VOp3:
757341825Sdim  case X86Local::MRMSrcRegOp4:
758353358Sdim  case X86Local::MRMSrcRegCC:
759353358Sdim  case X86Local::MRMXrCC:
760341825Sdim  case X86Local::MRMXr:
761360784Sdim    filter = std::make_unique<ModFilter>(true);
762341825Sdim    break;
763341825Sdim  case X86Local::MRMDestMem:
764341825Sdim  case X86Local::MRMSrcMem:
765341825Sdim  case X86Local::MRMSrcMem4VOp3:
766341825Sdim  case X86Local::MRMSrcMemOp4:
767353358Sdim  case X86Local::MRMSrcMemCC:
768353358Sdim  case X86Local::MRMXmCC:
769341825Sdim  case X86Local::MRMXm:
770360784Sdim    filter = std::make_unique<ModFilter>(false);
771341825Sdim    break;
772341825Sdim  case X86Local::MRM0r: case X86Local::MRM1r:
773341825Sdim  case X86Local::MRM2r: case X86Local::MRM3r:
774341825Sdim  case X86Local::MRM4r: case X86Local::MRM5r:
775341825Sdim  case X86Local::MRM6r: case X86Local::MRM7r:
776360784Sdim    filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0r);
777341825Sdim    break;
778341825Sdim  case X86Local::MRM0m: case X86Local::MRM1m:
779341825Sdim  case X86Local::MRM2m: case X86Local::MRM3m:
780341825Sdim  case X86Local::MRM4m: case X86Local::MRM5m:
781341825Sdim  case X86Local::MRM6m: case X86Local::MRM7m:
782360784Sdim    filter = std::make_unique<ExtendedFilter>(false, Form - X86Local::MRM0m);
783341825Sdim    break;
784341825Sdim  X86_INSTR_MRM_MAPPING
785360784Sdim    filter = std::make_unique<ExactFilter>(0xC0 + Form - X86Local::MRM_C0);
786341825Sdim    break;
787341825Sdim  } // switch (Form)
788201360Srdivacky
789341825Sdim  uint8_t opcodeToSet = Opcode;
790341825Sdim
791280031Sdim  unsigned AddressSize = 0;
792280031Sdim  switch (AdSize) {
793280031Sdim  case X86Local::AdSize16: AddressSize = 16; break;
794280031Sdim  case X86Local::AdSize32: AddressSize = 32; break;
795280031Sdim  case X86Local::AdSize64: AddressSize = 64; break;
796280031Sdim  }
797280031Sdim
798327952Sdim  assert(opcodeType && "Opcode type not set");
799201360Srdivacky  assert(filter && "Filter not set");
800201360Srdivacky
801353358Sdim  if (Form == X86Local::AddRegFrm || Form == X86Local::MRMSrcRegCC ||
802353358Sdim      Form == X86Local::MRMSrcMemCC || Form == X86Local::MRMXrCC ||
803353358Sdim      Form == X86Local::MRMXmCC || Form == X86Local::AddCCFrm) {
804353358Sdim    unsigned Count = Form == X86Local::AddRegFrm ? 8 : 16;
805353358Sdim    assert(((opcodeToSet % Count) == 0) && "ADDREG_FRM opcode not aligned");
806239462Sdim
807276479Sdim    uint8_t currentOpcode;
808201360Srdivacky
809353358Sdim    for (currentOpcode = opcodeToSet; currentOpcode < opcodeToSet + Count;
810276479Sdim         ++currentOpcode)
811327952Sdim      tables.setTableFields(*opcodeType, insnContext(), currentOpcode, *filter,
812327952Sdim                            UID, Is32Bit, OpPrefix == 0,
813327952Sdim                            IgnoresVEX_L || EncodeRC,
814353358Sdim                            IgnoresVEX_W, AddressSize);
815201360Srdivacky  } else {
816327952Sdim    tables.setTableFields(*opcodeType, insnContext(), opcodeToSet, *filter, UID,
817327952Sdim                          Is32Bit, OpPrefix == 0, IgnoresVEX_L || EncodeRC,
818353358Sdim                          IgnoresVEX_W, AddressSize);
819201360Srdivacky  }
820239462Sdim
821203954Srdivacky#undef MAP
822201360Srdivacky}
823201360Srdivacky
824201360Srdivacky#define TYPE(str, type) if (s == str) return type;
825201360SrdivackyOperandType RecognizableInstr::typeFromString(const std::string &s,
826201360Srdivacky                                              bool hasREX_WPrefix,
827276479Sdim                                              uint8_t OpSize) {
828201360Srdivacky  if(hasREX_WPrefix) {
829201360Srdivacky    // For instructions with a REX_W prefix, a declared 32-bit register encoding
830201360Srdivacky    // is special.
831201360Srdivacky    TYPE("GR32",              TYPE_R32)
832201360Srdivacky  }
833276479Sdim  if(OpSize == X86Local::OpSize16) {
834276479Sdim    // For OpSize16 instructions, a declared 16-bit register or
835201360Srdivacky    // immediate encoding is special.
836276479Sdim    TYPE("GR16",              TYPE_Rv)
837276479Sdim  } else if(OpSize == X86Local::OpSize32) {
838276479Sdim    // For OpSize32 instructions, a declared 32-bit register or
839276479Sdim    // immediate encoding is special.
840276479Sdim    TYPE("GR32",              TYPE_Rv)
841201360Srdivacky  }
842321369Sdim  TYPE("i16mem",              TYPE_M)
843321369Sdim  TYPE("i16imm",              TYPE_IMM)
844321369Sdim  TYPE("i16i8imm",            TYPE_IMM)
845276479Sdim  TYPE("GR16",                TYPE_R16)
846321369Sdim  TYPE("i32mem",              TYPE_M)
847321369Sdim  TYPE("i32imm",              TYPE_IMM)
848321369Sdim  TYPE("i32i8imm",            TYPE_IMM)
849276479Sdim  TYPE("GR32",                TYPE_R32)
850261991Sdim  TYPE("GR32orGR64",          TYPE_R32)
851321369Sdim  TYPE("i64mem",              TYPE_M)
852321369Sdim  TYPE("i64i32imm",           TYPE_IMM)
853321369Sdim  TYPE("i64i8imm",            TYPE_IMM)
854201360Srdivacky  TYPE("GR64",                TYPE_R64)
855321369Sdim  TYPE("i8mem",               TYPE_M)
856321369Sdim  TYPE("i8imm",               TYPE_IMM)
857360784Sdim  TYPE("u4imm",               TYPE_UIMM8)
858288943Sdim  TYPE("u8imm",               TYPE_UIMM8)
859353358Sdim  TYPE("i16u8imm",            TYPE_UIMM8)
860288943Sdim  TYPE("i32u8imm",            TYPE_UIMM8)
861353358Sdim  TYPE("i64u8imm",            TYPE_UIMM8)
862201360Srdivacky  TYPE("GR8",                 TYPE_R8)
863321369Sdim  TYPE("VR128",               TYPE_XMM)
864321369Sdim  TYPE("VR128X",              TYPE_XMM)
865321369Sdim  TYPE("f128mem",             TYPE_M)
866321369Sdim  TYPE("f256mem",             TYPE_M)
867321369Sdim  TYPE("f512mem",             TYPE_M)
868321369Sdim  TYPE("FR128",               TYPE_XMM)
869321369Sdim  TYPE("FR64",                TYPE_XMM)
870321369Sdim  TYPE("FR64X",               TYPE_XMM)
871321369Sdim  TYPE("f64mem",              TYPE_M)
872321369Sdim  TYPE("sdmem",               TYPE_M)
873321369Sdim  TYPE("FR32",                TYPE_XMM)
874321369Sdim  TYPE("FR32X",               TYPE_XMM)
875321369Sdim  TYPE("f32mem",              TYPE_M)
876321369Sdim  TYPE("ssmem",               TYPE_M)
877201360Srdivacky  TYPE("RST",                 TYPE_ST)
878344779Sdim  TYPE("RSTi",                TYPE_ST)
879321369Sdim  TYPE("i128mem",             TYPE_M)
880321369Sdim  TYPE("i256mem",             TYPE_M)
881321369Sdim  TYPE("i512mem",             TYPE_M)
882360784Sdim  TYPE("i64i32imm_brtarget",  TYPE_REL)
883360784Sdim  TYPE("i16imm_brtarget",     TYPE_REL)
884360784Sdim  TYPE("i32imm_brtarget",     TYPE_REL)
885353358Sdim  TYPE("ccode",               TYPE_IMM)
886321369Sdim  TYPE("AVX512RC",            TYPE_IMM)
887321369Sdim  TYPE("brtarget32",          TYPE_REL)
888321369Sdim  TYPE("brtarget16",          TYPE_REL)
889321369Sdim  TYPE("brtarget8",           TYPE_REL)
890321369Sdim  TYPE("f80mem",              TYPE_M)
891321369Sdim  TYPE("lea64_32mem",         TYPE_M)
892321369Sdim  TYPE("lea64mem",            TYPE_M)
893201360Srdivacky  TYPE("VR64",                TYPE_MM64)
894321369Sdim  TYPE("i64imm",              TYPE_IMM)
895280031Sdim  TYPE("anymem",              TYPE_M)
896341825Sdim  TYPE("opaquemem",           TYPE_M)
897201360Srdivacky  TYPE("SEGMENT_REG",         TYPE_SEGMENTREG)
898201360Srdivacky  TYPE("DEBUG_REG",           TYPE_DEBUGREG)
899208599Srdivacky  TYPE("CONTROL_REG",         TYPE_CONTROLREG)
900321369Sdim  TYPE("srcidx8",             TYPE_SRCIDX)
901321369Sdim  TYPE("srcidx16",            TYPE_SRCIDX)
902321369Sdim  TYPE("srcidx32",            TYPE_SRCIDX)
903321369Sdim  TYPE("srcidx64",            TYPE_SRCIDX)
904321369Sdim  TYPE("dstidx8",             TYPE_DSTIDX)
905321369Sdim  TYPE("dstidx16",            TYPE_DSTIDX)
906321369Sdim  TYPE("dstidx32",            TYPE_DSTIDX)
907321369Sdim  TYPE("dstidx64",            TYPE_DSTIDX)
908321369Sdim  TYPE("offset16_8",          TYPE_MOFFS)
909321369Sdim  TYPE("offset16_16",         TYPE_MOFFS)
910321369Sdim  TYPE("offset16_32",         TYPE_MOFFS)
911321369Sdim  TYPE("offset32_8",          TYPE_MOFFS)
912321369Sdim  TYPE("offset32_16",         TYPE_MOFFS)
913321369Sdim  TYPE("offset32_32",         TYPE_MOFFS)
914321369Sdim  TYPE("offset32_64",         TYPE_MOFFS)
915321369Sdim  TYPE("offset64_8",          TYPE_MOFFS)
916321369Sdim  TYPE("offset64_16",         TYPE_MOFFS)
917321369Sdim  TYPE("offset64_32",         TYPE_MOFFS)
918321369Sdim  TYPE("offset64_64",         TYPE_MOFFS)
919321369Sdim  TYPE("VR256",               TYPE_YMM)
920321369Sdim  TYPE("VR256X",              TYPE_YMM)
921321369Sdim  TYPE("VR512",               TYPE_ZMM)
922321369Sdim  TYPE("VK1",                 TYPE_VK)
923321369Sdim  TYPE("VK1WM",               TYPE_VK)
924321369Sdim  TYPE("VK2",                 TYPE_VK)
925321369Sdim  TYPE("VK2WM",               TYPE_VK)
926321369Sdim  TYPE("VK4",                 TYPE_VK)
927321369Sdim  TYPE("VK4WM",               TYPE_VK)
928321369Sdim  TYPE("VK8",                 TYPE_VK)
929321369Sdim  TYPE("VK8WM",               TYPE_VK)
930321369Sdim  TYPE("VK16",                TYPE_VK)
931321369Sdim  TYPE("VK16WM",              TYPE_VK)
932321369Sdim  TYPE("VK32",                TYPE_VK)
933321369Sdim  TYPE("VK32WM",              TYPE_VK)
934321369Sdim  TYPE("VK64",                TYPE_VK)
935321369Sdim  TYPE("VK64WM",              TYPE_VK)
936353358Sdim  TYPE("VK1Pair",             TYPE_VK_PAIR)
937353358Sdim  TYPE("VK2Pair",             TYPE_VK_PAIR)
938353358Sdim  TYPE("VK4Pair",             TYPE_VK_PAIR)
939353358Sdim  TYPE("VK8Pair",             TYPE_VK_PAIR)
940353358Sdim  TYPE("VK16Pair",            TYPE_VK_PAIR)
941327952Sdim  TYPE("vx64mem",             TYPE_MVSIBX)
942327952Sdim  TYPE("vx128mem",            TYPE_MVSIBX)
943327952Sdim  TYPE("vx256mem",            TYPE_MVSIBX)
944327952Sdim  TYPE("vy128mem",            TYPE_MVSIBY)
945327952Sdim  TYPE("vy256mem",            TYPE_MVSIBY)
946327952Sdim  TYPE("vx64xmem",            TYPE_MVSIBX)
947327952Sdim  TYPE("vx128xmem",           TYPE_MVSIBX)
948327952Sdim  TYPE("vx256xmem",           TYPE_MVSIBX)
949327952Sdim  TYPE("vy128xmem",           TYPE_MVSIBY)
950327952Sdim  TYPE("vy256xmem",           TYPE_MVSIBY)
951341825Sdim  TYPE("vy512xmem",           TYPE_MVSIBY)
952341825Sdim  TYPE("vz256mem",            TYPE_MVSIBZ)
953327952Sdim  TYPE("vz512mem",            TYPE_MVSIBZ)
954288943Sdim  TYPE("BNDR",                TYPE_BNDR)
955201360Srdivacky  errs() << "Unhandled type string " << s << "\n";
956201360Srdivacky  llvm_unreachable("Unhandled type string");
957201360Srdivacky}
958201360Srdivacky#undef TYPE
959201360Srdivacky
960201360Srdivacky#define ENCODING(str, encoding) if (s == str) return encoding;
961276479SdimOperandEncoding
962276479SdimRecognizableInstr::immediateEncodingFromString(const std::string &s,
963276479Sdim                                               uint8_t OpSize) {
964276479Sdim  if(OpSize != X86Local::OpSize16) {
965201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
966201360Srdivacky    // immediate encoding is special.
967201360Srdivacky    ENCODING("i16imm",        ENCODING_IW)
968201360Srdivacky  }
969201360Srdivacky  ENCODING("i32i8imm",        ENCODING_IB)
970327952Sdim  ENCODING("AVX512RC",        ENCODING_IRC)
971201360Srdivacky  ENCODING("i16imm",          ENCODING_Iv)
972201360Srdivacky  ENCODING("i16i8imm",        ENCODING_IB)
973201360Srdivacky  ENCODING("i32imm",          ENCODING_Iv)
974201360Srdivacky  ENCODING("i64i32imm",       ENCODING_ID)
975201360Srdivacky  ENCODING("i64i8imm",        ENCODING_IB)
976201360Srdivacky  ENCODING("i8imm",           ENCODING_IB)
977360784Sdim  ENCODING("u4imm",           ENCODING_IB)
978288943Sdim  ENCODING("u8imm",           ENCODING_IB)
979353358Sdim  ENCODING("i16u8imm",        ENCODING_IB)
980288943Sdim  ENCODING("i32u8imm",        ENCODING_IB)
981353358Sdim  ENCODING("i64u8imm",        ENCODING_IB)
982221345Sdim  // This is not a typo.  Instructions like BLENDVPD put
983221345Sdim  // register IDs in 8-bit immediates nowadays.
984243830Sdim  ENCODING("FR32",            ENCODING_IB)
985243830Sdim  ENCODING("FR64",            ENCODING_IB)
986296417Sdim  ENCODING("FR128",           ENCODING_IB)
987261991Sdim  ENCODING("VR128",           ENCODING_IB)
988261991Sdim  ENCODING("VR256",           ENCODING_IB)
989261991Sdim  ENCODING("FR32X",           ENCODING_IB)
990261991Sdim  ENCODING("FR64X",           ENCODING_IB)
991261991Sdim  ENCODING("VR128X",          ENCODING_IB)
992261991Sdim  ENCODING("VR256X",          ENCODING_IB)
993261991Sdim  ENCODING("VR512",           ENCODING_IB)
994201360Srdivacky  errs() << "Unhandled immediate encoding " << s << "\n";
995201360Srdivacky  llvm_unreachable("Unhandled immediate encoding");
996201360Srdivacky}
997201360Srdivacky
998276479SdimOperandEncoding
999276479SdimRecognizableInstr::rmRegisterEncodingFromString(const std::string &s,
1000276479Sdim                                                uint8_t OpSize) {
1001276479Sdim  ENCODING("RST",             ENCODING_FP)
1002344779Sdim  ENCODING("RSTi",            ENCODING_FP)
1003201360Srdivacky  ENCODING("GR16",            ENCODING_RM)
1004201360Srdivacky  ENCODING("GR32",            ENCODING_RM)
1005261991Sdim  ENCODING("GR32orGR64",      ENCODING_RM)
1006201360Srdivacky  ENCODING("GR64",            ENCODING_RM)
1007201360Srdivacky  ENCODING("GR8",             ENCODING_RM)
1008201360Srdivacky  ENCODING("VR128",           ENCODING_RM)
1009261991Sdim  ENCODING("VR128X",          ENCODING_RM)
1010296417Sdim  ENCODING("FR128",           ENCODING_RM)
1011201360Srdivacky  ENCODING("FR64",            ENCODING_RM)
1012201360Srdivacky  ENCODING("FR32",            ENCODING_RM)
1013261991Sdim  ENCODING("FR64X",           ENCODING_RM)
1014261991Sdim  ENCODING("FR32X",           ENCODING_RM)
1015201360Srdivacky  ENCODING("VR64",            ENCODING_RM)
1016221345Sdim  ENCODING("VR256",           ENCODING_RM)
1017261991Sdim  ENCODING("VR256X",          ENCODING_RM)
1018261991Sdim  ENCODING("VR512",           ENCODING_RM)
1019276479Sdim  ENCODING("VK1",             ENCODING_RM)
1020288943Sdim  ENCODING("VK2",             ENCODING_RM)
1021288943Sdim  ENCODING("VK4",             ENCODING_RM)
1022261991Sdim  ENCODING("VK8",             ENCODING_RM)
1023261991Sdim  ENCODING("VK16",            ENCODING_RM)
1024280031Sdim  ENCODING("VK32",            ENCODING_RM)
1025280031Sdim  ENCODING("VK64",            ENCODING_RM)
1026353358Sdim  ENCODING("VK1PAIR",         ENCODING_RM)
1027353358Sdim  ENCODING("VK2PAIR",         ENCODING_RM)
1028353358Sdim  ENCODING("VK4PAIR",         ENCODING_RM)
1029353358Sdim  ENCODING("VK8PAIR",         ENCODING_RM)
1030353358Sdim  ENCODING("VK16PAIR",        ENCODING_RM)
1031288943Sdim  ENCODING("BNDR",            ENCODING_RM)
1032201360Srdivacky  errs() << "Unhandled R/M register encoding " << s << "\n";
1033201360Srdivacky  llvm_unreachable("Unhandled R/M register encoding");
1034201360Srdivacky}
1035201360Srdivacky
1036276479SdimOperandEncoding
1037276479SdimRecognizableInstr::roRegisterEncodingFromString(const std::string &s,
1038276479Sdim                                                uint8_t OpSize) {
1039201360Srdivacky  ENCODING("GR16",            ENCODING_REG)
1040201360Srdivacky  ENCODING("GR32",            ENCODING_REG)
1041261991Sdim  ENCODING("GR32orGR64",      ENCODING_REG)
1042201360Srdivacky  ENCODING("GR64",            ENCODING_REG)
1043201360Srdivacky  ENCODING("GR8",             ENCODING_REG)
1044201360Srdivacky  ENCODING("VR128",           ENCODING_REG)
1045296417Sdim  ENCODING("FR128",           ENCODING_REG)
1046201360Srdivacky  ENCODING("FR64",            ENCODING_REG)
1047201360Srdivacky  ENCODING("FR32",            ENCODING_REG)
1048201360Srdivacky  ENCODING("VR64",            ENCODING_REG)
1049201360Srdivacky  ENCODING("SEGMENT_REG",     ENCODING_REG)
1050201360Srdivacky  ENCODING("DEBUG_REG",       ENCODING_REG)
1051208599Srdivacky  ENCODING("CONTROL_REG",     ENCODING_REG)
1052221345Sdim  ENCODING("VR256",           ENCODING_REG)
1053261991Sdim  ENCODING("VR256X",          ENCODING_REG)
1054261991Sdim  ENCODING("VR128X",          ENCODING_REG)
1055261991Sdim  ENCODING("FR64X",           ENCODING_REG)
1056261991Sdim  ENCODING("FR32X",           ENCODING_REG)
1057261991Sdim  ENCODING("VR512",           ENCODING_REG)
1058276479Sdim  ENCODING("VK1",             ENCODING_REG)
1059280031Sdim  ENCODING("VK2",             ENCODING_REG)
1060280031Sdim  ENCODING("VK4",             ENCODING_REG)
1061261991Sdim  ENCODING("VK8",             ENCODING_REG)
1062261991Sdim  ENCODING("VK16",            ENCODING_REG)
1063280031Sdim  ENCODING("VK32",            ENCODING_REG)
1064280031Sdim  ENCODING("VK64",            ENCODING_REG)
1065353358Sdim  ENCODING("VK1Pair",         ENCODING_REG)
1066353358Sdim  ENCODING("VK2Pair",         ENCODING_REG)
1067353358Sdim  ENCODING("VK4Pair",         ENCODING_REG)
1068353358Sdim  ENCODING("VK8Pair",         ENCODING_REG)
1069353358Sdim  ENCODING("VK16Pair",        ENCODING_REG)
1070276479Sdim  ENCODING("VK1WM",           ENCODING_REG)
1071288943Sdim  ENCODING("VK2WM",           ENCODING_REG)
1072288943Sdim  ENCODING("VK4WM",           ENCODING_REG)
1073261991Sdim  ENCODING("VK8WM",           ENCODING_REG)
1074261991Sdim  ENCODING("VK16WM",          ENCODING_REG)
1075288943Sdim  ENCODING("VK32WM",          ENCODING_REG)
1076288943Sdim  ENCODING("VK64WM",          ENCODING_REG)
1077288943Sdim  ENCODING("BNDR",            ENCODING_REG)
1078201360Srdivacky  errs() << "Unhandled reg/opcode register encoding " << s << "\n";
1079201360Srdivacky  llvm_unreachable("Unhandled reg/opcode register encoding");
1080201360Srdivacky}
1081201360Srdivacky
1082276479SdimOperandEncoding
1083276479SdimRecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s,
1084276479Sdim                                                  uint8_t OpSize) {
1085226633Sdim  ENCODING("GR32",            ENCODING_VVVV)
1086226633Sdim  ENCODING("GR64",            ENCODING_VVVV)
1087221345Sdim  ENCODING("FR32",            ENCODING_VVVV)
1088296417Sdim  ENCODING("FR128",           ENCODING_VVVV)
1089221345Sdim  ENCODING("FR64",            ENCODING_VVVV)
1090221345Sdim  ENCODING("VR128",           ENCODING_VVVV)
1091221345Sdim  ENCODING("VR256",           ENCODING_VVVV)
1092261991Sdim  ENCODING("FR32X",           ENCODING_VVVV)
1093261991Sdim  ENCODING("FR64X",           ENCODING_VVVV)
1094261991Sdim  ENCODING("VR128X",          ENCODING_VVVV)
1095261991Sdim  ENCODING("VR256X",          ENCODING_VVVV)
1096261991Sdim  ENCODING("VR512",           ENCODING_VVVV)
1097276479Sdim  ENCODING("VK1",             ENCODING_VVVV)
1098276479Sdim  ENCODING("VK2",             ENCODING_VVVV)
1099276479Sdim  ENCODING("VK4",             ENCODING_VVVV)
1100261991Sdim  ENCODING("VK8",             ENCODING_VVVV)
1101261991Sdim  ENCODING("VK16",            ENCODING_VVVV)
1102280031Sdim  ENCODING("VK32",            ENCODING_VVVV)
1103280031Sdim  ENCODING("VK64",            ENCODING_VVVV)
1104353358Sdim  ENCODING("VK1PAIR",         ENCODING_VVVV)
1105353358Sdim  ENCODING("VK2PAIR",         ENCODING_VVVV)
1106353358Sdim  ENCODING("VK4PAIR",         ENCODING_VVVV)
1107353358Sdim  ENCODING("VK8PAIR",         ENCODING_VVVV)
1108353358Sdim  ENCODING("VK16PAIR",        ENCODING_VVVV)
1109221345Sdim  errs() << "Unhandled VEX.vvvv register encoding " << s << "\n";
1110221345Sdim  llvm_unreachable("Unhandled VEX.vvvv register encoding");
1111221345Sdim}
1112221345Sdim
1113276479SdimOperandEncoding
1114276479SdimRecognizableInstr::writemaskRegisterEncodingFromString(const std::string &s,
1115276479Sdim                                                       uint8_t OpSize) {
1116276479Sdim  ENCODING("VK1WM",           ENCODING_WRITEMASK)
1117276479Sdim  ENCODING("VK2WM",           ENCODING_WRITEMASK)
1118276479Sdim  ENCODING("VK4WM",           ENCODING_WRITEMASK)
1119261991Sdim  ENCODING("VK8WM",           ENCODING_WRITEMASK)
1120261991Sdim  ENCODING("VK16WM",          ENCODING_WRITEMASK)
1121276479Sdim  ENCODING("VK32WM",          ENCODING_WRITEMASK)
1122276479Sdim  ENCODING("VK64WM",          ENCODING_WRITEMASK)
1123261991Sdim  errs() << "Unhandled mask register encoding " << s << "\n";
1124261991Sdim  llvm_unreachable("Unhandled mask register encoding");
1125261991Sdim}
1126261991Sdim
1127276479SdimOperandEncoding
1128276479SdimRecognizableInstr::memoryEncodingFromString(const std::string &s,
1129276479Sdim                                            uint8_t OpSize) {
1130201360Srdivacky  ENCODING("i16mem",          ENCODING_RM)
1131201360Srdivacky  ENCODING("i32mem",          ENCODING_RM)
1132201360Srdivacky  ENCODING("i64mem",          ENCODING_RM)
1133201360Srdivacky  ENCODING("i8mem",           ENCODING_RM)
1134218893Sdim  ENCODING("ssmem",           ENCODING_RM)
1135218893Sdim  ENCODING("sdmem",           ENCODING_RM)
1136201360Srdivacky  ENCODING("f128mem",         ENCODING_RM)
1137218893Sdim  ENCODING("f256mem",         ENCODING_RM)
1138261991Sdim  ENCODING("f512mem",         ENCODING_RM)
1139201360Srdivacky  ENCODING("f64mem",          ENCODING_RM)
1140201360Srdivacky  ENCODING("f32mem",          ENCODING_RM)
1141201360Srdivacky  ENCODING("i128mem",         ENCODING_RM)
1142221345Sdim  ENCODING("i256mem",         ENCODING_RM)
1143261991Sdim  ENCODING("i512mem",         ENCODING_RM)
1144201360Srdivacky  ENCODING("f80mem",          ENCODING_RM)
1145201360Srdivacky  ENCODING("lea64_32mem",     ENCODING_RM)
1146201360Srdivacky  ENCODING("lea64mem",        ENCODING_RM)
1147280031Sdim  ENCODING("anymem",          ENCODING_RM)
1148341825Sdim  ENCODING("opaquemem",       ENCODING_RM)
1149321369Sdim  ENCODING("vx64mem",         ENCODING_VSIB)
1150321369Sdim  ENCODING("vx128mem",        ENCODING_VSIB)
1151321369Sdim  ENCODING("vx256mem",        ENCODING_VSIB)
1152321369Sdim  ENCODING("vy128mem",        ENCODING_VSIB)
1153321369Sdim  ENCODING("vy256mem",        ENCODING_VSIB)
1154321369Sdim  ENCODING("vx64xmem",        ENCODING_VSIB)
1155321369Sdim  ENCODING("vx128xmem",       ENCODING_VSIB)
1156321369Sdim  ENCODING("vx256xmem",       ENCODING_VSIB)
1157321369Sdim  ENCODING("vy128xmem",       ENCODING_VSIB)
1158321369Sdim  ENCODING("vy256xmem",       ENCODING_VSIB)
1159341825Sdim  ENCODING("vy512xmem",       ENCODING_VSIB)
1160341825Sdim  ENCODING("vz256mem",        ENCODING_VSIB)
1161321369Sdim  ENCODING("vz512mem",        ENCODING_VSIB)
1162201360Srdivacky  errs() << "Unhandled memory encoding " << s << "\n";
1163201360Srdivacky  llvm_unreachable("Unhandled memory encoding");
1164201360Srdivacky}
1165201360Srdivacky
1166276479SdimOperandEncoding
1167276479SdimRecognizableInstr::relocationEncodingFromString(const std::string &s,
1168276479Sdim                                                uint8_t OpSize) {
1169276479Sdim  if(OpSize != X86Local::OpSize16) {
1170201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
1171201360Srdivacky    // immediate encoding is special.
1172360784Sdim    ENCODING("i16imm",           ENCODING_IW)
1173201360Srdivacky  }
1174360784Sdim  ENCODING("i16imm",             ENCODING_Iv)
1175360784Sdim  ENCODING("i16i8imm",           ENCODING_IB)
1176360784Sdim  ENCODING("i32imm",             ENCODING_Iv)
1177360784Sdim  ENCODING("i32i8imm",           ENCODING_IB)
1178360784Sdim  ENCODING("i64i32imm",          ENCODING_ID)
1179360784Sdim  ENCODING("i64i8imm",           ENCODING_IB)
1180360784Sdim  ENCODING("i8imm",              ENCODING_IB)
1181360784Sdim  ENCODING("u8imm",              ENCODING_IB)
1182360784Sdim  ENCODING("i16u8imm",           ENCODING_IB)
1183360784Sdim  ENCODING("i32u8imm",           ENCODING_IB)
1184360784Sdim  ENCODING("i64u8imm",           ENCODING_IB)
1185360784Sdim  ENCODING("i64i32imm_brtarget", ENCODING_ID)
1186360784Sdim  ENCODING("i16imm_brtarget",    ENCODING_IW)
1187360784Sdim  ENCODING("i32imm_brtarget",    ENCODING_ID)
1188360784Sdim  ENCODING("brtarget32",         ENCODING_ID)
1189360784Sdim  ENCODING("brtarget16",         ENCODING_IW)
1190360784Sdim  ENCODING("brtarget8",          ENCODING_IB)
1191360784Sdim  ENCODING("i64imm",             ENCODING_IO)
1192360784Sdim  ENCODING("offset16_8",         ENCODING_Ia)
1193360784Sdim  ENCODING("offset16_16",        ENCODING_Ia)
1194360784Sdim  ENCODING("offset16_32",        ENCODING_Ia)
1195360784Sdim  ENCODING("offset32_8",         ENCODING_Ia)
1196360784Sdim  ENCODING("offset32_16",        ENCODING_Ia)
1197360784Sdim  ENCODING("offset32_32",        ENCODING_Ia)
1198360784Sdim  ENCODING("offset32_64",        ENCODING_Ia)
1199360784Sdim  ENCODING("offset64_8",         ENCODING_Ia)
1200360784Sdim  ENCODING("offset64_16",        ENCODING_Ia)
1201360784Sdim  ENCODING("offset64_32",        ENCODING_Ia)
1202360784Sdim  ENCODING("offset64_64",        ENCODING_Ia)
1203360784Sdim  ENCODING("srcidx8",            ENCODING_SI)
1204360784Sdim  ENCODING("srcidx16",           ENCODING_SI)
1205360784Sdim  ENCODING("srcidx32",           ENCODING_SI)
1206360784Sdim  ENCODING("srcidx64",           ENCODING_SI)
1207360784Sdim  ENCODING("dstidx8",            ENCODING_DI)
1208360784Sdim  ENCODING("dstidx16",           ENCODING_DI)
1209360784Sdim  ENCODING("dstidx32",           ENCODING_DI)
1210360784Sdim  ENCODING("dstidx64",           ENCODING_DI)
1211201360Srdivacky  errs() << "Unhandled relocation encoding " << s << "\n";
1212201360Srdivacky  llvm_unreachable("Unhandled relocation encoding");
1213201360Srdivacky}
1214201360Srdivacky
1215276479SdimOperandEncoding
1216276479SdimRecognizableInstr::opcodeModifierEncodingFromString(const std::string &s,
1217276479Sdim                                                    uint8_t OpSize) {
1218201360Srdivacky  ENCODING("GR32",            ENCODING_Rv)
1219201360Srdivacky  ENCODING("GR64",            ENCODING_RO)
1220201360Srdivacky  ENCODING("GR16",            ENCODING_Rv)
1221201360Srdivacky  ENCODING("GR8",             ENCODING_RB)
1222353358Sdim  ENCODING("ccode",           ENCODING_CC)
1223201360Srdivacky  errs() << "Unhandled opcode modifier encoding " << s << "\n";
1224201360Srdivacky  llvm_unreachable("Unhandled opcode modifier encoding");
1225201360Srdivacky}
1226201360Srdivacky#undef ENCODING
1227