X86RecognizableInstr.cpp revision 208599
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)           \
36203954Srdivacky  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
55203954Srdivacky#define MAP(from, to) MRM_##from = to,
56203954Srdivacky    MRM_MAPPING
57203954Srdivacky#undef MAP
58203954Srdivacky    lastMRM
59201360Srdivacky  };
60201360Srdivacky
61201360Srdivacky  enum {
62201360Srdivacky    TB  = 1,
63201360Srdivacky    REP = 2,
64201360Srdivacky    D8 = 3, D9 = 4, DA = 5, DB = 6,
65201360Srdivacky    DC = 7, DD = 8, DE = 9, DF = 10,
66201360Srdivacky    XD = 11,  XS = 12,
67203954Srdivacky    T8 = 13,  P_TA = 14,
68203954Srdivacky    P_0F_AE = 16, P_0F_01 = 17
69201360Srdivacky  };
70201360Srdivacky}
71203954Srdivacky
72203954Srdivacky// If rows are added to the opcode extension tables, then corresponding entries
73203954Srdivacky// must be added here.
74203954Srdivacky//
75203954Srdivacky// If the row corresponds to a single byte (i.e., 8f), then add an entry for
76203954Srdivacky// that byte to ONE_BYTE_EXTENSION_TABLES.
77203954Srdivacky//
78203954Srdivacky// If the row corresponds to two bytes where the first is 0f, add an entry for
79203954Srdivacky// the second byte to TWO_BYTE_EXTENSION_TABLES.
80203954Srdivacky//
81203954Srdivacky// If the row corresponds to some other set of bytes, you will need to modify
82203954Srdivacky// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes
83203954Srdivacky// to the X86 TD files, except in two cases: if the first two bytes of such a
84203954Srdivacky// new combination are 0f 38 or 0f 3a, you just have to add maps called
85203954Srdivacky// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a
86203954Srdivacky// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line
87203954Srdivacky// in RecognizableInstr::emitDecodePath().
88203954Srdivacky
89201360Srdivacky#define ONE_BYTE_EXTENSION_TABLES \
90201360Srdivacky  EXTENSION_TABLE(80)             \
91201360Srdivacky  EXTENSION_TABLE(81)             \
92201360Srdivacky  EXTENSION_TABLE(82)             \
93201360Srdivacky  EXTENSION_TABLE(83)             \
94201360Srdivacky  EXTENSION_TABLE(8f)             \
95201360Srdivacky  EXTENSION_TABLE(c0)             \
96201360Srdivacky  EXTENSION_TABLE(c1)             \
97201360Srdivacky  EXTENSION_TABLE(c6)             \
98201360Srdivacky  EXTENSION_TABLE(c7)             \
99201360Srdivacky  EXTENSION_TABLE(d0)             \
100201360Srdivacky  EXTENSION_TABLE(d1)             \
101201360Srdivacky  EXTENSION_TABLE(d2)             \
102201360Srdivacky  EXTENSION_TABLE(d3)             \
103201360Srdivacky  EXTENSION_TABLE(f6)             \
104201360Srdivacky  EXTENSION_TABLE(f7)             \
105201360Srdivacky  EXTENSION_TABLE(fe)             \
106201360Srdivacky  EXTENSION_TABLE(ff)
107201360Srdivacky
108201360Srdivacky#define TWO_BYTE_EXTENSION_TABLES \
109201360Srdivacky  EXTENSION_TABLE(00)             \
110201360Srdivacky  EXTENSION_TABLE(01)             \
111201360Srdivacky  EXTENSION_TABLE(18)             \
112201360Srdivacky  EXTENSION_TABLE(71)             \
113201360Srdivacky  EXTENSION_TABLE(72)             \
114201360Srdivacky  EXTENSION_TABLE(73)             \
115201360Srdivacky  EXTENSION_TABLE(ae)             \
116201360Srdivacky  EXTENSION_TABLE(b9)             \
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");
215201360Srdivacky  HasLockPrefix    = Rec->getValueAsBit("hasLockPrefix");
216201360Srdivacky  IsCodeGenOnly    = Rec->getValueAsBit("isCodeGenOnly");
217201360Srdivacky
218201360Srdivacky  Name      = Rec->getName();
219201360Srdivacky  AsmString = Rec->getValueAsString("AsmString");
220201360Srdivacky
221201360Srdivacky  Operands = &insn.OperandList;
222201360Srdivacky
223201360Srdivacky  IsSSE            = HasOpSizePrefix && (Name.find("16") == Name.npos);
224201360Srdivacky  HasFROperands    = false;
225201360Srdivacky
226201360Srdivacky  ShouldBeEmitted  = true;
227201360Srdivacky}
228201360Srdivacky
229201360Srdivackyvoid RecognizableInstr::processInstr(DisassemblerTables &tables,
230201360Srdivacky                                   const CodeGenInstruction &insn,
231201360Srdivacky                                   InstrUID uid)
232201360Srdivacky{
233208599Srdivacky  // Ignore "asm parser only" instructions.
234208599Srdivacky  if (insn.TheDef->getValueAsBit("isAsmParserOnly"))
235208599Srdivacky    return;
236208599Srdivacky
237201360Srdivacky  RecognizableInstr recogInstr(tables, insn, uid);
238201360Srdivacky
239201360Srdivacky  recogInstr.emitInstructionSpecifier(tables);
240201360Srdivacky
241201360Srdivacky  if (recogInstr.shouldBeEmitted())
242201360Srdivacky    recogInstr.emitDecodePath(tables);
243201360Srdivacky}
244201360Srdivacky
245201360SrdivackyInstructionContext RecognizableInstr::insnContext() const {
246201360Srdivacky  InstructionContext insnContext;
247201360Srdivacky
248201360Srdivacky  if (Name.find("64") != Name.npos || HasREX_WPrefix) {
249201360Srdivacky    if (HasREX_WPrefix && HasOpSizePrefix)
250201360Srdivacky      insnContext = IC_64BIT_REXW_OPSIZE;
251201360Srdivacky    else if (HasOpSizePrefix)
252201360Srdivacky      insnContext = IC_64BIT_OPSIZE;
253201360Srdivacky    else if (HasREX_WPrefix && Prefix == X86Local::XS)
254201360Srdivacky      insnContext = IC_64BIT_REXW_XS;
255201360Srdivacky    else if (HasREX_WPrefix && Prefix == X86Local::XD)
256201360Srdivacky      insnContext = IC_64BIT_REXW_XD;
257201360Srdivacky    else if (Prefix == X86Local::XD)
258201360Srdivacky      insnContext = IC_64BIT_XD;
259201360Srdivacky    else if (Prefix == X86Local::XS)
260201360Srdivacky      insnContext = IC_64BIT_XS;
261201360Srdivacky    else if (HasREX_WPrefix)
262201360Srdivacky      insnContext = IC_64BIT_REXW;
263201360Srdivacky    else
264201360Srdivacky      insnContext = IC_64BIT;
265201360Srdivacky  } else {
266201360Srdivacky    if (HasOpSizePrefix)
267201360Srdivacky      insnContext = IC_OPSIZE;
268201360Srdivacky    else if (Prefix == X86Local::XD)
269201360Srdivacky      insnContext = IC_XD;
270201360Srdivacky    else if (Prefix == X86Local::XS)
271201360Srdivacky      insnContext = IC_XS;
272201360Srdivacky    else
273201360Srdivacky      insnContext = IC;
274201360Srdivacky  }
275201360Srdivacky
276201360Srdivacky  return insnContext;
277201360Srdivacky}
278201360Srdivacky
279201360SrdivackyRecognizableInstr::filter_ret RecognizableInstr::filter() const {
280201360Srdivacky  // Filter out intrinsics
281201360Srdivacky
282201360Srdivacky  if (!Rec->isSubClassOf("X86Inst"))
283201360Srdivacky    return FILTER_STRONG;
284201360Srdivacky
285201360Srdivacky  if (Form == X86Local::Pseudo ||
286201360Srdivacky      IsCodeGenOnly)
287201360Srdivacky    return FILTER_STRONG;
288201360Srdivacky
289204642Srdivacky  if (Form == X86Local::MRMInitReg)
290204642Srdivacky    return FILTER_STRONG;
291204642Srdivacky
292204642Srdivacky
293201360Srdivacky  // Filter out instructions with a LOCK prefix;
294201360Srdivacky  //   prefer forms that do not have the prefix
295201360Srdivacky  if (HasLockPrefix)
296201360Srdivacky    return FILTER_WEAK;
297201360Srdivacky
298201360Srdivacky  // Filter out artificial instructions
299201360Srdivacky
300201360Srdivacky  if (Name.find("TAILJMP") != Name.npos    ||
301201360Srdivacky     Name.find("_Int") != Name.npos       ||
302201360Srdivacky     Name.find("_int") != Name.npos       ||
303201360Srdivacky     Name.find("Int_") != Name.npos       ||
304201360Srdivacky     Name.find("_NOREX") != Name.npos     ||
305205218Srdivacky     Name.find("_TC") != Name.npos     ||
306201360Srdivacky     Name.find("EH_RETURN") != Name.npos  ||
307201360Srdivacky     Name.find("V_SET") != Name.npos      ||
308201360Srdivacky     Name.find("LOCK_") != Name.npos      ||
309201360Srdivacky     Name.find("WIN") != Name.npos)
310201360Srdivacky    return FILTER_STRONG;
311201360Srdivacky
312201360Srdivacky  // Special cases.
313201360Srdivacky
314201360Srdivacky  if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI")
315201360Srdivacky    return FILTER_WEAK;
316201360Srdivacky  if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI")
317201360Srdivacky    return FILTER_WEAK;
318201360Srdivacky
319201360Srdivacky  if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos)
320201360Srdivacky    return FILTER_WEAK;
321201360Srdivacky  if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos)
322201360Srdivacky    return FILTER_WEAK;
323201360Srdivacky  if (Name.find("Fs") != Name.npos)
324201360Srdivacky    return FILTER_WEAK;
325201360Srdivacky  if (Name == "MOVLPDrr"          ||
326201360Srdivacky      Name == "MOVLPSrr"          ||
327201360Srdivacky      Name == "PUSHFQ"            ||
328201360Srdivacky      Name == "BSF16rr"           ||
329201360Srdivacky      Name == "BSF16rm"           ||
330201360Srdivacky      Name == "BSR16rr"           ||
331201360Srdivacky      Name == "BSR16rm"           ||
332201360Srdivacky      Name == "MOVSX16rm8"        ||
333201360Srdivacky      Name == "MOVSX16rr8"        ||
334201360Srdivacky      Name == "MOVZX16rm8"        ||
335201360Srdivacky      Name == "MOVZX16rr8"        ||
336201360Srdivacky      Name == "PUSH32i16"         ||
337201360Srdivacky      Name == "PUSH64i16"         ||
338201360Srdivacky      Name == "MOVPQI2QImr"       ||
339201360Srdivacky      Name == "MOVSDmr"           ||
340201360Srdivacky      Name == "MOVSDrm"           ||
341201360Srdivacky      Name == "MOVSSmr"           ||
342201360Srdivacky      Name == "MOVSSrm"           ||
343201360Srdivacky      Name == "MMX_MOVD64rrv164"  ||
344201360Srdivacky      Name == "CRC32m16"          ||
345201360Srdivacky      Name == "MOV64ri64i32"      ||
346201360Srdivacky      Name == "CRC32r16")
347201360Srdivacky    return FILTER_WEAK;
348201360Srdivacky
349201360Srdivacky  // Filter out instructions with segment override prefixes.
350201360Srdivacky  // They're too messy to handle now and we'll special case them if needed.
351201360Srdivacky
352201360Srdivacky  if (SegOvr)
353201360Srdivacky    return FILTER_STRONG;
354201360Srdivacky
355201360Srdivacky  // Filter out instructions that can't be printed.
356201360Srdivacky
357201360Srdivacky  if (AsmString.size() == 0)
358201360Srdivacky    return FILTER_STRONG;
359201360Srdivacky
360201360Srdivacky  // Filter out instructions with subreg operands.
361201360Srdivacky
362201360Srdivacky  if (AsmString.find("subreg") != AsmString.npos)
363201360Srdivacky    return FILTER_STRONG;
364201360Srdivacky
365201360Srdivacky  if (HasFROperands && Name.find("MOV") != Name.npos &&
366201360Srdivacky     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
367201360Srdivacky      (Name.find("to") != Name.npos)))
368201360Srdivacky    return FILTER_WEAK;
369201360Srdivacky
370201360Srdivacky  return FILTER_NORMAL;
371201360Srdivacky}
372201360Srdivacky
373201360Srdivackyvoid RecognizableInstr::handleOperand(
374201360Srdivacky  bool optional,
375201360Srdivacky  unsigned &operandIndex,
376201360Srdivacky  unsigned &physicalOperandIndex,
377201360Srdivacky  unsigned &numPhysicalOperands,
378201360Srdivacky  unsigned *operandMapping,
379201360Srdivacky  OperandEncoding (*encodingFromString)(const std::string&, bool hasOpSizePrefix)) {
380201360Srdivacky  if (optional) {
381201360Srdivacky    if (physicalOperandIndex >= numPhysicalOperands)
382201360Srdivacky      return;
383201360Srdivacky  } else {
384201360Srdivacky    assert(physicalOperandIndex < numPhysicalOperands);
385201360Srdivacky  }
386201360Srdivacky
387201360Srdivacky  while (operandMapping[operandIndex] != operandIndex) {
388201360Srdivacky    Spec->operands[operandIndex].encoding = ENCODING_DUP;
389201360Srdivacky    Spec->operands[operandIndex].type =
390201360Srdivacky      (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);
391201360Srdivacky    ++operandIndex;
392201360Srdivacky  }
393201360Srdivacky
394201360Srdivacky  const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
395201360Srdivacky
396201360Srdivacky  Spec->operands[operandIndex].encoding = encodingFromString(typeName,
397201360Srdivacky                                                              HasOpSizePrefix);
398201360Srdivacky  Spec->operands[operandIndex].type = typeFromString(typeName,
399201360Srdivacky                                                      IsSSE,
400201360Srdivacky                                                      HasREX_WPrefix,
401201360Srdivacky                                                      HasOpSizePrefix);
402201360Srdivacky
403201360Srdivacky  ++operandIndex;
404201360Srdivacky  ++physicalOperandIndex;
405201360Srdivacky}
406201360Srdivacky
407201360Srdivackyvoid RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
408201360Srdivacky  Spec->name       = Name;
409201360Srdivacky
410201360Srdivacky  if (!Rec->isSubClassOf("X86Inst"))
411201360Srdivacky    return;
412201360Srdivacky
413201360Srdivacky  switch (filter()) {
414201360Srdivacky  case FILTER_WEAK:
415201360Srdivacky    Spec->filtered = true;
416201360Srdivacky    break;
417201360Srdivacky  case FILTER_STRONG:
418201360Srdivacky    ShouldBeEmitted = false;
419201360Srdivacky    return;
420201360Srdivacky  case FILTER_NORMAL:
421201360Srdivacky    break;
422201360Srdivacky  }
423201360Srdivacky
424201360Srdivacky  Spec->insnContext = insnContext();
425201360Srdivacky
426201360Srdivacky  const std::vector<CodeGenInstruction::OperandInfo> &OperandList = *Operands;
427201360Srdivacky
428201360Srdivacky  unsigned operandIndex;
429201360Srdivacky  unsigned numOperands = OperandList.size();
430201360Srdivacky  unsigned numPhysicalOperands = 0;
431201360Srdivacky
432201360Srdivacky  // operandMapping maps from operands in OperandList to their originals.
433201360Srdivacky  // If operandMapping[i] != i, then the entry is a duplicate.
434201360Srdivacky  unsigned operandMapping[X86_MAX_OPERANDS];
435201360Srdivacky
436201360Srdivacky  bool hasFROperands = false;
437201360Srdivacky
438201360Srdivacky  assert(numOperands < X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough");
439201360Srdivacky
440201360Srdivacky  for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
441201360Srdivacky    if (OperandList[operandIndex].Constraints.size()) {
442203954Srdivacky      const CodeGenInstruction::ConstraintInfo &Constraint =
443203954Srdivacky        OperandList[operandIndex].Constraints[0];
444203954Srdivacky      if (Constraint.isTied()) {
445203954Srdivacky        operandMapping[operandIndex] = Constraint.getTiedOperand();
446201360Srdivacky      } else {
447201360Srdivacky        ++numPhysicalOperands;
448201360Srdivacky        operandMapping[operandIndex] = operandIndex;
449201360Srdivacky      }
450201360Srdivacky    } else {
451201360Srdivacky      ++numPhysicalOperands;
452201360Srdivacky      operandMapping[operandIndex] = operandIndex;
453201360Srdivacky    }
454201360Srdivacky
455201360Srdivacky    const std::string &recName = OperandList[operandIndex].Rec->getName();
456201360Srdivacky
457201360Srdivacky    if (recName.find("FR") != recName.npos)
458201360Srdivacky      hasFROperands = true;
459201360Srdivacky  }
460201360Srdivacky
461201360Srdivacky  if (hasFROperands && Name.find("MOV") != Name.npos &&
462201360Srdivacky     ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
463201360Srdivacky      (Name.find("to") != Name.npos)))
464201360Srdivacky    ShouldBeEmitted = false;
465201360Srdivacky
466201360Srdivacky  if (!ShouldBeEmitted)
467201360Srdivacky    return;
468201360Srdivacky
469201360Srdivacky#define HANDLE_OPERAND(class)               \
470201360Srdivacky  handleOperand(false,                      \
471201360Srdivacky                operandIndex,               \
472201360Srdivacky                physicalOperandIndex,       \
473201360Srdivacky                numPhysicalOperands,        \
474201360Srdivacky                operandMapping,             \
475201360Srdivacky                class##EncodingFromString);
476201360Srdivacky
477201360Srdivacky#define HANDLE_OPTIONAL(class)              \
478201360Srdivacky  handleOperand(true,                       \
479201360Srdivacky                operandIndex,               \
480201360Srdivacky                physicalOperandIndex,       \
481201360Srdivacky                numPhysicalOperands,        \
482201360Srdivacky                operandMapping,             \
483201360Srdivacky                class##EncodingFromString);
484201360Srdivacky
485201360Srdivacky  // operandIndex should always be < numOperands
486201360Srdivacky  operandIndex = 0;
487201360Srdivacky  // physicalOperandIndex should always be < numPhysicalOperands
488201360Srdivacky  unsigned physicalOperandIndex = 0;
489201360Srdivacky
490201360Srdivacky  switch (Form) {
491201360Srdivacky  case X86Local::RawFrm:
492201360Srdivacky    // Operand 1 (optional) is an address or immediate.
493201360Srdivacky    // Operand 2 (optional) is an immediate.
494201360Srdivacky    assert(numPhysicalOperands <= 2 &&
495201360Srdivacky           "Unexpected number of operands for RawFrm");
496201360Srdivacky    HANDLE_OPTIONAL(relocation)
497201360Srdivacky    HANDLE_OPTIONAL(immediate)
498201360Srdivacky    break;
499201360Srdivacky  case X86Local::AddRegFrm:
500201360Srdivacky    // Operand 1 is added to the opcode.
501201360Srdivacky    // Operand 2 (optional) is an address.
502201360Srdivacky    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
503201360Srdivacky           "Unexpected number of operands for AddRegFrm");
504201360Srdivacky    HANDLE_OPERAND(opcodeModifier)
505201360Srdivacky    HANDLE_OPTIONAL(relocation)
506201360Srdivacky    break;
507201360Srdivacky  case X86Local::MRMDestReg:
508201360Srdivacky    // Operand 1 is a register operand in the R/M field.
509201360Srdivacky    // Operand 2 is a register operand in the Reg/Opcode field.
510201360Srdivacky    // Operand 3 (optional) is an immediate.
511201360Srdivacky    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
512201360Srdivacky           "Unexpected number of operands for MRMDestRegFrm");
513201360Srdivacky    HANDLE_OPERAND(rmRegister)
514201360Srdivacky    HANDLE_OPERAND(roRegister)
515201360Srdivacky    HANDLE_OPTIONAL(immediate)
516201360Srdivacky    break;
517201360Srdivacky  case X86Local::MRMDestMem:
518201360Srdivacky    // Operand 1 is a memory operand (possibly SIB-extended)
519201360Srdivacky    // Operand 2 is a register operand in the Reg/Opcode field.
520201360Srdivacky    // Operand 3 (optional) is an immediate.
521201360Srdivacky    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
522201360Srdivacky           "Unexpected number of operands for MRMDestMemFrm");
523201360Srdivacky    HANDLE_OPERAND(memory)
524201360Srdivacky    HANDLE_OPERAND(roRegister)
525201360Srdivacky    HANDLE_OPTIONAL(immediate)
526201360Srdivacky    break;
527201360Srdivacky  case X86Local::MRMSrcReg:
528201360Srdivacky    // Operand 1 is a register operand in the Reg/Opcode field.
529201360Srdivacky    // Operand 2 is a register operand in the R/M field.
530201360Srdivacky    // Operand 3 (optional) is an immediate.
531201360Srdivacky    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
532201360Srdivacky           "Unexpected number of operands for MRMSrcRegFrm");
533201360Srdivacky    HANDLE_OPERAND(roRegister)
534201360Srdivacky    HANDLE_OPERAND(rmRegister)
535201360Srdivacky    HANDLE_OPTIONAL(immediate)
536201360Srdivacky    break;
537201360Srdivacky  case X86Local::MRMSrcMem:
538201360Srdivacky    // Operand 1 is a register operand in the Reg/Opcode field.
539201360Srdivacky    // Operand 2 is a memory operand (possibly SIB-extended)
540201360Srdivacky    // Operand 3 (optional) is an immediate.
541201360Srdivacky    assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
542201360Srdivacky           "Unexpected number of operands for MRMSrcMemFrm");
543201360Srdivacky    HANDLE_OPERAND(roRegister)
544201360Srdivacky    HANDLE_OPERAND(memory)
545201360Srdivacky    HANDLE_OPTIONAL(immediate)
546201360Srdivacky    break;
547201360Srdivacky  case X86Local::MRM0r:
548201360Srdivacky  case X86Local::MRM1r:
549201360Srdivacky  case X86Local::MRM2r:
550201360Srdivacky  case X86Local::MRM3r:
551201360Srdivacky  case X86Local::MRM4r:
552201360Srdivacky  case X86Local::MRM5r:
553201360Srdivacky  case X86Local::MRM6r:
554201360Srdivacky  case X86Local::MRM7r:
555201360Srdivacky    // Operand 1 is a register operand in the R/M field.
556201360Srdivacky    // Operand 2 (optional) is an immediate or relocation.
557201360Srdivacky    assert(numPhysicalOperands <= 2 &&
558201360Srdivacky           "Unexpected number of operands for MRMnRFrm");
559201360Srdivacky    HANDLE_OPTIONAL(rmRegister)
560201360Srdivacky    HANDLE_OPTIONAL(relocation)
561201360Srdivacky    break;
562201360Srdivacky  case X86Local::MRM0m:
563201360Srdivacky  case X86Local::MRM1m:
564201360Srdivacky  case X86Local::MRM2m:
565201360Srdivacky  case X86Local::MRM3m:
566201360Srdivacky  case X86Local::MRM4m:
567201360Srdivacky  case X86Local::MRM5m:
568201360Srdivacky  case X86Local::MRM6m:
569201360Srdivacky  case X86Local::MRM7m:
570201360Srdivacky    // Operand 1 is a memory operand (possibly SIB-extended)
571201360Srdivacky    // Operand 2 (optional) is an immediate or relocation.
572201360Srdivacky    assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
573201360Srdivacky           "Unexpected number of operands for MRMnMFrm");
574201360Srdivacky    HANDLE_OPERAND(memory)
575201360Srdivacky    HANDLE_OPTIONAL(relocation)
576201360Srdivacky    break;
577201360Srdivacky  case X86Local::MRMInitReg:
578201360Srdivacky    // Ignored.
579201360Srdivacky    break;
580201360Srdivacky  }
581201360Srdivacky
582201360Srdivacky  #undef HANDLE_OPERAND
583201360Srdivacky  #undef HANDLE_OPTIONAL
584201360Srdivacky}
585201360Srdivacky
586201360Srdivackyvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
587201360Srdivacky  // Special cases where the LLVM tables are not complete
588201360Srdivacky
589203954Srdivacky#define MAP(from, to)                     \
590203954Srdivacky  case X86Local::MRM_##from:              \
591203954Srdivacky    filter = new ExactFilter(0x##from);   \
592203954Srdivacky    break;
593201360Srdivacky
594201360Srdivacky  OpcodeType    opcodeType  = (OpcodeType)-1;
595201360Srdivacky
596201360Srdivacky  ModRMFilter*  filter      = NULL;
597201360Srdivacky  uint8_t       opcodeToSet = 0;
598201360Srdivacky
599201360Srdivacky  switch (Prefix) {
600201360Srdivacky  // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f
601201360Srdivacky  case X86Local::XD:
602201360Srdivacky  case X86Local::XS:
603201360Srdivacky  case X86Local::TB:
604201360Srdivacky    opcodeType = TWOBYTE;
605201360Srdivacky
606201360Srdivacky    switch (Opcode) {
607203954Srdivacky    default:
608203954Srdivacky      if (needsModRMForDecode(Form))
609203954Srdivacky        filter = new ModFilter(isRegFormat(Form));
610203954Srdivacky      else
611203954Srdivacky        filter = new DumbFilter();
612203954Srdivacky      break;
613201360Srdivacky#define EXTENSION_TABLE(n) case 0x##n:
614201360Srdivacky    TWO_BYTE_EXTENSION_TABLES
615201360Srdivacky#undef EXTENSION_TABLE
616201360Srdivacky      switch (Form) {
617201360Srdivacky      default:
618201360Srdivacky        llvm_unreachable("Unhandled two-byte extended opcode");
619201360Srdivacky      case X86Local::MRM0r:
620201360Srdivacky      case X86Local::MRM1r:
621201360Srdivacky      case X86Local::MRM2r:
622201360Srdivacky      case X86Local::MRM3r:
623201360Srdivacky      case X86Local::MRM4r:
624201360Srdivacky      case X86Local::MRM5r:
625201360Srdivacky      case X86Local::MRM6r:
626201360Srdivacky      case X86Local::MRM7r:
627201360Srdivacky        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
628201360Srdivacky        break;
629201360Srdivacky      case X86Local::MRM0m:
630201360Srdivacky      case X86Local::MRM1m:
631201360Srdivacky      case X86Local::MRM2m:
632201360Srdivacky      case X86Local::MRM3m:
633201360Srdivacky      case X86Local::MRM4m:
634201360Srdivacky      case X86Local::MRM5m:
635201360Srdivacky      case X86Local::MRM6m:
636201360Srdivacky      case X86Local::MRM7m:
637201360Srdivacky        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
638201360Srdivacky        break;
639203954Srdivacky      MRM_MAPPING
640201360Srdivacky      } // switch (Form)
641201360Srdivacky      break;
642203954Srdivacky    } // switch (Opcode)
643201360Srdivacky    opcodeToSet = Opcode;
644201360Srdivacky    break;
645201360Srdivacky  case X86Local::T8:
646201360Srdivacky    opcodeType = THREEBYTE_38;
647201360Srdivacky    if (needsModRMForDecode(Form))
648201360Srdivacky      filter = new ModFilter(isRegFormat(Form));
649201360Srdivacky    else
650201360Srdivacky      filter = new DumbFilter();
651201360Srdivacky    opcodeToSet = Opcode;
652201360Srdivacky    break;
653203954Srdivacky  case X86Local::P_TA:
654201360Srdivacky    opcodeType = THREEBYTE_3A;
655201360Srdivacky    if (needsModRMForDecode(Form))
656201360Srdivacky      filter = new ModFilter(isRegFormat(Form));
657201360Srdivacky    else
658201360Srdivacky      filter = new DumbFilter();
659201360Srdivacky    opcodeToSet = Opcode;
660201360Srdivacky    break;
661201360Srdivacky  case X86Local::D8:
662201360Srdivacky  case X86Local::D9:
663201360Srdivacky  case X86Local::DA:
664201360Srdivacky  case X86Local::DB:
665201360Srdivacky  case X86Local::DC:
666201360Srdivacky  case X86Local::DD:
667201360Srdivacky  case X86Local::DE:
668201360Srdivacky  case X86Local::DF:
669201360Srdivacky    assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
670201360Srdivacky    opcodeType = ONEBYTE;
671201360Srdivacky    if (Form == X86Local::AddRegFrm) {
672201360Srdivacky      Spec->modifierType = MODIFIER_MODRM;
673201360Srdivacky      Spec->modifierBase = Opcode;
674201360Srdivacky      filter = new AddRegEscapeFilter(Opcode);
675201360Srdivacky    } else {
676201360Srdivacky      filter = new EscapeFilter(true, Opcode);
677201360Srdivacky    }
678201360Srdivacky    opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
679201360Srdivacky    break;
680201360Srdivacky  default:
681201360Srdivacky    opcodeType = ONEBYTE;
682201360Srdivacky    switch (Opcode) {
683201360Srdivacky#define EXTENSION_TABLE(n) case 0x##n:
684201360Srdivacky    ONE_BYTE_EXTENSION_TABLES
685201360Srdivacky#undef EXTENSION_TABLE
686201360Srdivacky      switch (Form) {
687201360Srdivacky      default:
688201360Srdivacky        llvm_unreachable("Fell through the cracks of a single-byte "
689201360Srdivacky                         "extended opcode");
690201360Srdivacky      case X86Local::MRM0r:
691201360Srdivacky      case X86Local::MRM1r:
692201360Srdivacky      case X86Local::MRM2r:
693201360Srdivacky      case X86Local::MRM3r:
694201360Srdivacky      case X86Local::MRM4r:
695201360Srdivacky      case X86Local::MRM5r:
696201360Srdivacky      case X86Local::MRM6r:
697201360Srdivacky      case X86Local::MRM7r:
698201360Srdivacky        filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
699201360Srdivacky        break;
700201360Srdivacky      case X86Local::MRM0m:
701201360Srdivacky      case X86Local::MRM1m:
702201360Srdivacky      case X86Local::MRM2m:
703201360Srdivacky      case X86Local::MRM3m:
704201360Srdivacky      case X86Local::MRM4m:
705201360Srdivacky      case X86Local::MRM5m:
706201360Srdivacky      case X86Local::MRM6m:
707201360Srdivacky      case X86Local::MRM7m:
708201360Srdivacky        filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
709201360Srdivacky        break;
710203954Srdivacky      MRM_MAPPING
711201360Srdivacky      } // switch (Form)
712201360Srdivacky      break;
713201360Srdivacky    case 0xd8:
714201360Srdivacky    case 0xd9:
715201360Srdivacky    case 0xda:
716201360Srdivacky    case 0xdb:
717201360Srdivacky    case 0xdc:
718201360Srdivacky    case 0xdd:
719201360Srdivacky    case 0xde:
720201360Srdivacky    case 0xdf:
721201360Srdivacky      filter = new EscapeFilter(false, Form - X86Local::MRM0m);
722201360Srdivacky      break;
723201360Srdivacky    default:
724201360Srdivacky      if (needsModRMForDecode(Form))
725201360Srdivacky        filter = new ModFilter(isRegFormat(Form));
726201360Srdivacky      else
727201360Srdivacky        filter = new DumbFilter();
728201360Srdivacky      break;
729201360Srdivacky    } // switch (Opcode)
730201360Srdivacky    opcodeToSet = Opcode;
731201360Srdivacky  } // switch (Prefix)
732201360Srdivacky
733201360Srdivacky  assert(opcodeType != (OpcodeType)-1 &&
734201360Srdivacky         "Opcode type not set");
735201360Srdivacky  assert(filter && "Filter not set");
736201360Srdivacky
737201360Srdivacky  if (Form == X86Local::AddRegFrm) {
738201360Srdivacky    if(Spec->modifierType != MODIFIER_MODRM) {
739201360Srdivacky      assert(opcodeToSet < 0xf9 &&
740201360Srdivacky             "Not enough room for all ADDREG_FRM operands");
741201360Srdivacky
742201360Srdivacky      uint8_t currentOpcode;
743201360Srdivacky
744201360Srdivacky      for (currentOpcode = opcodeToSet;
745201360Srdivacky           currentOpcode < opcodeToSet + 8;
746201360Srdivacky           ++currentOpcode)
747201360Srdivacky        tables.setTableFields(opcodeType,
748201360Srdivacky                              insnContext(),
749201360Srdivacky                              currentOpcode,
750201360Srdivacky                              *filter,
751201360Srdivacky                              UID);
752201360Srdivacky
753201360Srdivacky      Spec->modifierType = MODIFIER_OPCODE;
754201360Srdivacky      Spec->modifierBase = opcodeToSet;
755201360Srdivacky    } else {
756201360Srdivacky      // modifierBase was set where MODIFIER_MODRM was set
757201360Srdivacky      tables.setTableFields(opcodeType,
758201360Srdivacky                            insnContext(),
759201360Srdivacky                            opcodeToSet,
760201360Srdivacky                            *filter,
761201360Srdivacky                            UID);
762201360Srdivacky    }
763201360Srdivacky  } else {
764201360Srdivacky    tables.setTableFields(opcodeType,
765201360Srdivacky                          insnContext(),
766201360Srdivacky                          opcodeToSet,
767201360Srdivacky                          *filter,
768201360Srdivacky                          UID);
769201360Srdivacky
770201360Srdivacky    Spec->modifierType = MODIFIER_NONE;
771201360Srdivacky    Spec->modifierBase = opcodeToSet;
772201360Srdivacky  }
773201360Srdivacky
774201360Srdivacky  delete filter;
775203954Srdivacky
776203954Srdivacky#undef MAP
777201360Srdivacky}
778201360Srdivacky
779201360Srdivacky#define TYPE(str, type) if (s == str) return type;
780201360SrdivackyOperandType RecognizableInstr::typeFromString(const std::string &s,
781201360Srdivacky                                              bool isSSE,
782201360Srdivacky                                              bool hasREX_WPrefix,
783201360Srdivacky                                              bool hasOpSizePrefix) {
784201360Srdivacky  if (isSSE) {
785201360Srdivacky    // For SSE instructions, we ignore the OpSize prefix and force operand
786201360Srdivacky    // sizes.
787201360Srdivacky    TYPE("GR16",              TYPE_R16)
788201360Srdivacky    TYPE("GR32",              TYPE_R32)
789201360Srdivacky    TYPE("GR64",              TYPE_R64)
790201360Srdivacky  }
791201360Srdivacky  if(hasREX_WPrefix) {
792201360Srdivacky    // For instructions with a REX_W prefix, a declared 32-bit register encoding
793201360Srdivacky    // is special.
794201360Srdivacky    TYPE("GR32",              TYPE_R32)
795201360Srdivacky  }
796201360Srdivacky  if(!hasOpSizePrefix) {
797201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
798201360Srdivacky    // immediate encoding is special.
799201360Srdivacky    TYPE("GR16",              TYPE_R16)
800201360Srdivacky    TYPE("i16imm",            TYPE_IMM16)
801201360Srdivacky  }
802201360Srdivacky  TYPE("i16mem",              TYPE_Mv)
803201360Srdivacky  TYPE("i16imm",              TYPE_IMMv)
804201360Srdivacky  TYPE("i16i8imm",            TYPE_IMMv)
805201360Srdivacky  TYPE("GR16",                TYPE_Rv)
806201360Srdivacky  TYPE("i32mem",              TYPE_Mv)
807201360Srdivacky  TYPE("i32imm",              TYPE_IMMv)
808201360Srdivacky  TYPE("i32i8imm",            TYPE_IMM32)
809201360Srdivacky  TYPE("GR32",                TYPE_Rv)
810201360Srdivacky  TYPE("i64mem",              TYPE_Mv)
811201360Srdivacky  TYPE("i64i32imm",           TYPE_IMM64)
812201360Srdivacky  TYPE("i64i8imm",            TYPE_IMM64)
813201360Srdivacky  TYPE("GR64",                TYPE_R64)
814201360Srdivacky  TYPE("i8mem",               TYPE_M8)
815201360Srdivacky  TYPE("i8imm",               TYPE_IMM8)
816201360Srdivacky  TYPE("GR8",                 TYPE_R8)
817201360Srdivacky  TYPE("VR128",               TYPE_XMM128)
818201360Srdivacky  TYPE("f128mem",             TYPE_M128)
819201360Srdivacky  TYPE("FR64",                TYPE_XMM64)
820201360Srdivacky  TYPE("f64mem",              TYPE_M64FP)
821201360Srdivacky  TYPE("FR32",                TYPE_XMM32)
822201360Srdivacky  TYPE("f32mem",              TYPE_M32FP)
823201360Srdivacky  TYPE("RST",                 TYPE_ST)
824201360Srdivacky  TYPE("i128mem",             TYPE_M128)
825201360Srdivacky  TYPE("i64i32imm_pcrel",     TYPE_REL64)
826201360Srdivacky  TYPE("i32imm_pcrel",        TYPE_REL32)
827207618Srdivacky  TYPE("SSECC",               TYPE_IMM3)
828201360Srdivacky  TYPE("brtarget",            TYPE_RELv)
829201360Srdivacky  TYPE("brtarget8",           TYPE_REL8)
830201360Srdivacky  TYPE("f80mem",              TYPE_M80FP)
831201360Srdivacky  TYPE("lea32mem",            TYPE_LEA)
832201360Srdivacky  TYPE("lea64_32mem",         TYPE_LEA)
833201360Srdivacky  TYPE("lea64mem",            TYPE_LEA)
834201360Srdivacky  TYPE("VR64",                TYPE_MM64)
835201360Srdivacky  TYPE("i64imm",              TYPE_IMMv)
836201360Srdivacky  TYPE("opaque32mem",         TYPE_M1616)
837201360Srdivacky  TYPE("opaque48mem",         TYPE_M1632)
838201360Srdivacky  TYPE("opaque80mem",         TYPE_M1664)
839201360Srdivacky  TYPE("opaque512mem",        TYPE_M512)
840201360Srdivacky  TYPE("SEGMENT_REG",         TYPE_SEGMENTREG)
841201360Srdivacky  TYPE("DEBUG_REG",           TYPE_DEBUGREG)
842208599Srdivacky  TYPE("CONTROL_REG",         TYPE_CONTROLREG)
843201360Srdivacky  TYPE("offset8",             TYPE_MOFFS8)
844201360Srdivacky  TYPE("offset16",            TYPE_MOFFS16)
845201360Srdivacky  TYPE("offset32",            TYPE_MOFFS32)
846201360Srdivacky  TYPE("offset64",            TYPE_MOFFS64)
847201360Srdivacky  errs() << "Unhandled type string " << s << "\n";
848201360Srdivacky  llvm_unreachable("Unhandled type string");
849201360Srdivacky}
850201360Srdivacky#undef TYPE
851201360Srdivacky
852201360Srdivacky#define ENCODING(str, encoding) if (s == str) return encoding;
853201360SrdivackyOperandEncoding RecognizableInstr::immediateEncodingFromString
854201360Srdivacky  (const std::string &s,
855201360Srdivacky   bool hasOpSizePrefix) {
856201360Srdivacky  if(!hasOpSizePrefix) {
857201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
858201360Srdivacky    // immediate encoding is special.
859201360Srdivacky    ENCODING("i16imm",        ENCODING_IW)
860201360Srdivacky  }
861201360Srdivacky  ENCODING("i32i8imm",        ENCODING_IB)
862201360Srdivacky  ENCODING("SSECC",           ENCODING_IB)
863201360Srdivacky  ENCODING("i16imm",          ENCODING_Iv)
864201360Srdivacky  ENCODING("i16i8imm",        ENCODING_IB)
865201360Srdivacky  ENCODING("i32imm",          ENCODING_Iv)
866201360Srdivacky  ENCODING("i64i32imm",       ENCODING_ID)
867201360Srdivacky  ENCODING("i64i8imm",        ENCODING_IB)
868201360Srdivacky  ENCODING("i8imm",           ENCODING_IB)
869201360Srdivacky  errs() << "Unhandled immediate encoding " << s << "\n";
870201360Srdivacky  llvm_unreachable("Unhandled immediate encoding");
871201360Srdivacky}
872201360Srdivacky
873201360SrdivackyOperandEncoding RecognizableInstr::rmRegisterEncodingFromString
874201360Srdivacky  (const std::string &s,
875201360Srdivacky   bool hasOpSizePrefix) {
876201360Srdivacky  ENCODING("GR16",            ENCODING_RM)
877201360Srdivacky  ENCODING("GR32",            ENCODING_RM)
878201360Srdivacky  ENCODING("GR64",            ENCODING_RM)
879201360Srdivacky  ENCODING("GR8",             ENCODING_RM)
880201360Srdivacky  ENCODING("VR128",           ENCODING_RM)
881201360Srdivacky  ENCODING("FR64",            ENCODING_RM)
882201360Srdivacky  ENCODING("FR32",            ENCODING_RM)
883201360Srdivacky  ENCODING("VR64",            ENCODING_RM)
884201360Srdivacky  errs() << "Unhandled R/M register encoding " << s << "\n";
885201360Srdivacky  llvm_unreachable("Unhandled R/M register encoding");
886201360Srdivacky}
887201360Srdivacky
888201360SrdivackyOperandEncoding RecognizableInstr::roRegisterEncodingFromString
889201360Srdivacky  (const std::string &s,
890201360Srdivacky   bool hasOpSizePrefix) {
891201360Srdivacky  ENCODING("GR16",            ENCODING_REG)
892201360Srdivacky  ENCODING("GR32",            ENCODING_REG)
893201360Srdivacky  ENCODING("GR64",            ENCODING_REG)
894201360Srdivacky  ENCODING("GR8",             ENCODING_REG)
895201360Srdivacky  ENCODING("VR128",           ENCODING_REG)
896201360Srdivacky  ENCODING("FR64",            ENCODING_REG)
897201360Srdivacky  ENCODING("FR32",            ENCODING_REG)
898201360Srdivacky  ENCODING("VR64",            ENCODING_REG)
899201360Srdivacky  ENCODING("SEGMENT_REG",     ENCODING_REG)
900201360Srdivacky  ENCODING("DEBUG_REG",       ENCODING_REG)
901208599Srdivacky  ENCODING("CONTROL_REG",     ENCODING_REG)
902201360Srdivacky  errs() << "Unhandled reg/opcode register encoding " << s << "\n";
903201360Srdivacky  llvm_unreachable("Unhandled reg/opcode register encoding");
904201360Srdivacky}
905201360Srdivacky
906201360SrdivackyOperandEncoding RecognizableInstr::memoryEncodingFromString
907201360Srdivacky  (const std::string &s,
908201360Srdivacky   bool hasOpSizePrefix) {
909201360Srdivacky  ENCODING("i16mem",          ENCODING_RM)
910201360Srdivacky  ENCODING("i32mem",          ENCODING_RM)
911201360Srdivacky  ENCODING("i64mem",          ENCODING_RM)
912201360Srdivacky  ENCODING("i8mem",           ENCODING_RM)
913201360Srdivacky  ENCODING("f128mem",         ENCODING_RM)
914201360Srdivacky  ENCODING("f64mem",          ENCODING_RM)
915201360Srdivacky  ENCODING("f32mem",          ENCODING_RM)
916201360Srdivacky  ENCODING("i128mem",         ENCODING_RM)
917201360Srdivacky  ENCODING("f80mem",          ENCODING_RM)
918201360Srdivacky  ENCODING("lea32mem",        ENCODING_RM)
919201360Srdivacky  ENCODING("lea64_32mem",     ENCODING_RM)
920201360Srdivacky  ENCODING("lea64mem",        ENCODING_RM)
921201360Srdivacky  ENCODING("opaque32mem",     ENCODING_RM)
922201360Srdivacky  ENCODING("opaque48mem",     ENCODING_RM)
923201360Srdivacky  ENCODING("opaque80mem",     ENCODING_RM)
924201360Srdivacky  ENCODING("opaque512mem",    ENCODING_RM)
925201360Srdivacky  errs() << "Unhandled memory encoding " << s << "\n";
926201360Srdivacky  llvm_unreachable("Unhandled memory encoding");
927201360Srdivacky}
928201360Srdivacky
929201360SrdivackyOperandEncoding RecognizableInstr::relocationEncodingFromString
930201360Srdivacky  (const std::string &s,
931201360Srdivacky   bool hasOpSizePrefix) {
932201360Srdivacky  if(!hasOpSizePrefix) {
933201360Srdivacky    // For instructions without an OpSize prefix, a declared 16-bit register or
934201360Srdivacky    // immediate encoding is special.
935201360Srdivacky    ENCODING("i16imm",        ENCODING_IW)
936201360Srdivacky  }
937201360Srdivacky  ENCODING("i16imm",          ENCODING_Iv)
938201360Srdivacky  ENCODING("i16i8imm",        ENCODING_IB)
939201360Srdivacky  ENCODING("i32imm",          ENCODING_Iv)
940201360Srdivacky  ENCODING("i32i8imm",        ENCODING_IB)
941201360Srdivacky  ENCODING("i64i32imm",       ENCODING_ID)
942201360Srdivacky  ENCODING("i64i8imm",        ENCODING_IB)
943201360Srdivacky  ENCODING("i8imm",           ENCODING_IB)
944201360Srdivacky  ENCODING("i64i32imm_pcrel", ENCODING_ID)
945201360Srdivacky  ENCODING("i32imm_pcrel",    ENCODING_ID)
946201360Srdivacky  ENCODING("brtarget",        ENCODING_Iv)
947201360Srdivacky  ENCODING("brtarget8",       ENCODING_IB)
948201360Srdivacky  ENCODING("i64imm",          ENCODING_IO)
949201360Srdivacky  ENCODING("offset8",         ENCODING_Ia)
950201360Srdivacky  ENCODING("offset16",        ENCODING_Ia)
951201360Srdivacky  ENCODING("offset32",        ENCODING_Ia)
952201360Srdivacky  ENCODING("offset64",        ENCODING_Ia)
953201360Srdivacky  errs() << "Unhandled relocation encoding " << s << "\n";
954201360Srdivacky  llvm_unreachable("Unhandled relocation encoding");
955201360Srdivacky}
956201360Srdivacky
957201360SrdivackyOperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
958201360Srdivacky  (const std::string &s,
959201360Srdivacky   bool hasOpSizePrefix) {
960201360Srdivacky  ENCODING("RST",             ENCODING_I)
961201360Srdivacky  ENCODING("GR32",            ENCODING_Rv)
962201360Srdivacky  ENCODING("GR64",            ENCODING_RO)
963201360Srdivacky  ENCODING("GR16",            ENCODING_Rv)
964201360Srdivacky  ENCODING("GR8",             ENCODING_RB)
965201360Srdivacky  errs() << "Unhandled opcode modifier encoding " << s << "\n";
966201360Srdivacky  llvm_unreachable("Unhandled opcode modifier encoding");
967201360Srdivacky}
968201360Srdivacky#undef ENCODING
969