X86RecognizableInstr.cpp revision 29480fd798dc6452948f63825ff41c66f09c2493
18ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===// 28ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 38ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// The LLVM Compiler Infrastructure 48ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 58ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// This file is distributed under the University of Illinois Open Source 68ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// License. See LICENSE.TXT for details. 78ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 88ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan//===----------------------------------------------------------------------===// 98ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// This file is part of the X86 Disassembler Emitter. 118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// It contains the implementation of a single recognizable instruction. 128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// Documentation for the disassembler emitter in general can be found in 138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// X86DisasemblerEmitter.h. 148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// 158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan//===----------------------------------------------------------------------===// 168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "X86DisassemblerShared.h" 188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "X86RecognizableInstr.h" 198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "X86ModRMFilters.h" 208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include "llvm/Support/ErrorHandling.h" 228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#include <string> 248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananusing namespace llvm; 268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 279492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan#define MRM_MAPPING \ 289492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan MAP(C1, 33) \ 29a599de241041eebc84867ac8e4cb76668cabd236Chris Lattner MAP(C2, 34) \ 30a599de241041eebc84867ac8e4cb76668cabd236Chris Lattner MAP(C3, 35) \ 31a599de241041eebc84867ac8e4cb76668cabd236Chris Lattner MAP(C4, 36) \ 32a599de241041eebc84867ac8e4cb76668cabd236Chris Lattner MAP(C8, 37) \ 33a599de241041eebc84867ac8e4cb76668cabd236Chris Lattner MAP(C9, 38) \ 34a599de241041eebc84867ac8e4cb76668cabd236Chris Lattner MAP(E8, 39) \ 35a599de241041eebc84867ac8e4cb76668cabd236Chris Lattner MAP(F0, 40) \ 363472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands MAP(F8, 41) \ 3787ca0e077d91b96a765b3b24cadfa8891026a33aRafael Espindola MAP(F9, 42) \ 3887ca0e077d91b96a765b3b24cadfa8891026a33aRafael Espindola MAP(D0, 45) \ 3987ca0e077d91b96a765b3b24cadfa8891026a33aRafael Espindola MAP(D1, 46) 409492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan 418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan// A clone of X86 since we can't depend on something that is generated. 428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanannamespace X86Local { 438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan enum { 448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Pseudo = 0, 458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan RawFrm = 1, 468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan AddRegFrm = 2, 478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MRMDestReg = 3, 488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MRMDestMem = 4, 498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MRMSrcReg = 5, 508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MRMSrcMem = 6, 518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19, 528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23, 538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27, 548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31, 559492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan MRMInitReg = 32, 569492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan#define MAP(from, to) MRM_##from = to, 579492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan MRM_MAPPING 589492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan#undef MAP 596aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan RawFrmImm8 = 43, 606aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan RawFrmImm16 = 44, 619492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan lastMRM 628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan }; 638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan enum { 658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TB = 1, 668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan REP = 2, 678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan D8 = 3, D9 = 4, DA = 5, DB = 6, 688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan DC = 7, DD = 8, DE = 9, DF = 10, 698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan XD = 11, XS = 12, 700d8db8e0a8492ab2d4bef725ec61b519471b97ecChris Lattner T8 = 13, P_TA = 14, 71fff64ca9cfdcb8e2fd2e124fcda1c1053523afc6Kevin Enderby A6 = 15, A7 = 16, TF = 17 728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan }; 738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 749492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan 759492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// If rows are added to the opcode extension tables, then corresponding entries 769492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// must be added here. 779492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// 789492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// If the row corresponds to a single byte (i.e., 8f), then add an entry for 799492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// that byte to ONE_BYTE_EXTENSION_TABLES. 809492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// 819492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// If the row corresponds to two bytes where the first is 0f, add an entry for 829492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// the second byte to TWO_BYTE_EXTENSION_TABLES. 839492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// 849492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// If the row corresponds to some other set of bytes, you will need to modify 859492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes 869492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// to the X86 TD files, except in two cases: if the first two bytes of such a 879492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// new combination are 0f 38 or 0f 3a, you just have to add maps called 889492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a 899492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line 909492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan// in RecognizableInstr::emitDecodePath(). 919492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan 928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define ONE_BYTE_EXTENSION_TABLES \ 938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(80) \ 948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(81) \ 958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(82) \ 968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(83) \ 978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(8f) \ 988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(c0) \ 998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(c1) \ 1008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(c6) \ 1018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(c7) \ 1028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(d0) \ 1038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(d1) \ 1048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(d2) \ 1058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(d3) \ 1068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(f6) \ 1078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(f7) \ 1088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(fe) \ 1098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(ff) 1108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define TWO_BYTE_EXTENSION_TABLES \ 1128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(00) \ 1138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(01) \ 1148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(18) \ 1158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(71) \ 1168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(72) \ 1178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(73) \ 1188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(ae) \ 1198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(ba) \ 1208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan EXTENSION_TABLE(c7) 1218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananusing namespace X86Disassembler; 1238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// needsModRMForDecode - Indicates whether a particular instruction requires a 1258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// ModR/M byte for the instruction to be properly decoded. For example, a 1268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to 1278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 0b11. 1288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 1298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param form - The form of the instruction. 1308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @return - true if the form implies that a ModR/M byte is required, false 1318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// otherwise. 1328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananstatic bool needsModRMForDecode(uint8_t form) { 1338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (form == X86Local::MRMDestReg || 1348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan form == X86Local::MRMDestMem || 1358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan form == X86Local::MRMSrcReg || 1368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan form == X86Local::MRMSrcMem || 1378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (form >= X86Local::MRM0r && form <= X86Local::MRM7r) || 1388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (form >= X86Local::MRM0m && form <= X86Local::MRM7m)) 1398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return true; 1408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else 1418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return false; 1428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 1438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// isRegFormat - Indicates whether a particular form requires the Mod field of 1458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// the ModR/M byte to be 0b11. 1468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 1478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param form - The form of the instruction. 1488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @return - true if the form implies that Mod must be 0b11, false 1498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// otherwise. 1508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananstatic bool isRegFormat(uint8_t form) { 1518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (form == X86Local::MRMDestReg || 1528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan form == X86Local::MRMSrcReg || 1538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (form >= X86Local::MRM0r && form <= X86Local::MRM7r)) 1548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return true; 1558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else 1568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return false; 1578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 1588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit. 1608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// Useful for switch statements and the like. 1618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 1628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param init - A reference to the BitsInit to be decoded. 1638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @return - The field, with the first bit in the BitsInit as the lowest 1648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// order bit. 16505bce0beee87512e52428d4b80f5a8e79a949576David Greenestatic uint8_t byteFromBitsInit(BitsInit &init) { 1668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan int width = init.getNumBits(); 1678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(width <= 8 && "Field is too large for uint8_t!"); 1698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan int index; 1718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan uint8_t mask = 0x01; 1728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan uint8_t ret = 0; 1748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1758ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan for (index = 0; index < width; index++) { 17605bce0beee87512e52428d4b80f5a8e79a949576David Greene if (static_cast<BitInit*>(init.getBit(index))->getValue()) 1778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ret |= mask; 1788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan mask <<= 1; 1808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 1818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return ret; 1838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 1848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// byteFromRec - Extract a value at most 8 bits in with from a Record given the 1868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// name of the field. 1878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// 1888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param rec - The record from which to extract the value. 1898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @param name - The name of the field in the record. 1908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan/// @return - The field, as translated by byteFromBitsInit(). 1918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananstatic uint8_t byteFromRec(const Record* rec, const std::string &name) { 19205bce0beee87512e52428d4b80f5a8e79a949576David Greene BitsInit* bits = rec->getValueAsBitsInit(name); 1938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return byteFromBitsInit(*bits); 1948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 1958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananRecognizableInstr::RecognizableInstr(DisassemblerTables &tables, 1978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan const CodeGenInstruction &insn, 1988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan InstrUID uid) { 1998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan UID = uid; 2008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Rec = insn.TheDef; 2028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name = Rec->getName(); 2038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec = &tables.specForUID(UID); 2048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (!Rec->isSubClassOf("X86Inst")) { 2068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ShouldBeEmitted = false; 2078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return; 2088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 2098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Prefix = byteFromRec(Rec, "Prefix"); 2118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Opcode = byteFromRec(Rec, "Opcode"); 2128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Form = byteFromRec(Rec, "FormBits"); 2138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan SegOvr = byteFromRec(Rec, "SegOvrBits"); 2148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix"); 2168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix"); 217a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix"); 21899405df044f2c584242e711cc9023ec90356da82Bruno Cardoso Lopes HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix"); 219a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix"); 2206744a17dcfb941d9fdd869b9f06e20660e18ff88Craig Topper IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); 2218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HasLockPrefix = Rec->getValueAsBit("hasLockPrefix"); 2228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); 2238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name = Rec->getName(); 2258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan AsmString = Rec->getValueAsString("AsmString"); 2268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 227c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner Operands = &insn.Operands.OperandList; 2288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 22998f213cd60f21437846ce4075c0fe15d7f09a3fdKevin Enderby IsSSE = (HasOpSizePrefix && (Name.find("16") == Name.npos)) || 23098f213cd60f21437846ce4075c0fe15d7f09a3fdKevin Enderby (Name.find("CRC32") != Name.npos); 231a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HasFROperands = hasFROperands(); 232a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HasVEX_LPrefix = has256BitOperands() || Rec->getValueAsBit("hasVEX_L"); 2338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2347105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman // Check for 64-bit inst which does not require REX 2354da632e6e09b96db4b3f9202cde4e6ca732001c1Craig Topper Is32Bit = false; 2367105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Is64Bit = false; 2377105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman // FIXME: Is there some better way to check for In64BitMode? 2387105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates"); 2397105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman for (unsigned i = 0, e = Predicates.size(); i != e; ++i) { 2404da632e6e09b96db4b3f9202cde4e6ca732001c1Craig Topper if (Predicates[i]->getName().find("32Bit") != Name.npos) { 2414da632e6e09b96db4b3f9202cde4e6ca732001c1Craig Topper Is32Bit = true; 2424da632e6e09b96db4b3f9202cde4e6ca732001c1Craig Topper break; 2434da632e6e09b96db4b3f9202cde4e6ca732001c1Craig Topper } 2447105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman if (Predicates[i]->getName().find("64Bit") != Name.npos) { 2457105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Is64Bit = true; 2467105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman break; 2477105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman } 2487105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman } 2497105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman // FIXME: These instructions aren't marked as 64-bit in any way 2507105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Is64Bit |= Rec->getName() == "JMP64pcrel32" || 2517105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName() == "MASKMOVDQU64" || 2527105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName() == "POPFS64" || 2537105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName() == "POPGS64" || 2547105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName() == "PUSHFS64" || 2557105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName() == "PUSHGS64" || 2567105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName() == "REX64_PREFIX" || 2577105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName().find("VMREAD64") != Name.npos || 2587105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName().find("VMWRITE64") != Name.npos || 259846a2dcada30a3507a1e9af9eabc2919674e669fCraig Topper Rec->getName().find("INVEPT64") != Name.npos || 260846a2dcada30a3507a1e9af9eabc2919674e669fCraig Topper Rec->getName().find("INVVPID64") != Name.npos || 2617105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName().find("MOV64") != Name.npos || 2627105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName().find("PUSH64") != Name.npos || 2637105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman Rec->getName().find("POP64") != Name.npos; 2647105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman 2658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ShouldBeEmitted = true; 2668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 2678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananvoid RecognizableInstr::processInstr(DisassemblerTables &tables, 269fff64ca9cfdcb8e2fd2e124fcda1c1053523afc6Kevin Enderby const CodeGenInstruction &insn, 2708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan InstrUID uid) 2718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan{ 2724072886a690a853c57c79a87a6423a7bfe0ce61fDaniel Dunbar // Ignore "asm parser only" instructions. 2734072886a690a853c57c79a87a6423a7bfe0ce61fDaniel Dunbar if (insn.TheDef->getValueAsBit("isAsmParserOnly")) 2744072886a690a853c57c79a87a6423a7bfe0ce61fDaniel Dunbar return; 2754072886a690a853c57c79a87a6423a7bfe0ce61fDaniel Dunbar 2768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan RecognizableInstr recogInstr(tables, insn, uid); 2778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan recogInstr.emitInstructionSpecifier(tables); 2798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (recogInstr.shouldBeEmitted()) 2818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan recogInstr.emitDecodePath(tables); 2828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 2838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 2848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananInstructionContext RecognizableInstr::insnContext() const { 2858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan InstructionContext insnContext; 2868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 287a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (HasVEX_4VPrefix || HasVEXPrefix) { 2886744a17dcfb941d9fdd869b9f06e20660e18ff88Craig Topper if (HasVEX_LPrefix && HasVEX_WPrefix) 2896744a17dcfb941d9fdd869b9f06e20660e18ff88Craig Topper llvm_unreachable("Don't support VEX.L and VEX.W together"); 2906744a17dcfb941d9fdd869b9f06e20660e18ff88Craig Topper else if (HasOpSizePrefix && HasVEX_LPrefix) 291a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_L_OPSIZE; 292a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (HasOpSizePrefix && HasVEX_WPrefix) 293a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_W_OPSIZE; 294a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (HasOpSizePrefix) 295a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_OPSIZE; 296a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (HasVEX_LPrefix && Prefix == X86Local::XS) 297a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_L_XS; 298a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (HasVEX_LPrefix && Prefix == X86Local::XD) 299a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_L_XD; 300a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (HasVEX_WPrefix && Prefix == X86Local::XS) 301a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_W_XS; 302a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (HasVEX_WPrefix && Prefix == X86Local::XD) 303a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_W_XD; 304a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (HasVEX_WPrefix) 305a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_W; 306a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (HasVEX_LPrefix) 307a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_L; 308a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (Prefix == X86Local::XD) 309a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_XD; 310a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else if (Prefix == X86Local::XS) 311a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX_XS; 312a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else 313a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan insnContext = IC_VEX; 3147105259ce8e9fd78ce9fc1b7a9aaab123fb5db64Eli Friedman } else if (Is64Bit || HasREX_WPrefix) { 3158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (HasREX_WPrefix && HasOpSizePrefix) 3168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_64BIT_REXW_OPSIZE; 31729480fd798dc6452948f63825ff41c66f09c2493Craig Topper else if (HasOpSizePrefix && 31829480fd798dc6452948f63825ff41c66f09c2493Craig Topper (Prefix == X86Local::XD || Prefix == X86Local::TF)) 319e1b4a1a07ec79440536e4535721f15de3893cd13Craig Topper insnContext = IC_64BIT_XD_OPSIZE; 32029480fd798dc6452948f63825ff41c66f09c2493Craig Topper else if (HasOpSizePrefix && Prefix == X86Local::XS) 32129480fd798dc6452948f63825ff41c66f09c2493Craig Topper insnContext = IC_64BIT_XS_OPSIZE; 3228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else if (HasOpSizePrefix) 3238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_64BIT_OPSIZE; 3248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else if (HasREX_WPrefix && Prefix == X86Local::XS) 3258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_64BIT_REXW_XS; 32629480fd798dc6452948f63825ff41c66f09c2493Craig Topper else if (HasREX_WPrefix && 32729480fd798dc6452948f63825ff41c66f09c2493Craig Topper (Prefix == X86Local::XD || Prefix == X86Local::TF)) 3288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_64BIT_REXW_XD; 329e1b4a1a07ec79440536e4535721f15de3893cd13Craig Topper else if (Prefix == X86Local::XD || Prefix == X86Local::TF) 3308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_64BIT_XD; 3318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else if (Prefix == X86Local::XS) 3328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_64BIT_XS; 3338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else if (HasREX_WPrefix) 3348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_64BIT_REXW; 3358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else 3368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_64BIT; 3378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 338e1b4a1a07ec79440536e4535721f15de3893cd13Craig Topper if (HasOpSizePrefix && 339e1b4a1a07ec79440536e4535721f15de3893cd13Craig Topper (Prefix == X86Local::XD || Prefix == X86Local::TF)) 340e1b4a1a07ec79440536e4535721f15de3893cd13Craig Topper insnContext = IC_XD_OPSIZE; 34129480fd798dc6452948f63825ff41c66f09c2493Craig Topper else if (HasOpSizePrefix && Prefix == X86Local::XS) 34229480fd798dc6452948f63825ff41c66f09c2493Craig Topper insnContext = IC_XS_OPSIZE; 34398f213cd60f21437846ce4075c0fe15d7f09a3fdKevin Enderby else if (HasOpSizePrefix) 3448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_OPSIZE; 345e1b4a1a07ec79440536e4535721f15de3893cd13Craig Topper else if (Prefix == X86Local::XD || Prefix == X86Local::TF) 3468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_XD; 347842f58f9be82e1a0d2751e7982ef3641829acf87Craig Topper else if (Prefix == X86Local::XS || Prefix == X86Local::REP) 3488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC_XS; 3498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else 3508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext = IC; 3518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 3528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return insnContext; 3548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 3558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananRecognizableInstr::filter_ret RecognizableInstr::filter() const { 357a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan /////////////////// 358a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // FILTER_STRONG 359a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // 360a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 3618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Filter out intrinsics 3628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (!Rec->isSubClassOf("X86Inst")) 3648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_STRONG; 3658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 3668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Form == X86Local::Pseudo || 367038197988bcd7619657633da7116c7292187d4aeCraig Topper (IsCodeGenOnly && Name.find("_REV") == Name.npos)) 3688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_STRONG; 3698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 37080443f914624098db7088d751efbb8dae7743b76Sean Callanan if (Form == X86Local::MRMInitReg) 37180443f914624098db7088d751efbb8dae7743b76Sean Callanan return FILTER_STRONG; 372a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 373a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 374a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // Filter out artificial instructions 375a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 376a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (Name.find("TAILJMP") != Name.npos || 377a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("_Int") != Name.npos || 378a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("_int") != Name.npos || 379a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("Int_") != Name.npos || 380a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("_NOREX") != Name.npos || 381a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("_TC") != Name.npos || 382a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("EH_RETURN") != Name.npos || 383a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("V_SET") != Name.npos || 384a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("LOCK_") != Name.npos || 385a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("WIN") != Name.npos || 386a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("_AVX") != Name.npos || 387a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("2SDL") != Name.npos) 388a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return FILTER_STRONG; 389a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 390a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // Filter out instructions with segment override prefixes. 391a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // They're too messy to handle now and we'll special case them if needed. 392a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 393a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (SegOvr) 394a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return FILTER_STRONG; 395a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 396a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // Filter out instructions that can't be printed. 397a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 398a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (AsmString.size() == 0) 399a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return FILTER_STRONG; 400a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 401a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // Filter out instructions with subreg operands. 402a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 403a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (AsmString.find("subreg") != AsmString.npos) 404a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return FILTER_STRONG; 405a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 406a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ///////////////// 407a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // FILTER_WEAK 408a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // 409a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 410a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 4118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Filter out instructions with a LOCK prefix; 4128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // prefer forms that do not have the prefix 4138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (HasLockPrefix) 4148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_WEAK; 4158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 416a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // Filter out alternate forms of AVX instructions 417a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (Name.find("_alt") != Name.npos || 418a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("XrYr") != Name.npos || 419e1b4a1a07ec79440536e4535721f15de3893cd13Craig Topper (Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos) || 420a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("_64mr") != Name.npos || 421a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("Xrr") != Name.npos || 422a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name.find("rr64") != Name.npos) 423a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return FILTER_WEAK; 424a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 425a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (Name == "VMASKMOVDQU64" || 426a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name == "VEXTRACTPSrr64" || 427a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name == "VMOVQd64rr" || 428a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name == "VMOVQs64rr") 429a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return FILTER_WEAK; 4308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 4318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Special cases. 43286097c384f84981494ed9c200ff5763afcd960deDale Johannesen 4338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI") 4348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_WEAK; 4358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI") 4368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_WEAK; 4378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 4388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos) 4398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_WEAK; 4408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos) 4418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_WEAK; 4428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Name.find("Fs") != Name.npos) 4438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_WEAK; 4448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Name == "MOVLPDrr" || 4458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVLPSrr" || 4468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "PUSHFQ" || 4478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "BSF16rr" || 4488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "BSF16rm" || 4498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "BSR16rr" || 4508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "BSR16rm" || 4518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVSX16rm8" || 4528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVSX16rr8" || 4538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVZX16rm8" || 4548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVZX16rr8" || 4558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "PUSH32i16" || 4568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "PUSH64i16" || 4578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVPQI2QImr" || 458a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan Name == "VMOVPQI2QImr" || 4598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVSDmr" || 4608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVSDrm" || 4618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVSSmr" || 4628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOVSSrm" || 4638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MMX_MOVD64rrv164" || 4648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "CRC32m16" || 4658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "MOV64ri64i32" || 4668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Name == "CRC32r16") 4678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_WEAK; 4688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 4698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (HasFROperands && Name.find("MOV") != Name.npos && 4708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) || 4718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (Name.find("to") != Name.npos))) 4728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_WEAK; 4738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 4748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return FILTER_NORMAL; 4758ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 476a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 477a21e2eae3def2fe39caed861dcb73c76c715569bSean Callananbool RecognizableInstr::hasFROperands() const { 478a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 479a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan unsigned numOperands = OperandList.size(); 480a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 481a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 482a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan const std::string &recName = OperandList[operandIndex].Rec->getName(); 483a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 484a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (recName.find("FR") != recName.npos) 485a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return true; 486a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan } 487a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return false; 488a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan} 489a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 490a21e2eae3def2fe39caed861dcb73c76c715569bSean Callananbool RecognizableInstr::has256BitOperands() const { 491a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 492a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan unsigned numOperands = OperandList.size(); 493a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 494a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan for (unsigned operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 495a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan const std::string &recName = OperandList[operandIndex].Rec->getName(); 496a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 497a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (!recName.compare("VR256") || !recName.compare("f256mem")) { 498a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return true; 499a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan } 500a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan } 501a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan return false; 502a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan} 5038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananvoid RecognizableInstr::handleOperand( 5058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool optional, 5068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned &operandIndex, 5078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned &physicalOperandIndex, 5088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned &numPhysicalOperands, 5098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned *operandMapping, 5108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan OperandEncoding (*encodingFromString)(const std::string&, bool hasOpSizePrefix)) { 5118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (optional) { 5128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (physicalOperandIndex >= numPhysicalOperands) 5138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return; 5148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 5158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(physicalOperandIndex < numPhysicalOperands); 5168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan while (operandMapping[operandIndex] != operandIndex) { 5198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->operands[operandIndex].encoding = ENCODING_DUP; 5208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->operands[operandIndex].type = 5218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]); 5228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ++operandIndex; 5238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan const std::string &typeName = (*Operands)[operandIndex].Rec->getName(); 526a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 5278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->operands[operandIndex].encoding = encodingFromString(typeName, 5288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HasOpSizePrefix); 5298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->operands[operandIndex].type = typeFromString(typeName, 530a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan IsSSE, 531a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HasREX_WPrefix, 532a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HasOpSizePrefix); 5338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ++operandIndex; 5358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ++physicalOperandIndex; 5368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 5378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananvoid RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { 5398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->name = Name; 5408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (!Rec->isSubClassOf("X86Inst")) 5428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return; 5438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (filter()) { 5458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case FILTER_WEAK: 5468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->filtered = true; 5478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 5488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case FILTER_STRONG: 5498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ShouldBeEmitted = false; 5508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return; 5518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case FILTER_NORMAL: 5528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 5538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->insnContext = insnContext(); 5568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 557c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 5588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned operandIndex; 5608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned numOperands = OperandList.size(); 5618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned numPhysicalOperands = 0; 5628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // operandMapping maps from operands in OperandList to their originals. 5648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // If operandMapping[i] != i, then the entry is a duplicate. 5658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned operandMapping[X86_MAX_OPERANDS]; 5668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasFROperands = false; 5688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(numOperands < X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough"); 5708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 5728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (OperandList[operandIndex].Constraints.size()) { 573c240bb0ede0541426254d0e0dc81d891beda4b22Chris Lattner const CGIOperandList::ConstraintInfo &Constraint = 574a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner OperandList[operandIndex].Constraints[0]; 575a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner if (Constraint.isTied()) { 576a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7eChris Lattner operandMapping[operandIndex] = Constraint.getTiedOperand(); 5778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 5788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ++numPhysicalOperands; 5798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan operandMapping[operandIndex] = operandIndex; 5808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 5828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ++numPhysicalOperands; 5838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan operandMapping[operandIndex] = operandIndex; 5848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan const std::string &recName = OperandList[operandIndex].Rec->getName(); 5878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (recName.find("FR") != recName.npos) 5898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan hasFROperands = true; 5908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 5918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (hasFROperands && Name.find("MOV") != Name.npos && 5938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) || 5948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (Name.find("to") != Name.npos))) 5958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ShouldBeEmitted = false; 5968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 5978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (!ShouldBeEmitted) 5988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan return; 5998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 6008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define HANDLE_OPERAND(class) \ 6018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan handleOperand(false, \ 6028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan operandIndex, \ 6038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan physicalOperandIndex, \ 6048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan numPhysicalOperands, \ 6058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan operandMapping, \ 6068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan class##EncodingFromString); 6078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 6088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define HANDLE_OPTIONAL(class) \ 6098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan handleOperand(true, \ 6108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan operandIndex, \ 6118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan physicalOperandIndex, \ 6128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan numPhysicalOperands, \ 6138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan operandMapping, \ 6148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan class##EncodingFromString); 6158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 6168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // operandIndex should always be < numOperands 6178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan operandIndex = 0; 6188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // physicalOperandIndex should always be < numPhysicalOperands 6198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan unsigned physicalOperandIndex = 0; 6208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 6218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (Form) { 6228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::RawFrm: 6238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 1 (optional) is an address or immediate. 6248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 2 (optional) is an immediate. 6258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(numPhysicalOperands <= 2 && 6268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan "Unexpected number of operands for RawFrm"); 6278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(relocation) 6288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(immediate) 6298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 6308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::AddRegFrm: 6318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 1 is added to the opcode. 6328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 2 (optional) is an address. 6338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 6348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan "Unexpected number of operands for AddRegFrm"); 6358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPERAND(opcodeModifier) 6368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(relocation) 6378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 6388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRMDestReg: 6398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 1 is a register operand in the R/M field. 6408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 2 is a register operand in the Reg/Opcode field. 6413daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper // - In AVX, there is a register operand in the VEX.vvvv field here - 6428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 3 (optional) is an immediate. 6433daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper if (HasVEX_4VPrefix) 6443daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 6453daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper "Unexpected number of operands for MRMDestRegFrm with VEX_4V"); 6463daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper else 6473daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 6483daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper "Unexpected number of operands for MRMDestRegFrm"); 6493daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper 6508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPERAND(rmRegister) 6513daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper 6523daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper if (HasVEX_4VPrefix) 6533daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper // FIXME: In AVX, the register below becomes the one encoded 6543daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper // in ModRMVEX and the one above the one in the VEX.VVVV field 6553daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper HANDLE_OPERAND(vvvvRegister) 6563daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper 6578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPERAND(roRegister) 6588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(immediate) 6598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 6608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRMDestMem: 6618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 1 is a memory operand (possibly SIB-extended) 6628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 2 is a register operand in the Reg/Opcode field. 6633daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper // - In AVX, there is a register operand in the VEX.vvvv field here - 6648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 3 (optional) is an immediate. 6653daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper if (HasVEX_4VPrefix) 6663daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 6673daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); 6683daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper else 6693daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 6703daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper "Unexpected number of operands for MRMDestMemFrm"); 6718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPERAND(memory) 6723daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper 6733daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper if (HasVEX_4VPrefix) 6743daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper // FIXME: In AVX, the register below becomes the one encoded 6753daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper // in ModRMVEX and the one above the one in the VEX.VVVV field 6763daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper HANDLE_OPERAND(vvvvRegister) 6773daa5c29d444a759a0c60656d1aaf2579e5e447cCraig Topper 6788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPERAND(roRegister) 6798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(immediate) 6808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 6818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRMSrcReg: 6828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 1 is a register operand in the Reg/Opcode field. 6838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 2 is a register operand in the R/M field. 684a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // - In AVX, there is a register operand in the VEX.vvvv field here - 6858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 3 (optional) is an immediate. 68699405df044f2c584242e711cc9023ec90356da82Bruno Cardoso Lopes 68799405df044f2c584242e711cc9023ec90356da82Bruno Cardoso Lopes if (HasVEX_4VPrefix) 688a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 689a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan "Unexpected number of operands for MRMSrcRegFrm with VEX_4V"); 690a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else 691a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 692a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan "Unexpected number of operands for MRMSrcRegFrm"); 693a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 694a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HANDLE_OPERAND(roRegister) 695a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 696a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (HasVEX_4VPrefix) 697c902a59f4c786a2a047f0b4c964a93108f248915Bruno Cardoso Lopes // FIXME: In AVX, the register below becomes the one encoded 698c902a59f4c786a2a047f0b4c964a93108f248915Bruno Cardoso Lopes // in ModRMVEX and the one above the one in the VEX.VVVV field 699a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HANDLE_OPERAND(vvvvRegister) 700a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 701a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HANDLE_OPERAND(rmRegister) 702a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HANDLE_OPTIONAL(immediate) 7038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 7048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRMSrcMem: 7058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 1 is a register operand in the Reg/Opcode field. 7068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 2 is a memory operand (possibly SIB-extended) 707a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // - In AVX, there is a register operand in the VEX.vvvv field here - 7088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 3 (optional) is an immediate. 709a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 710a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (HasVEX_4VPrefix) 711a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && 712a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan "Unexpected number of operands for MRMSrcMemFrm with VEX_4V"); 713a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else 714a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 715a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan "Unexpected number of operands for MRMSrcMemFrm"); 716a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 7178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPERAND(roRegister) 718c902a59f4c786a2a047f0b4c964a93108f248915Bruno Cardoso Lopes 719c902a59f4c786a2a047f0b4c964a93108f248915Bruno Cardoso Lopes if (HasVEX_4VPrefix) 720c902a59f4c786a2a047f0b4c964a93108f248915Bruno Cardoso Lopes // FIXME: In AVX, the register below becomes the one encoded 721c902a59f4c786a2a047f0b4c964a93108f248915Bruno Cardoso Lopes // in ModRMVEX and the one above the one in the VEX.VVVV field 722a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HANDLE_OPERAND(vvvvRegister) 723c902a59f4c786a2a047f0b4c964a93108f248915Bruno Cardoso Lopes 7248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPERAND(memory) 7258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(immediate) 7268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 7278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM0r: 7288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM1r: 7298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM2r: 7308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM3r: 7318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM4r: 7328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM5r: 7338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM6r: 7348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM7r: 7358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 1 is a register operand in the R/M field. 7368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 2 (optional) is an immediate or relocation. 737a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (HasVEX_4VPrefix) 738a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan assert(numPhysicalOperands <= 3 && 739a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan "Unexpected number of operands for MRMSrcMemFrm with VEX_4V"); 740a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan else 741a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan assert(numPhysicalOperands <= 2 && 742a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan "Unexpected number of operands for MRMnRFrm"); 743a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan if (HasVEX_4VPrefix) 744a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan HANDLE_OPERAND(vvvvRegister); 7458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(rmRegister) 7468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(relocation) 7478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 7488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM0m: 7498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM1m: 7508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM2m: 7518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM3m: 7528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM4m: 7538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM5m: 7548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM6m: 7558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM7m: 7568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 1 is a memory operand (possibly SIB-extended) 7578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Operand 2 (optional) is an immediate or relocation. 7588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 7598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan "Unexpected number of operands for MRMnMFrm"); 7608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPERAND(memory) 7618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan HANDLE_OPTIONAL(relocation) 7628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 7636aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan case X86Local::RawFrmImm8: 7646aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan // operand 1 is a 16-bit immediate 7656aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan // operand 2 is an 8-bit immediate 7666aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan assert(numPhysicalOperands == 2 && 7676aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan "Unexpected number of operands for X86Local::RawFrmImm8"); 7686aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan HANDLE_OPERAND(immediate) 7696aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan HANDLE_OPERAND(immediate) 7706aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan break; 7716aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan case X86Local::RawFrmImm16: 7726aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan // operand 1 is a 16-bit immediate 7736aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan // operand 2 is a 16-bit immediate 7746aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan HANDLE_OPERAND(immediate) 7756aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan HANDLE_OPERAND(immediate) 7766aeb2e32b7724e7c4bd878d4c899be917492cb32Sean Callanan break; 7778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRMInitReg: 7788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Ignored. 7798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 7808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 7818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan #undef HANDLE_OPERAND 7838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan #undef HANDLE_OPTIONAL 7848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 7858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callananvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { 7878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Special cases where the LLVM tables are not complete 7888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7899492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan#define MAP(from, to) \ 7909492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan case X86Local::MRM_##from: \ 7919492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan filter = new ExactFilter(0x##from); \ 7929492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan break; 7938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan OpcodeType opcodeType = (OpcodeType)-1; 7958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ModRMFilter* filter = NULL; 7978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan uint8_t opcodeToSet = 0; 7988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 7998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (Prefix) { 8008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f 8018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::XD: 8028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::XS: 8038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::TB: 8048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeType = TWOBYTE; 8058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 8068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (Opcode) { 80795a5a7d57015c21b355a351c2efc6866f89b2f61Sean Callanan default: 80895a5a7d57015c21b355a351c2efc6866f89b2f61Sean Callanan if (needsModRMForDecode(Form)) 80995a5a7d57015c21b355a351c2efc6866f89b2f61Sean Callanan filter = new ModFilter(isRegFormat(Form)); 81095a5a7d57015c21b355a351c2efc6866f89b2f61Sean Callanan else 81195a5a7d57015c21b355a351c2efc6866f89b2f61Sean Callanan filter = new DumbFilter(); 81295a5a7d57015c21b355a351c2efc6866f89b2f61Sean Callanan break; 8138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define EXTENSION_TABLE(n) case 0x##n: 8148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TWO_BYTE_EXTENSION_TABLES 8158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef EXTENSION_TABLE 8168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (Form) { 8178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 8188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Unhandled two-byte extended opcode"); 8198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM0r: 8208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM1r: 8218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM2r: 8228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM3r: 8238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM4r: 8248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM5r: 8258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM6r: 8268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM7r: 8278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 8288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 8298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM0m: 8308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM1m: 8318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM2m: 8328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM3m: 8338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM4m: 8348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM5m: 8358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM6m: 8368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM7m: 8378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 8388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 8399492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan MRM_MAPPING 8408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } // switch (Form) 8418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 84295a5a7d57015c21b355a351c2efc6866f89b2f61Sean Callanan } // switch (Opcode) 8438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeToSet = Opcode; 8448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 8458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::T8: 846fff64ca9cfdcb8e2fd2e124fcda1c1053523afc6Kevin Enderby case X86Local::TF: 8478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeType = THREEBYTE_38; 8488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (needsModRMForDecode(Form)) 8498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new ModFilter(isRegFormat(Form)); 8508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else 8518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new DumbFilter(); 8528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeToSet = Opcode; 8538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 8540d8db8e0a8492ab2d4bef725ec61b519471b97ecChris Lattner case X86Local::P_TA: 8558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeType = THREEBYTE_3A; 8568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (needsModRMForDecode(Form)) 8578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new ModFilter(isRegFormat(Form)); 8588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else 8598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new DumbFilter(); 8608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeToSet = Opcode; 8618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 8624a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger case X86Local::A6: 8634a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger opcodeType = THREEBYTE_A6; 8644a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger if (needsModRMForDecode(Form)) 8654a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger filter = new ModFilter(isRegFormat(Form)); 8664a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger else 8674a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger filter = new DumbFilter(); 8684a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger opcodeToSet = Opcode; 8694a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger break; 8704a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger case X86Local::A7: 8714a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger opcodeType = THREEBYTE_A7; 8724a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger if (needsModRMForDecode(Form)) 8734a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger filter = new ModFilter(isRegFormat(Form)); 8744a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger else 8754a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger filter = new DumbFilter(); 8764a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger opcodeToSet = Opcode; 8774a8ac8de1ddfeaadb9ff13ce361bfc6435f18028Joerg Sonnenberger break; 8788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::D8: 8798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::D9: 8808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::DA: 8818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::DB: 8828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::DC: 8838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::DD: 8848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::DE: 8858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::DF: 8868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode"); 8878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeType = ONEBYTE; 8888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Form == X86Local::AddRegFrm) { 8898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->modifierType = MODIFIER_MODRM; 8908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->modifierBase = Opcode; 8918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new AddRegEscapeFilter(Opcode); 8928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 8938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new EscapeFilter(true, Opcode); 8948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 8958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeToSet = 0xd8 + (Prefix - X86Local::D8); 8968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 897842f58f9be82e1a0d2751e7982ef3641829acf87Craig Topper case X86Local::REP: 8988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 8998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeType = ONEBYTE; 9008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (Opcode) { 9018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define EXTENSION_TABLE(n) case 0x##n: 9028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ONE_BYTE_EXTENSION_TABLES 9038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef EXTENSION_TABLE 9048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan switch (Form) { 9058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 9068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Fell through the cracks of a single-byte " 9078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan "extended opcode"); 9088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM0r: 9098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM1r: 9108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM2r: 9118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM3r: 9128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM4r: 9138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM5r: 9148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM6r: 9158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM7r: 9168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 9178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 9188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM0m: 9198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM1m: 9208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM2m: 9218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM3m: 9228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM4m: 9238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM5m: 9248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM6m: 9258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case X86Local::MRM7m: 9268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 9278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 9289492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan MRM_MAPPING 9298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } // switch (Form) 9308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 9318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case 0xd8: 9328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case 0xd9: 9338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case 0xda: 9348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case 0xdb: 9358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case 0xdc: 9368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case 0xdd: 9378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case 0xde: 9388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan case 0xdf: 9398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new EscapeFilter(false, Form - X86Local::MRM0m); 9408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 9418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan default: 9428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (needsModRMForDecode(Form)) 9438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new ModFilter(isRegFormat(Form)); 9448ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan else 9458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan filter = new DumbFilter(); 9468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan break; 9478ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } // switch (Opcode) 9488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeToSet = Opcode; 9498ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } // switch (Prefix) 9508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 9518ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(opcodeType != (OpcodeType)-1 && 9528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan "Opcode type not set"); 9538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(filter && "Filter not set"); 9548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 9558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (Form == X86Local::AddRegFrm) { 9568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if(Spec->modifierType != MODIFIER_MODRM) { 9578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan assert(opcodeToSet < 0xf9 && 9588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan "Not enough room for all ADDREG_FRM operands"); 9598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 9608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan uint8_t currentOpcode; 9618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 9628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan for (currentOpcode = opcodeToSet; 9638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan currentOpcode < opcodeToSet + 8; 9648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ++currentOpcode) 9658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan tables.setTableFields(opcodeType, 9668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext(), 9678ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan currentOpcode, 9688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan *filter, 9696744a17dcfb941d9fdd869b9f06e20660e18ff88Craig Topper UID, Is32Bit, IgnoresVEX_L); 9708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 9718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->modifierType = MODIFIER_OPCODE; 9728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->modifierBase = opcodeToSet; 9738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 9748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // modifierBase was set where MODIFIER_MODRM was set 9758ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan tables.setTableFields(opcodeType, 9768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext(), 9778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeToSet, 9788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan *filter, 9796744a17dcfb941d9fdd869b9f06e20660e18ff88Craig Topper UID, Is32Bit, IgnoresVEX_L); 9808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 9818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } else { 9828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan tables.setTableFields(opcodeType, 9838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan insnContext(), 9848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan opcodeToSet, 9858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan *filter, 9866744a17dcfb941d9fdd869b9f06e20660e18ff88Craig Topper UID, Is32Bit, IgnoresVEX_L); 9878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 9888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->modifierType = MODIFIER_NONE; 9898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan Spec->modifierBase = opcodeToSet; 9908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 9918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 9928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan delete filter; 9939492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan 9949492be8d10d7df8efaf33bcf2eb3ad13d49ddd60Sean Callanan#undef MAP 9958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 9968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 9978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define TYPE(str, type) if (s == str) return type; 9988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananOperandType RecognizableInstr::typeFromString(const std::string &s, 9998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool isSSE, 10008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasREX_WPrefix, 10018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasOpSizePrefix) { 10028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if (isSSE) { 10038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // For SSE instructions, we ignore the OpSize prefix and force operand 10048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // sizes. 10058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR16", TYPE_R16) 10068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR32", TYPE_R32) 10078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR64", TYPE_R64) 10088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 10098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if(hasREX_WPrefix) { 10108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // For instructions with a REX_W prefix, a declared 32-bit register encoding 10118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // is special. 10128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR32", TYPE_R32) 10138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 10148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if(!hasOpSizePrefix) { 10158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // For instructions without an OpSize prefix, a declared 16-bit register or 10168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // immediate encoding is special. 10178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR16", TYPE_R16) 10188ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i16imm", TYPE_IMM16) 10198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 10208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i16mem", TYPE_Mv) 10218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i16imm", TYPE_IMMv) 10228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i16i8imm", TYPE_IMMv) 10238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR16", TYPE_Rv) 10248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i32mem", TYPE_Mv) 10258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i32imm", TYPE_IMMv) 10268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i32i8imm", TYPE_IMM32) 1027c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby TYPE("u32u8imm", TYPE_IMM32) 10288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR32", TYPE_Rv) 10298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i64mem", TYPE_Mv) 10308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i64i32imm", TYPE_IMM64) 10318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i64i8imm", TYPE_IMM64) 10328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR64", TYPE_R64) 10338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i8mem", TYPE_M8) 10348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i8imm", TYPE_IMM8) 10358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("GR8", TYPE_R8) 10368ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("VR128", TYPE_XMM128) 10378ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("f128mem", TYPE_M128) 1038b2ef4c1235c846c2503d0796541f4255ef1e13f5Chris Lattner TYPE("f256mem", TYPE_M256) 10398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("FR64", TYPE_XMM64) 10408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("f64mem", TYPE_M64FP) 1041b2ef4c1235c846c2503d0796541f4255ef1e13f5Chris Lattner TYPE("sdmem", TYPE_M64FP) 10428ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("FR32", TYPE_XMM32) 10438ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("f32mem", TYPE_M32FP) 1044b2ef4c1235c846c2503d0796541f4255ef1e13f5Chris Lattner TYPE("ssmem", TYPE_M32FP) 10458ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("RST", TYPE_ST) 10468ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i128mem", TYPE_M128) 1047a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan TYPE("i256mem", TYPE_M256) 10488ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i64i32imm_pcrel", TYPE_REL64) 10499fc05227a2596c545b845ed9a72673995e49d16bChris Lattner TYPE("i16imm_pcrel", TYPE_REL16) 10508ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i32imm_pcrel", TYPE_REL32) 10515edca8162623b742282f5f03b0872ac3469b5bedSean Callanan TYPE("SSECC", TYPE_IMM3) 10528ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("brtarget", TYPE_RELv) 1053c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson TYPE("uncondbrtarget", TYPE_RELv) 10548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("brtarget8", TYPE_REL8) 10558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("f80mem", TYPE_M80FP) 10567fb35a2fd83f5deadefcb230669b07e1d5b98137Sean Callanan TYPE("lea32mem", TYPE_LEA) 10577fb35a2fd83f5deadefcb230669b07e1d5b98137Sean Callanan TYPE("lea64_32mem", TYPE_LEA) 10587fb35a2fd83f5deadefcb230669b07e1d5b98137Sean Callanan TYPE("lea64mem", TYPE_LEA) 10598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("VR64", TYPE_MM64) 10608ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("i64imm", TYPE_IMMv) 10618ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("opaque32mem", TYPE_M1616) 10628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("opaque48mem", TYPE_M1632) 10638ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("opaque80mem", TYPE_M1664) 10648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("opaque512mem", TYPE_M512) 10658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("SEGMENT_REG", TYPE_SEGMENTREG) 10668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("DEBUG_REG", TYPE_DEBUGREG) 10671a8b789a4b8290d263c1c75411788ca45bae3230Sean Callanan TYPE("CONTROL_REG", TYPE_CONTROLREG) 10688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("offset8", TYPE_MOFFS8) 10698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("offset16", TYPE_MOFFS16) 10708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("offset32", TYPE_MOFFS32) 10718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan TYPE("offset64", TYPE_MOFFS64) 1072a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan TYPE("VR256", TYPE_XMM256) 10737ea16b01fad5236cc132cb5fc3e443fcbf70d3b8Craig Topper TYPE("GR16_NOAX", TYPE_Rv) 10747ea16b01fad5236cc132cb5fc3e443fcbf70d3b8Craig Topper TYPE("GR32_NOAX", TYPE_Rv) 10757ea16b01fad5236cc132cb5fc3e443fcbf70d3b8Craig Topper TYPE("GR64_NOAX", TYPE_R64) 10768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan errs() << "Unhandled type string " << s << "\n"; 10778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Unhandled type string"); 10788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 10798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#undef TYPE 10808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 10818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan#define ENCODING(str, encoding) if (s == str) return encoding; 10828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananOperandEncoding RecognizableInstr::immediateEncodingFromString 10838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (const std::string &s, 10848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasOpSizePrefix) { 10858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if(!hasOpSizePrefix) { 10868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // For instructions without an OpSize prefix, a declared 16-bit register or 10878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // immediate encoding is special. 10888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i16imm", ENCODING_IW) 10898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 10908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i32i8imm", ENCODING_IB) 1091c37d4bbf1f33c5e4b1c2f1bf1a6e2cae2ae5603aKevin Enderby ENCODING("u32u8imm", ENCODING_IB) 10928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("SSECC", ENCODING_IB) 10938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i16imm", ENCODING_Iv) 10948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i16i8imm", ENCODING_IB) 10958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i32imm", ENCODING_Iv) 10968ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i64i32imm", ENCODING_ID) 10978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i64i8imm", ENCODING_IB) 10988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i8imm", ENCODING_IB) 1099a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // This is not a typo. Instructions like BLENDVPD put 1100a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan // register IDs in 8-bit immediates nowadays. 1101a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("VR256", ENCODING_IB) 1102a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("VR128", ENCODING_IB) 11038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan errs() << "Unhandled immediate encoding " << s << "\n"; 11048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Unhandled immediate encoding"); 11058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 11068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 11078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananOperandEncoding RecognizableInstr::rmRegisterEncodingFromString 11088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (const std::string &s, 11098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasOpSizePrefix) { 11108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR16", ENCODING_RM) 11118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR32", ENCODING_RM) 11128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR64", ENCODING_RM) 11138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR8", ENCODING_RM) 11148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("VR128", ENCODING_RM) 11158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("FR64", ENCODING_RM) 11168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("FR32", ENCODING_RM) 11178ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("VR64", ENCODING_RM) 1118a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("VR256", ENCODING_RM) 11198ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan errs() << "Unhandled R/M register encoding " << s << "\n"; 11208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Unhandled R/M register encoding"); 11218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 11228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 11238ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananOperandEncoding RecognizableInstr::roRegisterEncodingFromString 11248ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (const std::string &s, 11258ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasOpSizePrefix) { 11268ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR16", ENCODING_REG) 11278ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR32", ENCODING_REG) 11288ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR64", ENCODING_REG) 11298ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR8", ENCODING_REG) 11308ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("VR128", ENCODING_REG) 11318ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("FR64", ENCODING_REG) 11328ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("FR32", ENCODING_REG) 11338ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("VR64", ENCODING_REG) 11348ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("SEGMENT_REG", ENCODING_REG) 11358ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("DEBUG_REG", ENCODING_REG) 11361a8b789a4b8290d263c1c75411788ca45bae3230Sean Callanan ENCODING("CONTROL_REG", ENCODING_REG) 1137a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("VR256", ENCODING_REG) 11388ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan errs() << "Unhandled reg/opcode register encoding " << s << "\n"; 11398ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Unhandled reg/opcode register encoding"); 11408ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 11418ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 1142a21e2eae3def2fe39caed861dcb73c76c715569bSean CallananOperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString 1143a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan (const std::string &s, 1144a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan bool hasOpSizePrefix) { 1145a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("FR32", ENCODING_VVVV) 1146a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("FR64", ENCODING_VVVV) 1147a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("VR128", ENCODING_VVVV) 1148a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("VR256", ENCODING_VVVV) 1149a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan errs() << "Unhandled VEX.vvvv register encoding " << s << "\n"; 1150a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan llvm_unreachable("Unhandled VEX.vvvv register encoding"); 1151a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan} 1152a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan 11538ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananOperandEncoding RecognizableInstr::memoryEncodingFromString 11548ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (const std::string &s, 11558ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasOpSizePrefix) { 11568ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i16mem", ENCODING_RM) 11578ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i32mem", ENCODING_RM) 11588ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i64mem", ENCODING_RM) 11598ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i8mem", ENCODING_RM) 1160b2ef4c1235c846c2503d0796541f4255ef1e13f5Chris Lattner ENCODING("ssmem", ENCODING_RM) 1161b2ef4c1235c846c2503d0796541f4255ef1e13f5Chris Lattner ENCODING("sdmem", ENCODING_RM) 11628ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("f128mem", ENCODING_RM) 1163b2ef4c1235c846c2503d0796541f4255ef1e13f5Chris Lattner ENCODING("f256mem", ENCODING_RM) 11648ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("f64mem", ENCODING_RM) 11658ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("f32mem", ENCODING_RM) 11668ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i128mem", ENCODING_RM) 1167a21e2eae3def2fe39caed861dcb73c76c715569bSean Callanan ENCODING("i256mem", ENCODING_RM) 11688ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("f80mem", ENCODING_RM) 11698ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("lea32mem", ENCODING_RM) 11708ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("lea64_32mem", ENCODING_RM) 11718ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("lea64mem", ENCODING_RM) 11728ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("opaque32mem", ENCODING_RM) 11738ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("opaque48mem", ENCODING_RM) 11748ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("opaque80mem", ENCODING_RM) 11758ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("opaque512mem", ENCODING_RM) 11768ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan errs() << "Unhandled memory encoding " << s << "\n"; 11778ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Unhandled memory encoding"); 11788ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 11798ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 11808ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananOperandEncoding RecognizableInstr::relocationEncodingFromString 11818ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (const std::string &s, 11828ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasOpSizePrefix) { 11838ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan if(!hasOpSizePrefix) { 11848ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // For instructions without an OpSize prefix, a declared 16-bit register or 11858ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan // immediate encoding is special. 11868ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i16imm", ENCODING_IW) 11878ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan } 11888ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i16imm", ENCODING_Iv) 11898ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i16i8imm", ENCODING_IB) 11908ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i32imm", ENCODING_Iv) 11918ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i32i8imm", ENCODING_IB) 11928ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i64i32imm", ENCODING_ID) 11938ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i64i8imm", ENCODING_IB) 11948ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i8imm", ENCODING_IB) 11958ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i64i32imm_pcrel", ENCODING_ID) 11969fc05227a2596c545b845ed9a72673995e49d16bChris Lattner ENCODING("i16imm_pcrel", ENCODING_IW) 11978ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i32imm_pcrel", ENCODING_ID) 11988ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("brtarget", ENCODING_Iv) 11998ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("brtarget8", ENCODING_IB) 12008ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("i64imm", ENCODING_IO) 12018ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("offset8", ENCODING_Ia) 12028ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("offset16", ENCODING_Ia) 12038ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("offset32", ENCODING_Ia) 12048ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("offset64", ENCODING_Ia) 12058ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan errs() << "Unhandled relocation encoding " << s << "\n"; 12068ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Unhandled relocation encoding"); 12078ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 12088ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan 12098ed9f51663bc5533f36ca62e5668ae08e9a1313fSean CallananOperandEncoding RecognizableInstr::opcodeModifierEncodingFromString 12108ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan (const std::string &s, 12118ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan bool hasOpSizePrefix) { 12128ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("RST", ENCODING_I) 12138ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR32", ENCODING_Rv) 12148ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR64", ENCODING_RO) 12158ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR16", ENCODING_Rv) 12168ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan ENCODING("GR8", ENCODING_RB) 12177ea16b01fad5236cc132cb5fc3e443fcbf70d3b8Craig Topper ENCODING("GR16_NOAX", ENCODING_Rv) 12187ea16b01fad5236cc132cb5fc3e443fcbf70d3b8Craig Topper ENCODING("GR32_NOAX", ENCODING_Rv) 12197ea16b01fad5236cc132cb5fc3e443fcbf70d3b8Craig Topper ENCODING("GR64_NOAX", ENCODING_RO) 12208ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan errs() << "Unhandled opcode modifier encoding " << s << "\n"; 12218ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan llvm_unreachable("Unhandled opcode modifier encoding"); 12228ed9f51663bc5533f36ca62e5668ae08e9a1313fSean Callanan} 12239e6d1d1f5034347d237941f1bf08fba5c1583cd3Daniel Dunbar#undef ENCODING 1224