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