X86RecognizableInstr.cpp revision 218893
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
17201360Srdivacky#include "X86DisassemblerShared.h"
18201360Srdivacky#include "X86RecognizableInstr.h"
19201360Srdivacky#include "X86ModRMFilters.h"
20201360Srdivacky
21201360Srdivacky#include "llvm/Support/ErrorHandling.h"
22201360Srdivacky
23201360Srdivacky#include <string>
24201360Srdivacky
25201360Srdivackyusing namespace llvm;
26201360Srdivacky
27203954Srdivacky#define MRM_MAPPING     \
28203954Srdivacky  MAP(C1, 33)           \
29203954Srdivacky  MAP(C2, 34)           \
30203954Srdivacky  MAP(C3, 35)           \
31203954Srdivacky  MAP(C4, 36)           \
32203954Srdivacky  MAP(C8, 37)           \
33203954Srdivacky  MAP(C9, 38)           \
34203954Srdivacky  MAP(E8, 39)           \
35203954Srdivacky  MAP(F0, 40)           \
36210299Sed  MAP(F8, 41)           \
37203954Srdivacky  MAP(F9, 42)
38203954Srdivacky
39201360Srdivacky// A clone of X86 since we can't depend on something that is generated.
40201360Srdivackynamespace X86Local {
41201360Srdivacky  enum {
42201360Srdivacky    Pseudo      = 0,
43201360Srdivacky    RawFrm      = 1,
44201360Srdivacky    AddRegFrm   = 2,
45201360Srdivacky    MRMDestReg  = 3,
46201360Srdivacky    MRMDestMem  = 4,
47201360Srdivacky    MRMSrcReg   = 5,
48201360Srdivacky    MRMSrcMem   = 6,
49201360Srdivacky    MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19,
50201360Srdivacky    MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
51201360Srdivacky    MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
52201360Srdivacky    MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
53203954Srdivacky    MRMInitReg  = 32,
54203954Srdivacky#define MAP(from, to) MRM_##from = to,
55203954Srdivacky    MRM_MAPPING
56203954Srdivacky#undef MAP
57218893Sdim    RawFrmImm8  = 43,
58218893Sdim    RawFrmImm16 = 44,
59203954Srdivacky    lastMRM
60201360Srdivacky  };
61201360Srdivacky
62201360Srdivacky  enum {
63201360Srdivacky    TB  = 1,
64201360Srdivacky    REP = 2,
65201360Srdivacky    D8 = 3, D9 = 4, DA = 5, DB = 6,
66201360Srdivacky    DC = 7, DD = 8, DE = 9, DF = 10,
67201360Srdivacky    XD = 11,  XS = 12,
68203954Srdivacky    T8 = 13,  P_TA = 14,
69203954Srdivacky    P_0F_AE = 16, P_0F_01 = 17
70201360Srdivacky  };
71201360Srdivacky}
72203954Srdivacky
73203954Srdivacky// If rows are added to the opcode extension tables, then corresponding entries
74203954Srdivacky// must be added here.
75203954Srdivacky//
76203954Srdivacky// If the row corresponds to a single byte (i.e., 8f), then add an entry for
77203954Srdivacky// that byte to ONE_BYTE_EXTENSION_TABLES.
78203954Srdivacky//
79203954Srdivacky// If the row corresponds to two bytes where the first is 0f, add an entry for
80203954Srdivacky// the second byte to TWO_BYTE_EXTENSION_TABLES.
81203954Srdivacky//
82203954Srdivacky// If the row corresponds to some other set of bytes, you will need to modify
83203954Srdivacky// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes
84203954Srdivacky// to the X86 TD files, except in two cases: if the first two bytes of such a
85203954Srdivacky// new combination are 0f 38 or 0f 3a, you just have to add maps called
86203954Srdivacky// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a
87203954Srdivacky// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line
88203954Srdivacky// in RecognizableInstr::emitDecodePath().
89203954Srdivacky
90201360Srdivacky#define ONE_BYTE_EXTENSION_TABLES \
91201360Srdivacky  EXTENSION_TABLE(80)             \
92201360Srdivacky  EXTENSION_TABLE(81)             \
93201360Srdivacky  EXTENSION_TABLE(82)             \
94201360Srdivacky  EXTENSION_TABLE(83)             \
95201360Srdivacky  EXTENSION_TABLE(8f)             \
96201360Srdivacky  EXTENSION_TABLE(c0)             \
97201360Srdivacky  EXTENSION_TABLE(c1)             \
98201360Srdivacky  EXTENSION_TABLE(c6)             \
99201360Srdivacky  EXTENSION_TABLE(c7)             \
100201360Srdivacky  EXTENSION_TABLE(d0)             \
101201360Srdivacky  EXTENSION_TABLE(d1)             \
102201360Srdivacky  EXTENSION_TABLE(d2)             \
103201360Srdivacky  EXTENSION_TABLE(d3)             \
104201360Srdivacky  EXTENSION_TABLE(f6)             \
105201360Srdivacky  EXTENSION_TABLE(f7)             \
106201360Srdivacky  EXTENSION_TABLE(fe)             \
107201360Srdivacky  EXTENSION_TABLE(ff)
108201360Srdivacky
109201360Srdivacky#define TWO_BYTE_EXTENSION_TABLES \
110201360Srdivacky  EXTENSION_TABLE(00)             \
111201360Srdivacky  EXTENSION_TABLE(01)             \
112201360Srdivacky  EXTENSION_TABLE(18)             \
113201360Srdivacky  EXTENSION_TABLE(71)             \
114201360Srdivacky  EXTENSION_TABLE(72)             \
115201360Srdivacky  EXTENSION_TABLE(73)             \
116201360Srdivacky  EXTENSION_TABLE(ae)             \
117201360Srdivacky  EXTENSION_TABLE(ba)             \
118201360Srdivacky  EXTENSION_TABLE(c7)
119201360Srdivacky
120201360Srdivackyusing namespace X86Disassembler;
121201360Srdivacky
122201360Srdivacky/// needsModRMForDecode - Indicates whether a particular instruction requires a
123201360Srdivacky///   ModR/M byte for the instruction to be properly decoded.  For example, a
124201360Srdivacky///   MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to
125201360Srdivacky///   0b11.
126201360Srdivacky///
127201360Srdivacky/// @param form - The form of the instruction.
128201360Srdivacky/// @return     - true if the form implies that a ModR/M byte is required, false
129201360Srdivacky///               otherwise.
130201360Srdivackystatic bool needsModRMForDecode(uint8_t form) {
131201360Srdivacky  if (form == X86Local::MRMDestReg    ||
132201360Srdivacky     form == X86Local::MRMDestMem    ||
133201360Srdivacky     form == X86Local::MRMSrcReg     ||
134201360Srdivacky     form == X86Local::MRMSrcMem     ||
135201360Srdivacky     (form >= X86Local::MRM0r && form <= X86Local::MRM7r) ||
136201360Srdivacky     (form >= X86Local::MRM0m && form <= X86Local::MRM7m))
137201360Srdivacky    return true;
138201360Srdivacky  else
139201360Srdivacky    return false;
140201360Srdivacky}
141201360Srdivacky
142201360Srdivacky/// isRegFormat - Indicates whether a particular form requires the Mod field of
143201360Srdivacky///   the ModR/M byte to be 0b11.
144201360Srdivacky///
145201360Srdivacky/// @param form - The form of the instruction.
146201360Srdivacky/// @return     - true if the form implies that Mod must be 0b11, false
147201360Srdivacky///               otherwise.
148201360Srdivackystatic bool isRegFormat(uint8_t form) {
149201360Srdivacky  if (form == X86Local::MRMDestReg ||
150201360Srdivacky     form == X86Local::MRMSrcReg  ||
151201360Srdivacky     (form >= X86Local::MRM0r && form <= X86Local::MRM7r))
152201360Srdivacky    return true;
153201360Srdivacky  else
154201360Srdivacky    return false;
155201360Srdivacky}
156201360Srdivacky
157201360Srdivacky/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
158201360Srdivacky///   Useful for switch statements and the like.
159201360Srdivacky///
160201360Srdivacky/// @param init - A reference to the BitsInit to be decoded.
161201360Srdivacky/// @return     - The field, with the first bit in the BitsInit as the lowest
162201360Srdivacky///               order bit.
163201360Srdivackystatic uint8_t byteFromBitsInit(BitsInit &init) {
164201360Srdivacky  int width = init.getNumBits();
165201360Srdivacky
166201360Srdivacky  assert(width <= 8 && "Field is too large for uint8_t!");
167201360Srdivacky
168201360Srdivacky  int     index;
169201360Srdivacky  uint8_t mask = 0x01;
170201360Srdivacky
171201360Srdivacky  uint8_t ret = 0;
172201360Srdivacky
173201360Srdivacky  for (index = 0; index < width; index++) {
174201360Srdivacky    if (static_cast<BitInit*>(init.getBit(index))->getValue())
175201360Srdivacky      ret |= mask;
176201360Srdivacky
177201360Srdivacky    mask <<= 1;
178201360Srdivacky  }
179201360Srdivacky
180201360Srdivacky  return ret;
181201360Srdivacky}
182201360Srdivacky
183201360Srdivacky/// byteFromRec - Extract a value at most 8 bits in with from a Record given the
184201360Srdivacky///   name of the field.
185201360Srdivacky///
186201360Srdivacky/// @param rec  - The record from which to extract the value.
187201360Srdivacky/// @param name - The name of the field in the record.
188201360Srdivacky/// @return     - The field, as translated by byteFromBitsInit().
189201360Srdivackystatic uint8_t byteFromRec(const Record* rec, const std::string &name) {
190201360Srdivacky  BitsInit* bits = rec->getValueAsBitsInit(name);
191201360Srdivacky  return byteFromBitsInit(*bits);
192201360Srdivacky}
193201360Srdivacky
194201360SrdivackyRecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
195201360Srdivacky                                     const CodeGenInstruction &insn,
196201360Srdivacky                                     InstrUID uid) {
197201360Srdivacky  UID = uid;
198201360Srdivacky
199201360Srdivacky  Rec = insn.TheDef;
200201360Srdivacky  Name = Rec->getName();
201201360Srdivacky  Spec = &tables.specForUID(UID);
202201360Srdivacky
203201360Srdivacky  if (!Rec->isSubClassOf("X86Inst")) {
204201360Srdivacky    ShouldBeEmitted = false;
205201360Srdivacky    return;
206201360Srdivacky  }
207201360Srdivacky
208201360Srdivacky  Prefix   = byteFromRec(Rec, "Prefix");
209201360Srdivacky  Opcode   = byteFromRec(Rec, "Opcode");
210201360Srdivacky  Form     = byteFromRec(Rec, "FormBits");
211201360Srdivacky  SegOvr   = byteFromRec(Rec, "SegOvrBits");
212201360Srdivacky
213201360Srdivacky  HasOpSizePrefix  = Rec->getValueAsBit("hasOpSizePrefix");
214201360Srdivacky  HasREX_WPrefix   = Rec->getValueAsBit("hasREX_WPrefix");
215210299Sed  HasVEX_4VPrefix  = Rec->getValueAsBit("hasVEX_4VPrefix");
216201360Srdivacky  HasLockPrefix    = Rec->getValueAsBit("hasLockPrefix");
217201360Srdivacky  IsCodeGenOnly    = Rec->getValueAsBit("isCodeGenOnly");
218201360Srdivacky
219201360Srdivacky  Name      = Rec->getName();
220201360Srdivacky  AsmString = Rec->getValueAsString("AsmString");
221201360Srdivacky
222218893Sdim  Operands = &insn.Operands.OperandList;
223201360Srdivacky
224201360Srdivacky  IsSSE            = HasOpSizePrefix && (Name.find("16") == Name.npos);
225201360Srdivacky  HasFROperands    = false;
226201360Srdivacky
227201360Srdivacky  ShouldBeEmitted  = true;
228201360Srdivacky}
229201360Srdivacky
230201360Srdivackyvoid RecognizableInstr::processInstr(DisassemblerTables &tables,
231201360Srdivacky                                   const CodeGenInstruction &insn,
232201360Srdivacky                                   InstrUID uid)
233201360Srdivacky{
234208599Srdivacky  // Ignore "asm parser only" instructions.
235208599Srdivacky  if (insn.TheDef->getValueAsBit("isAsmParserOnly"))
236208599Srdivacky    return;
237208599Srdivacky
238201360Srdivacky  RecognizableInstr recogInstr(tables, insn, uid);
239201360Srdivacky
240201360Srdivacky  recogInstr.emitInstructionSpecifier(tables);
241201360Srdivacky
242201360Srdivacky  if (recogInstr.shouldBeEmitted())
243201360Srdivacky    recogInstr.emitDecodePath(tables);
244201360Srdivacky}
245201360Srdivacky
246201360SrdivackyInstructionContext RecognizableInstr::insnContext() const {
247201360Srdivacky  InstructionContext insnContext;
248201360Srdivacky
249201360Srdivacky  if (Name.find("64") != Name.npos || HasREX_WPrefix) {
250201360Srdivacky    if (HasREX_WPrefix && HasOpSizePrefix)
251201360Srdivacky      insnContext = IC_64BIT_REXW_OPSIZE;
252201360Srdivacky    else if (HasOpSizePrefix)
253201360Srdivacky      insnContext = IC_64BIT_OPSIZE;
254201360Srdivacky    else if (HasREX_WPrefix && Prefix == X86Local::XS)
255201360Srdivacky      insnContext = IC_64BIT_REXW_XS;
256201360Srdivacky    else if (HasREX_WPrefix && Prefix == X86Local::XD)
257201360Srdivacky      insnContext = IC_64BIT_REXW_XD;
258201360Srdivacky    else if (Prefix == X86Local::XD)
259201360Srdivacky      insnContext = IC_64BIT_XD;
260201360Srdivacky    else if (Prefix == X86Local::XS)
261201360Srdivacky      insnContext = IC_64BIT_XS;
262201360Srdivacky    else if (HasREX_WPrefix)
263201360Srdivacky      insnContext = IC_64BIT_REXW;
264201360Srdivacky    else
265201360Srdivacky      insnContext = IC_64BIT;
266201360Srdivacky  } else {
267201360Srdivacky    if (HasOpSizePrefix)
268201360Srdivacky      insnContext = IC_OPSIZE;
269201360Srdivacky    else if (Prefix == X86Local::XD)
270201360Srdivacky      insnContext = IC_XD;
271201360Srdivacky    else if (Prefix == X86Local::XS)
272201360Srdivacky      insnContext = IC_XS;
273201360Srdivacky    else
274201360Srdivacky      insnContext = IC;
275201360Srdivacky  }
276201360Srdivacky
277201360Srdivacky  return insnContext;
278201360Srdivacky}
279201360Srdivacky
280201360SrdivackyRecognizableInstr::filter_ret RecognizableInstr::filter() const {
281201360Srdivacky  // Filter out intrinsics
282201360Srdivacky
283201360Srdivacky  if (!Rec->isSubClassOf("X86Inst"))
284201360Srdivacky    return FILTER_STRONG;
285201360Srdivacky
286201360Srdivacky  if (Form == X86Local::Pseudo ||
287201360Srdivacky      IsCodeGenOnly)
288201360Srdivacky    return FILTER_STRONG;
289201360Srdivacky
290204642Srdivacky  if (Form == X86Local::MRMInitReg)
291204642Srdivacky    return FILTER_STRONG;
292204642Srdivacky
293204642Srdivacky
294201360Srdivacky  // Filter out instructions with a LOCK prefix;
295201360Srdivacky  //   prefer forms that do not have the prefix
296201360Srdivacky  if (HasLockPrefix)
297201360Srdivacky    return FILTER_WEAK;
298201360Srdivacky
299201360Srdivacky  // Filter out artificial instructions
300201360Srdivacky
301201360Srdivacky  if (Name.find("TAILJMP") != Name.npos    ||
302201360Srdivacky     Name.find("_Int") != Name.npos       ||
303201360Srdivacky     Name.find("_int") != Name.npos       ||
304201360Srdivacky     Name.find("Int_") != Name.npos       ||
305201360Srdivacky     Name.find("_NOREX") != Name.npos     ||
306205218Srdivacky     Name.find("_TC") != Name.npos     ||
307201360Srdivacky     Name.find("EH_RETURN") != Name.npos  ||
308201360Srdivacky     Name.find("V_SET") != Name.npos      ||
309201360Srdivacky     Name.find("LOCK_") != Name.npos      ||
310201360Srdivacky     Name.find("WIN") != Name.npos)
311201360Srdivacky    return FILTER_STRONG;
312201360Srdivacky
313201360Srdivacky  // Special cases.
314218893Sdim
315201360Srdivacky  if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI")
316201360Srdivacky    return FILTER_WEAK;
317201360Srdivacky  if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI")
318201360Srdivacky    return FILTER_WEAK;
319201360Srdivacky
320201360Srdivacky  if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos)
321201360Srdivacky    return FILTER_WEAK;
322201360Srdivacky  if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos)
323201360Srdivacky    return FILTER_WEAK;
324201360Srdivacky  if (Name.find("Fs") != Name.npos)
325201360Srdivacky    return FILTER_WEAK;
326201360Srdivacky  if (Name == "MOVLPDrr"          ||
327201360Srdivacky      Name == "MOVLPSrr"          ||
328201360Srdivacky      Name == "PUSHFQ"            ||
329201360Srdivacky      Name == "BSF16rr"           ||
330201360Srdivacky      Name == "BSF16rm"           ||
331201360Srdivacky      Name == "BSR16rr"           ||
332201360Srdivacky      Name == "BSR16rm"           ||
333201360Srdivacky      Name == "MOVSX16rm8"        ||
334201360Srdivacky      Name == "MOVSX16rr8"        ||
335201360Srdivacky      Name == "MOVZX16rm8"        ||
336201360Srdivacky      Name == "MOVZX16rr8"        ||
337201360Srdivacky      Name == "PUSH32i16"         ||
338201360Srdivacky      Name == "PUSH64i16"         ||
339201360Srdivacky      Name == "MOVPQI2QImr"       ||
340201360Srdivacky      Name == "MOVSDmr"           ||
341201360Srdivacky      Name == "MOVSDrm"           ||
342201360Srdivacky      Name == "MOVSSmr"           ||
343201360Srdivacky      Name == "MOVSSrm"           ||
344201360Srdivacky      Name == "MMX_MOVD64rrv164"  ||
345201360Srdivacky      Name == "CRC32m16"          ||
346201360Srdivacky      Name == "MOV64ri64i32"      ||
347201360Srdivacky      Name == "CRC32r16")
348201360Srdivacky    return FILTER_WEAK;
349201360Srdivacky
350201360Srdivacky  // Filter out instructions with segment override prefixes.
351201360Srdivacky  // They're too messy to handle now and we'll special case them if needed.
352201360Srdivacky
353201360Srdivacky  if (SegOvr)
354201360Srdivacky    return FILTER_STRONG;
355201360Srdivacky
356201360Srdivacky  // Filter out instructions that can't be printed.
357201360Srdivacky
358201360Srdivacky  if (AsmString.size() == 0)
359201360Srdivacky    return FILTER_STRONG;
360201360Srdivacky
361201360Srdivacky  // Filter out instructions with subreg operands.
362201360Srdivacky
363201360Srdivacky  if (AsmString.find("subreg") != AsmString.npos)
364201360Srdivacky    return FILTER_STRONG;
365201360Srdivacky
366201360Srdivacky  if (HasFROperands && Name.find("MOV") != Name.npos &&
367201360Srdivacky     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
368201360Srdivacky      (Name.find("to") != Name.npos)))
369201360Srdivacky    return FILTER_WEAK;
370201360Srdivacky
371201360Srdivacky  return FILTER_NORMAL;
372201360Srdivacky}
373201360Srdivacky
374201360Srdivackyvoid RecognizableInstr::handleOperand(
375201360Srdivacky  bool optional,
376201360Srdivacky  unsigned &operandIndex,
377201360Srdivacky  unsigned &physicalOperandIndex,
378201360Srdivacky  unsigned &numPhysicalOperands,
379201360Srdivacky  unsigned *operandMapping,
380201360Srdivacky  OperandEncoding (*encodingFromString)(const std::string&, bool hasOpSizePrefix)) {
381201360Srdivacky  if (optional) {
382201360Srdivacky    if (physicalOperandIndex >= numPhysicalOperands)
383201360Srdivacky      return;
384201360Srdivacky  } else {
385201360Srdivacky    assert(physicalOperandIndex < numPhysicalOperands);
386201360Srdivacky  }
387201360Srdivacky
388201360Srdivacky  while (operandMapping[operandIndex] != operandIndex) {
389201360Srdivacky    Spec->operands[operandIndex].encoding = ENCODING_DUP;
390201360Srdivacky    Spec->operands[operandIndex].type =
391201360Srdivacky      (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);
392201360Srdivacky    ++operandIndex;
393201360Srdivacky  }
394201360Srdivacky
395201360Srdivacky  const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
396201360Srdivacky
397201360Srdivacky  Spec->operands[operandIndex].encoding = encodingFromString(typeName,
398201360Srdivacky                                                              HasOpSizePrefix);
399201360Srdivacky  Spec->operands[operandIndex].type = typeFromString(typeName,
400201360Srdivacky                                                      IsSSE,
401201360Srdivacky                                                      HasREX_WPrefix,
402201360Srdivacky                                                      HasOpSizePrefix);
403201360Srdivacky
404201360Srdivacky  ++operandIndex;
405201360Srdivacky  ++physicalOperandIndex;
406201360Srdivacky}
407201360Srdivacky
408201360Srdivackyvoid RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
409201360Srdivacky  Spec->name       = Name;
410201360Srdivacky
411201360Srdivacky  if (!Rec->isSubClassOf("X86Inst"))
412201360Srdivacky    return;
413201360Srdivacky
414201360Srdivacky  switch (filter()) {
415201360Srdivacky  case FILTER_WEAK:
416201360Srdivacky    Spec->filtered = true;
417201360Srdivacky    break;
418201360Srdivacky  case FILTER_STRONG:
419201360Srdivacky    ShouldBeEmitted = false;
420201360Srdivacky    return;
421201360Srdivacky  case FILTER_NORMAL:
422201360Srdivacky    break;
423201360Srdivacky  }
424201360Srdivacky
425201360Srdivacky  Spec->insnContext = insnContext();
426201360Srdivacky
427218893Sdim  const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
428201360Srdivacky
429201360Srdivacky  unsigned operandIndex;
430201360Srdivacky  unsigned numOperands = OperandList.size();
431201360Srdivacky  unsigned numPhysicalOperands = 0;
432201360Srdivacky
433201360Srdivacky  // operandMapping maps from operands in OperandList to their originals.
434201360Srdivacky  // If operandMapping[i] != i, then the entry is a duplicate.
435201360Srdivacky  unsigned operandMapping[X86_MAX_OPERANDS];
436201360Srdivacky
437201360Srdivacky  bool hasFROperands = false;
438201360Srdivacky
439201360Srdivacky  assert(numOperands < X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough");
440201360Srdivacky
441201360Srdivacky  for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
442201360Srdivacky    if (OperandList[operandIndex].Constraints.size()) {
443218893Sdim      const CGIOperandList::ConstraintInfo &Constraint =
444203954Srdivacky        OperandList[operandIndex].Constraints[0];
445203954Srdivacky      if (Constraint.isTied()) {
446203954Srdivacky        operandMapping[operandIndex] = Constraint.getTiedOperand();
447201360Srdivacky      } else {
448201360Srdivacky        ++numPhysicalOperands;
449201360Srdivacky        operandMapping[operandIndex] = operandIndex;
450201360Srdivacky      }
451201360Srdivacky    } else {
452201360Srdivacky      ++numPhysicalOperands;
453201360Srdivacky      operandMapping[operandIndex] = operandIndex;
454201360Srdivacky    }
455201360Srdivacky
456201360Srdivacky    const std::string &recName = OperandList[operandIndex].Rec->getName();
457201360Srdivacky
458201360Srdivacky    if (recName.find("FR") != recName.npos)
459201360Srdivacky      hasFROperands = true;
460201360Srdivacky  }
461201360Srdivacky
462201360Srdivacky  if (hasFROperands && Name.find("MOV") != Name.npos &&
463201360Srdivacky     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
464201360Srdivacky      (Name.find("to") != Name.npos)))
465201360Srdivacky    ShouldBeEmitted = false;
466201360Srdivacky
467201360Srdivacky  if (!ShouldBeEmitted)
468201360Srdivacky    return;
469201360Srdivacky
470201360Srdivacky#define HANDLE_OPERAND(class)               \
471201360Srdivacky  handleOperand(false,                      \
472201360Srdivacky                operandIndex,               \
473201360Srdivacky                physicalOperandIndex,       \
474201360Srdivacky                numPhysicalOperands,        \
475201360Srdivacky                operandMapping,             \
476201360Srdivacky                class##EncodingFromString);
477201360Srdivacky
478201360Srdivacky#define HANDLE_OPTIONAL(class)              \
479201360Srdivacky  handleOperand(true,                       \
480201360Srdivacky                operandIndex,               \
481201360Srdivacky                physicalOperandIndex,       \
482201360Srdivacky                numPhysicalOperands,        \
483201360Srdivacky                operandMapping,             \
484201360Srdivacky                class##EncodingFromString);
485201360Srdivacky
486201360Srdivacky  // operandIndex should always be < numOperands
487201360Srdivacky  operandIndex = 0;
488201360Srdivacky  // physicalOperandIndex should always be < numPhysicalOperands
489201360Srdivacky  unsigned physicalOperandIndex = 0;
490201360Srdivacky
491201360Srdivacky  switch (Form) {
492201360Srdivacky  case X86Local::RawFrm:
493201360Srdivacky    // Operand 1 (optional) is an address or immediate.
494201360Srdivacky    // Operand 2 (optional) is an immediate.
495201360Srdivacky    assert(numPhysicalOperands <= 2 &&
496201360Srdivacky           "Unexpected number of operands for RawFrm");
497201360Srdivacky    HANDLE_OPTIONAL(relocation)
498201360Srdivacky    HANDLE_OPTIONAL(immediate)
499201360Srdivacky    break;
500201360Srdivacky  case X86Local::AddRegFrm:
501201360Srdivacky    // Operand 1 is added to the opcode.
502201360Srdivacky    // Operand 2 (optional) is an address.
503201360Srdivacky    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
504201360Srdivacky           "Unexpected number of operands for AddRegFrm");
505201360Srdivacky    HANDLE_OPERAND(opcodeModifier)
506201360Srdivacky    HANDLE_OPTIONAL(relocation)
507201360Srdivacky    break;
508201360Srdivacky  case X86Local::MRMDestReg:
509201360Srdivacky    // Operand 1 is a register operand in the R/M field.
510201360Srdivacky    // Operand 2 is a register operand in the Reg/Opcode field.
511201360Srdivacky    // Operand 3 (optional) is an immediate.
512201360Srdivacky    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
513201360Srdivacky           "Unexpected number of operands for MRMDestRegFrm");
514201360Srdivacky    HANDLE_OPERAND(rmRegister)
515201360Srdivacky    HANDLE_OPERAND(roRegister)
516201360Srdivacky    HANDLE_OPTIONAL(immediate)
517201360Srdivacky    break;
518201360Srdivacky  case X86Local::MRMDestMem:
519201360Srdivacky    // Operand 1 is a memory operand (possibly SIB-extended)
520201360Srdivacky    // Operand 2 is a register operand in the Reg/Opcode field.
521201360Srdivacky    // Operand 3 (optional) is an immediate.
522201360Srdivacky    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
523201360Srdivacky           "Unexpected number of operands for MRMDestMemFrm");
524201360Srdivacky    HANDLE_OPERAND(memory)
525201360Srdivacky    HANDLE_OPERAND(roRegister)
526201360Srdivacky    HANDLE_OPTIONAL(immediate)
527201360Srdivacky    break;
528201360Srdivacky  case X86Local::MRMSrcReg:
529201360Srdivacky    // Operand 1 is a register operand in the Reg/Opcode field.
530201360Srdivacky    // Operand 2 is a register operand in the R/M field.
531201360Srdivacky    // Operand 3 (optional) is an immediate.
532201360Srdivacky    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
533201360Srdivacky           "Unexpected number of operands for MRMSrcRegFrm");
534201360Srdivacky    HANDLE_OPERAND(roRegister)
535201360Srdivacky    HANDLE_OPERAND(rmRegister)
536210299Sed
537210299Sed    if (HasVEX_4VPrefix)
538210299Sed      // FIXME: In AVX, the register below becomes the one encoded
539210299Sed      // in ModRMVEX and the one above the one in the VEX.VVVV field
540210299Sed      HANDLE_OPTIONAL(rmRegister)
541210299Sed    else
542210299Sed      HANDLE_OPTIONAL(immediate)
543201360Srdivacky    break;
544201360Srdivacky  case X86Local::MRMSrcMem:
545201360Srdivacky    // Operand 1 is a register operand in the Reg/Opcode field.
546201360Srdivacky    // Operand 2 is a memory operand (possibly SIB-extended)
547201360Srdivacky    // Operand 3 (optional) is an immediate.
548201360Srdivacky    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
549201360Srdivacky           "Unexpected number of operands for MRMSrcMemFrm");
550201360Srdivacky    HANDLE_OPERAND(roRegister)
551210299Sed
552210299Sed    if (HasVEX_4VPrefix)
553210299Sed      // FIXME: In AVX, the register below becomes the one encoded
554210299Sed      // in ModRMVEX and the one above the one in the VEX.VVVV field
555210299Sed      HANDLE_OPTIONAL(rmRegister)
556210299Sed
557201360Srdivacky    HANDLE_OPERAND(memory)
558201360Srdivacky    HANDLE_OPTIONAL(immediate)
559201360Srdivacky    break;
560201360Srdivacky  case X86Local::MRM0r:
561201360Srdivacky  case X86Local::MRM1r:
562201360Srdivacky  case X86Local::MRM2r:
563201360Srdivacky  case X86Local::MRM3r:
564201360Srdivacky  case X86Local::MRM4r:
565201360Srdivacky  case X86Local::MRM5r:
566201360Srdivacky  case X86Local::MRM6r:
567201360Srdivacky  case X86Local::MRM7r:
568201360Srdivacky    // Operand 1 is a register operand in the R/M field.
569201360Srdivacky    // Operand 2 (optional) is an immediate or relocation.
570201360Srdivacky    assert(numPhysicalOperands <= 2 &&
571201360Srdivacky           "Unexpected number of operands for MRMnRFrm");
572201360Srdivacky    HANDLE_OPTIONAL(rmRegister)
573201360Srdivacky    HANDLE_OPTIONAL(relocation)
574201360Srdivacky    break;
575201360Srdivacky  case X86Local::MRM0m:
576201360Srdivacky  case X86Local::MRM1m:
577201360Srdivacky  case X86Local::MRM2m:
578201360Srdivacky  case X86Local::MRM3m:
579201360Srdivacky  case X86Local::MRM4m:
580201360Srdivacky  case X86Local::MRM5m:
581201360Srdivacky  case X86Local::MRM6m:
582201360Srdivacky  case X86Local::MRM7m:
583201360Srdivacky    // Operand 1 is a memory operand (possibly SIB-extended)
584201360Srdivacky    // Operand 2 (optional) is an immediate or relocation.
585201360Srdivacky    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
586201360Srdivacky           "Unexpected number of operands for MRMnMFrm");
587201360Srdivacky    HANDLE_OPERAND(memory)
588201360Srdivacky    HANDLE_OPTIONAL(relocation)
589201360Srdivacky    break;
590218893Sdim  case X86Local::RawFrmImm8:
591218893Sdim    // operand 1 is a 16-bit immediate
592218893Sdim    // operand 2 is an 8-bit immediate
593218893Sdim    assert(numPhysicalOperands == 2 &&
594218893Sdim           "Unexpected number of operands for X86Local::RawFrmImm8");
595218893Sdim    HANDLE_OPERAND(immediate)
596218893Sdim    HANDLE_OPERAND(immediate)
597218893Sdim    break;
598218893Sdim  case X86Local::RawFrmImm16:
599218893Sdim    // operand 1 is a 16-bit immediate
600218893Sdim    // operand 2 is a 16-bit immediate
601218893Sdim    HANDLE_OPERAND(immediate)
602218893Sdim    HANDLE_OPERAND(immediate)
603218893Sdim    break;
604201360Srdivacky  case X86Local::MRMInitReg:
605201360Srdivacky    // Ignored.
606201360Srdivacky    break;
607201360Srdivacky  }
608201360Srdivacky
609201360Srdivacky  #undef HANDLE_OPERAND
610201360Srdivacky  #undef HANDLE_OPTIONAL
611201360Srdivacky}
612201360Srdivacky
613201360Srdivackyvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
614201360Srdivacky  // Special cases where the LLVM tables are not complete
615201360Srdivacky
616203954Srdivacky#define MAP(from, to)                     \
617203954Srdivacky  case X86Local::MRM_##from:              \
618203954Srdivacky    filter = new ExactFilter(0x##from);   \
619203954Srdivacky    break;
620201360Srdivacky
621201360Srdivacky  OpcodeType    opcodeType  = (OpcodeType)-1;
622201360Srdivacky
623201360Srdivacky  ModRMFilter*  filter      = NULL;
624201360Srdivacky  uint8_t       opcodeToSet = 0;
625201360Srdivacky
626201360Srdivacky  switch (Prefix) {
627201360Srdivacky  // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f
628201360Srdivacky  case X86Local::XD:
629201360Srdivacky  case X86Local::XS:
630201360Srdivacky  case X86Local::TB:
631201360Srdivacky    opcodeType = TWOBYTE;
632201360Srdivacky
633201360Srdivacky    switch (Opcode) {
634203954Srdivacky    default:
635203954Srdivacky      if (needsModRMForDecode(Form))
636203954Srdivacky        filter = new ModFilter(isRegFormat(Form));
637203954Srdivacky      else
638203954Srdivacky        filter = new DumbFilter();
639203954Srdivacky      break;
640201360Srdivacky#define EXTENSION_TABLE(n) case 0x##n:
641201360Srdivacky    TWO_BYTE_EXTENSION_TABLES
642201360Srdivacky#undef EXTENSION_TABLE
643201360Srdivacky      switch (Form) {
644201360Srdivacky      default:
645201360Srdivacky        llvm_unreachable("Unhandled two-byte extended opcode");
646201360Srdivacky      case X86Local::MRM0r:
647201360Srdivacky      case X86Local::MRM1r:
648201360Srdivacky      case X86Local::MRM2r:
649201360Srdivacky      case X86Local::MRM3r:
650201360Srdivacky      case X86Local::MRM4r:
651201360Srdivacky      case X86Local::MRM5r:
652201360Srdivacky      case X86Local::MRM6r:
653201360Srdivacky      case X86Local::MRM7r:
654201360Srdivacky        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
655201360Srdivacky        break;
656201360Srdivacky      case X86Local::MRM0m:
657201360Srdivacky      case X86Local::MRM1m:
658201360Srdivacky      case X86Local::MRM2m:
659201360Srdivacky      case X86Local::MRM3m:
660201360Srdivacky      case X86Local::MRM4m:
661201360Srdivacky      case X86Local::MRM5m:
662201360Srdivacky      case X86Local::MRM6m:
663201360Srdivacky      case X86Local::MRM7m:
664201360Srdivacky        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
665201360Srdivacky        break;
666203954Srdivacky      MRM_MAPPING
667201360Srdivacky      } // switch (Form)
668201360Srdivacky      break;
669203954Srdivacky    } // switch (Opcode)
670201360Srdivacky    opcodeToSet = Opcode;
671201360Srdivacky    break;
672201360Srdivacky  case X86Local::T8:
673201360Srdivacky    opcodeType = THREEBYTE_38;
674201360Srdivacky    if (needsModRMForDecode(Form))
675201360Srdivacky      filter = new ModFilter(isRegFormat(Form));
676201360Srdivacky    else
677201360Srdivacky      filter = new DumbFilter();
678201360Srdivacky    opcodeToSet = Opcode;
679201360Srdivacky    break;
680203954Srdivacky  case X86Local::P_TA:
681201360Srdivacky    opcodeType = THREEBYTE_3A;
682201360Srdivacky    if (needsModRMForDecode(Form))
683201360Srdivacky      filter = new ModFilter(isRegFormat(Form));
684201360Srdivacky    else
685201360Srdivacky      filter = new DumbFilter();
686201360Srdivacky    opcodeToSet = Opcode;
687201360Srdivacky    break;
688201360Srdivacky  case X86Local::D8:
689201360Srdivacky  case X86Local::D9:
690201360Srdivacky  case X86Local::DA:
691201360Srdivacky  case X86Local::DB:
692201360Srdivacky  case X86Local::DC:
693201360Srdivacky  case X86Local::DD:
694201360Srdivacky  case X86Local::DE:
695201360Srdivacky  case X86Local::DF:
696201360Srdivacky    assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
697201360Srdivacky    opcodeType = ONEBYTE;
698201360Srdivacky    if (Form == X86Local::AddRegFrm) {
699201360Srdivacky      Spec->modifierType = MODIFIER_MODRM;
700201360Srdivacky      Spec->modifierBase = Opcode;
701201360Srdivacky      filter = new AddRegEscapeFilter(Opcode);
702201360Srdivacky    } else {
703201360Srdivacky      filter = new EscapeFilter(true, Opcode);
704201360Srdivacky    }
705201360Srdivacky    opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
706201360Srdivacky    break;
707201360Srdivacky  default:
708201360Srdivacky    opcodeType = ONEBYTE;
709201360Srdivacky    switch (Opcode) {
710201360Srdivacky#define EXTENSION_TABLE(n) case 0x##n:
711201360Srdivacky    ONE_BYTE_EXTENSION_TABLES
712201360Srdivacky#undef EXTENSION_TABLE
713201360Srdivacky      switch (Form) {
714201360Srdivacky      default:
715201360Srdivacky        llvm_unreachable("Fell through the cracks of a single-byte "
716201360Srdivacky                         "extended opcode");
717201360Srdivacky      case X86Local::MRM0r:
718201360Srdivacky      case X86Local::MRM1r:
719201360Srdivacky      case X86Local::MRM2r:
720201360Srdivacky      case X86Local::MRM3r:
721201360Srdivacky      case X86Local::MRM4r:
722201360Srdivacky      case X86Local::MRM5r:
723201360Srdivacky      case X86Local::MRM6r:
724201360Srdivacky      case X86Local::MRM7r:
725201360Srdivacky        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
726201360Srdivacky        break;
727201360Srdivacky      case X86Local::MRM0m:
728201360Srdivacky      case X86Local::MRM1m:
729201360Srdivacky      case X86Local::MRM2m:
730201360Srdivacky      case X86Local::MRM3m:
731201360Srdivacky      case X86Local::MRM4m:
732201360Srdivacky      case X86Local::MRM5m:
733201360Srdivacky      case X86Local::MRM6m:
734201360Srdivacky      case X86Local::MRM7m:
735201360Srdivacky        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
736201360Srdivacky        break;
737203954Srdivacky      MRM_MAPPING
738201360Srdivacky      } // switch (Form)
739201360Srdivacky      break;
740201360Srdivacky    case 0xd8:
741201360Srdivacky    case 0xd9:
742201360Srdivacky    case 0xda:
743201360Srdivacky    case 0xdb:
744201360Srdivacky    case 0xdc:
745201360Srdivacky    case 0xdd:
746201360Srdivacky    case 0xde:
747201360Srdivacky    case 0xdf:
748201360Srdivacky      filter = new EscapeFilter(false, Form - X86Local::MRM0m);
749201360Srdivacky      break;
750201360Srdivacky    default:
751201360Srdivacky      if (needsModRMForDecode(Form))
752201360Srdivacky        filter = new ModFilter(isRegFormat(Form));
753201360Srdivacky      else
754201360Srdivacky        filter = new DumbFilter();
755201360Srdivacky      break;
756201360Srdivacky    } // switch (Opcode)
757201360Srdivacky    opcodeToSet = Opcode;
758201360Srdivacky  } // switch (Prefix)
759201360Srdivacky
760201360Srdivacky  assert(opcodeType != (OpcodeType)-1 &&
761201360Srdivacky         "Opcode type not set");
762201360Srdivacky  assert(filter && "Filter not set");
763201360Srdivacky
764201360Srdivacky  if (Form == X86Local::AddRegFrm) {
765201360Srdivacky    if(Spec->modifierType != MODIFIER_MODRM) {
766201360Srdivacky      assert(opcodeToSet < 0xf9 &&
767201360Srdivacky             "Not enough room for all ADDREG_FRM operands");
768201360Srdivacky
769201360Srdivacky      uint8_t currentOpcode;
770201360Srdivacky
771201360Srdivacky      for (currentOpcode = opcodeToSet;
772201360Srdivacky           currentOpcode < opcodeToSet + 8;
773201360Srdivacky           ++currentOpcode)
774201360Srdivacky        tables.setTableFields(opcodeType,
775201360Srdivacky                              insnContext(),
776201360Srdivacky                              currentOpcode,
777201360Srdivacky                              *filter,
778201360Srdivacky                              UID);
779201360Srdivacky
780201360Srdivacky      Spec->modifierType = MODIFIER_OPCODE;
781201360Srdivacky      Spec->modifierBase = opcodeToSet;
782201360Srdivacky    } else {
783201360Srdivacky      // modifierBase was set where MODIFIER_MODRM was set
784201360Srdivacky      tables.setTableFields(opcodeType,
785201360Srdivacky                            insnContext(),
786201360Srdivacky                            opcodeToSet,
787201360Srdivacky                            *filter,
788201360Srdivacky                            UID);
789201360Srdivacky    }
790201360Srdivacky  } else {
791201360Srdivacky    tables.setTableFields(opcodeType,
792201360Srdivacky                          insnContext(),
793201360Srdivacky                          opcodeToSet,
794201360Srdivacky                          *filter,
795201360Srdivacky                          UID);
796201360Srdivacky
797201360Srdivacky    Spec->modifierType = MODIFIER_NONE;
798201360Srdivacky    Spec->modifierBase = opcodeToSet;
799201360Srdivacky  }
800201360Srdivacky
801201360Srdivacky  delete filter;
802203954Srdivacky
803203954Srdivacky#undef MAP
804201360Srdivacky}
805201360Srdivacky
806201360Srdivacky#define TYPE(str, type) if (s == str) return type;
807201360SrdivackyOperandType RecognizableInstr::typeFromString(const std::string &s,
808201360Srdivacky                                              bool isSSE,
809201360Srdivacky                                              bool hasREX_WPrefix,
810201360Srdivacky                                              bool hasOpSizePrefix) {
811201360Srdivacky  if (isSSE) {
812201360Srdivacky    // For SSE instructions, we ignore the OpSize prefix and force operand
813201360Srdivacky    // sizes.
814201360Srdivacky    TYPE("GR16",              TYPE_R16)
815201360Srdivacky    TYPE("GR32",              TYPE_R32)
816201360Srdivacky    TYPE("GR64",              TYPE_R64)
817201360Srdivacky  }
818201360Srdivacky  if(hasREX_WPrefix) {
819201360Srdivacky    // For instructions with a REX_W prefix, a declared 32-bit register encoding
820201360Srdivacky    // is special.
821201360Srdivacky    TYPE("GR32",              TYPE_R32)
822201360Srdivacky  }
823201360Srdivacky  if(!hasOpSizePrefix) {
824201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
825201360Srdivacky    // immediate encoding is special.
826201360Srdivacky    TYPE("GR16",              TYPE_R16)
827201360Srdivacky    TYPE("i16imm",            TYPE_IMM16)
828201360Srdivacky  }
829201360Srdivacky  TYPE("i16mem",              TYPE_Mv)
830201360Srdivacky  TYPE("i16imm",              TYPE_IMMv)
831201360Srdivacky  TYPE("i16i8imm",            TYPE_IMMv)
832201360Srdivacky  TYPE("GR16",                TYPE_Rv)
833201360Srdivacky  TYPE("i32mem",              TYPE_Mv)
834201360Srdivacky  TYPE("i32imm",              TYPE_IMMv)
835201360Srdivacky  TYPE("i32i8imm",            TYPE_IMM32)
836201360Srdivacky  TYPE("GR32",                TYPE_Rv)
837201360Srdivacky  TYPE("i64mem",              TYPE_Mv)
838201360Srdivacky  TYPE("i64i32imm",           TYPE_IMM64)
839201360Srdivacky  TYPE("i64i8imm",            TYPE_IMM64)
840201360Srdivacky  TYPE("GR64",                TYPE_R64)
841201360Srdivacky  TYPE("i8mem",               TYPE_M8)
842201360Srdivacky  TYPE("i8imm",               TYPE_IMM8)
843201360Srdivacky  TYPE("GR8",                 TYPE_R8)
844201360Srdivacky  TYPE("VR128",               TYPE_XMM128)
845201360Srdivacky  TYPE("f128mem",             TYPE_M128)
846218893Sdim  TYPE("f256mem",             TYPE_M256)
847201360Srdivacky  TYPE("FR64",                TYPE_XMM64)
848201360Srdivacky  TYPE("f64mem",              TYPE_M64FP)
849218893Sdim  TYPE("sdmem",               TYPE_M64FP)
850201360Srdivacky  TYPE("FR32",                TYPE_XMM32)
851201360Srdivacky  TYPE("f32mem",              TYPE_M32FP)
852218893Sdim  TYPE("ssmem",               TYPE_M32FP)
853201360Srdivacky  TYPE("RST",                 TYPE_ST)
854201360Srdivacky  TYPE("i128mem",             TYPE_M128)
855201360Srdivacky  TYPE("i64i32imm_pcrel",     TYPE_REL64)
856210299Sed  TYPE("i16imm_pcrel",        TYPE_REL16)
857201360Srdivacky  TYPE("i32imm_pcrel",        TYPE_REL32)
858207618Srdivacky  TYPE("SSECC",               TYPE_IMM3)
859201360Srdivacky  TYPE("brtarget",            TYPE_RELv)
860218893Sdim  TYPE("uncondbrtarget",      TYPE_RELv)
861201360Srdivacky  TYPE("brtarget8",           TYPE_REL8)
862201360Srdivacky  TYPE("f80mem",              TYPE_M80FP)
863201360Srdivacky  TYPE("lea32mem",            TYPE_LEA)
864201360Srdivacky  TYPE("lea64_32mem",         TYPE_LEA)
865201360Srdivacky  TYPE("lea64mem",            TYPE_LEA)
866201360Srdivacky  TYPE("VR64",                TYPE_MM64)
867201360Srdivacky  TYPE("i64imm",              TYPE_IMMv)
868201360Srdivacky  TYPE("opaque32mem",         TYPE_M1616)
869201360Srdivacky  TYPE("opaque48mem",         TYPE_M1632)
870201360Srdivacky  TYPE("opaque80mem",         TYPE_M1664)
871201360Srdivacky  TYPE("opaque512mem",        TYPE_M512)
872201360Srdivacky  TYPE("SEGMENT_REG",         TYPE_SEGMENTREG)
873201360Srdivacky  TYPE("DEBUG_REG",           TYPE_DEBUGREG)
874208599Srdivacky  TYPE("CONTROL_REG",         TYPE_CONTROLREG)
875201360Srdivacky  TYPE("offset8",             TYPE_MOFFS8)
876201360Srdivacky  TYPE("offset16",            TYPE_MOFFS16)
877201360Srdivacky  TYPE("offset32",            TYPE_MOFFS32)
878201360Srdivacky  TYPE("offset64",            TYPE_MOFFS64)
879201360Srdivacky  errs() << "Unhandled type string " << s << "\n";
880201360Srdivacky  llvm_unreachable("Unhandled type string");
881201360Srdivacky}
882201360Srdivacky#undef TYPE
883201360Srdivacky
884201360Srdivacky#define ENCODING(str, encoding) if (s == str) return encoding;
885201360SrdivackyOperandEncoding RecognizableInstr::immediateEncodingFromString
886201360Srdivacky  (const std::string &s,
887201360Srdivacky   bool hasOpSizePrefix) {
888201360Srdivacky  if(!hasOpSizePrefix) {
889201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
890201360Srdivacky    // immediate encoding is special.
891201360Srdivacky    ENCODING("i16imm",        ENCODING_IW)
892201360Srdivacky  }
893201360Srdivacky  ENCODING("i32i8imm",        ENCODING_IB)
894201360Srdivacky  ENCODING("SSECC",           ENCODING_IB)
895201360Srdivacky  ENCODING("i16imm",          ENCODING_Iv)
896201360Srdivacky  ENCODING("i16i8imm",        ENCODING_IB)
897201360Srdivacky  ENCODING("i32imm",          ENCODING_Iv)
898201360Srdivacky  ENCODING("i64i32imm",       ENCODING_ID)
899201360Srdivacky  ENCODING("i64i8imm",        ENCODING_IB)
900201360Srdivacky  ENCODING("i8imm",           ENCODING_IB)
901201360Srdivacky  errs() << "Unhandled immediate encoding " << s << "\n";
902201360Srdivacky  llvm_unreachable("Unhandled immediate encoding");
903201360Srdivacky}
904201360Srdivacky
905201360SrdivackyOperandEncoding RecognizableInstr::rmRegisterEncodingFromString
906201360Srdivacky  (const std::string &s,
907201360Srdivacky   bool hasOpSizePrefix) {
908201360Srdivacky  ENCODING("GR16",            ENCODING_RM)
909201360Srdivacky  ENCODING("GR32",            ENCODING_RM)
910201360Srdivacky  ENCODING("GR64",            ENCODING_RM)
911201360Srdivacky  ENCODING("GR8",             ENCODING_RM)
912201360Srdivacky  ENCODING("VR128",           ENCODING_RM)
913201360Srdivacky  ENCODING("FR64",            ENCODING_RM)
914201360Srdivacky  ENCODING("FR32",            ENCODING_RM)
915201360Srdivacky  ENCODING("VR64",            ENCODING_RM)
916201360Srdivacky  errs() << "Unhandled R/M register encoding " << s << "\n";
917201360Srdivacky  llvm_unreachable("Unhandled R/M register encoding");
918201360Srdivacky}
919201360Srdivacky
920201360SrdivackyOperandEncoding RecognizableInstr::roRegisterEncodingFromString
921201360Srdivacky  (const std::string &s,
922201360Srdivacky   bool hasOpSizePrefix) {
923201360Srdivacky  ENCODING("GR16",            ENCODING_REG)
924201360Srdivacky  ENCODING("GR32",            ENCODING_REG)
925201360Srdivacky  ENCODING("GR64",            ENCODING_REG)
926201360Srdivacky  ENCODING("GR8",             ENCODING_REG)
927201360Srdivacky  ENCODING("VR128",           ENCODING_REG)
928201360Srdivacky  ENCODING("FR64",            ENCODING_REG)
929201360Srdivacky  ENCODING("FR32",            ENCODING_REG)
930201360Srdivacky  ENCODING("VR64",            ENCODING_REG)
931201360Srdivacky  ENCODING("SEGMENT_REG",     ENCODING_REG)
932201360Srdivacky  ENCODING("DEBUG_REG",       ENCODING_REG)
933208599Srdivacky  ENCODING("CONTROL_REG",     ENCODING_REG)
934201360Srdivacky  errs() << "Unhandled reg/opcode register encoding " << s << "\n";
935201360Srdivacky  llvm_unreachable("Unhandled reg/opcode register encoding");
936201360Srdivacky}
937201360Srdivacky
938201360SrdivackyOperandEncoding RecognizableInstr::memoryEncodingFromString
939201360Srdivacky  (const std::string &s,
940201360Srdivacky   bool hasOpSizePrefix) {
941201360Srdivacky  ENCODING("i16mem",          ENCODING_RM)
942201360Srdivacky  ENCODING("i32mem",          ENCODING_RM)
943201360Srdivacky  ENCODING("i64mem",          ENCODING_RM)
944201360Srdivacky  ENCODING("i8mem",           ENCODING_RM)
945218893Sdim  ENCODING("ssmem",           ENCODING_RM)
946218893Sdim  ENCODING("sdmem",           ENCODING_RM)
947201360Srdivacky  ENCODING("f128mem",         ENCODING_RM)
948218893Sdim  ENCODING("f256mem",         ENCODING_RM)
949201360Srdivacky  ENCODING("f64mem",          ENCODING_RM)
950201360Srdivacky  ENCODING("f32mem",          ENCODING_RM)
951201360Srdivacky  ENCODING("i128mem",         ENCODING_RM)
952201360Srdivacky  ENCODING("f80mem",          ENCODING_RM)
953201360Srdivacky  ENCODING("lea32mem",        ENCODING_RM)
954201360Srdivacky  ENCODING("lea64_32mem",     ENCODING_RM)
955201360Srdivacky  ENCODING("lea64mem",        ENCODING_RM)
956201360Srdivacky  ENCODING("opaque32mem",     ENCODING_RM)
957201360Srdivacky  ENCODING("opaque48mem",     ENCODING_RM)
958201360Srdivacky  ENCODING("opaque80mem",     ENCODING_RM)
959201360Srdivacky  ENCODING("opaque512mem",    ENCODING_RM)
960201360Srdivacky  errs() << "Unhandled memory encoding " << s << "\n";
961201360Srdivacky  llvm_unreachable("Unhandled memory encoding");
962201360Srdivacky}
963201360Srdivacky
964201360SrdivackyOperandEncoding RecognizableInstr::relocationEncodingFromString
965201360Srdivacky  (const std::string &s,
966201360Srdivacky   bool hasOpSizePrefix) {
967201360Srdivacky  if(!hasOpSizePrefix) {
968201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
969201360Srdivacky    // immediate encoding is special.
970201360Srdivacky    ENCODING("i16imm",        ENCODING_IW)
971201360Srdivacky  }
972201360Srdivacky  ENCODING("i16imm",          ENCODING_Iv)
973201360Srdivacky  ENCODING("i16i8imm",        ENCODING_IB)
974201360Srdivacky  ENCODING("i32imm",          ENCODING_Iv)
975201360Srdivacky  ENCODING("i32i8imm",        ENCODING_IB)
976201360Srdivacky  ENCODING("i64i32imm",       ENCODING_ID)
977201360Srdivacky  ENCODING("i64i8imm",        ENCODING_IB)
978201360Srdivacky  ENCODING("i8imm",           ENCODING_IB)
979201360Srdivacky  ENCODING("i64i32imm_pcrel", ENCODING_ID)
980210299Sed  ENCODING("i16imm_pcrel",    ENCODING_IW)
981201360Srdivacky  ENCODING("i32imm_pcrel",    ENCODING_ID)
982201360Srdivacky  ENCODING("brtarget",        ENCODING_Iv)
983201360Srdivacky  ENCODING("brtarget8",       ENCODING_IB)
984201360Srdivacky  ENCODING("i64imm",          ENCODING_IO)
985201360Srdivacky  ENCODING("offset8",         ENCODING_Ia)
986201360Srdivacky  ENCODING("offset16",        ENCODING_Ia)
987201360Srdivacky  ENCODING("offset32",        ENCODING_Ia)
988201360Srdivacky  ENCODING("offset64",        ENCODING_Ia)
989201360Srdivacky  errs() << "Unhandled relocation encoding " << s << "\n";
990201360Srdivacky  llvm_unreachable("Unhandled relocation encoding");
991201360Srdivacky}
992201360Srdivacky
993201360SrdivackyOperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
994201360Srdivacky  (const std::string &s,
995201360Srdivacky   bool hasOpSizePrefix) {
996201360Srdivacky  ENCODING("RST",             ENCODING_I)
997201360Srdivacky  ENCODING("GR32",            ENCODING_Rv)
998201360Srdivacky  ENCODING("GR64",            ENCODING_RO)
999201360Srdivacky  ENCODING("GR16",            ENCODING_Rv)
1000201360Srdivacky  ENCODING("GR8",             ENCODING_RB)
1001201360Srdivacky  errs() << "Unhandled opcode modifier encoding " << s << "\n";
1002201360Srdivacky  llvm_unreachable("Unhandled opcode modifier encoding");
1003201360Srdivacky}
1004201360Srdivacky#undef ENCODING
1005