X86RecognizableInstr.cpp revision c266600bec4b5ba0ee93ffdfeaafcab8f1295145
15b955920c1d8f2cd35aae3c85b656578286a8bc1Anders Carlsson//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===// 25d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 35d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// The LLVM Compiler Infrastructure 45d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 55d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This file is distributed under the University of Illinois Open Source 65d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// License. See LICENSE.TXT for details. 75d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 85d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson//===----------------------------------------------------------------------===// 95d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// 105d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// This file is part of the X86 Disassembler Emitter. 115d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// It contains the implementation of a single recognizable instruction. 125d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// Documentation for the disassembler emitter in general can be found in 135d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson// X86DisasemblerEmitter.h. 1464bee65a3436e3f0c352fcfe2130676f3502cffeEli Friedman// 15d67ef0eed463b43980f04a444155f423114be34bDevang Patel//===----------------------------------------------------------------------===// 1656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 175d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#include "X86DisassemblerShared.h" 182f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson#include "X86RecognizableInstr.h" 197e1dff7a68a4d00e71debafa7f5c259473091746John McCall#include "X86ModRMFilters.h" 205d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall#include "llvm/Support/ErrorHandling.h" 2256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 233ee36af5bbb8c2cd203a140c3785215539cd56b4Devang Patel#include <string> 242f1986b557fa671c4f8c9dd0d071398edfc073d5Anders Carlsson 255d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlssonusing namespace llvm; 265d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 275d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson#define MRM_MAPPING \ 2855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck MAP(C1, 33) \ 2934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MAP(C2, 34) \ 3034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MAP(C3, 35) \ 31f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall MAP(C4, 36) \ 32f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall MAP(C8, 37) \ 3355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck MAP(C9, 38) \ 3434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MAP(E8, 39) \ 3534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MAP(F0, 40) \ 3634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MAP(F8, 41) \ 37f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall MAP(F9, 42) 3834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 3934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson// A clone of X86 since we can't depend on something that is generated. 4034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlssonnamespace X86Local { 4134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson enum { 4234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Pseudo = 0, 4334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson RawFrm = 1, 4434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson AddRegFrm = 2, 4534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MRMDestReg = 3, 4634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MRMDestMem = 4, 4734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MRMSrcReg = 5, 4855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck MRMSrcMem = 6, 4934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19, 5034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23, 5134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27, 5234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31, 5355c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck MRMInitReg = 32, 5434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson#define MAP(from, to) MRM_##from = to, 555d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson MRM_MAPPING 5684080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson#undef MAP 57a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson RawFrmImm8 = 43, 58f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall RawFrmImm16 = 44, 59f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall lastMRM 60f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall }; 61a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson 6255c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck enum { 63f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall TB = 1, 64f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall REP = 2, 6555c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck D8 = 3, D9 = 4, DA = 5, DB = 6, 66a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson DC = 7, DD = 8, DE = 9, DF = 10, 67a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson XD = 11, XS = 12, 682acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner T8 = 13, P_TA = 14, 69a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson P_0F_AE = 16, P_0F_01 = 17 70a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson }; 7155c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck} 7284080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson 7384080ec16ede6a6fe85a1d991690c6bda82a59eeAnders Carlsson// If rows are added to the opcode extension tables, then corresponding entries 748561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// must be added here. 75bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// 76bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// If the row corresponds to a single byte (i.e., 8f), then add an entry for 77bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// that byte to ONE_BYTE_EXTENSION_TABLES. 78bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// 79bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// If the row corresponds to two bytes where the first is 0f, add an entry for 808561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// the second byte to TWO_BYTE_EXTENSION_TABLES. 818561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// 828561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// If the row corresponds to some other set of bytes, you will need to modify 838561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson// the code in RecognizableInstr::emitDecodePath() as well, and add new prefixes 84bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// to the X86 TD files, except in two cases: if the first two bytes of such a 85bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// new combination are 0f 38 or 0f 3a, you just have to add maps called 86bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// THREE_BYTE_38_EXTENSION_TABLES and THREE_BYTE_3A_EXTENSION_TABLES and add a 87bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// switch(Opcode) just below the case X86Local::T8: or case X86Local::TA: line 88bff225ecf77fb891596ecb1b27196310d268365eJohn McCall// in RecognizableInstr::emitDecodePath(). 89bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 905fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck#define ONE_BYTE_EXTENSION_TABLES \ 91bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(80) \ 928561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson EXTENSION_TABLE(81) \ 935fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck EXTENSION_TABLE(82) \ 94bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(83) \ 955fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck EXTENSION_TABLE(8f) \ 96bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(c0) \ 97bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(c1) \ 98bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(c6) \ 99bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(c7) \ 1005fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck EXTENSION_TABLE(d0) \ 101bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(d1) \ 1025fff46b65389f7e7eb576e47c7bc3ca67326a206Ken Dyck EXTENSION_TABLE(d2) \ 103bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(d3) \ 104bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(f6) \ 105bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(f7) \ 106bff225ecf77fb891596ecb1b27196310d268365eJohn McCall EXTENSION_TABLE(fe) \ 107d103f9f9b401b419e756f8c1849683cd77586067Anders Carlsson EXTENSION_TABLE(ff) 108bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 1099dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson#define TWO_BYTE_EXTENSION_TABLES \ 1107916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(00) \ 1117916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(01) \ 1127916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(18) \ 1137916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(71) \ 1147916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(72) \ 1157916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(73) \ 1167916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(ae) \ 1177916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(ba) \ 1187916c997127fe616ba255ba4cade10e5de0c8812John McCall EXTENSION_TABLE(c7) 1197916c997127fe616ba255ba4cade10e5de0c8812John McCall 1207916c997127fe616ba255ba4cade10e5de0c8812John McCallusing namespace X86Disassembler; 1217916c997127fe616ba255ba4cade10e5de0c8812John McCall 1227916c997127fe616ba255ba4cade10e5de0c8812John McCall/// needsModRMForDecode - Indicates whether a particular instruction requires a 1237916c997127fe616ba255ba4cade10e5de0c8812John McCall/// ModR/M byte for the instruction to be properly decoded. For example, a 1247916c997127fe616ba255ba4cade10e5de0c8812John McCall/// MRMDestReg instruction needs the Mod field in the ModR/M byte to be set to 1257916c997127fe616ba255ba4cade10e5de0c8812John McCall/// 0b11. 1267916c997127fe616ba255ba4cade10e5de0c8812John McCall/// 1279dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson/// @param form - The form of the instruction. 1289dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson/// @return - true if the form implies that a ModR/M byte is required, false 1297916c997127fe616ba255ba4cade10e5de0c8812John McCall/// otherwise. 1307916c997127fe616ba255ba4cade10e5de0c8812John McCallstatic bool needsModRMForDecode(uint8_t form) { 1317916c997127fe616ba255ba4cade10e5de0c8812John McCall if (form == X86Local::MRMDestReg || 1329dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson form == X86Local::MRMDestMem || 1339dc228a1b971aa884766a9bdfdf5fa8ee4730b5bAnders Carlsson form == X86Local::MRMSrcReg || 1345d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson form == X86Local::MRMSrcMem || 13534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson (form >= X86Local::MRM0r && form <= X86Local::MRM7r) || 1368561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson (form >= X86Local::MRM0m && form <= X86Local::MRM7m)) 137f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall return true; 138f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall else 13934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return false; 140f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall} 14134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 142f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall/// isRegFormat - Indicates whether a particular form requires the Mod field of 14334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson/// the ModR/M byte to be 0b11. 14434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson/// 1457916c997127fe616ba255ba4cade10e5de0c8812John McCall/// @param form - The form of the instruction. 1467916c997127fe616ba255ba4cade10e5de0c8812John McCall/// @return - true if the form implies that Mod must be 0b11, false 1477916c997127fe616ba255ba4cade10e5de0c8812John McCall/// otherwise. 1487916c997127fe616ba255ba4cade10e5de0c8812John McCallstatic bool isRegFormat(uint8_t form) { 14934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson if (form == X86Local::MRMDestReg || 15034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson form == X86Local::MRMSrcReg || 15134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson (form >= X86Local::MRM0r && form <= X86Local::MRM7r)) 15234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return true; 15334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson else 1547916c997127fe616ba255ba4cade10e5de0c8812John McCall return false; 1557916c997127fe616ba255ba4cade10e5de0c8812John McCall} 1567916c997127fe616ba255ba4cade10e5de0c8812John McCall 1577916c997127fe616ba255ba4cade10e5de0c8812John McCall/// byteFromBitsInit - Extracts a value at most 8 bits in width from a BitsInit. 15855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck/// Useful for switch statements and the like. 1598561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson/// 160f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall/// @param init - A reference to the BitsInit to be decoded. 16134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson/// @return - The field, with the first bit in the BitsInit as the lowest 1627916c997127fe616ba255ba4cade10e5de0c8812John McCall/// order bit. 1637916c997127fe616ba255ba4cade10e5de0c8812John McCallstatic uint8_t byteFromBitsInit(BitsInit &init) { 1647916c997127fe616ba255ba4cade10e5de0c8812John McCall int width = init.getNumBits(); 1657916c997127fe616ba255ba4cade10e5de0c8812John McCall 1667916c997127fe616ba255ba4cade10e5de0c8812John McCall assert(width <= 8 && "Field is too large for uint8_t!"); 1677916c997127fe616ba255ba4cade10e5de0c8812John McCall 1687916c997127fe616ba255ba4cade10e5de0c8812John McCall int index; 1697916c997127fe616ba255ba4cade10e5de0c8812John McCall uint8_t mask = 0x01; 1707916c997127fe616ba255ba4cade10e5de0c8812John McCall 1717916c997127fe616ba255ba4cade10e5de0c8812John McCall uint8_t ret = 0; 17234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 1732acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner for (index = 0; index < width; index++) { 174f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall if (static_cast<BitInit*>(init.getBit(index))->getValue()) 1757916c997127fe616ba255ba4cade10e5de0c8812John McCall ret |= mask; 1767916c997127fe616ba255ba4cade10e5de0c8812John McCall 1777916c997127fe616ba255ba4cade10e5de0c8812John McCall mask <<= 1; 17855c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck } 17934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 18034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return ret; 1817916c997127fe616ba255ba4cade10e5de0c8812John McCall} 1827916c997127fe616ba255ba4cade10e5de0c8812John McCall 1837916c997127fe616ba255ba4cade10e5de0c8812John McCall/// byteFromRec - Extract a value at most 8 bits in with from a Record given the 18434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson/// name of the field. 1857916c997127fe616ba255ba4cade10e5de0c8812John McCall/// 1867916c997127fe616ba255ba4cade10e5de0c8812John McCall/// @param rec - The record from which to extract the value. 18734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson/// @param name - The name of the field in the record. 1887916c997127fe616ba255ba4cade10e5de0c8812John McCall/// @return - The field, as translated by byteFromBitsInit(). 1897916c997127fe616ba255ba4cade10e5de0c8812John McCallstatic uint8_t byteFromRec(const Record* rec, const std::string &name) { 1907916c997127fe616ba255ba4cade10e5de0c8812John McCall BitsInit* bits = rec->getValueAsBitsInit(name); 19134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson return byteFromBitsInit(*bits); 1927916c997127fe616ba255ba4cade10e5de0c8812John McCall} 1937916c997127fe616ba255ba4cade10e5de0c8812John McCall 1947916c997127fe616ba255ba4cade10e5de0c8812John McCallRecognizableInstr::RecognizableInstr(DisassemblerTables &tables, 19534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson const CodeGenInstruction &insn, 19634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson InstrUID uid) { 1977916c997127fe616ba255ba4cade10e5de0c8812John McCall UID = uid; 19834a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 199336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson Rec = insn.TheDef; 2007916c997127fe616ba255ba4cade10e5de0c8812John McCall Name = Rec->getName(); 201336a7dc56871ccfeceecc296c9624f66f7ac01ecAnders Carlsson Spec = &tables.specForUID(UID); 20234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2037916c997127fe616ba255ba4cade10e5de0c8812John McCall if (!Rec->isSubClassOf("X86Inst")) { 20455c02585de7b02bcb72352f731d9bc342c8282f3Ken Dyck ShouldBeEmitted = false; 2059a8ad9b28d54a3adc4cb8061d564f99f80144e30Ken Dyck return; 20634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson } 20734a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2087916c997127fe616ba255ba4cade10e5de0c8812John McCall Prefix = byteFromRec(Rec, "Prefix"); 20934a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Opcode = byteFromRec(Rec, "Opcode"); 2107916c997127fe616ba255ba4cade10e5de0c8812John McCall Form = byteFromRec(Rec, "FormBits"); 2117916c997127fe616ba255ba4cade10e5de0c8812John McCall SegOvr = byteFromRec(Rec, "SegOvrBits"); 21234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 2137916c997127fe616ba255ba4cade10e5de0c8812John McCall HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix"); 2147916c997127fe616ba255ba4cade10e5de0c8812John McCall HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix"); 2157916c997127fe616ba255ba4cade10e5de0c8812John McCall HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix"); 21634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson HasLockPrefix = Rec->getValueAsBit("hasLockPrefix"); 2177916c997127fe616ba255ba4cade10e5de0c8812John McCall IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); 2187916c997127fe616ba255ba4cade10e5de0c8812John McCall 2197916c997127fe616ba255ba4cade10e5de0c8812John McCall Name = Rec->getName(); 22034a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson AsmString = Rec->getValueAsString("AsmString"); 22134a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 22234a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson Operands = &insn.Operands.OperandList; 22334a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 22434a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson IsSSE = HasOpSizePrefix && (Name.find("16") == Name.npos); 22534a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson HasFROperands = false; 22634a2d384c745ebc39cae45dc1c0c4a6a7012e09bAnders Carlsson 227a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson ShouldBeEmitted = true; 2288561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson} 229f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall 230f871d0cc377a1367b519a6cce26be74607566ebaJohn McCallvoid RecognizableInstr::processInstr(DisassemblerTables &tables, 231a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson const CodeGenInstruction &insn, 232f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall InstrUID uid) 233a04efdf635d35d88e65041fad007225d8c8d64a5Anders Carlsson{ 234a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Ignore "asm parser only" instructions. 2358561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson if (insn.TheDef->getValueAsBit("isAsmParserOnly")) 2362acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner return; 237c764830bdb6de82baed068889096bd3e52d4cbdaRichard Smith 238a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson RecognizableInstr recogInstr(tables, insn, uid); 239f871d0cc377a1367b519a6cce26be74607566ebaJohn McCall 240a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson recogInstr.emitInstructionSpecifier(tables); 241a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 242a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson if (recogInstr.shouldBeEmitted()) 243a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson recogInstr.emitDecodePath(tables); 244a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson} 245a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson 246a3697c9c155bda93fd2802f37084b620f4738822Anders CarlssonInstructionContext RecognizableInstr::insnContext() const { 247a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson InstructionContext insnContext; 248a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 249a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (Name.find("64") != Name.npos || HasREX_WPrefix) { 250a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (HasREX_WPrefix && HasOpSizePrefix) 251a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson insnContext = IC_64BIT_REXW_OPSIZE; 252a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson else if (HasOpSizePrefix) 253a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson insnContext = IC_64BIT_OPSIZE; 254a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson else if (HasREX_WPrefix && Prefix == X86Local::XS) 255b924124316becf2968a37dab36d0c48ea167666fAnders Carlsson insnContext = IC_64BIT_REXW_XS; 256a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson else if (HasREX_WPrefix && Prefix == X86Local::XD) 257a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson insnContext = IC_64BIT_REXW_XD; 258a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson else if (Prefix == X86Local::XD) 259a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson insnContext = IC_64BIT_XD; 260a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson else if (Prefix == X86Local::XS) 261c5685438df6105052b02c9e02f01c34489606308Eli Friedman insnContext = IC_64BIT_XS; 262c5685438df6105052b02c9e02f01c34489606308Eli Friedman else if (HasREX_WPrefix) 263c5685438df6105052b02c9e02f01c34489606308Eli Friedman insnContext = IC_64BIT_REXW; 264a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson else 265a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson insnContext = IC_64BIT; 266a552ea76b0e4ce4ccdbb845667f0a12da6608c52Anders Carlsson } else { 267a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson if (HasOpSizePrefix) 268a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson insnContext = IC_OPSIZE; 269a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson else if (Prefix == X86Local::XD) 270a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson insnContext = IC_XD; 271a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson else if (Prefix == X86Local::XS) 272a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson insnContext = IC_XS; 273a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson else 274bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad insnContext = IC; 275a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson } 276a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson 27732baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson return insnContext; 278a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson} 27932baf62b9a3aea3b63be6925b64aa182b0a2278eAnders Carlsson 2805d58a1d50e2644668122b8efb6b603a706ecfd6bAnders CarlssonRecognizableInstr::filter_ret RecognizableInstr::filter() const { 281a3697c9c155bda93fd2802f37084b620f4738822Anders Carlsson // Filter out intrinsics 2825d58a1d50e2644668122b8efb6b603a706ecfd6bAnders Carlsson 28321c9ad9d29d08a287292c670e7c52bc522c7f8bbAnders Carlsson if (!Rec->isSubClassOf("X86Inst")) 284c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return FILTER_STRONG; 285c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 286314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson if (Form == X86Local::Pseudo || 287378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor IsCodeGenOnly) 288378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor return FILTER_STRONG; 289af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson 290c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (Form == X86Local::MRMInitReg) 291c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return FILTER_STRONG; 292c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 293c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 294c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // Filter out instructions with a LOCK prefix; 295c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson // prefer forms that do not have the prefix 2963b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (HasLockPrefix) 297c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return FILTER_WEAK; 298c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson 2993b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall // Filter out artificial instructions 3003b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall 301378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor if (Name.find("TAILJMP") != Name.npos || 302378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor Name.find("_Int") != Name.npos || 303378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor Name.find("_int") != Name.npos || 304378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor Name.find("Int_") != Name.npos || 305378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor Name.find("_NOREX") != Name.npos || 306378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor Name.find("_TC") != Name.npos || 307af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson Name.find("EH_RETURN") != Name.npos || 3083b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall Name.find("V_SET") != Name.npos || 309314e622d20e67ad2f9bd3e3d4473fb23bec93132Anders Carlsson Name.find("LOCK_") != Name.npos || 3103b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall Name.find("WIN") != Name.npos) 3113b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return FILTER_STRONG; 312c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson 313c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson // Special cases. 3144230d529a8797bbeef2328b60abeae333f7e143fKen Dyck 3154230d529a8797bbeef2328b60abeae333f7e143fKen Dyck if (Name.find("PCMPISTRI") != Name.npos && Name != "PCMPISTRI") 3164230d529a8797bbeef2328b60abeae333f7e143fKen Dyck return FILTER_WEAK; 317c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson if (Name.find("PCMPESTRI") != Name.npos && Name != "PCMPESTRI") 318c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson return FILTER_WEAK; 319c11bb2191088b9e74bec5007a4e05c78b41a8f64Anders Carlsson 3203b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall if (Name.find("MOV") != Name.npos && Name.find("r0") != Name.npos) 3213b47733ceac33306bd54ce9d6c7d8eeeae52c7caJohn McCall return FILTER_WEAK; 322c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (Name.find("MOVZ") != Name.npos && Name.find("MOVZX") == Name.npos) 323af4403545a50a60d208e6fcae057308d576a92e0Anders Carlsson return FILTER_WEAK; 324c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (Name.find("Fs") != Name.npos) 325c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson return FILTER_WEAK; 326c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson if (Name == "MOVLPDrr" || 327c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Name == "MOVLPSrr" || 328c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Name == "PUSHFQ" || 3291cbce125b91cad81c8be3f8bbae8df917211176cAnders Carlsson Name == "BSF16rr" || 330c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Name == "BSF16rm" || 331c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Name == "BSR16rr" || 332c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Name == "BSR16rm" || 333c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Name == "MOVSX16rm8" || 334c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Name == "MOVSX16rr8" || 335c997d4278d329e18891aac9698fb991b2d4622ebAnders Carlsson Name == "MOVZX16rm8" || 336182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall Name == "MOVZX16rr8" || 33750da2cadcc6da86abff6772de65280ace2cabc94John McCall Name == "PUSH32i16" || 3381f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall Name == "PUSH64i16" || 33950da2cadcc6da86abff6772de65280ace2cabc94John McCall Name == "MOVPQI2QImr" || 34050da2cadcc6da86abff6772de65280ace2cabc94John McCall Name == "MOVSDmr" || 34150da2cadcc6da86abff6772de65280ace2cabc94John McCall Name == "MOVSDrm" || 34250da2cadcc6da86abff6772de65280ace2cabc94John McCall Name == "MOVSSmr" || 343182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall Name == "MOVSSrm" || 344ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall Name == "MMX_MOVD64rrv164" || 34550da2cadcc6da86abff6772de65280ace2cabc94John McCall Name == "CRC32m16" || 34650da2cadcc6da86abff6772de65280ace2cabc94John McCall Name == "MOV64ri64i32" || 34750da2cadcc6da86abff6772de65280ace2cabc94John McCall Name == "CRC32r16") 34850da2cadcc6da86abff6772de65280ace2cabc94John McCall return FILTER_WEAK; 34950da2cadcc6da86abff6772de65280ace2cabc94John McCall 35050da2cadcc6da86abff6772de65280ace2cabc94John McCall // Filter out instructions with segment override prefixes. 35150da2cadcc6da86abff6772de65280ace2cabc94John McCall // They're too messy to handle now and we'll special case them if needed. 35250da2cadcc6da86abff6772de65280ace2cabc94John McCall 353378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor if (SegOvr) 354378e1e739aed97e9b278beeb20e9f5bbe34c0232Douglas Gregor return FILTER_STRONG; 355182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 356182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall // Filter out instructions that can't be printed. 3577e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3587e1dff7a68a4d00e71debafa7f5c259473091746John McCall if (AsmString.size() == 0) 3597e1dff7a68a4d00e71debafa7f5c259473091746John McCall return FILTER_STRONG; 3607e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3617e1dff7a68a4d00e71debafa7f5c259473091746John McCall // Filter out instructions with subreg operands. 3627e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3637e1dff7a68a4d00e71debafa7f5c259473091746John McCall if (AsmString.find("subreg") != AsmString.npos) 3647e1dff7a68a4d00e71debafa7f5c259473091746John McCall return FILTER_STRONG; 3657e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3667e1dff7a68a4d00e71debafa7f5c259473091746John McCall if (HasFROperands && Name.find("MOV") != Name.npos && 3677e1dff7a68a4d00e71debafa7f5c259473091746John McCall ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) || 3687e1dff7a68a4d00e71debafa7f5c259473091746John McCall (Name.find("to") != Name.npos))) 3697e1dff7a68a4d00e71debafa7f5c259473091746John McCall return FILTER_WEAK; 3707e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3717e1dff7a68a4d00e71debafa7f5c259473091746John McCall return FILTER_NORMAL; 3727e1dff7a68a4d00e71debafa7f5c259473091746John McCall} 3737e1dff7a68a4d00e71debafa7f5c259473091746John McCall 3747e1dff7a68a4d00e71debafa7f5c259473091746John McCallvoid RecognizableInstr::handleOperand( 3757e1dff7a68a4d00e71debafa7f5c259473091746John McCall bool optional, 3767e1dff7a68a4d00e71debafa7f5c259473091746John McCall unsigned &operandIndex, 3777e1dff7a68a4d00e71debafa7f5c259473091746John McCall unsigned &physicalOperandIndex, 3787e1dff7a68a4d00e71debafa7f5c259473091746John McCall unsigned &numPhysicalOperands, 3797e1dff7a68a4d00e71debafa7f5c259473091746John McCall unsigned *operandMapping, 380182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall OperandEncoding (*encodingFromString)(const std::string&, bool hasOpSizePrefix)) { 381182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall if (optional) { 382607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (physicalOperandIndex >= numPhysicalOperands) 383607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson return; 384cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt } else { 385607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson assert(physicalOperandIndex < numPhysicalOperands); 386607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 387607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 388607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson while (operandMapping[operandIndex] != operandIndex) { 389607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Spec->operands[operandIndex].encoding = ENCODING_DUP; 390607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Spec->operands[operandIndex].type = 391607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson (OperandType)(TYPE_DUP0 + operandMapping[operandIndex]); 392607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson ++operandIndex; 393607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson } 394607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 39580638c5e6395344c1e6096542b0ff3b8bfb2139eAnders Carlsson const std::string &typeName = (*Operands)[operandIndex].Rec->getName(); 396607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 397607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Spec->operands[operandIndex].encoding = encodingFromString(typeName, 398607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson HasOpSizePrefix); 399607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson Spec->operands[operandIndex].type = typeFromString(typeName, 400607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson IsSSE, 4017e1dff7a68a4d00e71debafa7f5c259473091746John McCall HasREX_WPrefix, 4027e1dff7a68a4d00e71debafa7f5c259473091746John McCall HasOpSizePrefix); 4037e1dff7a68a4d00e71debafa7f5c259473091746John McCall 4047e1dff7a68a4d00e71debafa7f5c259473091746John McCall ++operandIndex; 4057e1dff7a68a4d00e71debafa7f5c259473091746John McCall ++physicalOperandIndex; 4067e1dff7a68a4d00e71debafa7f5c259473091746John McCall} 407bff225ecf77fb891596ecb1b27196310d268365eJohn McCall 408bff225ecf77fb891596ecb1b27196310d268365eJohn McCallvoid RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { 4098561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson Spec->name = Name; 4108561a8666c70f924c8f0209c41b9b77bbbf90607Anders Carlsson 41150da2cadcc6da86abff6772de65280ace2cabc94John McCall if (!Rec->isSubClassOf("X86Inst")) 41250da2cadcc6da86abff6772de65280ace2cabc94John McCall return; 413d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman 4147c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall switch (filter()) { 415f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman case FILTER_WEAK: 4167c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall Spec->filtered = true; 417410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall break; 418649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier case FILTER_STRONG: 419558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall ShouldBeEmitted = false; 420558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall return; 421594d5e8bd9870080aad6a761538e272bc2dfcc13Anders Carlsson case FILTER_NORMAL: 4224e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie break; 423c1cfdf8647a499b6b3024f4bd14a236cddb23988Anders Carlsson } 4241f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall 4251f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall Spec->insnContext = insnContext(); 426607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson 427607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands; 428fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 429fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned operandIndex; 4300bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman unsigned numOperands = OperandList.size(); 431fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned numPhysicalOperands = 0; 432fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 4330bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // operandMapping maps from operands in OperandList to their originals. 434fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // If operandMapping[i] != i, then the entry is a duplicate. 4350bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman unsigned operandMapping[X86_MAX_OPERANDS]; 436f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman 437924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl bool hasFROperands = false; 438924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 439924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl assert(numOperands < X86_MAX_OPERANDS && "X86_MAX_OPERANDS is not large enough"); 440924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 441924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) { 442924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (OperandList[operandIndex].Constraints.size()) { 443924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl const CGIOperandList::ConstraintInfo &Constraint = 444924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl OperandList[operandIndex].Constraints[0]; 445924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (Constraint.isTied()) { 446924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl operandMapping[operandIndex] = Constraint.getTiedOperand(); 447924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } else { 448924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl ++numPhysicalOperands; 449924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl operandMapping[operandIndex] = operandIndex; 450924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 451924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } else { 452924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl ++numPhysicalOperands; 453924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl operandMapping[operandIndex] = operandIndex; 454924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 455924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 456924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl const std::string &recName = OperandList[operandIndex].Rec->getName(); 457924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 458924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (recName.find("FR") != recName.npos) 459924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl hasFROperands = true; 460924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl } 461924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 462924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (hasFROperands && Name.find("MOV") != Name.npos && 463924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl ((Name.find("2") != Name.npos && Name.find("32") == Name.npos) || 464924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl (Name.find("to") != Name.npos))) 465924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl ShouldBeEmitted = false; 466649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier 467924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl if (!ShouldBeEmitted) 468924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl return; 469924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl 470fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor#define HANDLE_OPERAND(class) \ 471558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall handleOperand(false, \ 472924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl operandIndex, \ 473924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl physicalOperandIndex, \ 474972edf0534d8a50f87fac1d0ff34eb22f593df11Sebastian Redl numPhysicalOperands, \ 475924db71fc8f6076c532c8c2ae93acc7f477452c8Sebastian Redl operandMapping, \ 476fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor class##EncodingFromString); 477fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 478fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor#define HANDLE_OPTIONAL(class) \ 479fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor handleOperand(true, \ 480fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor operandIndex, \ 481fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor physicalOperandIndex, \ 4820bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman numPhysicalOperands, \ 483fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor operandMapping, \ 484fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor class##EncodingFromString); 485fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 486fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // operandIndex should always be < numOperands 487fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor operandIndex = 0; 488fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // physicalOperandIndex should always be < numPhysicalOperands 489fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor unsigned physicalOperandIndex = 0; 490fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 491fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor switch (Form) { 492fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor case X86Local::RawFrm: 493fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 1 (optional) is an address or immediate. 494fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 2 (optional) is an immediate. 495fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(numPhysicalOperands <= 2 && 496fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "Unexpected number of operands for RawFrm"); 497fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPTIONAL(relocation) 498fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPTIONAL(immediate) 499fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor break; 500fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor case X86Local::AddRegFrm: 501fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 1 is added to the opcode. 502985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner // Operand 2 (optional) is an address. 503985f73960ac76842da4b10c30ca87a282ff9aa31Chris Lattner assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 504fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "Unexpected number of operands for AddRegFrm"); 505fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPERAND(opcodeModifier) 506fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPTIONAL(relocation) 507fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor break; 508fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor case X86Local::MRMDestReg: 509fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 1 is a register operand in the R/M field. 510fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 2 is a register operand in the Reg/Opcode field. 511fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 3 (optional) is an immediate. 512fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 513fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "Unexpected number of operands for MRMDestRegFrm"); 514f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall HANDLE_OPERAND(rmRegister) 515fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPERAND(roRegister) 516fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPTIONAL(immediate) 517fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor break; 5180bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman case X86Local::MRMDestMem: 5190bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Operand 1 is a memory operand (possibly SIB-extended) 520fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 2 is a register operand in the Reg/Opcode field. 521fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 3 (optional) is an immediate. 522fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 523fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "Unexpected number of operands for MRMDestMemFrm"); 524fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPERAND(memory) 525fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPERAND(roRegister) 526fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPTIONAL(immediate) 527fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor break; 528fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor case X86Local::MRMSrcReg: 529fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 1 is a register operand in the Reg/Opcode field. 530fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 2 is a register operand in the R/M field. 531fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Operand 3 (optional) is an immediate. 532fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 533fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor "Unexpected number of operands for MRMSrcRegFrm"); 534fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPERAND(roRegister) 535fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPERAND(rmRegister) 536182ab5112650d3228291c4dadd64a9f77f5aeb51John McCall 537607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson if (HasVEX_4VPrefix) 538607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // FIXME: In AVX, the register below becomes the one encoded 539cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt // in ModRMVEX and the one above the one in the VEX.VVVV field 540fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor HANDLE_OPTIONAL(rmRegister) 541fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor else 54200eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet HANDLE_OPTIONAL(immediate) 543607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson break; 5447a614d8380297fcd2bc23986241905d97222948cRichard Smith case X86Local::MRMSrcMem: 545607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Operand 1 is a register operand in the Reg/Opcode field. 546607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Operand 2 is a memory operand (possibly SIB-extended) 54700eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet // Operand 3 (optional) is an immediate. 5480bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && 549607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson "Unexpected number of operands for MRMSrcMemFrm"); 550607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson HANDLE_OPERAND(roRegister) 551377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman 552859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman if (HasVEX_4VPrefix) 553377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman // FIXME: In AVX, the register below becomes the one encoded 55400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet // in ModRMVEX and the one above the one in the VEX.VVVV field 555859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman HANDLE_OPTIONAL(rmRegister) 556859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman 557859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman HANDLE_OPERAND(memory) 558859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman HANDLE_OPTIONAL(immediate) 559859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman break; 560859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman case X86Local::MRM0r: 561859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman case X86Local::MRM1r: 56200eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet case X86Local::MRM2r: 563a9976d3b192690db20f59dc44099ac4ca939bdb7John McCall case X86Local::MRM3r: 564859c65cdbe730fd0e940b71ab4ba4884d44a8298Eli Friedman case X86Local::MRM4r: 565607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson case X86Local::MRM5r: 566607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson case X86Local::MRM6r: 5670bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman case X86Local::MRM7r: 5680bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Operand 1 is a register operand in the R/M field. 5690bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Operand 2 (optional) is an immediate or relocation. 5700bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman assert(numPhysicalOperands <= 2 && 5710bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman "Unexpected number of operands for MRMnRFrm"); 5720bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman HANDLE_OPTIONAL(rmRegister) 5730bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman HANDLE_OPTIONAL(relocation) 5740bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman break; 5750bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman case X86Local::MRM0m: 5760bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman case X86Local::MRM1m: 577e9385363069388d8e3536052a138f17332e00620Richard Smith case X86Local::MRM2m: 5780bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman case X86Local::MRM3m: 579e9385363069388d8e3536052a138f17332e00620Richard Smith case X86Local::MRM4m: 580e9385363069388d8e3536052a138f17332e00620Richard Smith case X86Local::MRM5m: 581e9385363069388d8e3536052a138f17332e00620Richard Smith case X86Local::MRM6m: 5820bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman case X86Local::MRM7m: 5830bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Operand 1 is a memory operand (possibly SIB-extended) 5840bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // Operand 2 (optional) is an immediate or relocation. 585377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman assert(numPhysicalOperands >= 1 && numPhysicalOperands <= 2 && 586377ecc7996dce6803f7b7b6208cab5e197c9c5b8Eli Friedman "Unexpected number of operands for MRMnMFrm"); 5870bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman HANDLE_OPERAND(memory) 5880bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman HANDLE_OPTIONAL(relocation) 5890bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman break; 590649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier case X86Local::RawFrmImm8: 5910bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // operand 1 is a 16-bit immediate 5920bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // operand 2 is an 8-bit immediate 5930bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman assert(numPhysicalOperands == 2 && 5940bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman "Unexpected number of operands for X86Local::RawFrmImm8"); 5950bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman HANDLE_OPERAND(immediate) 5960bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman HANDLE_OPERAND(immediate) 5970bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman break; 598b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman case X86Local::RawFrmImm16: 5990bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // operand 1 is a 16-bit immediate 6000bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman // operand 2 is a 16-bit immediate 601b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman HANDLE_OPERAND(immediate) 602b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman HANDLE_OPERAND(immediate) 603b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman break; 6040bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman case X86Local::MRMInitReg: 605b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman // Ignored. 606f85e193739c953358c865005855253af4f68a497John McCall break; 607b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman } 608f85e193739c953358c865005855253af4f68a497John McCall 609b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman #undef HANDLE_OPERAND 610b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman #undef HANDLE_OPTIONAL 611f85e193739c953358c865005855253af4f68a497John McCall} 6120bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman 613b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedmanvoid RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { 614607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson // Special cases where the LLVM tables are not complete 615fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 6160bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman#define MAP(from, to) \ 617b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman case X86Local::MRM_##from: \ 618fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor filter = new ExactFilter(0x##from); \ 619fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor break; 620fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor 621b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman OpcodeType opcodeType = (OpcodeType)-1; 622b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman 623fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor ModRMFilter* filter = NULL; 624b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman uint8_t opcodeToSet = 0; 625b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman 626b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman switch (Prefix) { 627fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor // Extended two-byte opcodes can start with f2 0f, f3 0f, or 0f 628fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor case X86Local::XD: 629fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor case X86Local::XS: 630b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman case X86Local::TB: 631fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor opcodeType = TWOBYTE; 632b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman 633fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor switch (Opcode) { 634fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor default: 635fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor if (needsModRMForDecode(Form)) 6360bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman filter = new ModFilter(isRegFormat(Form)); 637b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman else 638fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor filter = new DumbFilter(); 639fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor break; 640b74ed087469db042325bad76fdf3ff6ed67dec09Eli Friedman#define EXTENSION_TABLE(n) case 0x##n: 6410bdb5aa1a3384d194b0e14a9ecbe3309ff33daa3Eli Friedman TWO_BYTE_EXTENSION_TABLES 642607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson#undef EXTENSION_TABLE 643074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall switch (Form) { 644074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall default: 645074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall llvm_unreachable("Unhandled two-byte extended opcode"); 646074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall case X86Local::MRM0r: 647074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall case X86Local::MRM1r: 648074cae0861a87bf96d8ea56d02e34839d9ccbd0aJohn McCall case X86Local::MRM2r: 649607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson case X86Local::MRM3r: 650607d037c3f4376cbc8979d0eb9cd2f49a58ea033Anders Carlsson case X86Local::MRM4r: 651c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM5r: 652c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM6r: 653c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM7r: 654c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 655c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall break; 656c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM0m: 657c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM1m: 658c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM2m: 659c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM3m: 660c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM4m: 661c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM5m: 662c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM6m: 663c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM7m: 664c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 665c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall break; 666c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall MRM_MAPPING 667c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } // switch (Form) 668c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall break; 669c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } // switch (Opcode) 670c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall opcodeToSet = Opcode; 671c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall break; 672c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::T8: 673c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall opcodeType = THREEBYTE_38; 674c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (needsModRMForDecode(Form)) 675c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall filter = new ModFilter(isRegFormat(Form)); 676c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall else 677c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall filter = new DumbFilter(); 678c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall opcodeToSet = Opcode; 679c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall break; 680c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::P_TA: 681c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall opcodeType = THREEBYTE_3A; 682c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (needsModRMForDecode(Form)) 683c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall filter = new ModFilter(isRegFormat(Form)); 684c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall else 685c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall filter = new DumbFilter(); 686c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall opcodeToSet = Opcode; 687c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall break; 688c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::D8: 689c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::D9: 690c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::DA: 691c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::DB: 692059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt case X86Local::DC: 693059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt case X86Local::DD: 694059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt case X86Local::DE: 695059ce0d92eb5a7da900ae735dc0a2ea3d64f4b0bSean Hunt case X86Local::DF: 696c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode"); 697c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall opcodeType = ONEBYTE; 698c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall if (Form == X86Local::AddRegFrm) { 6999fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Spec->modifierType = MODIFIER_MODRM; 7009fc6a7774643a810c8501dae2323e863fefb623eJohn McCall Spec->modifierBase = Opcode; 7019fc6a7774643a810c8501dae2323e863fefb623eJohn McCall filter = new AddRegEscapeFilter(Opcode); 7029fc6a7774643a810c8501dae2323e863fefb623eJohn McCall } else { 7039fc6a7774643a810c8501dae2323e863fefb623eJohn McCall filter = new EscapeFilter(true, Opcode); 704c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall } 705c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall opcodeToSet = 0xd8 + (Prefix - X86Local::D8); 7068560791791e7b33249feb0ffafeca427076b37b4Timur Iskhodzhanov break; 707b8b2c9da87e7d70a1679db026f40548b3192b705John McCall default: 708d67ef0eed463b43980f04a444155f423114be34bDevang Patel opcodeType = ONEBYTE; 70973fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher switch (Opcode) { 710c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall#define EXTENSION_TABLE(n) case 0x##n: 711c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall ONE_BYTE_EXTENSION_TABLES 712c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall#undef EXTENSION_TABLE 713c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall switch (Form) { 7149fc6a7774643a810c8501dae2323e863fefb623eJohn McCall default: 7159fc6a7774643a810c8501dae2323e863fefb623eJohn McCall llvm_unreachable("Fell through the cracks of a single-byte " 716c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall "extended opcode"); 717c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM0r: 718c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM1r: 719c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM2r: 72059a7000a79118e4c140885ccbb2ac6a686a73092John McCall case X86Local::MRM3r: 7219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case X86Local::MRM4r: 722f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall case X86Local::MRM5r: 7239fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case X86Local::MRM6r: 72456ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall case X86Local::MRM7r: 72556ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall filter = new ExtendedFilter(true, Form - X86Local::MRM0r); 72656ea377bc58a3a821da917599ed26c6b37b9727cJohn McCall break; 727c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM0m: 728c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM1m: 729fb8cc253420e93cee33d29df5a2bdae6aaf16e39Douglas Gregor case X86Local::MRM2m: 7309fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case X86Local::MRM3m: 7319fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case X86Local::MRM4m: 732c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case X86Local::MRM5m: 7339fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case X86Local::MRM6m: 7349fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case X86Local::MRM7m: 7359fc6a7774643a810c8501dae2323e863fefb623eJohn McCall filter = new ExtendedFilter(false, Form - X86Local::MRM0m); 7369fc6a7774643a810c8501dae2323e863fefb623eJohn McCall break; 7379fc6a7774643a810c8501dae2323e863fefb623eJohn McCall MRM_MAPPING 7389fc6a7774643a810c8501dae2323e863fefb623eJohn McCall } // switch (Form) 7399fc6a7774643a810c8501dae2323e863fefb623eJohn McCall break; 7409fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case 0xd8: 741f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall case 0xd9: 7429fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case 0xda: 743c0bf462cf35fe050bddbd8bff967298e4a67e79dJohn McCall case 0xdb: 74459a7000a79118e4c140885ccbb2ac6a686a73092John McCall case 0xdc: 7459fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case 0xdd: 7469fc6a7774643a810c8501dae2323e863fefb623eJohn McCall case 0xde: 74756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames case 0xdf: 74856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames filter = new EscapeFilter(false, Form - X86Local::MRM0m); 74956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames break; 75056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames default: 75156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (needsModRMForDecode(Form)) 75256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames filter = new ModFilter(isRegFormat(Form)); 75356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames else 75456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames filter = new DumbFilter(); 75556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames break; 75656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } // switch (Opcode) 75756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames opcodeToSet = Opcode; 75856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } // switch (Prefix) 75956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 76056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(opcodeType != (OpcodeType)-1 && 76156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames "Opcode type not set"); 76256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(filter && "Filter not set"); 76356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 76456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (Form == X86Local::AddRegFrm) { 76556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if(Spec->modifierType != MODIFIER_MODRM) { 76656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames assert(opcodeToSet < 0xf9 && 76756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames "Not enough room for all ADDREG_FRM operands"); 76856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 76956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames uint8_t currentOpcode; 77056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 77156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames for (currentOpcode = opcodeToSet; 77256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames currentOpcode < opcodeToSet + 8; 77356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ++currentOpcode) 77456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames tables.setTableFields(opcodeType, 77556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames insnContext(), 77656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames currentOpcode, 77756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames *filter, 77856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UID); 77956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 78056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Spec->modifierType = MODIFIER_OPCODE; 78156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames Spec->modifierBase = opcodeToSet; 78256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else { 78356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // modifierBase was set where MODIFIER_MODRM was set 78456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames tables.setTableFields(opcodeType, 78556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames insnContext(), 78656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames opcodeToSet, 78756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames *filter, 78856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UID); 78956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 79056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } else { 7915e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames tables.setTableFields(opcodeType, 79256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames insnContext(), 79356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames opcodeToSet, 79456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames *filter, 79556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames UID); 79656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 7975e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Spec->modifierType = MODIFIER_NONE; 7985e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames Spec->modifierBase = opcodeToSet; 7995e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames } 8005e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames 8015e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames delete filter; 8025e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames 8035e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames#undef MAP 8045e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames} 8055e8577ece79b5ed07b0ab4dcb284a26076efdf65Lang Hames 80656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#define TYPE(str, type) if (s == str) return type; 80756c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandType RecognizableInstr::typeFromString(const std::string &s, 80856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool isSSE, 80956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool hasREX_WPrefix, 81056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool hasOpSizePrefix) { 81156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if (isSSE) { 81256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // For SSE instructions, we ignore the OpSize prefix and force operand 81356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // sizes. 81456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR16", TYPE_R16) 81556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR32", TYPE_R32) 81656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR64", TYPE_R64) 81756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 81856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if(hasREX_WPrefix) { 81956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // For instructions with a REX_W prefix, a declared 32-bit register encoding 82056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // is special. 82156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR32", TYPE_R32) 82256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 82356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if(!hasOpSizePrefix) { 82456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // For instructions without an OpSize prefix, a declared 16-bit register or 82556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // immediate encoding is special. 82656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR16", TYPE_R16) 82756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i16imm", TYPE_IMM16) 82856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 82956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i16mem", TYPE_Mv) 83056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i16imm", TYPE_IMMv) 83156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i16i8imm", TYPE_IMMv) 83256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR16", TYPE_Rv) 83356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i32mem", TYPE_Mv) 83456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i32imm", TYPE_IMMv) 83556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i32i8imm", TYPE_IMM32) 83656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR32", TYPE_Rv) 83756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i64mem", TYPE_Mv) 83856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i64i32imm", TYPE_IMM64) 83956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i64i8imm", TYPE_IMM64) 84056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR64", TYPE_R64) 84156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i8mem", TYPE_M8) 84256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i8imm", TYPE_IMM8) 84356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("GR8", TYPE_R8) 84456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("VR128", TYPE_XMM128) 84556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("f128mem", TYPE_M128) 84656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("f256mem", TYPE_M256) 84756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("FR64", TYPE_XMM64) 84856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("f64mem", TYPE_M64FP) 84956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("sdmem", TYPE_M64FP) 85056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("FR32", TYPE_XMM32) 85156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("f32mem", TYPE_M32FP) 85256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("ssmem", TYPE_M32FP) 85356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("RST", TYPE_ST) 85456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i128mem", TYPE_M128) 85556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i64i32imm_pcrel", TYPE_REL64) 85656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i16imm_pcrel", TYPE_REL16) 85756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i32imm_pcrel", TYPE_REL32) 85856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("SSECC", TYPE_IMM3) 85956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("brtarget", TYPE_RELv) 86056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("uncondbrtarget", TYPE_RELv) 86156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("brtarget8", TYPE_REL8) 86256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("f80mem", TYPE_M80FP) 86356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("lea32mem", TYPE_LEA) 86456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("lea64_32mem", TYPE_LEA) 86556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("lea64mem", TYPE_LEA) 86656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("VR64", TYPE_MM64) 86756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("i64imm", TYPE_IMMv) 86856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("opaque32mem", TYPE_M1616) 86956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("opaque48mem", TYPE_M1632) 87056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("opaque80mem", TYPE_M1664) 87156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("opaque512mem", TYPE_M512) 87256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("SEGMENT_REG", TYPE_SEGMENTREG) 87356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("DEBUG_REG", TYPE_DEBUGREG) 87456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("CONTROL_REG", TYPE_CONTROLREG) 87556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("offset8", TYPE_MOFFS8) 87656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("offset16", TYPE_MOFFS16) 87756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("offset32", TYPE_MOFFS32) 87856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames TYPE("offset64", TYPE_MOFFS64) 87956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames errs() << "Unhandled type string " << s << "\n"; 88056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm_unreachable("Unhandled type string"); 88156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 88256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#undef TYPE 88356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 88456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#define ENCODING(str, encoding) if (s == str) return encoding; 88556c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::immediateEncodingFromString 88656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames (const std::string &s, 88756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool hasOpSizePrefix) { 88856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if(!hasOpSizePrefix) { 88956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // For instructions without an OpSize prefix, a declared 16-bit register or 89056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // immediate encoding is special. 89156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i16imm", ENCODING_IW) 89256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 89356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i32i8imm", ENCODING_IB) 89456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("SSECC", ENCODING_IB) 89556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i16imm", ENCODING_Iv) 89656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i16i8imm", ENCODING_IB) 89756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i32imm", ENCODING_Iv) 89856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i64i32imm", ENCODING_ID) 89956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i64i8imm", ENCODING_IB) 90056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i8imm", ENCODING_IB) 90156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames errs() << "Unhandled immediate encoding " << s << "\n"; 90256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm_unreachable("Unhandled immediate encoding"); 90356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 90456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 90556c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::rmRegisterEncodingFromString 90656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames (const std::string &s, 90756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool hasOpSizePrefix) { 90856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR16", ENCODING_RM) 90956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR32", ENCODING_RM) 91056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR64", ENCODING_RM) 91156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR8", ENCODING_RM) 91256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("VR128", ENCODING_RM) 91356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("FR64", ENCODING_RM) 91456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("FR32", ENCODING_RM) 91556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("VR64", ENCODING_RM) 91656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames errs() << "Unhandled R/M register encoding " << s << "\n"; 91756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm_unreachable("Unhandled R/M register encoding"); 91856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 91956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 92056c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::roRegisterEncodingFromString 92156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames (const std::string &s, 92256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool hasOpSizePrefix) { 92356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR16", ENCODING_REG) 92456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR32", ENCODING_REG) 92556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR64", ENCODING_REG) 92656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR8", ENCODING_REG) 92756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("VR128", ENCODING_REG) 92856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("FR64", ENCODING_REG) 92956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("FR32", ENCODING_REG) 93056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("VR64", ENCODING_REG) 93156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("SEGMENT_REG", ENCODING_REG) 93256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("DEBUG_REG", ENCODING_REG) 93356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("CONTROL_REG", ENCODING_REG) 93456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames errs() << "Unhandled reg/opcode register encoding " << s << "\n"; 93556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm_unreachable("Unhandled reg/opcode register encoding"); 93656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 93756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 93856c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::memoryEncodingFromString 93956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames (const std::string &s, 94056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool hasOpSizePrefix) { 94156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i16mem", ENCODING_RM) 94256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i32mem", ENCODING_RM) 94356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i64mem", ENCODING_RM) 94456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i8mem", ENCODING_RM) 94556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("ssmem", ENCODING_RM) 94656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("sdmem", ENCODING_RM) 94756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("f128mem", ENCODING_RM) 94856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("f256mem", ENCODING_RM) 94956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("f64mem", ENCODING_RM) 95056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("f32mem", ENCODING_RM) 95156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i128mem", ENCODING_RM) 95256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("f80mem", ENCODING_RM) 95356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("lea32mem", ENCODING_RM) 95456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("lea64_32mem", ENCODING_RM) 95556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("lea64mem", ENCODING_RM) 95656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("opaque32mem", ENCODING_RM) 95756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("opaque48mem", ENCODING_RM) 95856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("opaque80mem", ENCODING_RM) 95956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("opaque512mem", ENCODING_RM) 96056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames errs() << "Unhandled memory encoding " << s << "\n"; 96156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm_unreachable("Unhandled memory encoding"); 96256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 96356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 96456c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::relocationEncodingFromString 96556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames (const std::string &s, 96656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool hasOpSizePrefix) { 96756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames if(!hasOpSizePrefix) { 96856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // For instructions without an OpSize prefix, a declared 16-bit register or 96956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames // immediate encoding is special. 97056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i16imm", ENCODING_IW) 97156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames } 97256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i16imm", ENCODING_Iv) 97356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i16i8imm", ENCODING_IB) 97456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i32imm", ENCODING_Iv) 97556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i32i8imm", ENCODING_IB) 97656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i64i32imm", ENCODING_ID) 97756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i64i8imm", ENCODING_IB) 97856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i8imm", ENCODING_IB) 97956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i64i32imm_pcrel", ENCODING_ID) 98056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i16imm_pcrel", ENCODING_IW) 98156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i32imm_pcrel", ENCODING_ID) 98256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("brtarget", ENCODING_Iv) 98356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("brtarget8", ENCODING_IB) 98456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("i64imm", ENCODING_IO) 98556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("offset8", ENCODING_Ia) 98656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("offset16", ENCODING_Ia) 98756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("offset32", ENCODING_Ia) 98856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("offset64", ENCODING_Ia) 98956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames errs() << "Unhandled relocation encoding " << s << "\n"; 99056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm_unreachable("Unhandled relocation encoding"); 99156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 99256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames 99356c00c4868831c9a137ca7b0e16d063cf986d110Lang HamesOperandEncoding RecognizableInstr::opcodeModifierEncodingFromString 99456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames (const std::string &s, 99556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames bool hasOpSizePrefix) { 99656c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("RST", ENCODING_I) 99756c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR32", ENCODING_Rv) 99856c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR64", ENCODING_RO) 99956c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR16", ENCODING_Rv) 100056c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames ENCODING("GR8", ENCODING_RB) 100156c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames errs() << "Unhandled opcode modifier encoding " << s << "\n"; 100256c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames llvm_unreachable("Unhandled opcode modifier encoding"); 100356c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames} 100456c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames#undef ENCODING 100556c00c4868831c9a137ca7b0e16d063cf986d110Lang Hames