1//===- X86RecognizableInstr.cpp - Disassembler instruction spec -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is part of the X86 Disassembler Emitter.
10// It contains the implementation of a single recognizable instruction.
11// Documentation for the disassembler emitter in general can be found in
12// X86DisassemblerEmitter.h.
13//
14//===----------------------------------------------------------------------===//
15
16#include "X86RecognizableInstr.h"
17#include "X86DisassemblerShared.h"
18#include "X86DisassemblerTables.h"
19#include "X86ModRMFilters.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/TableGen/Record.h"
23#include <string>
24
25using namespace llvm;
26using namespace X86Disassembler;
27
28std::string X86Disassembler::getMnemonic(const CodeGenInstruction *I,
29 unsigned Variant) {
30 // Extract a mnemonic assuming it's separated by \t
31 std::string Mnemonic =
32 StringRef(I->FlattenAsmStringVariants(AsmString: I->AsmString, Variant))
33 .take_until(F: [](char C) { return C == '\t'; })
34 .str();
35
36 // Special case: CMOVCC, JCC, SETCC, CMPCCXADD have "${cond}" in mnemonic.
37 // Replace it with "CC" in-place.
38 auto CondPos = Mnemonic.find(s: "${cond}");
39 if (CondPos != std::string::npos)
40 Mnemonic = Mnemonic.replace(pos: CondPos, n1: 7, s: "CC");
41 return StringRef(Mnemonic).upper();
42}
43
44bool X86Disassembler::isRegisterOperand(const Record *Rec) {
45 return Rec->isSubClassOf(Name: "RegisterClass") ||
46 Rec->isSubClassOf(Name: "RegisterOperand");
47}
48
49bool X86Disassembler::isMemoryOperand(const Record *Rec) {
50 return Rec->isSubClassOf(Name: "Operand") &&
51 Rec->getValueAsString(FieldName: "OperandType") == "OPERAND_MEMORY";
52}
53
54bool X86Disassembler::isImmediateOperand(const Record *Rec) {
55 return Rec->isSubClassOf(Name: "Operand") &&
56 Rec->getValueAsString(FieldName: "OperandType") == "OPERAND_IMMEDIATE";
57}
58
59unsigned X86Disassembler::getRegOperandSize(const Record *RegRec) {
60 if (RegRec->isSubClassOf(Name: "RegisterClass"))
61 return RegRec->getValueAsInt(FieldName: "Alignment");
62 if (RegRec->isSubClassOf(Name: "RegisterOperand"))
63 return RegRec->getValueAsDef(FieldName: "RegClass")->getValueAsInt(FieldName: "Alignment");
64
65 llvm_unreachable("Register operand's size not known!");
66}
67
68unsigned X86Disassembler::getMemOperandSize(const Record *MemRec) {
69 if (MemRec->isSubClassOf(Name: "X86MemOperand"))
70 return MemRec->getValueAsInt(FieldName: "Size");
71
72 llvm_unreachable("Memory operand's size not known!");
73}
74
75/// byteFromRec - Extract a value at most 8 bits in with from a Record given the
76/// name of the field.
77///
78/// @param rec - The record from which to extract the value.
79/// @param name - The name of the field in the record.
80/// @return - The field, as translated by byteFromBitsInit().
81static uint8_t byteFromRec(const Record *rec, StringRef name) {
82 const BitsInit *bits = rec->getValueAsBitsInit(FieldName: name);
83 return byteFromBitsInit(B: bits);
84}
85
86RecognizableInstrBase::RecognizableInstrBase(const CodeGenInstruction &insn) {
87 const Record *Rec = insn.TheDef;
88 assert(Rec->isSubClassOf("X86Inst") && "Not a X86 Instruction");
89 OpPrefix = byteFromRec(rec: Rec, name: "OpPrefixBits");
90 OpMap = byteFromRec(rec: Rec, name: "OpMapBits");
91 Opcode = byteFromRec(rec: Rec, name: "Opcode");
92 Form = byteFromRec(rec: Rec, name: "FormBits");
93 Encoding = byteFromRec(rec: Rec, name: "OpEncBits");
94 OpSize = byteFromRec(rec: Rec, name: "OpSizeBits");
95 AdSize = byteFromRec(rec: Rec, name: "AdSizeBits");
96 HasREX_W = Rec->getValueAsBit(FieldName: "hasREX_W");
97 HasVEX_4V = Rec->getValueAsBit(FieldName: "hasVEX_4V");
98 IgnoresW = Rec->getValueAsBit(FieldName: "IgnoresW");
99 IgnoresVEX_L = Rec->getValueAsBit(FieldName: "ignoresVEX_L");
100 HasEVEX_L2 = Rec->getValueAsBit(FieldName: "hasEVEX_L2");
101 HasEVEX_K = Rec->getValueAsBit(FieldName: "hasEVEX_K");
102 HasEVEX_KZ = Rec->getValueAsBit(FieldName: "hasEVEX_Z");
103 HasEVEX_B = Rec->getValueAsBit(FieldName: "hasEVEX_B");
104 HasEVEX_U = Rec->getValueAsBit(FieldName: "hasEVEX_U");
105 HasEVEX_NF = Rec->getValueAsBit(FieldName: "hasEVEX_NF");
106 HasTwoConditionalOps = Rec->getValueAsBit(FieldName: "hasTwoConditionalOps");
107 IsCodeGenOnly = Rec->getValueAsBit(FieldName: "isCodeGenOnly");
108 IsAsmParserOnly = Rec->getValueAsBit(FieldName: "isAsmParserOnly");
109 ForceDisassemble = Rec->getValueAsBit(FieldName: "ForceDisassemble");
110 CD8_Scale = byteFromRec(rec: Rec, name: "CD8_Scale");
111 HasVEX_L = Rec->getValueAsBit(FieldName: "hasVEX_L");
112 ExplicitREX2Prefix =
113 byteFromRec(rec: Rec, name: "explicitOpPrefixBits") == X86Local::ExplicitREX2;
114
115 EncodeRC = HasEVEX_B &&
116 (Form == X86Local::MRMDestReg || Form == X86Local::MRMSrcReg);
117}
118
119bool RecognizableInstrBase::shouldBeEmitted() const {
120 return Form != X86Local::Pseudo && (!IsCodeGenOnly || ForceDisassemble) &&
121 !IsAsmParserOnly;
122}
123
124RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
125 const CodeGenInstruction &insn,
126 InstrUID uid)
127 : RecognizableInstrBase(insn), Rec(insn.TheDef), Name(Rec->getName().str()),
128 Is32Bit(false), Is64Bit(false), Operands(&insn.Operands.OperandList),
129 UID(uid), Spec(&tables.specForUID(uid)) {
130 // Check for 64-bit inst which does not require REX
131 // FIXME: Is there some better way to check for In64BitMode?
132 for (const Record *Predicate : Rec->getValueAsListOfDefs(FieldName: "Predicates")) {
133 if (Predicate->getName().contains(Other: "Not64Bit") ||
134 Predicate->getName().contains(Other: "In32Bit")) {
135 Is32Bit = true;
136 break;
137 }
138 if (Predicate->getName().contains(Other: "In64Bit")) {
139 Is64Bit = true;
140 break;
141 }
142 }
143}
144
145void RecognizableInstr::processInstr(DisassemblerTables &tables,
146 const CodeGenInstruction &insn,
147 InstrUID uid) {
148 if (!insn.TheDef->isSubClassOf(Name: "X86Inst"))
149 return;
150 RecognizableInstr recogInstr(tables, insn, uid);
151
152 if (!recogInstr.shouldBeEmitted())
153 return;
154 recogInstr.emitInstructionSpecifier();
155 recogInstr.emitDecodePath(tables);
156}
157
158#define EVEX_KB(n) \
159 (HasEVEX_KZ && HasEVEX_B \
160 ? n##_KZ_B \
161 : (HasEVEX_K && HasEVEX_B \
162 ? n##_K_B \
163 : (HasEVEX_KZ ? n##_KZ \
164 : (HasEVEX_K ? n##_K : (HasEVEX_B ? n##_B : n)))))
165
166#define EVEX_NF(n) (HasEVEX_NF ? n##_NF : n)
167#define EVEX_B_NF(n) (HasEVEX_B ? EVEX_NF(n##_B) : EVEX_NF(n))
168#define EVEX_KB_ADSIZE(n) AdSize == X86Local::AdSize32 ? n##_ADSIZE : EVEX_KB(n)
169#define EVEX_KB_U(n) \
170 (HasEVEX_KZ ? n##_KZ_B_U : (HasEVEX_K ? n##_K_B_U : n##_B_U))
171
172InstructionContext RecognizableInstr::insnContext() const {
173 InstructionContext insnContext;
174
175 if (Encoding == X86Local::EVEX) {
176 if (HasVEX_L && HasEVEX_L2) {
177 errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n";
178 llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
179 }
180 if (EncodeRC && HasEVEX_U) {
181 // EVEX_U
182 if (HasREX_W) {
183 if (OpPrefix == X86Local::PD)
184 insnContext = EVEX_KB_U(IC_EVEX_W_OPSIZE);
185 else if (OpPrefix == X86Local::XS)
186 insnContext = EVEX_KB_U(IC_EVEX_W_XS);
187 else if (OpPrefix == X86Local::XD)
188 insnContext = EVEX_KB_U(IC_EVEX_W_XD);
189 else if (OpPrefix == X86Local::PS)
190 insnContext = EVEX_KB_U(IC_EVEX_W);
191 else {
192 errs() << "Instruction does not use a prefix: " << Name << "\n";
193 llvm_unreachable("Invalid prefix");
194 }
195 } else {
196 if (OpPrefix == X86Local::PD)
197 insnContext = EVEX_KB_U(IC_EVEX_OPSIZE);
198 else if (OpPrefix == X86Local::XS)
199 insnContext = EVEX_KB_U(IC_EVEX_XS);
200 else if (OpPrefix == X86Local::XD)
201 insnContext = EVEX_KB_U(IC_EVEX_XD);
202 else if (OpPrefix == X86Local::PS)
203 insnContext = EVEX_KB_U(IC_EVEX);
204 else {
205 errs() << "Instruction does not use a prefix: " << Name << "\n";
206 llvm_unreachable("Invalid prefix");
207 }
208 }
209 } else if (HasEVEX_NF) {
210 if (OpPrefix == X86Local::PD)
211 insnContext = EVEX_B_NF(IC_EVEX_OPSIZE);
212 else if (HasREX_W)
213 insnContext = EVEX_B_NF(IC_EVEX_W);
214 else
215 insnContext = EVEX_B_NF(IC_EVEX);
216 } else if (!EncodeRC && HasVEX_L && HasREX_W) {
217 // VEX_L & VEX_W
218 if (OpPrefix == X86Local::PD)
219 insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
220 else if (OpPrefix == X86Local::XS)
221 insnContext = EVEX_KB(IC_EVEX_L_W_XS);
222 else if (OpPrefix == X86Local::XD)
223 insnContext = EVEX_KB(IC_EVEX_L_W_XD);
224 else if (OpPrefix == X86Local::PS)
225 insnContext = EVEX_KB(IC_EVEX_L_W);
226 else {
227 errs() << "Instruction does not use a prefix: " << Name << "\n";
228 llvm_unreachable("Invalid prefix");
229 }
230 } else if (!EncodeRC && HasVEX_L) {
231 // VEX_L
232 if (OpPrefix == X86Local::PD)
233 insnContext = EVEX_KB(IC_EVEX_L_OPSIZE);
234 else if (OpPrefix == X86Local::XS)
235 insnContext = EVEX_KB(IC_EVEX_L_XS);
236 else if (OpPrefix == X86Local::XD)
237 insnContext = EVEX_KB(IC_EVEX_L_XD);
238 else if (OpPrefix == X86Local::PS)
239 insnContext = EVEX_KB(IC_EVEX_L);
240 else {
241 errs() << "Instruction does not use a prefix: " << Name << "\n";
242 llvm_unreachable("Invalid prefix");
243 }
244 } else if (!EncodeRC && HasEVEX_L2 && HasREX_W) {
245 // EVEX_L2 & VEX_W
246 if (OpPrefix == X86Local::PD)
247 insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
248 else if (OpPrefix == X86Local::XS)
249 insnContext = EVEX_KB(IC_EVEX_L2_W_XS);
250 else if (OpPrefix == X86Local::XD)
251 insnContext = EVEX_KB(IC_EVEX_L2_W_XD);
252 else if (OpPrefix == X86Local::PS)
253 insnContext = EVEX_KB(IC_EVEX_L2_W);
254 else {
255 errs() << "Instruction does not use a prefix: " << Name << "\n";
256 llvm_unreachable("Invalid prefix");
257 }
258 } else if (!EncodeRC && HasEVEX_L2) {
259 // EVEX_L2
260 if (OpPrefix == X86Local::PD)
261 insnContext = EVEX_KB(IC_EVEX_L2_OPSIZE);
262 else if (OpPrefix == X86Local::XD)
263 insnContext = EVEX_KB(IC_EVEX_L2_XD);
264 else if (OpPrefix == X86Local::XS)
265 insnContext = EVEX_KB(IC_EVEX_L2_XS);
266 else if (OpPrefix == X86Local::PS)
267 insnContext = EVEX_KB(IC_EVEX_L2);
268 else {
269 errs() << "Instruction does not use a prefix: " << Name << "\n";
270 llvm_unreachable("Invalid prefix");
271 }
272 } else if (HasREX_W) {
273 // VEX_W
274 if (OpPrefix == X86Local::PD)
275 insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
276 else if (OpPrefix == X86Local::XS)
277 insnContext = EVEX_KB(IC_EVEX_W_XS);
278 else if (OpPrefix == X86Local::XD)
279 insnContext = EVEX_KB(IC_EVEX_W_XD);
280 else if (OpPrefix == X86Local::PS)
281 insnContext = EVEX_KB(IC_EVEX_W);
282 else {
283 errs() << "Instruction does not use a prefix: " << Name << "\n";
284 llvm_unreachable("Invalid prefix");
285 }
286 }
287 // No L, no W
288 else if (OpPrefix == X86Local::PD) {
289 insnContext = EVEX_KB_ADSIZE(IC_EVEX_OPSIZE);
290 } else if (OpPrefix == X86Local::XD)
291 insnContext = EVEX_KB_ADSIZE(IC_EVEX_XD);
292 else if (OpPrefix == X86Local::XS)
293 insnContext = EVEX_KB_ADSIZE(IC_EVEX_XS);
294 else if (OpPrefix == X86Local::PS)
295 insnContext = EVEX_KB(IC_EVEX);
296 else {
297 errs() << "Instruction does not use a prefix: " << Name << "\n";
298 llvm_unreachable("Invalid prefix");
299 }
300 /// eof EVEX
301 } else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {
302 if (HasVEX_L && HasREX_W) {
303 if (OpPrefix == X86Local::PD)
304 insnContext = IC_VEX_L_W_OPSIZE;
305 else if (OpPrefix == X86Local::XS)
306 insnContext = IC_VEX_L_W_XS;
307 else if (OpPrefix == X86Local::XD)
308 insnContext = IC_VEX_L_W_XD;
309 else if (OpPrefix == X86Local::PS)
310 insnContext = IC_VEX_L_W;
311 else {
312 errs() << "Instruction does not use a prefix: " << Name << "\n";
313 llvm_unreachable("Invalid prefix");
314 }
315 } else if (OpPrefix == X86Local::PD && HasVEX_L)
316 insnContext = IC_VEX_L_OPSIZE;
317 else if (OpPrefix == X86Local::PD && HasREX_W)
318 insnContext = IC_VEX_W_OPSIZE;
319 else if (OpPrefix == X86Local::PD)
320 insnContext = IC_VEX_OPSIZE;
321 else if (HasVEX_L && OpPrefix == X86Local::XS)
322 insnContext = IC_VEX_L_XS;
323 else if (HasVEX_L && OpPrefix == X86Local::XD)
324 insnContext = IC_VEX_L_XD;
325 else if (HasREX_W && OpPrefix == X86Local::XS)
326 insnContext = IC_VEX_W_XS;
327 else if (HasREX_W && OpPrefix == X86Local::XD)
328 insnContext = IC_VEX_W_XD;
329 else if (HasREX_W && OpPrefix == X86Local::PS)
330 insnContext = IC_VEX_W;
331 else if (HasVEX_L && OpPrefix == X86Local::PS)
332 insnContext = IC_VEX_L;
333 else if (OpPrefix == X86Local::XD)
334 insnContext = IC_VEX_XD;
335 else if (OpPrefix == X86Local::XS)
336 insnContext = IC_VEX_XS;
337 else if (OpPrefix == X86Local::PS)
338 insnContext = IC_VEX;
339 else {
340 errs() << "Instruction does not use a prefix: " << Name << "\n";
341 llvm_unreachable("Invalid prefix");
342 }
343 } else if (Is64Bit || HasREX_W || AdSize == X86Local::AdSize64) {
344 if (HasREX_W && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD))
345 insnContext = IC_64BIT_REXW_OPSIZE;
346 else if (HasREX_W && AdSize == X86Local::AdSize32)
347 insnContext = IC_64BIT_REXW_ADSIZE;
348 else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
349 insnContext = IC_64BIT_XD_OPSIZE;
350 else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
351 insnContext = IC_64BIT_XS_OPSIZE;
352 else if (AdSize == X86Local::AdSize32 && OpPrefix == X86Local::PD)
353 insnContext = IC_64BIT_OPSIZE_ADSIZE;
354 else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize32)
355 insnContext = IC_64BIT_OPSIZE_ADSIZE;
356 else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
357 insnContext = IC_64BIT_OPSIZE;
358 else if (AdSize == X86Local::AdSize32)
359 insnContext = IC_64BIT_ADSIZE;
360 else if (HasREX_W && OpPrefix == X86Local::XS)
361 insnContext = IC_64BIT_REXW_XS;
362 else if (HasREX_W && OpPrefix == X86Local::XD)
363 insnContext = IC_64BIT_REXW_XD;
364 else if (OpPrefix == X86Local::XD)
365 insnContext = IC_64BIT_XD;
366 else if (OpPrefix == X86Local::XS)
367 insnContext = IC_64BIT_XS;
368 else if (HasREX_W && ExplicitREX2Prefix)
369 insnContext = IC_64BIT_REX2_REXW;
370 else if (ExplicitREX2Prefix)
371 insnContext = IC_64BIT_REX2;
372 else if (HasREX_W)
373 insnContext = IC_64BIT_REXW;
374 else
375 insnContext = IC_64BIT;
376 } else {
377 if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
378 insnContext = IC_XD_OPSIZE;
379 else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
380 insnContext = IC_XS_OPSIZE;
381 else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XD)
382 insnContext = IC_XD_ADSIZE;
383 else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::XS)
384 insnContext = IC_XS_ADSIZE;
385 else if (AdSize == X86Local::AdSize16 && OpPrefix == X86Local::PD)
386 insnContext = IC_OPSIZE_ADSIZE;
387 else if (OpSize == X86Local::OpSize16 && AdSize == X86Local::AdSize16)
388 insnContext = IC_OPSIZE_ADSIZE;
389 else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
390 insnContext = IC_OPSIZE;
391 else if (AdSize == X86Local::AdSize16)
392 insnContext = IC_ADSIZE;
393 else if (OpPrefix == X86Local::XD)
394 insnContext = IC_XD;
395 else if (OpPrefix == X86Local::XS)
396 insnContext = IC_XS;
397 else
398 insnContext = IC;
399 }
400
401 return insnContext;
402}
403
404void RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) {
405 // The scaling factor for AVX512 compressed displacement encoding is an
406 // instruction attribute. Adjust the ModRM encoding type to include the
407 // scale for compressed displacement.
408 if ((encoding != ENCODING_RM && encoding != ENCODING_VSIB &&
409 encoding != ENCODING_SIB) ||
410 CD8_Scale == 0)
411 return;
412 encoding = (OperandEncoding)(encoding + Log2_32(Value: CD8_Scale));
413 assert(((encoding >= ENCODING_RM && encoding <= ENCODING_RM_CD64) ||
414 (encoding == ENCODING_SIB) ||
415 (encoding >= ENCODING_VSIB && encoding <= ENCODING_VSIB_CD64)) &&
416 "Invalid CDisp scaling");
417}
418
419void RecognizableInstr::handleOperand(bool optional, unsigned &operandIndex,
420 unsigned &physicalOperandIndex,
421 unsigned numPhysicalOperands,
422 const unsigned *operandMapping,
423 EncodingFn encodingFromString) {
424 if (optional) {
425 if (physicalOperandIndex >= numPhysicalOperands)
426 return;
427 } else {
428 assert(physicalOperandIndex < numPhysicalOperands);
429 }
430
431 while (operandMapping[operandIndex] != operandIndex) {
432 Spec->operands[operandIndex].encoding = ENCODING_DUP;
433 Spec->operands[operandIndex].type =
434 (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);
435 ++operandIndex;
436 }
437
438 StringRef typeName = (*Operands)[operandIndex].Rec->getName();
439
440 OperandEncoding encoding = encodingFromString(typeName, OpSize);
441 // Adjust the encoding type for an operand based on the instruction.
442 adjustOperandEncoding(encoding);
443 Spec->operands[operandIndex].encoding = encoding;
444 Spec->operands[operandIndex].type =
445 typeFromString(Str: typeName, hasREX_W: HasREX_W, OpSize);
446
447 ++operandIndex;
448 ++physicalOperandIndex;
449}
450
451void RecognizableInstr::emitInstructionSpecifier() {
452 Spec->name = Name;
453
454 Spec->insnContext = insnContext();
455
456 const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
457
458 unsigned numOperands = OperandList.size();
459 unsigned numPhysicalOperands = 0;
460
461 // operandMapping maps from operands in OperandList to their originals.
462 // If operandMapping[i] != i, then the entry is a duplicate.
463 unsigned operandMapping[X86_MAX_OPERANDS];
464 assert(numOperands <= X86_MAX_OPERANDS &&
465 "X86_MAX_OPERANDS is not large enough");
466
467 for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
468 if (!OperandList[operandIndex].Constraints.empty()) {
469 const CGIOperandList::ConstraintInfo &Constraint =
470 OperandList[operandIndex].Constraints[0];
471 if (Constraint.isTied()) {
472 operandMapping[operandIndex] = operandIndex;
473 operandMapping[Constraint.getTiedOperand()] = operandIndex;
474 } else {
475 ++numPhysicalOperands;
476 operandMapping[operandIndex] = operandIndex;
477 }
478 } else {
479 ++numPhysicalOperands;
480 operandMapping[operandIndex] = operandIndex;
481 }
482 }
483
484#define HANDLE_OPERAND(class) \
485 handleOperand(false, operandIndex, physicalOperandIndex, \
486 numPhysicalOperands, operandMapping, \
487 class##EncodingFromString);
488
489#define HANDLE_OPTIONAL(class) \
490 handleOperand(true, operandIndex, physicalOperandIndex, numPhysicalOperands, \
491 operandMapping, class##EncodingFromString);
492
493 // operandIndex should always be < numOperands
494 unsigned operandIndex = 0;
495 // physicalOperandIndex should always be < numPhysicalOperands
496 unsigned physicalOperandIndex = 0;
497
498#ifndef NDEBUG
499 // Given the set of prefix bits, how many additional operands does the
500 // instruction have?
501 unsigned additionalOperands = 0;
502 if (HasVEX_4V)
503 ++additionalOperands;
504 if (HasEVEX_K)
505 ++additionalOperands;
506 if (HasTwoConditionalOps)
507 additionalOperands += 2;
508#endif
509
510 bool IsND = OpMap == X86Local::T_MAP4 && HasEVEX_B && HasVEX_4V;
511 switch (Form) {
512 default:
513 llvm_unreachable("Unhandled form");
514 case X86Local::PrefixByte:
515 return;
516 case X86Local::RawFrmSrc:
517 HANDLE_OPERAND(relocation);
518 return;
519 case X86Local::RawFrmDst:
520 HANDLE_OPERAND(relocation);
521 return;
522 case X86Local::RawFrmDstSrc:
523 HANDLE_OPERAND(relocation);
524 HANDLE_OPERAND(relocation);
525 return;
526 case X86Local::RawFrm:
527 // Operand 1 (optional) is an address or immediate.
528 assert(numPhysicalOperands <= 1 &&
529 "Unexpected number of operands for RawFrm");
530 HANDLE_OPTIONAL(relocation)
531 break;
532 case X86Local::RawFrmMemOffs:
533 // Operand 1 is an address.
534 HANDLE_OPERAND(relocation);
535 break;
536 case X86Local::AddRegFrm:
537 // Operand 1 is added to the opcode.
538 // Operand 2 (optional) is an address.
539 assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
540 "Unexpected number of operands for AddRegFrm");
541 HANDLE_OPERAND(opcodeModifier)
542 HANDLE_OPTIONAL(relocation)
543 break;
544 case X86Local::AddCCFrm:
545 // Operand 1 (optional) is an address or immediate.
546 assert(numPhysicalOperands == 2 &&
547 "Unexpected number of operands for AddCCFrm");
548 HANDLE_OPERAND(relocation)
549 HANDLE_OPERAND(opcodeModifier)
550 break;
551 case X86Local::MRMDestRegCC:
552 assert(numPhysicalOperands == 3 &&
553 "Unexpected number of operands for MRMDestRegCC");
554 HANDLE_OPERAND(rmRegister)
555 HANDLE_OPERAND(roRegister)
556 HANDLE_OPERAND(opcodeModifier)
557 break;
558 case X86Local::MRMDestReg:
559 // Operand 1 is a register operand in the R/M field.
560 // - In AVX512 there may be a mask operand here -
561 // Operand 2 is a register operand in the Reg/Opcode field.
562 // - In AVX, there is a register operand in the VEX.vvvv field here -
563 // Operand 3 (optional) is an immediate.
564 assert(numPhysicalOperands >= 2 + additionalOperands &&
565 numPhysicalOperands <= 3 + additionalOperands &&
566 "Unexpected number of operands for MRMDestReg");
567
568 if (IsND)
569 HANDLE_OPERAND(vvvvRegister)
570
571 HANDLE_OPERAND(rmRegister)
572 if (HasEVEX_K)
573 HANDLE_OPERAND(writemaskRegister)
574
575 if (!IsND && HasVEX_4V)
576 // FIXME: In AVX, the register below becomes the one encoded
577 // in ModRMVEX and the one above the one in the VEX.VVVV field
578 HANDLE_OPERAND(vvvvRegister)
579
580 HANDLE_OPERAND(roRegister)
581 HANDLE_OPTIONAL(immediate)
582 HANDLE_OPTIONAL(immediate)
583 break;
584 case X86Local::MRMDestMemCC:
585 assert(numPhysicalOperands == 3 &&
586 "Unexpected number of operands for MRMDestMemCC");
587 HANDLE_OPERAND(memory)
588 HANDLE_OPERAND(roRegister)
589 HANDLE_OPERAND(opcodeModifier)
590 break;
591 case X86Local::MRMDestMem4VOp3CC:
592 // Operand 1 is a register operand in the Reg/Opcode field.
593 // Operand 2 is a register operand in the R/M field.
594 // Operand 3 is VEX.vvvv
595 // Operand 4 is condition code.
596 assert(numPhysicalOperands == 4 &&
597 "Unexpected number of operands for MRMDestMem4VOp3CC");
598 HANDLE_OPERAND(roRegister)
599 HANDLE_OPERAND(memory)
600 HANDLE_OPERAND(vvvvRegister)
601 HANDLE_OPERAND(opcodeModifier)
602 break;
603 case X86Local::MRMDestMem:
604 case X86Local::MRMDestMemFSIB:
605 // Operand 1 is a memory operand (possibly SIB-extended)
606 // Operand 2 is a register operand in the Reg/Opcode field.
607 // - In AVX, there is a register operand in the VEX.vvvv field here -
608 // Operand 3 (optional) is an immediate.
609 assert(numPhysicalOperands >= 2 + additionalOperands &&
610 numPhysicalOperands <= 3 + additionalOperands &&
611 "Unexpected number of operands for MRMDestMemFrm with VEX_4V");
612
613 if (IsND)
614 HANDLE_OPERAND(vvvvRegister)
615
616 HANDLE_OPERAND(memory)
617
618 if (HasEVEX_K)
619 HANDLE_OPERAND(writemaskRegister)
620
621 if (!IsND && HasVEX_4V)
622 // FIXME: In AVX, the register below becomes the one encoded
623 // in ModRMVEX and the one above the one in the VEX.VVVV field
624 HANDLE_OPERAND(vvvvRegister)
625
626 HANDLE_OPERAND(roRegister)
627 HANDLE_OPTIONAL(immediate)
628 HANDLE_OPTIONAL(immediate)
629 break;
630 case X86Local::MRMSrcReg:
631 // Operand 1 is a register operand in the Reg/Opcode field.
632 // Operand 2 is a register operand in the R/M field.
633 // - In AVX, there is a register operand in the VEX.vvvv field here -
634 // Operand 3 (optional) is an immediate.
635 // Operand 4 (optional) is an immediate.
636
637 assert(numPhysicalOperands >= 2 + additionalOperands &&
638 numPhysicalOperands <= 4 + additionalOperands &&
639 "Unexpected number of operands for MRMSrcRegFrm");
640
641 if (IsND)
642 HANDLE_OPERAND(vvvvRegister)
643
644 HANDLE_OPERAND(roRegister)
645
646 if (HasEVEX_K)
647 HANDLE_OPERAND(writemaskRegister)
648
649 if (!IsND && HasVEX_4V)
650 // FIXME: In AVX, the register below becomes the one encoded
651 // in ModRMVEX and the one above the one in the VEX.VVVV field
652 HANDLE_OPERAND(vvvvRegister)
653
654 HANDLE_OPERAND(rmRegister)
655 HANDLE_OPTIONAL(immediate)
656 HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
657 break;
658 case X86Local::MRMSrcReg4VOp3:
659 assert(numPhysicalOperands == 3 &&
660 "Unexpected number of operands for MRMSrcReg4VOp3Frm");
661 HANDLE_OPERAND(roRegister)
662 HANDLE_OPERAND(rmRegister)
663 HANDLE_OPERAND(vvvvRegister)
664 break;
665 case X86Local::MRMSrcRegOp4:
666 assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 &&
667 "Unexpected number of operands for MRMSrcRegOp4Frm");
668 HANDLE_OPERAND(roRegister)
669 HANDLE_OPERAND(vvvvRegister)
670 HANDLE_OPERAND(immediate) // Register in imm[7:4]
671 HANDLE_OPERAND(rmRegister)
672 HANDLE_OPTIONAL(immediate)
673 break;
674 case X86Local::MRMSrcRegCC:
675 assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&
676 "Unexpected number of operands for MRMSrcRegCC");
677 if (IsND)
678 HANDLE_OPERAND(vvvvRegister)
679 HANDLE_OPERAND(roRegister)
680 HANDLE_OPERAND(rmRegister)
681 HANDLE_OPERAND(opcodeModifier)
682 break;
683 case X86Local::MRMSrcMem:
684 case X86Local::MRMSrcMemFSIB:
685 // Operand 1 is a register operand in the Reg/Opcode field.
686 // Operand 2 is a memory operand (possibly SIB-extended)
687 // - In AVX, there is a register operand in the VEX.vvvv field here -
688 // Operand 3 (optional) is an immediate.
689
690 assert(numPhysicalOperands >= 2 + additionalOperands &&
691 numPhysicalOperands <= 4 + additionalOperands &&
692 "Unexpected number of operands for MRMSrcMemFrm");
693 if (IsND)
694 HANDLE_OPERAND(vvvvRegister)
695
696 HANDLE_OPERAND(roRegister)
697
698 if (HasEVEX_K)
699 HANDLE_OPERAND(writemaskRegister)
700
701 if (!IsND && HasVEX_4V)
702 // FIXME: In AVX, the register below becomes the one encoded
703 // in ModRMVEX and the one above the one in the VEX.VVVV field
704 HANDLE_OPERAND(vvvvRegister)
705
706 HANDLE_OPERAND(memory)
707 HANDLE_OPTIONAL(immediate)
708 HANDLE_OPTIONAL(immediate) // above might be a register in 7:4
709 break;
710 case X86Local::MRMSrcMem4VOp3:
711 assert(numPhysicalOperands == 3 &&
712 "Unexpected number of operands for MRMSrcMem4VOp3Frm");
713 HANDLE_OPERAND(roRegister)
714 HANDLE_OPERAND(memory)
715 HANDLE_OPERAND(vvvvRegister)
716 break;
717 case X86Local::MRMSrcMemOp4:
718 assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 &&
719 "Unexpected number of operands for MRMSrcMemOp4Frm");
720 HANDLE_OPERAND(roRegister)
721 HANDLE_OPERAND(vvvvRegister)
722 HANDLE_OPERAND(immediate) // Register in imm[7:4]
723 HANDLE_OPERAND(memory)
724 HANDLE_OPTIONAL(immediate)
725 break;
726 case X86Local::MRMSrcMemCC:
727 assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&
728 "Unexpected number of operands for MRMSrcMemCC");
729 if (IsND)
730 HANDLE_OPERAND(vvvvRegister)
731 HANDLE_OPERAND(roRegister)
732 HANDLE_OPERAND(memory)
733 HANDLE_OPERAND(opcodeModifier)
734 break;
735 case X86Local::MRMXrCC:
736 assert(numPhysicalOperands == 2 &&
737 "Unexpected number of operands for MRMXrCC");
738 HANDLE_OPERAND(rmRegister)
739 HANDLE_OPERAND(opcodeModifier)
740 break;
741 case X86Local::MRMr0:
742 // Operand 1 is a register operand in the R/M field.
743 HANDLE_OPERAND(roRegister)
744 break;
745 case X86Local::MRMXr:
746 case X86Local::MRM0r:
747 case X86Local::MRM1r:
748 case X86Local::MRM2r:
749 case X86Local::MRM3r:
750 case X86Local::MRM4r:
751 case X86Local::MRM5r:
752 case X86Local::MRM6r:
753 case X86Local::MRM7r:
754 // Operand 1 is a register operand in the R/M field.
755 // Operand 2 (optional) is an immediate or relocation.
756 // Operand 3 (optional) is an immediate.
757 assert(numPhysicalOperands >= 0 + additionalOperands &&
758 numPhysicalOperands <= 3 + additionalOperands &&
759 "Unexpected number of operands for MRMnr");
760
761 if (HasVEX_4V)
762 HANDLE_OPERAND(vvvvRegister)
763
764 if (HasEVEX_K)
765 HANDLE_OPERAND(writemaskRegister)
766 HANDLE_OPTIONAL(rmRegister)
767 HANDLE_OPTIONAL(relocation)
768 HANDLE_OPTIONAL(immediate)
769 HANDLE_OPTIONAL(immediate)
770 break;
771 case X86Local::MRMXmCC:
772 assert(numPhysicalOperands == 2 &&
773 "Unexpected number of operands for MRMXm");
774 HANDLE_OPERAND(memory)
775 HANDLE_OPERAND(opcodeModifier)
776 break;
777 case X86Local::MRMXm:
778 case X86Local::MRM0m:
779 case X86Local::MRM1m:
780 case X86Local::MRM2m:
781 case X86Local::MRM3m:
782 case X86Local::MRM4m:
783 case X86Local::MRM5m:
784 case X86Local::MRM6m:
785 case X86Local::MRM7m:
786 // Operand 1 is a memory operand (possibly SIB-extended)
787 // Operand 2 (optional) is an immediate or relocation.
788 assert(numPhysicalOperands >= 1 + additionalOperands &&
789 numPhysicalOperands <= 2 + additionalOperands &&
790 "Unexpected number of operands for MRMnm");
791
792 if (HasVEX_4V)
793 HANDLE_OPERAND(vvvvRegister)
794 if (HasEVEX_K)
795 HANDLE_OPERAND(writemaskRegister)
796 HANDLE_OPERAND(memory)
797 HANDLE_OPTIONAL(relocation)
798 HANDLE_OPTIONAL(immediate)
799 HANDLE_OPTIONAL(immediate)
800 break;
801 case X86Local::RawFrmImm8:
802 // operand 1 is a 16-bit immediate
803 // operand 2 is an 8-bit immediate
804 assert(numPhysicalOperands == 2 &&
805 "Unexpected number of operands for X86Local::RawFrmImm8");
806 HANDLE_OPERAND(immediate)
807 HANDLE_OPERAND(immediate)
808 break;
809 case X86Local::RawFrmImm16:
810 // operand 1 is a 16-bit immediate
811 // operand 2 is a 16-bit immediate
812 HANDLE_OPERAND(immediate)
813 HANDLE_OPERAND(immediate)
814 break;
815 case X86Local::MRM0X:
816 case X86Local::MRM1X:
817 case X86Local::MRM2X:
818 case X86Local::MRM3X:
819 case X86Local::MRM4X:
820 case X86Local::MRM5X:
821 case X86Local::MRM6X:
822 case X86Local::MRM7X:
823#define MAP(from, to) case X86Local::MRM_##from:
824 X86_INSTR_MRM_MAPPING
825#undef MAP
826 HANDLE_OPTIONAL(relocation)
827 break;
828 }
829
830#undef HANDLE_OPERAND
831#undef HANDLE_OPTIONAL
832}
833
834void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
835 // Special cases where the LLVM tables are not complete
836
837#define MAP(from, to) case X86Local::MRM_##from:
838
839 std::optional<OpcodeType> opcodeType;
840 switch (OpMap) {
841 default:
842 llvm_unreachable("Invalid map!");
843 case X86Local::OB:
844 opcodeType = ONEBYTE;
845 break;
846 case X86Local::TB:
847 opcodeType = TWOBYTE;
848 break;
849 case X86Local::T8:
850 opcodeType = THREEBYTE_38;
851 break;
852 case X86Local::TA:
853 opcodeType = THREEBYTE_3A;
854 break;
855 case X86Local::XOP8:
856 opcodeType = XOP8_MAP;
857 break;
858 case X86Local::XOP9:
859 opcodeType = XOP9_MAP;
860 break;
861 case X86Local::XOPA:
862 opcodeType = XOPA_MAP;
863 break;
864 case X86Local::ThreeDNow:
865 opcodeType = THREEDNOW_MAP;
866 break;
867 case X86Local::T_MAP4:
868 opcodeType = MAP4;
869 break;
870 case X86Local::T_MAP5:
871 opcodeType = MAP5;
872 break;
873 case X86Local::T_MAP6:
874 opcodeType = MAP6;
875 break;
876 case X86Local::T_MAP7:
877 opcodeType = MAP7;
878 break;
879 }
880
881 std::unique_ptr<ModRMFilter> filter;
882 switch (Form) {
883 default:
884 llvm_unreachable("Invalid form!");
885 case X86Local::Pseudo:
886 llvm_unreachable("Pseudo should not be emitted!");
887 case X86Local::RawFrm:
888 case X86Local::AddRegFrm:
889 case X86Local::RawFrmMemOffs:
890 case X86Local::RawFrmSrc:
891 case X86Local::RawFrmDst:
892 case X86Local::RawFrmDstSrc:
893 case X86Local::RawFrmImm8:
894 case X86Local::RawFrmImm16:
895 case X86Local::AddCCFrm:
896 case X86Local::PrefixByte:
897 filter = std::make_unique<DumbFilter>();
898 break;
899 case X86Local::MRMDestReg:
900 case X86Local::MRMDestRegCC:
901 case X86Local::MRMSrcReg:
902 case X86Local::MRMSrcReg4VOp3:
903 case X86Local::MRMSrcRegOp4:
904 case X86Local::MRMSrcRegCC:
905 case X86Local::MRMXrCC:
906 case X86Local::MRMXr:
907 filter = std::make_unique<ModFilter>(args: true);
908 break;
909 case X86Local::MRMDestMem:
910 case X86Local::MRMDestMemCC:
911 case X86Local::MRMDestMem4VOp3CC:
912 case X86Local::MRMDestMemFSIB:
913 case X86Local::MRMSrcMem:
914 case X86Local::MRMSrcMemFSIB:
915 case X86Local::MRMSrcMem4VOp3:
916 case X86Local::MRMSrcMemOp4:
917 case X86Local::MRMSrcMemCC:
918 case X86Local::MRMXmCC:
919 case X86Local::MRMXm:
920 filter = std::make_unique<ModFilter>(args: false);
921 break;
922 case X86Local::MRM0r:
923 case X86Local::MRM1r:
924 case X86Local::MRM2r:
925 case X86Local::MRM3r:
926 case X86Local::MRM4r:
927 case X86Local::MRM5r:
928 case X86Local::MRM6r:
929 case X86Local::MRM7r:
930 filter = std::make_unique<ExtendedFilter>(args: true, args: Form - X86Local::MRM0r);
931 break;
932 case X86Local::MRM0X:
933 case X86Local::MRM1X:
934 case X86Local::MRM2X:
935 case X86Local::MRM3X:
936 case X86Local::MRM4X:
937 case X86Local::MRM5X:
938 case X86Local::MRM6X:
939 case X86Local::MRM7X:
940 filter = std::make_unique<ExtendedFilter>(args: true, args: Form - X86Local::MRM0X);
941 break;
942 case X86Local::MRMr0:
943 filter = std::make_unique<ExtendedRMFilter>(args: true, args: Form - X86Local::MRMr0);
944 break;
945 case X86Local::MRM0m:
946 case X86Local::MRM1m:
947 case X86Local::MRM2m:
948 case X86Local::MRM3m:
949 case X86Local::MRM4m:
950 case X86Local::MRM5m:
951 case X86Local::MRM6m:
952 case X86Local::MRM7m:
953 filter = std::make_unique<ExtendedFilter>(args: false, args: Form - X86Local::MRM0m);
954 break;
955 X86_INSTR_MRM_MAPPING
956 filter = std::make_unique<ExactFilter>(args: 0xC0 + Form - X86Local::MRM_C0);
957 break;
958 } // switch (Form)
959
960 uint8_t opcodeToSet = Opcode;
961
962 unsigned AddressSize = 0;
963 switch (AdSize) {
964 case X86Local::AdSize16:
965 AddressSize = 16;
966 break;
967 case X86Local::AdSize32:
968 AddressSize = 32;
969 break;
970 case X86Local::AdSize64:
971 AddressSize = 64;
972 break;
973 }
974
975 assert(opcodeType && "Opcode type not set");
976 assert(filter && "Filter not set");
977
978 if (Form == X86Local::AddRegFrm || Form == X86Local::MRMSrcRegCC ||
979 Form == X86Local::MRMSrcMemCC || Form == X86Local::MRMXrCC ||
980 Form == X86Local::MRMXmCC || Form == X86Local::AddCCFrm ||
981 Form == X86Local::MRMDestRegCC || Form == X86Local::MRMDestMemCC ||
982 Form == X86Local::MRMDestMem4VOp3CC) {
983 uint8_t Count = Form == X86Local::AddRegFrm ? 8 : 16;
984 assert(((opcodeToSet % Count) == 0) && "ADDREG_FRM opcode not aligned");
985
986 uint8_t currentOpcode;
987
988 for (currentOpcode = opcodeToSet;
989 currentOpcode < (uint8_t)(opcodeToSet + Count); ++currentOpcode)
990 tables.setTableFields(type: *opcodeType, insnContext: insnContext(), opcode: currentOpcode, filter: *filter,
991 uid: UID, is32bit: Is32Bit, noPrefix: OpPrefix == 0,
992 ignoresVEX_L: IgnoresVEX_L || EncodeRC, ignoresVEX_W: IgnoresW, AddrSize: AddressSize);
993 } else {
994 tables.setTableFields(type: *opcodeType, insnContext: insnContext(), opcode: opcodeToSet, filter: *filter, uid: UID,
995 is32bit: Is32Bit, noPrefix: OpPrefix == 0, ignoresVEX_L: IgnoresVEX_L || EncodeRC,
996 ignoresVEX_W: IgnoresW, AddrSize: AddressSize);
997 }
998
999#undef MAP
1000}
1001
1002OperandType RecognizableInstr::typeFromString(StringRef Str, bool hasREX_W,
1003 uint8_t OpSize) {
1004 StringSwitch<OperandType> Switch(Str);
1005 if (hasREX_W) {
1006 // For instructions with a REX_W prefix, a declared 32-bit register encoding
1007 // is special.
1008 Switch.Case(S: "GR32", Value: TYPE_R32);
1009 }
1010 if (OpSize == X86Local::OpSize16) {
1011 // For OpSize16 instructions, a declared 16-bit register or
1012 // immediate encoding is special.
1013 Switch.Case(S: "GR16", Value: TYPE_Rv);
1014 } else if (OpSize == X86Local::OpSize32) {
1015 // For OpSize32 instructions, a declared 32-bit register or
1016 // immediate encoding is special.
1017 Switch.Case(S: "GR32", Value: TYPE_Rv);
1018 }
1019 // clang-format off
1020 OperandType Type =
1021 Switch.Case(S: "i16mem", Value: TYPE_M)
1022 .Case(S: "i16imm", Value: TYPE_IMM)
1023 .Case(S: "i16i8imm", Value: TYPE_IMM)
1024 .Case(S: "GR16", Value: TYPE_R16)
1025 .Case(S: "GR16orGR32orGR64", Value: TYPE_R16)
1026 .Case(S: "i32mem", Value: TYPE_M)
1027 .Case(S: "i32imm", Value: TYPE_IMM)
1028 .Case(S: "i32i8imm", Value: TYPE_IMM)
1029 .Case(S: "GR32", Value: TYPE_R32)
1030 .Case(S: "GR32orGR64", Value: TYPE_R32)
1031 .Case(S: "i64mem", Value: TYPE_M)
1032 .Case(S: "i64i32imm", Value: TYPE_IMM)
1033 .Case(S: "i64i8imm", Value: TYPE_IMM)
1034 .Case(S: "GR64", Value: TYPE_R64)
1035 .Case(S: "i8mem", Value: TYPE_M)
1036 .Case(S: "i8imm", Value: TYPE_IMM)
1037 .Case(S: "u4imm", Value: TYPE_UIMM8)
1038 .Case(S: "u8imm", Value: TYPE_UIMM8)
1039 .Case(S: "i16u8imm", Value: TYPE_UIMM8)
1040 .Case(S: "i32u8imm", Value: TYPE_UIMM8)
1041 .Case(S: "i64u8imm", Value: TYPE_UIMM8)
1042 .Case(S: "GR8", Value: TYPE_R8)
1043 .Case(S: "VR128", Value: TYPE_XMM)
1044 .Case(S: "VR128X", Value: TYPE_XMM)
1045 .Case(S: "f128mem", Value: TYPE_M)
1046 .Case(S: "f256mem", Value: TYPE_M)
1047 .Case(S: "f512mem", Value: TYPE_M)
1048 .Case(S: "FR128", Value: TYPE_XMM)
1049 .Case(S: "FR64", Value: TYPE_XMM)
1050 .Case(S: "FR64X", Value: TYPE_XMM)
1051 .Case(S: "f64mem", Value: TYPE_M)
1052 .Case(S: "sdmem", Value: TYPE_M)
1053 .Case(S: "FR16X", Value: TYPE_XMM)
1054 .Case(S: "FR32", Value: TYPE_XMM)
1055 .Case(S: "FR32X", Value: TYPE_XMM)
1056 .Case(S: "f32mem", Value: TYPE_M)
1057 .Case(S: "f16mem", Value: TYPE_M)
1058 .Case(S: "ssmem", Value: TYPE_M)
1059 .Case(S: "shmem", Value: TYPE_M)
1060 .Case(S: "RST", Value: TYPE_ST)
1061 .Case(S: "RSTi", Value: TYPE_ST)
1062 .Case(S: "i128mem", Value: TYPE_M)
1063 .Case(S: "i256mem", Value: TYPE_M)
1064 .Case(S: "i512mem", Value: TYPE_M)
1065 .Case(S: "i512mem_GR16", Value: TYPE_M)
1066 .Case(S: "i512mem_GR32", Value: TYPE_M)
1067 .Case(S: "i512mem_GR64", Value: TYPE_M)
1068 .Case(S: "i64i32imm_brtarget", Value: TYPE_REL)
1069 .Case(S: "i8imm_brtarget", Value: TYPE_REL)
1070 .Case(S: "i16imm_brtarget", Value: TYPE_REL)
1071 .Case(S: "i32imm_brtarget", Value: TYPE_REL)
1072 .Case(S: "ccode", Value: TYPE_IMM)
1073 .Case(S: "cflags", Value: TYPE_IMM)
1074 .Case(S: "AVX512RC", Value: TYPE_IMM)
1075 .Case(S: "brtarget32", Value: TYPE_REL)
1076 .Case(S: "brtarget16", Value: TYPE_REL)
1077 .Case(S: "brtarget8", Value: TYPE_REL)
1078 .Case(S: "f80mem", Value: TYPE_M)
1079 .Case(S: "lea64_8mem", Value: TYPE_M)
1080 .Case(S: "lea64_16mem", Value: TYPE_M)
1081 .Case(S: "lea64_32mem", Value: TYPE_M)
1082 .Case(S: "lea64mem", Value: TYPE_M)
1083 .Case(S: "VR64", Value: TYPE_MM64)
1084 .Case(S: "i64imm", Value: TYPE_IMM)
1085 .Case(S: "anymem", Value: TYPE_M)
1086 .Case(S: "opaquemem", Value: TYPE_M)
1087 .Case(S: "sibmem", Value: TYPE_MSIB)
1088 .Case(S: "SEGMENT_REG", Value: TYPE_SEGMENTREG)
1089 .Case(S: "DEBUG_REG", Value: TYPE_DEBUGREG)
1090 .Case(S: "CONTROL_REG", Value: TYPE_CONTROLREG)
1091 .Case(S: "srcidx8", Value: TYPE_SRCIDX)
1092 .Case(S: "srcidx16", Value: TYPE_SRCIDX)
1093 .Case(S: "srcidx32", Value: TYPE_SRCIDX)
1094 .Case(S: "srcidx64", Value: TYPE_SRCIDX)
1095 .Case(S: "dstidx8", Value: TYPE_DSTIDX)
1096 .Case(S: "dstidx16", Value: TYPE_DSTIDX)
1097 .Case(S: "dstidx32", Value: TYPE_DSTIDX)
1098 .Case(S: "dstidx64", Value: TYPE_DSTIDX)
1099 .Case(S: "offset16_8", Value: TYPE_MOFFS)
1100 .Case(S: "offset16_16", Value: TYPE_MOFFS)
1101 .Case(S: "offset16_32", Value: TYPE_MOFFS)
1102 .Case(S: "offset32_8", Value: TYPE_MOFFS)
1103 .Case(S: "offset32_16", Value: TYPE_MOFFS)
1104 .Case(S: "offset32_32", Value: TYPE_MOFFS)
1105 .Case(S: "offset32_64", Value: TYPE_MOFFS)
1106 .Case(S: "offset64_8", Value: TYPE_MOFFS)
1107 .Case(S: "offset64_16", Value: TYPE_MOFFS)
1108 .Case(S: "offset64_32", Value: TYPE_MOFFS)
1109 .Case(S: "offset64_64", Value: TYPE_MOFFS)
1110 .Case(S: "VR256", Value: TYPE_YMM)
1111 .Case(S: "VR256X", Value: TYPE_YMM)
1112 .Case(S: "VR512", Value: TYPE_ZMM)
1113 .Case(S: "VK1", Value: TYPE_VK)
1114 .Case(S: "VK1WM", Value: TYPE_VK)
1115 .Case(S: "VK2", Value: TYPE_VK)
1116 .Case(S: "VK2WM", Value: TYPE_VK)
1117 .Case(S: "VK4", Value: TYPE_VK)
1118 .Case(S: "VK4WM", Value: TYPE_VK)
1119 .Case(S: "VK8", Value: TYPE_VK)
1120 .Case(S: "VK8WM", Value: TYPE_VK)
1121 .Case(S: "VK16", Value: TYPE_VK)
1122 .Case(S: "VK16WM", Value: TYPE_VK)
1123 .Case(S: "VK32", Value: TYPE_VK)
1124 .Case(S: "VK32WM", Value: TYPE_VK)
1125 .Case(S: "VK64", Value: TYPE_VK)
1126 .Case(S: "VK64WM", Value: TYPE_VK)
1127 .Case(S: "VK1Pair", Value: TYPE_VK_PAIR)
1128 .Case(S: "VK2Pair", Value: TYPE_VK_PAIR)
1129 .Case(S: "VK4Pair", Value: TYPE_VK_PAIR)
1130 .Case(S: "VK8Pair", Value: TYPE_VK_PAIR)
1131 .Case(S: "VK16Pair", Value: TYPE_VK_PAIR)
1132 .Case(S: "vx32mem", Value: TYPE_MVSIBX)
1133 .Case(S: "vx64mem", Value: TYPE_MVSIBX)
1134 .Case(S: "vy32mem", Value: TYPE_MVSIBY)
1135 .Case(S: "vy64mem", Value: TYPE_MVSIBY)
1136 .Case(S: "vx32xmem", Value: TYPE_MVSIBX)
1137 .Case(S: "vx64xmem", Value: TYPE_MVSIBX)
1138 .Case(S: "vy32xmem", Value: TYPE_MVSIBY)
1139 .Case(S: "vy64xmem", Value: TYPE_MVSIBY)
1140 .Case(S: "vz32mem", Value: TYPE_MVSIBZ)
1141 .Case(S: "vz64mem", Value: TYPE_MVSIBZ)
1142 .Case(S: "BNDR", Value: TYPE_BNDR)
1143 .Case(S: "TILE", Value: TYPE_TMM)
1144 .Default(Value: TYPE_NONE);
1145 // clang-format on
1146
1147 if (Type != TYPE_NONE)
1148 return Type;
1149 errs() << "Unhandled type string " << Str << "\n";
1150 llvm_unreachable("Unhandled type string");
1151}
1152
1153OperandEncoding RecognizableInstr::immediateEncodingFromString(StringRef Str,
1154 uint8_t OpSize) {
1155 StringSwitch<OperandEncoding> Switch(Str);
1156 if (OpSize != X86Local::OpSize16) {
1157 // For instructions without an OpSize prefix, a declared 16-bit register or
1158 // immediate encoding is special.
1159 Switch.Case(S: "i16imm", Value: ENCODING_IW);
1160 }
1161
1162 // clang-format off
1163 OperandEncoding Encoding =
1164 Switch.Case(S: "i32i8imm", Value: ENCODING_IB)
1165 .Case(S: "AVX512RC", Value: ENCODING_IRC)
1166 .Case(S: "i16imm", Value: ENCODING_Iv)
1167 .Case(S: "i16i8imm", Value: ENCODING_IB)
1168 .Case(S: "i32imm", Value: ENCODING_Iv)
1169 .Case(S: "i64i32imm", Value: ENCODING_ID)
1170 .Case(S: "i64i8imm", Value: ENCODING_IB)
1171 .Case(S: "i8imm", Value: ENCODING_IB)
1172 .Case(S: "ccode", Value: ENCODING_CC)
1173 .Case(S: "cflags", Value: ENCODING_CF)
1174 .Case(S: "u4imm", Value: ENCODING_IB)
1175 .Case(S: "u8imm", Value: ENCODING_IB)
1176 .Case(S: "i16u8imm", Value: ENCODING_IB)
1177 .Case(S: "i32u8imm", Value: ENCODING_IB)
1178 .Case(S: "i64u8imm", Value: ENCODING_IB)
1179 // This is not a typo. Instructions like BLENDVPD put
1180 // register IDs in 8-bit immediates nowadays.
1181 .Case(S: "FR32", Value: ENCODING_IB)
1182 .Case(S: "FR64", Value: ENCODING_IB)
1183 .Case(S: "FR128", Value: ENCODING_IB)
1184 .Case(S: "VR128", Value: ENCODING_IB)
1185 .Case(S: "VR256", Value: ENCODING_IB)
1186 .Case(S: "FR16X", Value: ENCODING_IB)
1187 .Case(S: "FR32X", Value: ENCODING_IB)
1188 .Case(S: "FR64X", Value: ENCODING_IB)
1189 .Case(S: "VR128X", Value: ENCODING_IB)
1190 .Case(S: "VR256X", Value: ENCODING_IB)
1191 .Case(S: "VR512", Value: ENCODING_IB)
1192 .Case(S: "TILE", Value: ENCODING_IB)
1193 .Default(Value: ENCODING_NONE);
1194 // clang-format on
1195
1196 if (Encoding != ENCODING_NONE)
1197 return Encoding;
1198 errs() << "Unhandled immediate encoding " << Str << "\n";
1199 llvm_unreachable("Unhandled immediate encoding");
1200}
1201
1202OperandEncoding
1203RecognizableInstr::rmRegisterEncodingFromString(StringRef Str, uint8_t OpSize) {
1204 // clang-format off
1205 auto Encoding =
1206 StringSwitch<OperandEncoding>(Str)
1207 .Case(S: "RST", Value: ENCODING_FP)
1208 .Case(S: "RSTi", Value: ENCODING_FP)
1209 .Case(S: "GR16", Value: ENCODING_RM)
1210 .Case(S: "GR16orGR32orGR64", Value: ENCODING_RM)
1211 .Case(S: "GR32", Value: ENCODING_RM)
1212 .Case(S: "GR32orGR64", Value: ENCODING_RM)
1213 .Case(S: "GR64", Value: ENCODING_RM)
1214 .Case(S: "GR8", Value: ENCODING_RM)
1215 .Case(S: "VR128", Value: ENCODING_RM)
1216 .Case(S: "VR128X", Value: ENCODING_RM)
1217 .Case(S: "FR128", Value: ENCODING_RM)
1218 .Case(S: "FR64", Value: ENCODING_RM)
1219 .Case(S: "FR32", Value: ENCODING_RM)
1220 .Case(S: "FR64X", Value: ENCODING_RM)
1221 .Case(S: "FR32X", Value: ENCODING_RM)
1222 .Case(S: "FR16X", Value: ENCODING_RM)
1223 .Case(S: "VR64", Value: ENCODING_RM)
1224 .Case(S: "VR256", Value: ENCODING_RM)
1225 .Case(S: "VR256X", Value: ENCODING_RM)
1226 .Case(S: "VR512", Value: ENCODING_RM)
1227 .Case(S: "VK1", Value: ENCODING_RM)
1228 .Case(S: "VK2", Value: ENCODING_RM)
1229 .Case(S: "VK4", Value: ENCODING_RM)
1230 .Case(S: "VK8", Value: ENCODING_RM)
1231 .Case(S: "VK16", Value: ENCODING_RM)
1232 .Case(S: "VK32", Value: ENCODING_RM)
1233 .Case(S: "VK64", Value: ENCODING_RM)
1234 .Case(S: "BNDR", Value: ENCODING_RM)
1235 .Case(S: "TILE", Value: ENCODING_RM)
1236 .Case(S: "TILEPair", Value: ENCODING_RM)
1237 .Default(Value: ENCODING_NONE);
1238 // clang-format on
1239 if (Encoding != ENCODING_NONE)
1240 return Encoding;
1241 errs() << "Unhandled R/M register encoding " << Str << "\n";
1242 llvm_unreachable("Unhandled R/M register encoding");
1243}
1244
1245OperandEncoding
1246RecognizableInstr::roRegisterEncodingFromString(StringRef Str, uint8_t OpSize) {
1247 // clang-format off
1248 auto Encoding =
1249 StringSwitch<OperandEncoding>(Str)
1250 .Case(S: "GR16", Value: ENCODING_REG)
1251 .Case(S: "GR16orGR32orGR64", Value: ENCODING_REG)
1252 .Case(S: "GR32", Value: ENCODING_REG)
1253 .Case(S: "GR32orGR64", Value: ENCODING_REG)
1254 .Case(S: "GR64", Value: ENCODING_REG)
1255 .Case(S: "GR8", Value: ENCODING_REG)
1256 .Case(S: "VR128", Value: ENCODING_REG)
1257 .Case(S: "FR128", Value: ENCODING_REG)
1258 .Case(S: "FR64", Value: ENCODING_REG)
1259 .Case(S: "FR32", Value: ENCODING_REG)
1260 .Case(S: "VR64", Value: ENCODING_REG)
1261 .Case(S: "SEGMENT_REG", Value: ENCODING_REG)
1262 .Case(S: "DEBUG_REG", Value: ENCODING_REG)
1263 .Case(S: "CONTROL_REG", Value: ENCODING_REG)
1264 .Case(S: "VR256", Value: ENCODING_REG)
1265 .Case(S: "VR256X", Value: ENCODING_REG)
1266 .Case(S: "VR128X", Value: ENCODING_REG)
1267 .Case(S: "FR64X", Value: ENCODING_REG)
1268 .Case(S: "FR32X", Value: ENCODING_REG)
1269 .Case(S: "FR16X", Value: ENCODING_REG)
1270 .Case(S: "VR512", Value: ENCODING_REG)
1271 .Case(S: "VK1", Value: ENCODING_REG)
1272 .Case(S: "VK2", Value: ENCODING_REG)
1273 .Case(S: "VK4", Value: ENCODING_REG)
1274 .Case(S: "VK8", Value: ENCODING_REG)
1275 .Case(S: "VK16", Value: ENCODING_REG)
1276 .Case(S: "VK32", Value: ENCODING_REG)
1277 .Case(S: "VK64", Value: ENCODING_REG)
1278 .Case(S: "VK1Pair", Value: ENCODING_REG)
1279 .Case(S: "VK2Pair", Value: ENCODING_REG)
1280 .Case(S: "VK4Pair", Value: ENCODING_REG)
1281 .Case(S: "VK8Pair", Value: ENCODING_REG)
1282 .Case(S: "VK16Pair", Value: ENCODING_REG)
1283 .Case(S: "VK1WM", Value: ENCODING_REG)
1284 .Case(S: "VK2WM", Value: ENCODING_REG)
1285 .Case(S: "VK4WM", Value: ENCODING_REG)
1286 .Case(S: "VK8WM", Value: ENCODING_REG)
1287 .Case(S: "VK16WM", Value: ENCODING_REG)
1288 .Case(S: "VK32WM", Value: ENCODING_REG)
1289 .Case(S: "VK64WM", Value: ENCODING_REG)
1290 .Case(S: "BNDR", Value: ENCODING_REG)
1291 .Case(S: "TILE", Value: ENCODING_REG)
1292 .Case(S: "TILEPair", Value: ENCODING_REG)
1293 .Default(Value: ENCODING_NONE);
1294 // clang-format on
1295
1296 if (Encoding != ENCODING_NONE)
1297 return Encoding;
1298
1299 errs() << "Unhandled reg/opcode register encoding " << Str << "\n";
1300 llvm_unreachable("Unhandled reg/opcode register encoding");
1301}
1302
1303OperandEncoding
1304RecognizableInstr::vvvvRegisterEncodingFromString(StringRef Str,
1305 uint8_t OpSize) {
1306 // clang-format off
1307 auto Encoding =
1308 StringSwitch<OperandEncoding>(Str)
1309 .Case(S: "GR8", Value: ENCODING_VVVV)
1310 .Case(S: "GR16", Value: ENCODING_VVVV)
1311 .Case(S: "GR32", Value: ENCODING_VVVV)
1312 .Case(S: "GR64", Value: ENCODING_VVVV)
1313 .Case(S: "FR32", Value: ENCODING_VVVV)
1314 .Case(S: "FR128", Value: ENCODING_VVVV)
1315 .Case(S: "FR64", Value: ENCODING_VVVV)
1316 .Case(S: "VR128", Value: ENCODING_VVVV)
1317 .Case(S: "VR256", Value: ENCODING_VVVV)
1318 .Case(S: "FR16X", Value: ENCODING_VVVV)
1319 .Case(S: "FR32X", Value: ENCODING_VVVV)
1320 .Case(S: "FR64X", Value: ENCODING_VVVV)
1321 .Case(S: "VR128X", Value: ENCODING_VVVV)
1322 .Case(S: "VR256X", Value: ENCODING_VVVV)
1323 .Case(S: "VR512", Value: ENCODING_VVVV)
1324 .Case(S: "VK1", Value: ENCODING_VVVV)
1325 .Case(S: "VK2", Value: ENCODING_VVVV)
1326 .Case(S: "VK4", Value: ENCODING_VVVV)
1327 .Case(S: "VK8", Value: ENCODING_VVVV)
1328 .Case(S: "VK16", Value: ENCODING_VVVV)
1329 .Case(S: "VK32", Value: ENCODING_VVVV)
1330 .Case(S: "VK64", Value: ENCODING_VVVV)
1331 .Case(S: "TILE", Value: ENCODING_VVVV)
1332 .Case(S: "TILEPair", Value: ENCODING_VVVV)
1333 .Default(Value: ENCODING_NONE);
1334 // clang-format on
1335 if (Encoding != ENCODING_NONE)
1336 return Encoding;
1337
1338 errs() << "Unhandled VEX.vvvv register encoding " << Str << "\n";
1339 llvm_unreachable("Unhandled VEX.vvvv register encoding");
1340}
1341
1342OperandEncoding
1343RecognizableInstr::writemaskRegisterEncodingFromString(StringRef Str,
1344 uint8_t OpSize) {
1345 // clang-format off
1346 auto Encoding =
1347 StringSwitch<OperandEncoding>(Str)
1348 .Case(S: "VK1WM", Value: ENCODING_WRITEMASK)
1349 .Case(S: "VK2WM", Value: ENCODING_WRITEMASK)
1350 .Case(S: "VK4WM", Value: ENCODING_WRITEMASK)
1351 .Case(S: "VK8WM", Value: ENCODING_WRITEMASK)
1352 .Case(S: "VK16WM", Value: ENCODING_WRITEMASK)
1353 .Case(S: "VK32WM", Value: ENCODING_WRITEMASK)
1354 .Case(S: "VK64WM", Value: ENCODING_WRITEMASK)
1355 .Default(Value: ENCODING_NONE);
1356 // clang-format on
1357
1358 if (Encoding != ENCODING_NONE)
1359 return Encoding;
1360
1361 errs() << "Unhandled mask register encoding " << Str << "\n";
1362 llvm_unreachable("Unhandled mask register encoding");
1363}
1364
1365OperandEncoding RecognizableInstr::memoryEncodingFromString(StringRef Str,
1366 uint8_t OpSize) {
1367 // clang-format off
1368 auto Encoding =
1369 StringSwitch<OperandEncoding>(Str)
1370 .Case(S: "i16mem", Value: ENCODING_RM)
1371 .Case(S: "i32mem", Value: ENCODING_RM)
1372 .Case(S: "i64mem", Value: ENCODING_RM)
1373 .Case(S: "i8mem", Value: ENCODING_RM)
1374 .Case(S: "shmem", Value: ENCODING_RM)
1375 .Case(S: "ssmem", Value: ENCODING_RM)
1376 .Case(S: "sdmem", Value: ENCODING_RM)
1377 .Case(S: "f128mem", Value: ENCODING_RM)
1378 .Case(S: "f256mem", Value: ENCODING_RM)
1379 .Case(S: "f512mem", Value: ENCODING_RM)
1380 .Case(S: "f64mem", Value: ENCODING_RM)
1381 .Case(S: "f32mem", Value: ENCODING_RM)
1382 .Case(S: "f16mem", Value: ENCODING_RM)
1383 .Case(S: "i128mem", Value: ENCODING_RM)
1384 .Case(S: "i256mem", Value: ENCODING_RM)
1385 .Case(S: "i512mem", Value: ENCODING_RM)
1386 .Case(S: "i512mem_GR16", Value: ENCODING_RM)
1387 .Case(S: "i512mem_GR32", Value: ENCODING_RM)
1388 .Case(S: "i512mem_GR64", Value: ENCODING_RM)
1389 .Case(S: "f80mem", Value: ENCODING_RM)
1390 .Case(S: "lea64_8mem", Value: ENCODING_RM)
1391 .Case(S: "lea64_16mem", Value: ENCODING_RM)
1392 .Case(S: "lea64_32mem", Value: ENCODING_RM)
1393 .Case(S: "lea64mem", Value: ENCODING_RM)
1394 .Case(S: "anymem", Value: ENCODING_RM)
1395 .Case(S: "opaquemem", Value: ENCODING_RM)
1396 .Case(S: "sibmem", Value: ENCODING_SIB)
1397 .Case(S: "vx32mem", Value: ENCODING_VSIB)
1398 .Case(S: "vx64mem", Value: ENCODING_VSIB)
1399 .Case(S: "vy32mem", Value: ENCODING_VSIB)
1400 .Case(S: "vy64mem", Value: ENCODING_VSIB)
1401 .Case(S: "vx32xmem", Value: ENCODING_VSIB)
1402 .Case(S: "vx64xmem", Value: ENCODING_VSIB)
1403 .Case(S: "vy32xmem", Value: ENCODING_VSIB)
1404 .Case(S: "vy64xmem", Value: ENCODING_VSIB)
1405 .Case(S: "vz32mem", Value: ENCODING_VSIB)
1406 .Case(S: "vz64mem", Value: ENCODING_VSIB)
1407 .Default(Value: ENCODING_NONE);
1408 // clang-format on
1409
1410 if (Encoding != ENCODING_NONE)
1411 return Encoding;
1412
1413 errs() << "Unhandled memory encoding " << Str << "\n";
1414 llvm_unreachable("Unhandled memory encoding");
1415}
1416
1417OperandEncoding
1418RecognizableInstr::relocationEncodingFromString(StringRef Str, uint8_t OpSize) {
1419 StringSwitch<OperandEncoding> Switch(Str);
1420
1421 if (OpSize != X86Local::OpSize16) {
1422 // For instructions without an OpSize prefix, a declared 16-bit register or
1423 // immediate encoding is special.
1424 Switch.Case(S: "i16imm", Value: ENCODING_IW);
1425 }
1426
1427 // clang-format off
1428 OperandEncoding Encoding =
1429 Switch.Case(S: "i16imm", Value: ENCODING_Iv)
1430 .Case(S: "i16i8imm", Value: ENCODING_IB)
1431 .Case(S: "i32imm", Value: ENCODING_Iv)
1432 .Case(S: "i32i8imm", Value: ENCODING_IB)
1433 .Case(S: "i64i32imm", Value: ENCODING_ID)
1434 .Case(S: "i64i8imm", Value: ENCODING_IB)
1435 .Case(S: "i8imm", Value: ENCODING_IB)
1436 .Case(S: "u8imm", Value: ENCODING_IB)
1437 .Case(S: "i16u8imm", Value: ENCODING_IB)
1438 .Case(S: "i32u8imm", Value: ENCODING_IB)
1439 .Case(S: "i64u8imm", Value: ENCODING_IB)
1440 .Case(S: "i64i32imm_brtarget", Value: ENCODING_ID)
1441 .Case(S: "i16imm_brtarget", Value: ENCODING_IW)
1442 .Case(S: "i32imm_brtarget", Value: ENCODING_ID)
1443 .Case(S: "i8imm_brtarget", Value: ENCODING_IB)
1444 .Case(S: "brtarget32", Value: ENCODING_ID)
1445 .Case(S: "brtarget16", Value: ENCODING_IW)
1446 .Case(S: "brtarget8", Value: ENCODING_IB)
1447 .Case(S: "i64imm", Value: ENCODING_IO)
1448 .Case(S: "offset16_8", Value: ENCODING_Ia)
1449 .Case(S: "offset16_16", Value: ENCODING_Ia)
1450 .Case(S: "offset16_32", Value: ENCODING_Ia)
1451 .Case(S: "offset32_8", Value: ENCODING_Ia)
1452 .Case(S: "offset32_16", Value: ENCODING_Ia)
1453 .Case(S: "offset32_32", Value: ENCODING_Ia)
1454 .Case(S: "offset32_64", Value: ENCODING_Ia)
1455 .Case(S: "offset64_8", Value: ENCODING_Ia)
1456 .Case(S: "offset64_16", Value: ENCODING_Ia)
1457 .Case(S: "offset64_32", Value: ENCODING_Ia)
1458 .Case(S: "offset64_64", Value: ENCODING_Ia)
1459 .Case(S: "srcidx8", Value: ENCODING_SI)
1460 .Case(S: "srcidx16", Value: ENCODING_SI)
1461 .Case(S: "srcidx32", Value: ENCODING_SI)
1462 .Case(S: "srcidx64", Value: ENCODING_SI)
1463 .Case(S: "dstidx8", Value: ENCODING_DI)
1464 .Case(S: "dstidx16", Value: ENCODING_DI)
1465 .Case(S: "dstidx32", Value: ENCODING_DI)
1466 .Case(S: "dstidx64", Value: ENCODING_DI)
1467 .Default(Value: ENCODING_NONE);
1468 // clang-format on
1469
1470 if (Encoding != ENCODING_NONE)
1471 return Encoding;
1472
1473 errs() << "Unhandled relocation encoding " << Str << "\n";
1474 llvm_unreachable("Unhandled relocation encoding");
1475}
1476
1477OperandEncoding
1478RecognizableInstr::opcodeModifierEncodingFromString(StringRef Str,
1479 uint8_t OpSize) {
1480 // clang-format off
1481 auto Encoding =
1482 StringSwitch<OperandEncoding>(Str)
1483 .Case(S: "GR32", Value: ENCODING_Rv)
1484 .Case(S: "GR64", Value: ENCODING_RO)
1485 .Case(S: "GR16", Value: ENCODING_Rv)
1486 .Case(S: "GR8", Value: ENCODING_RB)
1487 .Case(S: "ccode", Value: ENCODING_CC)
1488 .Default(Value: ENCODING_NONE);
1489 // clang-format on
1490 if (Encoding != ENCODING_NONE)
1491 return Encoding;
1492
1493 errs() << "Unhandled opcode modifier encoding " << Str << "\n";
1494 llvm_unreachable("Unhandled opcode modifier encoding");
1495}
1496