X86BaseInfo.h revision 251662
1226584Sdim//===-- X86BaseInfo.h - Top level definitions for X86 -------- --*- C++ -*-===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim// 10226584Sdim// This file contains small standalone helper functions and enum definitions for 11226584Sdim// the X86 target useful for the compiler back-end and the MC libraries. 12226584Sdim// As such, it deliberately does not include references to LLVM core 13226584Sdim// code gen types, passes, etc.. 14226584Sdim// 15226584Sdim//===----------------------------------------------------------------------===// 16226584Sdim 17226584Sdim#ifndef X86BASEINFO_H 18226584Sdim#define X86BASEINFO_H 19226584Sdim 20226584Sdim#include "X86MCTargetDesc.h" 21226584Sdim#include "llvm/Support/DataTypes.h" 22234353Sdim#include "llvm/Support/ErrorHandling.h" 23251662Sdim#include "llvm/MC/MCInstrInfo.h" 24226584Sdim 25226584Sdimnamespace llvm { 26226584Sdim 27226584Sdimnamespace X86 { 28226584Sdim // Enums for memory operand decoding. Each memory operand is represented with 29226584Sdim // a 5 operand sequence in the form: 30226584Sdim // [BaseReg, ScaleAmt, IndexReg, Disp, Segment] 31226584Sdim // These enums help decode this. 32226584Sdim enum { 33226584Sdim AddrBaseReg = 0, 34226584Sdim AddrScaleAmt = 1, 35226584Sdim AddrIndexReg = 2, 36226584Sdim AddrDisp = 3, 37226584Sdim 38226584Sdim /// AddrSegmentReg - The operand # of the segment in the memory operand. 39226584Sdim AddrSegmentReg = 4, 40226584Sdim 41226584Sdim /// AddrNumOperands - Total number of operands in a memory reference. 42226584Sdim AddrNumOperands = 5 43226584Sdim }; 44226584Sdim} // end namespace X86; 45226584Sdim 46226584Sdim/// X86II - This namespace holds all of the target specific flags that 47226584Sdim/// instruction info tracks. 48226584Sdim/// 49226584Sdimnamespace X86II { 50226584Sdim /// Target Operand Flag enum. 51226584Sdim enum TOF { 52226584Sdim //===------------------------------------------------------------------===// 53226584Sdim // X86 Specific MachineOperand flags. 54226584Sdim 55226584Sdim MO_NO_FLAG, 56226584Sdim 57226584Sdim /// MO_GOT_ABSOLUTE_ADDRESS - On a symbol operand, this represents a 58226584Sdim /// relocation of: 59226584Sdim /// SYMBOL_LABEL + [. - PICBASELABEL] 60226584Sdim MO_GOT_ABSOLUTE_ADDRESS, 61226584Sdim 62226584Sdim /// MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the 63226584Sdim /// immediate should get the value of the symbol minus the PIC base label: 64226584Sdim /// SYMBOL_LABEL - PICBASELABEL 65226584Sdim MO_PIC_BASE_OFFSET, 66226584Sdim 67226584Sdim /// MO_GOT - On a symbol operand this indicates that the immediate is the 68226584Sdim /// offset to the GOT entry for the symbol name from the base of the GOT. 69226584Sdim /// 70226584Sdim /// See the X86-64 ELF ABI supplement for more details. 71226584Sdim /// SYMBOL_LABEL @GOT 72226584Sdim MO_GOT, 73226584Sdim 74226584Sdim /// MO_GOTOFF - On a symbol operand this indicates that the immediate is 75226584Sdim /// the offset to the location of the symbol name from the base of the GOT. 76226584Sdim /// 77226584Sdim /// See the X86-64 ELF ABI supplement for more details. 78226584Sdim /// SYMBOL_LABEL @GOTOFF 79226584Sdim MO_GOTOFF, 80226584Sdim 81226584Sdim /// MO_GOTPCREL - On a symbol operand this indicates that the immediate is 82226584Sdim /// offset to the GOT entry for the symbol name from the current code 83226584Sdim /// location. 84226584Sdim /// 85226584Sdim /// See the X86-64 ELF ABI supplement for more details. 86226584Sdim /// SYMBOL_LABEL @GOTPCREL 87226584Sdim MO_GOTPCREL, 88226584Sdim 89226584Sdim /// MO_PLT - On a symbol operand this indicates that the immediate is 90226584Sdim /// offset to the PLT entry of symbol name from the current code location. 91226584Sdim /// 92226584Sdim /// See the X86-64 ELF ABI supplement for more details. 93226584Sdim /// SYMBOL_LABEL @PLT 94226584Sdim MO_PLT, 95226584Sdim 96226584Sdim /// MO_TLSGD - On a symbol operand this indicates that the immediate is 97239462Sdim /// the offset of the GOT entry with the TLS index structure that contains 98239462Sdim /// the module number and variable offset for the symbol. Used in the 99239462Sdim /// general dynamic TLS access model. 100226584Sdim /// 101226584Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 102226584Sdim /// SYMBOL_LABEL @TLSGD 103226584Sdim MO_TLSGD, 104226584Sdim 105239462Sdim /// MO_TLSLD - On a symbol operand this indicates that the immediate is 106239462Sdim /// the offset of the GOT entry with the TLS index for the module that 107249423Sdim /// contains the symbol. When this index is passed to a call to 108239462Sdim /// __tls_get_addr, the function will return the base address of the TLS 109239462Sdim /// block for the symbol. Used in the x86-64 local dynamic TLS access model. 110239462Sdim /// 111239462Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 112239462Sdim /// SYMBOL_LABEL @TLSLD 113239462Sdim MO_TLSLD, 114239462Sdim 115239462Sdim /// MO_TLSLDM - On a symbol operand this indicates that the immediate is 116239462Sdim /// the offset of the GOT entry with the TLS index for the module that 117249423Sdim /// contains the symbol. When this index is passed to a call to 118239462Sdim /// ___tls_get_addr, the function will return the base address of the TLS 119239462Sdim /// block for the symbol. Used in the IA32 local dynamic TLS access model. 120239462Sdim /// 121239462Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 122239462Sdim /// SYMBOL_LABEL @TLSLDM 123239462Sdim MO_TLSLDM, 124239462Sdim 125226584Sdim /// MO_GOTTPOFF - On a symbol operand this indicates that the immediate is 126239462Sdim /// the offset of the GOT entry with the thread-pointer offset for the 127239462Sdim /// symbol. Used in the x86-64 initial exec TLS access model. 128226584Sdim /// 129226584Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 130226584Sdim /// SYMBOL_LABEL @GOTTPOFF 131226584Sdim MO_GOTTPOFF, 132226584Sdim 133226584Sdim /// MO_INDNTPOFF - On a symbol operand this indicates that the immediate is 134239462Sdim /// the absolute address of the GOT entry with the negative thread-pointer 135239462Sdim /// offset for the symbol. Used in the non-PIC IA32 initial exec TLS access 136239462Sdim /// model. 137226584Sdim /// 138226584Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 139226584Sdim /// SYMBOL_LABEL @INDNTPOFF 140226584Sdim MO_INDNTPOFF, 141226584Sdim 142226584Sdim /// MO_TPOFF - On a symbol operand this indicates that the immediate is 143239462Sdim /// the thread-pointer offset for the symbol. Used in the x86-64 local 144239462Sdim /// exec TLS access model. 145226584Sdim /// 146226584Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 147226584Sdim /// SYMBOL_LABEL @TPOFF 148226584Sdim MO_TPOFF, 149226584Sdim 150239462Sdim /// MO_DTPOFF - On a symbol operand this indicates that the immediate is 151239462Sdim /// the offset of the GOT entry with the TLS offset of the symbol. Used 152239462Sdim /// in the local dynamic TLS access model. 153239462Sdim /// 154239462Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 155239462Sdim /// SYMBOL_LABEL @DTPOFF 156239462Sdim MO_DTPOFF, 157239462Sdim 158226584Sdim /// MO_NTPOFF - On a symbol operand this indicates that the immediate is 159239462Sdim /// the negative thread-pointer offset for the symbol. Used in the IA32 160239462Sdim /// local exec TLS access model. 161226584Sdim /// 162226584Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 163226584Sdim /// SYMBOL_LABEL @NTPOFF 164226584Sdim MO_NTPOFF, 165226584Sdim 166239462Sdim /// MO_GOTNTPOFF - On a symbol operand this indicates that the immediate is 167239462Sdim /// the offset of the GOT entry with the negative thread-pointer offset for 168239462Sdim /// the symbol. Used in the PIC IA32 initial exec TLS access model. 169239462Sdim /// 170239462Sdim /// See 'ELF Handling for Thread-Local Storage' for more details. 171239462Sdim /// SYMBOL_LABEL @GOTNTPOFF 172239462Sdim MO_GOTNTPOFF, 173239462Sdim 174226584Sdim /// MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the 175226584Sdim /// reference is actually to the "__imp_FOO" symbol. This is used for 176226584Sdim /// dllimport linkage on windows. 177226584Sdim MO_DLLIMPORT, 178226584Sdim 179226584Sdim /// MO_DARWIN_STUB - On a symbol operand "FOO", this indicates that the 180226584Sdim /// reference is actually to the "FOO$stub" symbol. This is used for calls 181226584Sdim /// and jumps to external functions on Tiger and earlier. 182226584Sdim MO_DARWIN_STUB, 183226584Sdim 184226584Sdim /// MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the 185226584Sdim /// reference is actually to the "FOO$non_lazy_ptr" symbol, which is a 186226584Sdim /// non-PIC-base-relative reference to a non-hidden dyld lazy pointer stub. 187226584Sdim MO_DARWIN_NONLAZY, 188226584Sdim 189226584Sdim /// MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates 190226584Sdim /// that the reference is actually to "FOO$non_lazy_ptr - PICBASE", which is 191226584Sdim /// a PIC-base-relative reference to a non-hidden dyld lazy pointer stub. 192226584Sdim MO_DARWIN_NONLAZY_PIC_BASE, 193226584Sdim 194226584Sdim /// MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this 195226584Sdim /// indicates that the reference is actually to "FOO$non_lazy_ptr -PICBASE", 196226584Sdim /// which is a PIC-base-relative reference to a hidden dyld lazy pointer 197226584Sdim /// stub. 198226584Sdim MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE, 199226584Sdim 200226584Sdim /// MO_TLVP - On a symbol operand this indicates that the immediate is 201226584Sdim /// some TLS offset. 202226584Sdim /// 203226584Sdim /// This is the TLS offset for the Darwin TLS mechanism. 204226584Sdim MO_TLVP, 205226584Sdim 206226584Sdim /// MO_TLVP_PIC_BASE - On a symbol operand this indicates that the immediate 207226584Sdim /// is some TLS offset from the picbase. 208226584Sdim /// 209226584Sdim /// This is the 32-bit TLS offset for Darwin TLS in PIC mode. 210234353Sdim MO_TLVP_PIC_BASE, 211234353Sdim 212234353Sdim /// MO_SECREL - On a symbol operand this indicates that the immediate is 213234353Sdim /// the offset from beginning of section. 214234353Sdim /// 215234353Sdim /// This is the TLS offset for the COFF/Windows TLS mechanism. 216234353Sdim MO_SECREL 217226584Sdim }; 218226584Sdim 219226584Sdim enum { 220226584Sdim //===------------------------------------------------------------------===// 221226584Sdim // Instruction encodings. These are the standard/most common forms for X86 222226584Sdim // instructions. 223226584Sdim // 224226584Sdim 225226584Sdim // PseudoFrm - This represents an instruction that is a pseudo instruction 226226584Sdim // or one that has not been implemented yet. It is illegal to code generate 227226584Sdim // it, but tolerated for intermediate implementation stages. 228226584Sdim Pseudo = 0, 229226584Sdim 230226584Sdim /// Raw - This form is for instructions that don't have any operands, so 231226584Sdim /// they are just a fixed opcode value, like 'leave'. 232226584Sdim RawFrm = 1, 233226584Sdim 234226584Sdim /// AddRegFrm - This form is used for instructions like 'push r32' that have 235226584Sdim /// their one register operand added to their opcode. 236226584Sdim AddRegFrm = 2, 237226584Sdim 238226584Sdim /// MRMDestReg - This form is used for instructions that use the Mod/RM byte 239226584Sdim /// to specify a destination, which in this case is a register. 240226584Sdim /// 241226584Sdim MRMDestReg = 3, 242226584Sdim 243226584Sdim /// MRMDestMem - This form is used for instructions that use the Mod/RM byte 244226584Sdim /// to specify a destination, which in this case is memory. 245226584Sdim /// 246226584Sdim MRMDestMem = 4, 247226584Sdim 248226584Sdim /// MRMSrcReg - This form is used for instructions that use the Mod/RM byte 249226584Sdim /// to specify a source, which in this case is a register. 250226584Sdim /// 251226584Sdim MRMSrcReg = 5, 252226584Sdim 253226584Sdim /// MRMSrcMem - This form is used for instructions that use the Mod/RM byte 254226584Sdim /// to specify a source, which in this case is memory. 255226584Sdim /// 256226584Sdim MRMSrcMem = 6, 257226584Sdim 258226584Sdim /// MRM[0-7][rm] - These forms are used to represent instructions that use 259226584Sdim /// a Mod/RM byte, and use the middle field to hold extended opcode 260226584Sdim /// information. In the intel manual these are represented as /0, /1, ... 261226584Sdim /// 262226584Sdim 263226584Sdim // First, instructions that operate on a register r/m operand... 264226584Sdim MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19, // Format /0 /1 /2 /3 265226584Sdim MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23, // Format /4 /5 /6 /7 266226584Sdim 267226584Sdim // Next, instructions that operate on a memory r/m operand... 268226584Sdim MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27, // Format /0 /1 /2 /3 269226584Sdim MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31, // Format /4 /5 /6 /7 270226584Sdim 271226584Sdim // MRMInitReg - This form is used for instructions whose source and 272226584Sdim // destinations are the same register. 273226584Sdim MRMInitReg = 32, 274226584Sdim 275234353Sdim //// MRM_XX - A mod/rm byte of exactly 0xXX. 276234353Sdim MRM_C1 = 33, MRM_C2 = 34, MRM_C3 = 35, MRM_C4 = 36, 277251662Sdim MRM_C8 = 37, MRM_C9 = 38, MRM_CA = 39, MRM_CB = 40, 278251662Sdim MRM_E8 = 41, MRM_F0 = 42, MRM_F8 = 45, MRM_F9 = 46, 279251662Sdim MRM_D0 = 47, MRM_D1 = 48, MRM_D4 = 49, MRM_D5 = 50, 280251662Sdim MRM_D6 = 51, MRM_D8 = 52, MRM_D9 = 53, MRM_DA = 54, 281251662Sdim MRM_DB = 55, MRM_DC = 56, MRM_DD = 57, MRM_DE = 58, 282251662Sdim MRM_DF = 59, 283226584Sdim 284226584Sdim /// RawFrmImm8 - This is used for the ENTER instruction, which has two 285226584Sdim /// immediates, the first of which is a 16-bit immediate (specified by 286226584Sdim /// the imm encoding) and the second is a 8-bit fixed value. 287226584Sdim RawFrmImm8 = 43, 288226584Sdim 289226584Sdim /// RawFrmImm16 - This is used for CALL FAR instructions, which have two 290226584Sdim /// immediates, the first of which is a 16 or 32-bit immediate (specified by 291226584Sdim /// the imm encoding) and the second is a 16-bit fixed value. In the AMD 292226584Sdim /// manual, this operand is described as pntr16:32 and pntr16:16 293226584Sdim RawFrmImm16 = 44, 294226584Sdim 295226584Sdim FormMask = 63, 296226584Sdim 297226584Sdim //===------------------------------------------------------------------===// 298226584Sdim // Actual flags... 299226584Sdim 300226584Sdim // OpSize - Set if this instruction requires an operand size prefix (0x66), 301226584Sdim // which most often indicates that the instruction operates on 16 bit data 302226584Sdim // instead of 32 bit data. 303226584Sdim OpSize = 1 << 6, 304226584Sdim 305226584Sdim // AsSize - Set if this instruction requires an operand size prefix (0x67), 306226584Sdim // which most often indicates that the instruction address 16 bit address 307226584Sdim // instead of 32 bit address (or 32 bit address in 64 bit mode). 308226584Sdim AdSize = 1 << 7, 309226584Sdim 310226584Sdim //===------------------------------------------------------------------===// 311226584Sdim // Op0Mask - There are several prefix bytes that are used to form two byte 312226584Sdim // opcodes. These are currently 0x0F, 0xF3, and 0xD8-0xDF. This mask is 313226584Sdim // used to obtain the setting of this field. If no bits in this field is 314226584Sdim // set, there is no prefix byte for obtaining a multibyte opcode. 315226584Sdim // 316226584Sdim Op0Shift = 8, 317226584Sdim Op0Mask = 0x1F << Op0Shift, 318226584Sdim 319226584Sdim // TB - TwoByte - Set if this instruction has a two byte opcode, which 320226584Sdim // starts with a 0x0F byte before the real opcode. 321226584Sdim TB = 1 << Op0Shift, 322226584Sdim 323226584Sdim // REP - The 0xF3 prefix byte indicating repetition of the following 324226584Sdim // instruction. 325226584Sdim REP = 2 << Op0Shift, 326226584Sdim 327226584Sdim // D8-DF - These escape opcodes are used by the floating point unit. These 328226584Sdim // values must remain sequential. 329226584Sdim D8 = 3 << Op0Shift, D9 = 4 << Op0Shift, 330226584Sdim DA = 5 << Op0Shift, DB = 6 << Op0Shift, 331226584Sdim DC = 7 << Op0Shift, DD = 8 << Op0Shift, 332226584Sdim DE = 9 << Op0Shift, DF = 10 << Op0Shift, 333226584Sdim 334226584Sdim // XS, XD - These prefix codes are for single and double precision scalar 335226584Sdim // floating point operations performed in the SSE registers. 336226584Sdim XD = 11 << Op0Shift, XS = 12 << Op0Shift, 337226584Sdim 338226584Sdim // T8, TA, A6, A7 - Prefix after the 0x0F prefix. 339226584Sdim T8 = 13 << Op0Shift, TA = 14 << Op0Shift, 340226584Sdim A6 = 15 << Op0Shift, A7 = 16 << Op0Shift, 341226584Sdim 342234353Sdim // T8XD - Prefix before and after 0x0F. Combination of T8 and XD. 343234353Sdim T8XD = 17 << Op0Shift, 344226584Sdim 345234353Sdim // T8XS - Prefix before and after 0x0F. Combination of T8 and XS. 346234353Sdim T8XS = 18 << Op0Shift, 347234353Sdim 348234353Sdim // TAXD - Prefix before and after 0x0F. Combination of TA and XD. 349234353Sdim TAXD = 19 << Op0Shift, 350234353Sdim 351234353Sdim // XOP8 - Prefix to include use of imm byte. 352234353Sdim XOP8 = 20 << Op0Shift, 353234353Sdim 354234353Sdim // XOP9 - Prefix to exclude use of imm byte. 355234353Sdim XOP9 = 21 << Op0Shift, 356234353Sdim 357226584Sdim //===------------------------------------------------------------------===// 358226584Sdim // REX_W - REX prefixes are instruction prefixes used in 64-bit mode. 359226584Sdim // They are used to specify GPRs and SSE registers, 64-bit operand size, 360226584Sdim // etc. We only cares about REX.W and REX.R bits and only the former is 361226584Sdim // statically determined. 362226584Sdim // 363226584Sdim REXShift = Op0Shift + 5, 364226584Sdim REX_W = 1 << REXShift, 365226584Sdim 366226584Sdim //===------------------------------------------------------------------===// 367226584Sdim // This three-bit field describes the size of an immediate operand. Zero is 368226584Sdim // unused so that we can tell if we forgot to set a value. 369226584Sdim ImmShift = REXShift + 1, 370226584Sdim ImmMask = 7 << ImmShift, 371226584Sdim Imm8 = 1 << ImmShift, 372226584Sdim Imm8PCRel = 2 << ImmShift, 373226584Sdim Imm16 = 3 << ImmShift, 374226584Sdim Imm16PCRel = 4 << ImmShift, 375226584Sdim Imm32 = 5 << ImmShift, 376226584Sdim Imm32PCRel = 6 << ImmShift, 377226584Sdim Imm64 = 7 << ImmShift, 378226584Sdim 379226584Sdim //===------------------------------------------------------------------===// 380226584Sdim // FP Instruction Classification... Zero is non-fp instruction. 381226584Sdim 382226584Sdim // FPTypeMask - Mask for all of the FP types... 383226584Sdim FPTypeShift = ImmShift + 3, 384226584Sdim FPTypeMask = 7 << FPTypeShift, 385226584Sdim 386226584Sdim // NotFP - The default, set for instructions that do not use FP registers. 387226584Sdim NotFP = 0 << FPTypeShift, 388226584Sdim 389226584Sdim // ZeroArgFP - 0 arg FP instruction which implicitly pushes ST(0), f.e. fld0 390226584Sdim ZeroArgFP = 1 << FPTypeShift, 391226584Sdim 392226584Sdim // OneArgFP - 1 arg FP instructions which implicitly read ST(0), such as fst 393226584Sdim OneArgFP = 2 << FPTypeShift, 394226584Sdim 395226584Sdim // OneArgFPRW - 1 arg FP instruction which implicitly read ST(0) and write a 396226584Sdim // result back to ST(0). For example, fcos, fsqrt, etc. 397226584Sdim // 398226584Sdim OneArgFPRW = 3 << FPTypeShift, 399226584Sdim 400226584Sdim // TwoArgFP - 2 arg FP instructions which implicitly read ST(0), and an 401226584Sdim // explicit argument, storing the result to either ST(0) or the implicit 402226584Sdim // argument. For example: fadd, fsub, fmul, etc... 403226584Sdim TwoArgFP = 4 << FPTypeShift, 404226584Sdim 405226584Sdim // CompareFP - 2 arg FP instructions which implicitly read ST(0) and an 406226584Sdim // explicit argument, but have no destination. Example: fucom, fucomi, ... 407226584Sdim CompareFP = 5 << FPTypeShift, 408226584Sdim 409226584Sdim // CondMovFP - "2 operand" floating point conditional move instructions. 410226584Sdim CondMovFP = 6 << FPTypeShift, 411226584Sdim 412226584Sdim // SpecialFP - Special instruction forms. Dispatch by opcode explicitly. 413226584Sdim SpecialFP = 7 << FPTypeShift, 414226584Sdim 415226584Sdim // Lock prefix 416226584Sdim LOCKShift = FPTypeShift + 3, 417226584Sdim LOCK = 1 << LOCKShift, 418226584Sdim 419226584Sdim // Segment override prefixes. Currently we just need ability to address 420226584Sdim // stuff in gs and fs segments. 421226584Sdim SegOvrShift = LOCKShift + 1, 422226584Sdim SegOvrMask = 3 << SegOvrShift, 423226584Sdim FS = 1 << SegOvrShift, 424226584Sdim GS = 2 << SegOvrShift, 425226584Sdim 426226584Sdim // Execution domain for SSE instructions in bits 23, 24. 427226584Sdim // 0 in bits 23-24 means normal, non-SSE instruction. 428226584Sdim SSEDomainShift = SegOvrShift + 2, 429226584Sdim 430226584Sdim OpcodeShift = SSEDomainShift + 2, 431226584Sdim 432226584Sdim //===------------------------------------------------------------------===// 433226584Sdim /// VEX - The opcode prefix used by AVX instructions 434226584Sdim VEXShift = OpcodeShift + 8, 435226584Sdim VEX = 1U << 0, 436226584Sdim 437226584Sdim /// VEX_W - Has a opcode specific functionality, but is used in the same 438226584Sdim /// way as REX_W is for regular SSE instructions. 439226584Sdim VEX_W = 1U << 1, 440226584Sdim 441226584Sdim /// VEX_4V - Used to specify an additional AVX/SSE register. Several 2 442226584Sdim /// address instructions in SSE are represented as 3 address ones in AVX 443226584Sdim /// and the additional register is encoded in VEX_VVVV prefix. 444226584Sdim VEX_4V = 1U << 2, 445226584Sdim 446234353Sdim /// VEX_4VOp3 - Similar to VEX_4V, but used on instructions that encode 447234353Sdim /// operand 3 with VEX.vvvv. 448234353Sdim VEX_4VOp3 = 1U << 3, 449234353Sdim 450226584Sdim /// VEX_I8IMM - Specifies that the last register used in a AVX instruction, 451226584Sdim /// must be encoded in the i8 immediate field. This usually happens in 452226584Sdim /// instructions with 4 operands. 453234353Sdim VEX_I8IMM = 1U << 4, 454226584Sdim 455226584Sdim /// VEX_L - Stands for a bit in the VEX opcode prefix meaning the current 456226584Sdim /// instruction uses 256-bit wide registers. This is usually auto detected 457226584Sdim /// if a VR256 register is used, but some AVX instructions also have this 458226584Sdim /// field marked when using a f256 memory references. 459234353Sdim VEX_L = 1U << 5, 460226584Sdim 461226584Sdim // VEX_LIG - Specifies that this instruction ignores the L-bit in the VEX 462226584Sdim // prefix. Usually used for scalar instructions. Needed by disassembler. 463234353Sdim VEX_LIG = 1U << 6, 464226584Sdim 465226584Sdim /// Has3DNow0F0FOpcode - This flag indicates that the instruction uses the 466226584Sdim /// wacky 0x0F 0x0F prefix for 3DNow! instructions. The manual documents 467226584Sdim /// this as having a 0x0F prefix with a 0x0F opcode, and each instruction 468226584Sdim /// storing a classifier in the imm8 field. To simplify our implementation, 469226584Sdim /// we handle this by storeing the classifier in the opcode field and using 470226584Sdim /// this flag to indicate that the encoder should do the wacky 3DNow! thing. 471234353Sdim Has3DNow0F0FOpcode = 1U << 7, 472234353Sdim 473234353Sdim /// MemOp4 - Used to indicate swapping of operand 3 and 4 to be encoded in 474234353Sdim /// ModRM or I8IMM. This is used for FMA4 and XOP instructions. 475234353Sdim MemOp4 = 1U << 8, 476234353Sdim 477234353Sdim /// XOP - Opcode prefix used by XOP instructions. 478234353Sdim XOP = 1U << 9 479234353Sdim 480226584Sdim }; 481226584Sdim 482226584Sdim // getBaseOpcodeFor - This function returns the "base" X86 opcode for the 483226584Sdim // specified machine instruction. 484226584Sdim // 485239462Sdim inline unsigned char getBaseOpcodeFor(uint64_t TSFlags) { 486226584Sdim return TSFlags >> X86II::OpcodeShift; 487226584Sdim } 488226584Sdim 489239462Sdim inline bool hasImm(uint64_t TSFlags) { 490226584Sdim return (TSFlags & X86II::ImmMask) != 0; 491226584Sdim } 492226584Sdim 493226584Sdim /// getSizeOfImm - Decode the "size of immediate" field from the TSFlags field 494226584Sdim /// of the specified instruction. 495239462Sdim inline unsigned getSizeOfImm(uint64_t TSFlags) { 496226584Sdim switch (TSFlags & X86II::ImmMask) { 497234353Sdim default: llvm_unreachable("Unknown immediate size"); 498226584Sdim case X86II::Imm8: 499226584Sdim case X86II::Imm8PCRel: return 1; 500226584Sdim case X86II::Imm16: 501226584Sdim case X86II::Imm16PCRel: return 2; 502226584Sdim case X86II::Imm32: 503226584Sdim case X86II::Imm32PCRel: return 4; 504226584Sdim case X86II::Imm64: return 8; 505226584Sdim } 506226584Sdim } 507226584Sdim 508226584Sdim /// isImmPCRel - Return true if the immediate of the specified instruction's 509226584Sdim /// TSFlags indicates that it is pc relative. 510239462Sdim inline unsigned isImmPCRel(uint64_t TSFlags) { 511226584Sdim switch (TSFlags & X86II::ImmMask) { 512234353Sdim default: llvm_unreachable("Unknown immediate size"); 513226584Sdim case X86II::Imm8PCRel: 514226584Sdim case X86II::Imm16PCRel: 515226584Sdim case X86II::Imm32PCRel: 516226584Sdim return true; 517226584Sdim case X86II::Imm8: 518226584Sdim case X86II::Imm16: 519226584Sdim case X86II::Imm32: 520226584Sdim case X86II::Imm64: 521226584Sdim return false; 522226584Sdim } 523226584Sdim } 524226584Sdim 525251662Sdim /// getOperandBias - compute any additional adjustment needed to 526251662Sdim /// the offset to the start of the memory operand 527251662Sdim /// in this instruction. 528251662Sdim /// If this is a two-address instruction,skip one of the register operands. 529251662Sdim /// FIXME: This should be handled during MCInst lowering. 530251662Sdim inline int getOperandBias(const MCInstrDesc& Desc) 531251662Sdim { 532251662Sdim unsigned NumOps = Desc.getNumOperands(); 533251662Sdim unsigned CurOp = 0; 534251662Sdim if (NumOps > 1 && Desc.getOperandConstraint(1, MCOI::TIED_TO) == 0) 535251662Sdim ++CurOp; 536251662Sdim else if (NumOps > 3 && Desc.getOperandConstraint(2, MCOI::TIED_TO) == 0) { 537251662Sdim assert(Desc.getOperandConstraint(NumOps - 1, MCOI::TIED_TO) == 1); 538251662Sdim // Special case for GATHER with 2 TIED_TO operands 539251662Sdim // Skip the first 2 operands: dst, mask_wb 540251662Sdim CurOp += 2; 541251662Sdim } 542251662Sdim return CurOp; 543251662Sdim } 544251662Sdim 545226584Sdim /// getMemoryOperandNo - The function returns the MCInst operand # for the 546226584Sdim /// first field of the memory operand. If the instruction doesn't have a 547226584Sdim /// memory operand, this returns -1. 548226584Sdim /// 549226584Sdim /// Note that this ignores tied operands. If there is a tied register which 550226584Sdim /// is duplicated in the MCInst (e.g. "EAX = addl EAX, [mem]") it is only 551226584Sdim /// counted as one operand. 552226584Sdim /// 553239462Sdim inline int getMemoryOperandNo(uint64_t TSFlags, unsigned Opcode) { 554226584Sdim switch (TSFlags & X86II::FormMask) { 555239462Sdim case X86II::MRMInitReg: 556239462Sdim // FIXME: Remove this form. 557239462Sdim return -1; 558234353Sdim default: llvm_unreachable("Unknown FormMask value in getMemoryOperandNo!"); 559226584Sdim case X86II::Pseudo: 560226584Sdim case X86II::RawFrm: 561226584Sdim case X86II::AddRegFrm: 562226584Sdim case X86II::MRMDestReg: 563226584Sdim case X86II::MRMSrcReg: 564226584Sdim case X86II::RawFrmImm8: 565226584Sdim case X86II::RawFrmImm16: 566226584Sdim return -1; 567226584Sdim case X86II::MRMDestMem: 568226584Sdim return 0; 569226584Sdim case X86II::MRMSrcMem: { 570226584Sdim bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V; 571234353Sdim bool HasMemOp4 = (TSFlags >> X86II::VEXShift) & X86II::MemOp4; 572226584Sdim unsigned FirstMemOp = 1; 573226584Sdim if (HasVEX_4V) 574226584Sdim ++FirstMemOp;// Skip the register source (which is encoded in VEX_VVVV). 575234353Sdim if (HasMemOp4) 576234353Sdim ++FirstMemOp;// Skip the register source (which is encoded in I8IMM). 577226584Sdim 578226584Sdim // FIXME: Maybe lea should have its own form? This is a horrible hack. 579226584Sdim //if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r || 580226584Sdim // Opcode == X86::LEA16r || Opcode == X86::LEA32r) 581226584Sdim return FirstMemOp; 582226584Sdim } 583226584Sdim case X86II::MRM0r: case X86II::MRM1r: 584226584Sdim case X86II::MRM2r: case X86II::MRM3r: 585226584Sdim case X86II::MRM4r: case X86II::MRM5r: 586226584Sdim case X86II::MRM6r: case X86II::MRM7r: 587226584Sdim return -1; 588226584Sdim case X86II::MRM0m: case X86II::MRM1m: 589226584Sdim case X86II::MRM2m: case X86II::MRM3m: 590226584Sdim case X86II::MRM4m: case X86II::MRM5m: 591234353Sdim case X86II::MRM6m: case X86II::MRM7m: { 592234353Sdim bool HasVEX_4V = (TSFlags >> X86II::VEXShift) & X86II::VEX_4V; 593234353Sdim unsigned FirstMemOp = 0; 594234353Sdim if (HasVEX_4V) 595234353Sdim ++FirstMemOp;// Skip the register dest (which is encoded in VEX_VVVV). 596234353Sdim return FirstMemOp; 597234353Sdim } 598249423Sdim case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3: 599249423Sdim case X86II::MRM_C4: case X86II::MRM_C8: case X86II::MRM_C9: 600251662Sdim case X86II::MRM_CA: case X86II::MRM_CB: case X86II::MRM_E8: 601251662Sdim case X86II::MRM_F0: case X86II::MRM_F8: case X86II::MRM_F9: 602251662Sdim case X86II::MRM_D0: case X86II::MRM_D1: case X86II::MRM_D4: 603251662Sdim case X86II::MRM_D5: case X86II::MRM_D6: case X86II::MRM_D8: 604251662Sdim case X86II::MRM_D9: case X86II::MRM_DA: case X86II::MRM_DB: 605251662Sdim case X86II::MRM_DC: case X86II::MRM_DD: case X86II::MRM_DE: 606251662Sdim case X86II::MRM_DF: 607226584Sdim return -1; 608226584Sdim } 609226584Sdim } 610226584Sdim 611226584Sdim /// isX86_64ExtendedReg - Is the MachineOperand a x86-64 extended (r8 or 612226584Sdim /// higher) register? e.g. r8, xmm8, xmm13, etc. 613239462Sdim inline bool isX86_64ExtendedReg(unsigned RegNo) { 614226584Sdim switch (RegNo) { 615226584Sdim default: break; 616226584Sdim case X86::R8: case X86::R9: case X86::R10: case X86::R11: 617226584Sdim case X86::R12: case X86::R13: case X86::R14: case X86::R15: 618226584Sdim case X86::R8D: case X86::R9D: case X86::R10D: case X86::R11D: 619226584Sdim case X86::R12D: case X86::R13D: case X86::R14D: case X86::R15D: 620226584Sdim case X86::R8W: case X86::R9W: case X86::R10W: case X86::R11W: 621226584Sdim case X86::R12W: case X86::R13W: case X86::R14W: case X86::R15W: 622226584Sdim case X86::R8B: case X86::R9B: case X86::R10B: case X86::R11B: 623226584Sdim case X86::R12B: case X86::R13B: case X86::R14B: case X86::R15B: 624226584Sdim case X86::XMM8: case X86::XMM9: case X86::XMM10: case X86::XMM11: 625226584Sdim case X86::XMM12: case X86::XMM13: case X86::XMM14: case X86::XMM15: 626226584Sdim case X86::YMM8: case X86::YMM9: case X86::YMM10: case X86::YMM11: 627226584Sdim case X86::YMM12: case X86::YMM13: case X86::YMM14: case X86::YMM15: 628226584Sdim case X86::CR8: case X86::CR9: case X86::CR10: case X86::CR11: 629226584Sdim case X86::CR12: case X86::CR13: case X86::CR14: case X86::CR15: 630226584Sdim return true; 631226584Sdim } 632226584Sdim return false; 633226584Sdim } 634226584Sdim 635239462Sdim inline bool isX86_64NonExtLowByteReg(unsigned reg) { 636226584Sdim return (reg == X86::SPL || reg == X86::BPL || 637226584Sdim reg == X86::SIL || reg == X86::DIL); 638226584Sdim } 639226584Sdim} 640226584Sdim 641226584Sdim} // end namespace llvm; 642226584Sdim 643226584Sdim#endif 644