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