blob: da2de6b3200bb5b1480a9c748a3e9b287a37a3e5 [file] [log] [blame]
Sean Callanan8ed9f512009-12-19 02:59:52 +00001//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is part of the X86 Disassembler Emitter.
11// It contains the implementation of a single recognizable instruction.
12// Documentation for the disassembler emitter in general can be found in
13// X86DisasemblerEmitter.h.
14//
15//===----------------------------------------------------------------------===//
16
17#include "X86DisassemblerShared.h"
18#include "X86RecognizableInstr.h"
19#include "X86ModRMFilters.h"
20
21#include "llvm/Support/ErrorHandling.h"
22
23#include <string>
24
25using namespace llvm;
26
27// A clone of X86 since we can't depend on something that is generated.
28namespace X86Local {
29 enum {
30 Pseudo = 0,
31 RawFrm = 1,
32 AddRegFrm = 2,
33 MRMDestReg = 3,
34 MRMDestMem = 4,
35 MRMSrcReg = 5,
36 MRMSrcMem = 6,
37 MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19,
38 MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
39 MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
40 MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
41 MRMInitReg = 32
42 };
43
44 enum {
45 TB = 1,
46 REP = 2,
47 D8 = 3, D9 = 4, DA = 5, DB = 6,
48 DC = 7, DD = 8, DE = 9, DF = 10,
49 XD = 11, XS = 12,
50 T8 = 13, TA = 14
51 };
52}
53
54#define ONE_BYTE_EXTENSION_TABLES \
55 EXTENSION_TABLE(80) \
56 EXTENSION_TABLE(81) \
57 EXTENSION_TABLE(82) \
58 EXTENSION_TABLE(83) \
59 EXTENSION_TABLE(8f) \
60 EXTENSION_TABLE(c0) \
61 EXTENSION_TABLE(c1) \
62 EXTENSION_TABLE(c6) \
63 EXTENSION_TABLE(c7) \
64 EXTENSION_TABLE(d0) \
65 EXTENSION_TABLE(d1) \
66 EXTENSION_TABLE(d2) \
67 EXTENSION_TABLE(d3) \
68 EXTENSION_TABLE(f6) \
69 EXTENSION_TABLE(f7) \
70 EXTENSION_TABLE(fe) \
71 EXTENSION_TABLE(ff)
72
73#define TWO_BYTE_EXTENSION_TABLES \
74 EXTENSION_TABLE(00) \
75 EXTENSION_TABLE(01) \
76 EXTENSION_TABLE(18) \
77 EXTENSION_TABLE(71) \
78 EXTENSION_TABLE(72) \
79 EXTENSION_TABLE(73) \
80 EXTENSION_TABLE(ae) \
81 EXTENSION_TABLE(b9) \
82 EXTENSION_TABLE(ba) \
83 EXTENSION_TABLE(c7)
84
85#define TWO_BYTE_FULL_EXTENSION_TABLES \
86 EXTENSION_TABLE(01)
87
88
89using namespace X86Disassembler;
90
91/// needsModRMForDecode - Indicates whether a particular instruction requires a
92/// ModR/M byte for the instruction to be properly decoded. For example, a
93/// MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to
94/// 0b11.
95///
96/// @param form - The form of the instruction.
97/// @return - true if the form implies that a ModR/M byte is required, false
98/// otherwise.
99static bool needsModRMForDecode(uint8_t form) {
100 if (form == X86Local::MRMDestReg ||
101 form == X86Local::MRMDestMem ||
102 form == X86Local::MRMSrcReg ||
103 form == X86Local::MRMSrcMem ||
104 (form >= X86Local::MRM0r && form <= X86Local::MRM7r) ||
105 (form >= X86Local::MRM0m && form <= X86Local::MRM7m))
106 return true;
107 else
108 return false;
109}
110
111/// isRegFormat - Indicates whether a particular form requires the Mod field of
112/// the ModR/M byte to be 0b11.
113///
114/// @param form - The form of the instruction.
115/// @return - true if the form implies that Mod must be 0b11, false
116/// otherwise.
117static bool isRegFormat(uint8_t form) {
118 if (form == X86Local::MRMDestReg ||
119 form == X86Local::MRMSrcReg ||
120 (form >= X86Local::MRM0r && form <= X86Local::MRM7r))
121 return true;
122 else
123 return false;
124}
125
126/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit.
127/// Useful for switch statements and the like.
128///
129/// @param init - A reference to the BitsInit to be decoded.
130/// @return - The field, with the first bit in the BitsInit as the lowest
131/// order bit.
132static uint8_t byteFromBitsInit(BitsInit &init) {
133 int width = init.getNumBits();
134
135 assert(width <= 8 && "Field is too large for uint8_t!");
136
137 int index;
138 uint8_t mask = 0x01;
139
140 uint8_t ret = 0;
141
142 for (index = 0; index < width; index++) {
143 if (static_cast<BitInit*>(init.getBit(index))->getValue())
144 ret |= mask;
145
146 mask <<= 1;
147 }
148
149 return ret;
150}
151
152/// byteFromRec - Extract a value at most 8 bits in with from a Record given the
153/// name of the field.
154///
155/// @param rec - The record from which to extract the value.
156/// @param name - The name of the field in the record.
157/// @return - The field, as translated by byteFromBitsInit().
158static uint8_t byteFromRec(const Record* rec, const std::string &name) {
159 BitsInit* bits = rec->getValueAsBitsInit(name);
160 return byteFromBitsInit(*bits);
161}
162
163RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
164 const CodeGenInstruction &insn,
165 InstrUID uid) {
166 UID = uid;
167
168 Rec = insn.TheDef;
169 Name = Rec->getName();
170 Spec = &tables.specForUID(UID);
171
172 if (!Rec->isSubClassOf("X86Inst")) {
173 ShouldBeEmitted = false;
174 return;
175 }
176
177 Prefix = byteFromRec(Rec, "Prefix");
178 Opcode = byteFromRec(Rec, "Opcode");
179 Form = byteFromRec(Rec, "FormBits");
180 SegOvr = byteFromRec(Rec, "SegOvrBits");
181
182 HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix");
183 HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix");
184 HasLockPrefix = Rec->getValueAsBit("hasLockPrefix");
185 IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly");
186
187 Name = Rec->getName();
188 AsmString = Rec->getValueAsString("AsmString");
189
190 Operands = &insn.OperandList;
191
192 IsSSE = HasOpSizePrefix && (Name.find("16") == Name.npos);
193 HasFROperands = false;
194
195 ShouldBeEmitted = true;
196}
197
198void RecognizableInstr::processInstr(DisassemblerTables &tables,
199 const CodeGenInstruction &insn,
200 InstrUID uid)
201{
202 RecognizableInstr recogInstr(tables, insn, uid);
203
204 recogInstr.emitInstructionSpecifier(tables);
205
206 if (recogInstr.shouldBeEmitted())
207 recogInstr.emitDecodePath(tables);
208}
209
210InstructionContext RecognizableInstr::insnContext() const {
211 InstructionContext insnContext;
212
213 if (Name.find("64") != Name.npos || HasREX_WPrefix) {
214 if (HasREX_WPrefix && HasOpSizePrefix)
215 insnContext = IC_64BIT_REXW_OPSIZE;
216 else if (HasOpSizePrefix)
217 insnContext = IC_64BIT_OPSIZE;
218 else if (HasREX_WPrefix && Prefix == X86Local::XS)
219 insnContext = IC_64BIT_REXW_XS;
220 else if (HasREX_WPrefix && Prefix == X86Local::XD)
221 insnContext = IC_64BIT_REXW_XD;
222 else if (Prefix == X86Local::XD)
223 insnContext = IC_64BIT_XD;
224 else if (Prefix == X86Local::XS)
225 insnContext = IC_64BIT_XS;
226 else if (HasREX_WPrefix)
227 insnContext = IC_64BIT_REXW;
228 else
229 insnContext = IC_64BIT;
230 } else {
231 if (HasOpSizePrefix)
232 insnContext = IC_OPSIZE;
233 else if (Prefix == X86Local::XD)
234 insnContext = IC_XD;
235 else if (Prefix == X86Local::XS)
236 insnContext = IC_XS;
237 else
238 insnContext = IC;
239 }
240
241 return insnContext;
242}
243
244RecognizableInstr::filter_ret RecognizableInstr::filter() const {
245 // Filter out intrinsics
246
247 if (!Rec->isSubClassOf("X86Inst"))
248 return FILTER_STRONG;
249
250 if (Form == X86Local::Pseudo ||
251 IsCodeGenOnly)
252 return FILTER_STRONG;
253
254 // Filter out instructions with a LOCK prefix;
255 // prefer forms that do not have the prefix
256 if (HasLockPrefix)
257 return FILTER_WEAK;
258
259 // Filter out artificial instructions
260
261 if (Name.find("TAILJMP") != Name.npos ||
262 Name.find("_Int") != Name.npos ||
263 Name.find("_int") != Name.npos ||
264 Name.find("Int_") != Name.npos ||
265 Name.find("_NOREX") != Name.npos ||
266 Name.find("EH_RETURN") != Name.npos ||
267 Name.find("V_SET") != Name.npos ||
268 Name.find("LOCK_") != Name.npos ||
269 Name.find("WIN") != Name.npos)
270 return FILTER_STRONG;
271
272 // Special cases.
273
274 if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI")
275 return FILTER_WEAK;
276 if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI")
277 return FILTER_WEAK;
278
279 if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos)
280 return FILTER_WEAK;
281 if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos)
282 return FILTER_WEAK;
283 if (Name.find("Fs") != Name.npos)
284 return FILTER_WEAK;
285 if (Name == "MOVLPDrr" ||
286 Name == "MOVLPSrr" ||
287 Name == "PUSHFQ" ||
288 Name == "BSF16rr" ||
289 Name == "BSF16rm" ||
290 Name == "BSR16rr" ||
291 Name == "BSR16rm" ||
292 Name == "MOVSX16rm8" ||
293 Name == "MOVSX16rr8" ||
294 Name == "MOVZX16rm8" ||
295 Name == "MOVZX16rr8" ||
296 Name == "PUSH32i16" ||
297 Name == "PUSH64i16" ||
298 Name == "MOVPQI2QImr" ||
299 Name == "MOVSDmr" ||
300 Name == "MOVSDrm" ||
301 Name == "MOVSSmr" ||
302 Name == "MOVSSrm" ||
303 Name == "MMX_MOVD64rrv164" ||
304 Name == "CRC32m16" ||
305 Name == "MOV64ri64i32" ||
306 Name == "CRC32r16")
307 return FILTER_WEAK;
308
309 // Filter out instructions with segment override prefixes.
310 // They're too messy to handle now and we'll special case them if needed.
311
312 if (SegOvr)
313 return FILTER_STRONG;
314
315 // Filter out instructions that can't be printed.
316
317 if (AsmString.size() == 0)
318 return FILTER_STRONG;
319
320 // Filter out instructions with subreg operands.
321
322 if (AsmString.find("subreg") != AsmString.npos)
323 return FILTER_STRONG;
324
325 assert(Form != X86Local::MRMInitReg &&
326 "FORMAT_MRMINITREG instruction not skipped");
327
328 if (HasFROperands && Name.find("MOV") != Name.npos &&
329 ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
330 (Name.find("to") != Name.npos)))
331 return FILTER_WEAK;
332
333 return FILTER_NORMAL;
334}
335
336void RecognizableInstr::handleOperand(
337 bool optional,
338 unsigned &operandIndex,
339 unsigned &physicalOperandIndex,
340 unsigned &numPhysicalOperands,
341 unsigned *operandMapping,
342 OperandEncoding (*encodingFromString)(const std::string&, bool hasOpSizePrefix)) {
343 if (optional) {
344 if (physicalOperandIndex >= numPhysicalOperands)
345 return;
346 } else {
347 assert(physicalOperandIndex < numPhysicalOperands);
348 }
349
350 while (operandMapping[operandIndex] != operandIndex) {
351 Spec->operands[operandIndex].encoding = ENCODING_DUP;
352 Spec->operands[operandIndex].type =
353 (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]);
354 ++operandIndex;
355 }
356
357 const std::string &typeName = (*Operands)[operandIndex].Rec->getName();
358
359 Spec->operands[operandIndex].encoding = encodingFromString(typeName,
360 HasOpSizePrefix);
361 Spec->operands[operandIndex].type = typeFromString(typeName,
362 IsSSE,
363 HasREX_WPrefix,
364 HasOpSizePrefix);
365
366 ++operandIndex;
367 ++physicalOperandIndex;
368}
369
370void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
371 Spec->name = Name;
372
373 if (!Rec->isSubClassOf("X86Inst"))
374 return;
375
376 switch (filter()) {
377 case FILTER_WEAK:
378 Spec->filtered = true;
379 break;
380 case FILTER_STRONG:
381 ShouldBeEmitted = false;
382 return;
383 case FILTER_NORMAL:
384 break;
385 }
386
387 Spec->insnContext = insnContext();
388
389 const std::vector<CodeGenInstruction::OperandInfo> &OperandList = *Operands;
390
391 unsigned operandIndex;
392 unsigned numOperands = OperandList.size();
393 unsigned numPhysicalOperands = 0;
394
395 // operandMapping maps from operands in OperandList to their originals.
396 // If operandMapping[i] != i, then the entry is a duplicate.
397 unsigned operandMapping[X86_MAX_OPERANDS];
398
399 bool hasFROperands = false;
400
401 assert(numOperands < X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough");
402
403 for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
404 if (OperandList[operandIndex].Constraints.size()) {
Chris Lattnera7d479c2010-02-10 01:45:28 +0000405 const CodeGenInstruction::ConstraintInfo &Constraint =
406 OperandList[operandIndex].Constraints[0];
407 if (Constraint.isTied()) {
408 operandMapping[operandIndex] = Constraint.getTiedOperand();
Sean Callanan8ed9f512009-12-19 02:59:52 +0000409 } else {
410 ++numPhysicalOperands;
411 operandMapping[operandIndex] = operandIndex;
412 }
413 } else {
414 ++numPhysicalOperands;
415 operandMapping[operandIndex] = operandIndex;
416 }
417
418 const std::string &recName = OperandList[operandIndex].Rec->getName();
419
420 if (recName.find("FR") != recName.npos)
421 hasFROperands = true;
422 }
423
424 if (hasFROperands && Name.find("MOV") != Name.npos &&
425 ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) ||
426 (Name.find("to") != Name.npos)))
427 ShouldBeEmitted = false;
428
429 if (!ShouldBeEmitted)
430 return;
431
432#define HANDLE_OPERAND(class) \
433 handleOperand(false, \
434 operandIndex, \
435 physicalOperandIndex, \
436 numPhysicalOperands, \
437 operandMapping, \
438 class##EncodingFromString);
439
440#define HANDLE_OPTIONAL(class) \
441 handleOperand(true, \
442 operandIndex, \
443 physicalOperandIndex, \
444 numPhysicalOperands, \
445 operandMapping, \
446 class##EncodingFromString);
447
448 // operandIndex should always be < numOperands
449 operandIndex = 0;
450 // physicalOperandIndex should always be < numPhysicalOperands
451 unsigned physicalOperandIndex = 0;
452
453 switch (Form) {
454 case X86Local::RawFrm:
455 // Operand 1 (optional) is an address or immediate.
456 // Operand 2 (optional) is an immediate.
457 assert(numPhysicalOperands <= 2 &&
458 "Unexpected number of operands for RawFrm");
459 HANDLE_OPTIONAL(relocation)
460 HANDLE_OPTIONAL(immediate)
461 break;
462 case X86Local::AddRegFrm:
463 // Operand 1 is added to the opcode.
464 // Operand 2 (optional) is an address.
465 assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
466 "Unexpected number of operands for AddRegFrm");
467 HANDLE_OPERAND(opcodeModifier)
468 HANDLE_OPTIONAL(relocation)
469 break;
470 case X86Local::MRMDestReg:
471 // Operand 1 is a register operand in the R/M field.
472 // Operand 2 is a register operand in the Reg/Opcode field.
473 // Operand 3 (optional) is an immediate.
474 assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
475 "Unexpected number of operands for MRMDestRegFrm");
476 HANDLE_OPERAND(rmRegister)
477 HANDLE_OPERAND(roRegister)
478 HANDLE_OPTIONAL(immediate)
479 break;
480 case X86Local::MRMDestMem:
481 // Operand 1 is a memory operand (possibly SIB-extended)
482 // Operand 2 is a register operand in the Reg/Opcode field.
483 // Operand 3 (optional) is an immediate.
484 assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
485 "Unexpected number of operands for MRMDestMemFrm");
486 HANDLE_OPERAND(memory)
487 HANDLE_OPERAND(roRegister)
488 HANDLE_OPTIONAL(immediate)
489 break;
490 case X86Local::MRMSrcReg:
491 // Operand 1 is a register operand in the Reg/Opcode field.
492 // Operand 2 is a register operand in the R/M field.
493 // Operand 3 (optional) is an immediate.
494 assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
495 "Unexpected number of operands for MRMSrcRegFrm");
496 HANDLE_OPERAND(roRegister)
497 HANDLE_OPERAND(rmRegister)
498 HANDLE_OPTIONAL(immediate)
499 break;
500 case X86Local::MRMSrcMem:
501 // Operand 1 is a register operand in the Reg/Opcode field.
502 // Operand 2 is a memory operand (possibly SIB-extended)
503 // Operand 3 (optional) is an immediate.
504 assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
505 "Unexpected number of operands for MRMSrcMemFrm");
506 HANDLE_OPERAND(roRegister)
507 HANDLE_OPERAND(memory)
508 HANDLE_OPTIONAL(immediate)
509 break;
510 case X86Local::MRM0r:
511 case X86Local::MRM1r:
512 case X86Local::MRM2r:
513 case X86Local::MRM3r:
514 case X86Local::MRM4r:
515 case X86Local::MRM5r:
516 case X86Local::MRM6r:
517 case X86Local::MRM7r:
518 // Operand 1 is a register operand in the R/M field.
519 // Operand 2 (optional) is an immediate or relocation.
520 assert(numPhysicalOperands <= 2 &&
521 "Unexpected number of operands for MRMnRFrm");
522 HANDLE_OPTIONAL(rmRegister)
523 HANDLE_OPTIONAL(relocation)
524 break;
525 case X86Local::MRM0m:
526 case X86Local::MRM1m:
527 case X86Local::MRM2m:
528 case X86Local::MRM3m:
529 case X86Local::MRM4m:
530 case X86Local::MRM5m:
531 case X86Local::MRM6m:
532 case X86Local::MRM7m:
533 // Operand 1 is a memory operand (possibly SIB-extended)
534 // Operand 2 (optional) is an immediate or relocation.
535 assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 &&
536 "Unexpected number of operands for MRMnMFrm");
537 HANDLE_OPERAND(memory)
538 HANDLE_OPTIONAL(relocation)
539 break;
540 case X86Local::MRMInitReg:
541 // Ignored.
542 break;
543 }
544
545 #undef HANDLE_OPERAND
546 #undef HANDLE_OPTIONAL
547}
548
549void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
550 // Special cases where the LLVM tables are not complete
551
552#define EXACTCASE(class, name, lastbyte) \
553 if (Name == name) { \
554 tables.setTableFields(class, \
555 insnContext(), \
556 Opcode, \
557 ExactFilter(lastbyte), \
558 UID); \
559 Spec->modifierBase = Opcode; \
560 return; \
561 }
562
563 EXACTCASE(TWOBYTE, "MONITOR", 0xc8)
564 EXACTCASE(TWOBYTE, "MWAIT", 0xc9)
565 EXACTCASE(TWOBYTE, "SWPGS", 0xf8)
566 EXACTCASE(TWOBYTE, "INVEPT", 0x80)
567 EXACTCASE(TWOBYTE, "INVVPID", 0x81)
568 EXACTCASE(TWOBYTE, "VMCALL", 0xc1)
569 EXACTCASE(TWOBYTE, "VMLAUNCH", 0xc2)
570 EXACTCASE(TWOBYTE, "VMRESUME", 0xc3)
571 EXACTCASE(TWOBYTE, "VMXOFF", 0xc4)
572
573 if (Name == "INVLPG") {
574 tables.setTableFields(TWOBYTE,
575 insnContext(),
576 Opcode,
577 ExtendedFilter(false, 7),
578 UID);
579 Spec->modifierBase = Opcode;
580 return;
581 }
582
583 OpcodeType opcodeType = (OpcodeType)-1;
584
585 ModRMFilter* filter = NULL;
586 uint8_t opcodeToSet = 0;
587
588 switch (Prefix) {
589 // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f
590 case X86Local::XD:
591 case X86Local::XS:
592 case X86Local::TB:
593 opcodeType = TWOBYTE;
594
595 switch (Opcode) {
596#define EXTENSION_TABLE(n) case 0x##n:
597 TWO_BYTE_EXTENSION_TABLES
598#undef EXTENSION_TABLE
599 switch (Form) {
600 default:
601 llvm_unreachable("Unhandled two-byte extended opcode");
602 case X86Local::MRM0r:
603 case X86Local::MRM1r:
604 case X86Local::MRM2r:
605 case X86Local::MRM3r:
606 case X86Local::MRM4r:
607 case X86Local::MRM5r:
608 case X86Local::MRM6r:
609 case X86Local::MRM7r:
610 filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
611 break;
612 case X86Local::MRM0m:
613 case X86Local::MRM1m:
614 case X86Local::MRM2m:
615 case X86Local::MRM3m:
616 case X86Local::MRM4m:
617 case X86Local::MRM5m:
618 case X86Local::MRM6m:
619 case X86Local::MRM7m:
620 filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
621 break;
622 } // switch (Form)
623 break;
624 default:
625 if (needsModRMForDecode(Form))
626 filter = new ModFilter(isRegFormat(Form));
627 else
628 filter = new DumbFilter();
629
630 break;
631 } // switch (opcode)
632 opcodeToSet = Opcode;
633 break;
634 case X86Local::T8:
635 opcodeType = THREEBYTE_38;
636 if (needsModRMForDecode(Form))
637 filter = new ModFilter(isRegFormat(Form));
638 else
639 filter = new DumbFilter();
640 opcodeToSet = Opcode;
641 break;
642 case X86Local::TA:
643 opcodeType = THREEBYTE_3A;
644 if (needsModRMForDecode(Form))
645 filter = new ModFilter(isRegFormat(Form));
646 else
647 filter = new DumbFilter();
648 opcodeToSet = Opcode;
649 break;
650 case X86Local::D8:
651 case X86Local::D9:
652 case X86Local::DA:
653 case X86Local::DB:
654 case X86Local::DC:
655 case X86Local::DD:
656 case X86Local::DE:
657 case X86Local::DF:
658 assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
659 opcodeType = ONEBYTE;
660 if (Form == X86Local::AddRegFrm) {
661 Spec->modifierType = MODIFIER_MODRM;
662 Spec->modifierBase = Opcode;
663 filter = new AddRegEscapeFilter(Opcode);
664 } else {
665 filter = new EscapeFilter(true, Opcode);
666 }
667 opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
668 break;
669 default:
670 opcodeType = ONEBYTE;
671 switch (Opcode) {
672#define EXTENSION_TABLE(n) case 0x##n:
673 ONE_BYTE_EXTENSION_TABLES
674#undef EXTENSION_TABLE
675 switch (Form) {
676 default:
677 llvm_unreachable("Fell through the cracks of a single-byte "
678 "extended opcode");
679 case X86Local::MRM0r:
680 case X86Local::MRM1r:
681 case X86Local::MRM2r:
682 case X86Local::MRM3r:
683 case X86Local::MRM4r:
684 case X86Local::MRM5r:
685 case X86Local::MRM6r:
686 case X86Local::MRM7r:
687 filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
688 break;
689 case X86Local::MRM0m:
690 case X86Local::MRM1m:
691 case X86Local::MRM2m:
692 case X86Local::MRM3m:
693 case X86Local::MRM4m:
694 case X86Local::MRM5m:
695 case X86Local::MRM6m:
696 case X86Local::MRM7m:
697 filter = new ExtendedFilter(false, Form - X86Local::MRM0m);
698 break;
699 } // switch (Form)
700 break;
701 case 0xd8:
702 case 0xd9:
703 case 0xda:
704 case 0xdb:
705 case 0xdc:
706 case 0xdd:
707 case 0xde:
708 case 0xdf:
709 filter = new EscapeFilter(false, Form - X86Local::MRM0m);
710 break;
711 default:
712 if (needsModRMForDecode(Form))
713 filter = new ModFilter(isRegFormat(Form));
714 else
715 filter = new DumbFilter();
716 break;
717 } // switch (Opcode)
718 opcodeToSet = Opcode;
719 } // switch (Prefix)
720
721 assert(opcodeType != (OpcodeType)-1 &&
722 "Opcode type not set");
723 assert(filter && "Filter not set");
724
725 if (Form == X86Local::AddRegFrm) {
726 if(Spec->modifierType != MODIFIER_MODRM) {
727 assert(opcodeToSet < 0xf9 &&
728 "Not enough room for all ADDREG_FRM operands");
729
730 uint8_t currentOpcode;
731
732 for (currentOpcode = opcodeToSet;
733 currentOpcode < opcodeToSet + 8;
734 ++currentOpcode)
735 tables.setTableFields(opcodeType,
736 insnContext(),
737 currentOpcode,
738 *filter,
739 UID);
740
741 Spec->modifierType = MODIFIER_OPCODE;
742 Spec->modifierBase = opcodeToSet;
743 } else {
744 // modifierBase was set where MODIFIER_MODRM was set
745 tables.setTableFields(opcodeType,
746 insnContext(),
747 opcodeToSet,
748 *filter,
749 UID);
750 }
751 } else {
752 tables.setTableFields(opcodeType,
753 insnContext(),
754 opcodeToSet,
755 *filter,
756 UID);
757
758 Spec->modifierType = MODIFIER_NONE;
759 Spec->modifierBase = opcodeToSet;
760 }
761
762 delete filter;
763}
764
765#define TYPE(str, type) if (s == str) return type;
766OperandType RecognizableInstr::typeFromString(const std::string &s,
767 bool isSSE,
768 bool hasREX_WPrefix,
769 bool hasOpSizePrefix) {
770 if (isSSE) {
771 // For SSE instructions, we ignore the OpSize prefix and force operand
772 // sizes.
773 TYPE("GR16", TYPE_R16)
774 TYPE("GR32", TYPE_R32)
775 TYPE("GR64", TYPE_R64)
776 }
777 if(hasREX_WPrefix) {
778 // For instructions with a REX_W prefix, a declared 32-bit register encoding
779 // is special.
780 TYPE("GR32", TYPE_R32)
781 }
782 if(!hasOpSizePrefix) {
783 // For instructions without an OpSize prefix, a declared 16-bit register or
784 // immediate encoding is special.
785 TYPE("GR16", TYPE_R16)
786 TYPE("i16imm", TYPE_IMM16)
787 }
788 TYPE("i16mem", TYPE_Mv)
789 TYPE("i16imm", TYPE_IMMv)
790 TYPE("i16i8imm", TYPE_IMMv)
791 TYPE("GR16", TYPE_Rv)
792 TYPE("i32mem", TYPE_Mv)
793 TYPE("i32imm", TYPE_IMMv)
794 TYPE("i32i8imm", TYPE_IMM32)
795 TYPE("GR32", TYPE_Rv)
796 TYPE("i64mem", TYPE_Mv)
797 TYPE("i64i32imm", TYPE_IMM64)
798 TYPE("i64i8imm", TYPE_IMM64)
799 TYPE("GR64", TYPE_R64)
800 TYPE("i8mem", TYPE_M8)
801 TYPE("i8imm", TYPE_IMM8)
802 TYPE("GR8", TYPE_R8)
803 TYPE("VR128", TYPE_XMM128)
804 TYPE("f128mem", TYPE_M128)
805 TYPE("FR64", TYPE_XMM64)
806 TYPE("f64mem", TYPE_M64FP)
807 TYPE("FR32", TYPE_XMM32)
808 TYPE("f32mem", TYPE_M32FP)
809 TYPE("RST", TYPE_ST)
810 TYPE("i128mem", TYPE_M128)
811 TYPE("i64i32imm_pcrel", TYPE_REL64)
812 TYPE("i32imm_pcrel", TYPE_REL32)
813 TYPE("SSECC", TYPE_IMM8)
814 TYPE("brtarget", TYPE_RELv)
815 TYPE("brtarget8", TYPE_REL8)
816 TYPE("f80mem", TYPE_M80FP)
Sean Callanan7fb35a22009-12-22 21:12:55 +0000817 TYPE("lea32mem", TYPE_LEA)
818 TYPE("lea64_32mem", TYPE_LEA)
819 TYPE("lea64mem", TYPE_LEA)
Sean Callanan8ed9f512009-12-19 02:59:52 +0000820 TYPE("VR64", TYPE_MM64)
821 TYPE("i64imm", TYPE_IMMv)
822 TYPE("opaque32mem", TYPE_M1616)
823 TYPE("opaque48mem", TYPE_M1632)
824 TYPE("opaque80mem", TYPE_M1664)
825 TYPE("opaque512mem", TYPE_M512)
826 TYPE("SEGMENT_REG", TYPE_SEGMENTREG)
827 TYPE("DEBUG_REG", TYPE_DEBUGREG)
828 TYPE("CONTROL_REG_32", TYPE_CR32)
829 TYPE("CONTROL_REG_64", TYPE_CR64)
830 TYPE("offset8", TYPE_MOFFS8)
831 TYPE("offset16", TYPE_MOFFS16)
832 TYPE("offset32", TYPE_MOFFS32)
833 TYPE("offset64", TYPE_MOFFS64)
834 errs() << "Unhandled type string " << s << "\n";
835 llvm_unreachable("Unhandled type string");
836}
837#undef TYPE
838
839#define ENCODING(str, encoding) if (s == str) return encoding;
840OperandEncoding RecognizableInstr::immediateEncodingFromString
841 (const std::string &s,
842 bool hasOpSizePrefix) {
843 if(!hasOpSizePrefix) {
844 // For instructions without an OpSize prefix, a declared 16-bit register or
845 // immediate encoding is special.
846 ENCODING("i16imm", ENCODING_IW)
847 }
848 ENCODING("i32i8imm", ENCODING_IB)
849 ENCODING("SSECC", ENCODING_IB)
850 ENCODING("i16imm", ENCODING_Iv)
851 ENCODING("i16i8imm", ENCODING_IB)
852 ENCODING("i32imm", ENCODING_Iv)
853 ENCODING("i64i32imm", ENCODING_ID)
854 ENCODING("i64i8imm", ENCODING_IB)
855 ENCODING("i8imm", ENCODING_IB)
856 errs() << "Unhandled immediate encoding " << s << "\n";
857 llvm_unreachable("Unhandled immediate encoding");
858}
859
860OperandEncoding RecognizableInstr::rmRegisterEncodingFromString
861 (const std::string &s,
862 bool hasOpSizePrefix) {
863 ENCODING("GR16", ENCODING_RM)
864 ENCODING("GR32", ENCODING_RM)
865 ENCODING("GR64", ENCODING_RM)
866 ENCODING("GR8", ENCODING_RM)
867 ENCODING("VR128", ENCODING_RM)
868 ENCODING("FR64", ENCODING_RM)
869 ENCODING("FR32", ENCODING_RM)
870 ENCODING("VR64", ENCODING_RM)
871 errs() << "Unhandled R/M register encoding " << s << "\n";
872 llvm_unreachable("Unhandled R/M register encoding");
873}
874
875OperandEncoding RecognizableInstr::roRegisterEncodingFromString
876 (const std::string &s,
877 bool hasOpSizePrefix) {
878 ENCODING("GR16", ENCODING_REG)
879 ENCODING("GR32", ENCODING_REG)
880 ENCODING("GR64", ENCODING_REG)
881 ENCODING("GR8", ENCODING_REG)
882 ENCODING("VR128", ENCODING_REG)
883 ENCODING("FR64", ENCODING_REG)
884 ENCODING("FR32", ENCODING_REG)
885 ENCODING("VR64", ENCODING_REG)
886 ENCODING("SEGMENT_REG", ENCODING_REG)
887 ENCODING("DEBUG_REG", ENCODING_REG)
888 ENCODING("CONTROL_REG_32", ENCODING_REG)
889 ENCODING("CONTROL_REG_64", ENCODING_REG)
890 errs() << "Unhandled reg/opcode register encoding " << s << "\n";
891 llvm_unreachable("Unhandled reg/opcode register encoding");
892}
893
894OperandEncoding RecognizableInstr::memoryEncodingFromString
895 (const std::string &s,
896 bool hasOpSizePrefix) {
897 ENCODING("i16mem", ENCODING_RM)
898 ENCODING("i32mem", ENCODING_RM)
899 ENCODING("i64mem", ENCODING_RM)
900 ENCODING("i8mem", ENCODING_RM)
901 ENCODING("f128mem", ENCODING_RM)
902 ENCODING("f64mem", ENCODING_RM)
903 ENCODING("f32mem", ENCODING_RM)
904 ENCODING("i128mem", ENCODING_RM)
905 ENCODING("f80mem", ENCODING_RM)
906 ENCODING("lea32mem", ENCODING_RM)
907 ENCODING("lea64_32mem", ENCODING_RM)
908 ENCODING("lea64mem", ENCODING_RM)
909 ENCODING("opaque32mem", ENCODING_RM)
910 ENCODING("opaque48mem", ENCODING_RM)
911 ENCODING("opaque80mem", ENCODING_RM)
912 ENCODING("opaque512mem", ENCODING_RM)
913 errs() << "Unhandled memory encoding " << s << "\n";
914 llvm_unreachable("Unhandled memory encoding");
915}
916
917OperandEncoding RecognizableInstr::relocationEncodingFromString
918 (const std::string &s,
919 bool hasOpSizePrefix) {
920 if(!hasOpSizePrefix) {
921 // For instructions without an OpSize prefix, a declared 16-bit register or
922 // immediate encoding is special.
923 ENCODING("i16imm", ENCODING_IW)
924 }
925 ENCODING("i16imm", ENCODING_Iv)
926 ENCODING("i16i8imm", ENCODING_IB)
927 ENCODING("i32imm", ENCODING_Iv)
928 ENCODING("i32i8imm", ENCODING_IB)
929 ENCODING("i64i32imm", ENCODING_ID)
930 ENCODING("i64i8imm", ENCODING_IB)
931 ENCODING("i8imm", ENCODING_IB)
932 ENCODING("i64i32imm_pcrel", ENCODING_ID)
933 ENCODING("i32imm_pcrel", ENCODING_ID)
934 ENCODING("brtarget", ENCODING_Iv)
935 ENCODING("brtarget8", ENCODING_IB)
936 ENCODING("i64imm", ENCODING_IO)
937 ENCODING("offset8", ENCODING_Ia)
938 ENCODING("offset16", ENCODING_Ia)
939 ENCODING("offset32", ENCODING_Ia)
940 ENCODING("offset64", ENCODING_Ia)
941 errs() << "Unhandled relocation encoding " << s << "\n";
942 llvm_unreachable("Unhandled relocation encoding");
943}
944
945OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
946 (const std::string &s,
947 bool hasOpSizePrefix) {
948 ENCODING("RST", ENCODING_I)
949 ENCODING("GR32", ENCODING_Rv)
950 ENCODING("GR64", ENCODING_RO)
951 ENCODING("GR16", ENCODING_Rv)
952 ENCODING("GR8", ENCODING_RB)
953 errs() << "Unhandled opcode modifier encoding " << s << "\n";
954 llvm_unreachable("Unhandled opcode modifier encoding");
955}
Daniel Dunbar9e6d1d12009-12-19 04:16:48 +0000956#undef ENCODING