106f32e7eSjoerg //===-- X86BaseInfo.h - Top level definitions for X86 -------- --*- C++ -*-===// 206f32e7eSjoerg // 306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606f32e7eSjoerg // 706f32e7eSjoerg //===----------------------------------------------------------------------===// 806f32e7eSjoerg // 906f32e7eSjoerg // This file contains small standalone helper functions and enum definitions for 1006f32e7eSjoerg // the X86 target useful for the compiler back-end and the MC libraries. 1106f32e7eSjoerg // As such, it deliberately does not include references to LLVM core 1206f32e7eSjoerg // code gen types, passes, etc.. 1306f32e7eSjoerg // 1406f32e7eSjoerg //===----------------------------------------------------------------------===// 1506f32e7eSjoerg 1606f32e7eSjoerg #ifndef LLVM_LIB_TARGET_X86_MCTARGETDESC_X86BASEINFO_H 1706f32e7eSjoerg #define LLVM_LIB_TARGET_X86_MCTARGETDESC_X86BASEINFO_H 1806f32e7eSjoerg 1906f32e7eSjoerg #include "X86MCTargetDesc.h" 2006f32e7eSjoerg #include "llvm/MC/MCInstrDesc.h" 2106f32e7eSjoerg #include "llvm/Support/DataTypes.h" 2206f32e7eSjoerg #include "llvm/Support/ErrorHandling.h" 2306f32e7eSjoerg 2406f32e7eSjoerg namespace llvm { 2506f32e7eSjoerg 2606f32e7eSjoerg namespace X86 { 2706f32e7eSjoerg // Enums for memory operand decoding. Each memory operand is represented with 2806f32e7eSjoerg // a 5 operand sequence in the form: 2906f32e7eSjoerg // [BaseReg, ScaleAmt, IndexReg, Disp, Segment] 3006f32e7eSjoerg // These enums help decode this. 3106f32e7eSjoerg enum { 3206f32e7eSjoerg AddrBaseReg = 0, 3306f32e7eSjoerg AddrScaleAmt = 1, 3406f32e7eSjoerg AddrIndexReg = 2, 3506f32e7eSjoerg AddrDisp = 3, 3606f32e7eSjoerg 3706f32e7eSjoerg /// AddrSegmentReg - The operand # of the segment in the memory operand. 3806f32e7eSjoerg AddrSegmentReg = 4, 3906f32e7eSjoerg 4006f32e7eSjoerg /// AddrNumOperands - Total number of operands in a memory reference. 4106f32e7eSjoerg AddrNumOperands = 5 4206f32e7eSjoerg }; 4306f32e7eSjoerg 4406f32e7eSjoerg /// AVX512 static rounding constants. These need to match the values in 4506f32e7eSjoerg /// avx512fintrin.h. 4606f32e7eSjoerg enum STATIC_ROUNDING { 4706f32e7eSjoerg TO_NEAREST_INT = 0, 4806f32e7eSjoerg TO_NEG_INF = 1, 4906f32e7eSjoerg TO_POS_INF = 2, 5006f32e7eSjoerg TO_ZERO = 3, 5106f32e7eSjoerg CUR_DIRECTION = 4, 5206f32e7eSjoerg NO_EXC = 8 5306f32e7eSjoerg }; 5406f32e7eSjoerg 5506f32e7eSjoerg /// The constants to describe instr prefixes if there are 5606f32e7eSjoerg enum IPREFIXES { 5706f32e7eSjoerg IP_NO_PREFIX = 0, 58*da58b97aSjoerg IP_HAS_OP_SIZE = 1U << 0, 59*da58b97aSjoerg IP_HAS_AD_SIZE = 1U << 1, 60*da58b97aSjoerg IP_HAS_REPEAT_NE = 1U << 2, 61*da58b97aSjoerg IP_HAS_REPEAT = 1U << 3, 62*da58b97aSjoerg IP_HAS_LOCK = 1U << 4, 63*da58b97aSjoerg IP_HAS_NOTRACK = 1U << 5, 64*da58b97aSjoerg IP_USE_VEX = 1U << 6, 65*da58b97aSjoerg IP_USE_VEX2 = 1U << 7, 66*da58b97aSjoerg IP_USE_VEX3 = 1U << 8, 67*da58b97aSjoerg IP_USE_EVEX = 1U << 9, 68*da58b97aSjoerg IP_USE_DISP8 = 1U << 10, 69*da58b97aSjoerg IP_USE_DISP32 = 1U << 11, 7006f32e7eSjoerg }; 7106f32e7eSjoerg 7206f32e7eSjoerg enum OperandType : unsigned { 7306f32e7eSjoerg /// AVX512 embedded rounding control. This should only have values 0-3. 7406f32e7eSjoerg OPERAND_ROUNDING_CONTROL = MCOI::OPERAND_FIRST_TARGET, 7506f32e7eSjoerg OPERAND_COND_CODE, 7606f32e7eSjoerg }; 7706f32e7eSjoerg 7806f32e7eSjoerg // X86 specific condition code. These correspond to X86_*_COND in 7906f32e7eSjoerg // X86InstrInfo.td. They must be kept in synch. 8006f32e7eSjoerg enum CondCode { 8106f32e7eSjoerg COND_O = 0, 8206f32e7eSjoerg COND_NO = 1, 8306f32e7eSjoerg COND_B = 2, 8406f32e7eSjoerg COND_AE = 3, 8506f32e7eSjoerg COND_E = 4, 8606f32e7eSjoerg COND_NE = 5, 8706f32e7eSjoerg COND_BE = 6, 8806f32e7eSjoerg COND_A = 7, 8906f32e7eSjoerg COND_S = 8, 9006f32e7eSjoerg COND_NS = 9, 9106f32e7eSjoerg COND_P = 10, 9206f32e7eSjoerg COND_NP = 11, 9306f32e7eSjoerg COND_L = 12, 9406f32e7eSjoerg COND_GE = 13, 9506f32e7eSjoerg COND_LE = 14, 9606f32e7eSjoerg COND_G = 15, 9706f32e7eSjoerg LAST_VALID_COND = COND_G, 9806f32e7eSjoerg 99*da58b97aSjoerg // Artificial condition codes. These are used by analyzeBranch 10006f32e7eSjoerg // to indicate a block terminated with two conditional branches that together 10106f32e7eSjoerg // form a compound condition. They occur in code using FCMP_OEQ or FCMP_UNE, 10206f32e7eSjoerg // which can't be represented on x86 with a single condition. These 10306f32e7eSjoerg // are never used in MachineInstrs and are inverses of one another. 10406f32e7eSjoerg COND_NE_OR_P, 10506f32e7eSjoerg COND_E_AND_NP, 10606f32e7eSjoerg 10706f32e7eSjoerg COND_INVALID 10806f32e7eSjoerg }; 109*da58b97aSjoerg 110*da58b97aSjoerg // The classification for the first instruction in macro fusion. 111*da58b97aSjoerg enum class FirstMacroFusionInstKind { 112*da58b97aSjoerg // TEST 113*da58b97aSjoerg Test, 114*da58b97aSjoerg // CMP 115*da58b97aSjoerg Cmp, 116*da58b97aSjoerg // AND 117*da58b97aSjoerg And, 118*da58b97aSjoerg // FIXME: Zen 3 support branch fusion for OR/XOR. 119*da58b97aSjoerg // ADD, SUB 120*da58b97aSjoerg AddSub, 121*da58b97aSjoerg // INC, DEC 122*da58b97aSjoerg IncDec, 123*da58b97aSjoerg // Not valid as a first macro fusion instruction 124*da58b97aSjoerg Invalid 125*da58b97aSjoerg }; 126*da58b97aSjoerg 127*da58b97aSjoerg enum class SecondMacroFusionInstKind { 128*da58b97aSjoerg // JA, JB and variants. 129*da58b97aSjoerg AB, 130*da58b97aSjoerg // JE, JL, JG and variants. 131*da58b97aSjoerg ELG, 132*da58b97aSjoerg // JS, JP, JO and variants 133*da58b97aSjoerg SPO, 134*da58b97aSjoerg // Not a fusible jump. 135*da58b97aSjoerg Invalid, 136*da58b97aSjoerg }; 137*da58b97aSjoerg 138*da58b97aSjoerg /// \returns the type of the first instruction in macro-fusion. 139*da58b97aSjoerg inline FirstMacroFusionInstKind classifyFirstOpcodeInMacroFusion(unsigned Opcode)140*da58b97aSjoerg classifyFirstOpcodeInMacroFusion(unsigned Opcode) { 141*da58b97aSjoerg switch (Opcode) { 142*da58b97aSjoerg default: 143*da58b97aSjoerg return FirstMacroFusionInstKind::Invalid; 144*da58b97aSjoerg // TEST 145*da58b97aSjoerg case X86::TEST16i16: 146*da58b97aSjoerg case X86::TEST16mr: 147*da58b97aSjoerg case X86::TEST16ri: 148*da58b97aSjoerg case X86::TEST16rr: 149*da58b97aSjoerg case X86::TEST32i32: 150*da58b97aSjoerg case X86::TEST32mr: 151*da58b97aSjoerg case X86::TEST32ri: 152*da58b97aSjoerg case X86::TEST32rr: 153*da58b97aSjoerg case X86::TEST64i32: 154*da58b97aSjoerg case X86::TEST64mr: 155*da58b97aSjoerg case X86::TEST64ri32: 156*da58b97aSjoerg case X86::TEST64rr: 157*da58b97aSjoerg case X86::TEST8i8: 158*da58b97aSjoerg case X86::TEST8mr: 159*da58b97aSjoerg case X86::TEST8ri: 160*da58b97aSjoerg case X86::TEST8rr: 161*da58b97aSjoerg return FirstMacroFusionInstKind::Test; 162*da58b97aSjoerg case X86::AND16i16: 163*da58b97aSjoerg case X86::AND16ri: 164*da58b97aSjoerg case X86::AND16ri8: 165*da58b97aSjoerg case X86::AND16rm: 166*da58b97aSjoerg case X86::AND16rr: 167*da58b97aSjoerg case X86::AND16rr_REV: 168*da58b97aSjoerg case X86::AND32i32: 169*da58b97aSjoerg case X86::AND32ri: 170*da58b97aSjoerg case X86::AND32ri8: 171*da58b97aSjoerg case X86::AND32rm: 172*da58b97aSjoerg case X86::AND32rr: 173*da58b97aSjoerg case X86::AND32rr_REV: 174*da58b97aSjoerg case X86::AND64i32: 175*da58b97aSjoerg case X86::AND64ri32: 176*da58b97aSjoerg case X86::AND64ri8: 177*da58b97aSjoerg case X86::AND64rm: 178*da58b97aSjoerg case X86::AND64rr: 179*da58b97aSjoerg case X86::AND64rr_REV: 180*da58b97aSjoerg case X86::AND8i8: 181*da58b97aSjoerg case X86::AND8ri: 182*da58b97aSjoerg case X86::AND8ri8: 183*da58b97aSjoerg case X86::AND8rm: 184*da58b97aSjoerg case X86::AND8rr: 185*da58b97aSjoerg case X86::AND8rr_REV: 186*da58b97aSjoerg return FirstMacroFusionInstKind::And; 187*da58b97aSjoerg // FIXME: Zen 3 support branch fusion for OR/XOR. 188*da58b97aSjoerg // CMP 189*da58b97aSjoerg case X86::CMP16i16: 190*da58b97aSjoerg case X86::CMP16mr: 191*da58b97aSjoerg case X86::CMP16ri: 192*da58b97aSjoerg case X86::CMP16ri8: 193*da58b97aSjoerg case X86::CMP16rm: 194*da58b97aSjoerg case X86::CMP16rr: 195*da58b97aSjoerg case X86::CMP16rr_REV: 196*da58b97aSjoerg case X86::CMP32i32: 197*da58b97aSjoerg case X86::CMP32mr: 198*da58b97aSjoerg case X86::CMP32ri: 199*da58b97aSjoerg case X86::CMP32ri8: 200*da58b97aSjoerg case X86::CMP32rm: 201*da58b97aSjoerg case X86::CMP32rr: 202*da58b97aSjoerg case X86::CMP32rr_REV: 203*da58b97aSjoerg case X86::CMP64i32: 204*da58b97aSjoerg case X86::CMP64mr: 205*da58b97aSjoerg case X86::CMP64ri32: 206*da58b97aSjoerg case X86::CMP64ri8: 207*da58b97aSjoerg case X86::CMP64rm: 208*da58b97aSjoerg case X86::CMP64rr: 209*da58b97aSjoerg case X86::CMP64rr_REV: 210*da58b97aSjoerg case X86::CMP8i8: 211*da58b97aSjoerg case X86::CMP8mr: 212*da58b97aSjoerg case X86::CMP8ri: 213*da58b97aSjoerg case X86::CMP8ri8: 214*da58b97aSjoerg case X86::CMP8rm: 215*da58b97aSjoerg case X86::CMP8rr: 216*da58b97aSjoerg case X86::CMP8rr_REV: 217*da58b97aSjoerg return FirstMacroFusionInstKind::Cmp; 218*da58b97aSjoerg // ADD 219*da58b97aSjoerg case X86::ADD16i16: 220*da58b97aSjoerg case X86::ADD16ri: 221*da58b97aSjoerg case X86::ADD16ri8: 222*da58b97aSjoerg case X86::ADD16rm: 223*da58b97aSjoerg case X86::ADD16rr: 224*da58b97aSjoerg case X86::ADD16rr_REV: 225*da58b97aSjoerg case X86::ADD32i32: 226*da58b97aSjoerg case X86::ADD32ri: 227*da58b97aSjoerg case X86::ADD32ri8: 228*da58b97aSjoerg case X86::ADD32rm: 229*da58b97aSjoerg case X86::ADD32rr: 230*da58b97aSjoerg case X86::ADD32rr_REV: 231*da58b97aSjoerg case X86::ADD64i32: 232*da58b97aSjoerg case X86::ADD64ri32: 233*da58b97aSjoerg case X86::ADD64ri8: 234*da58b97aSjoerg case X86::ADD64rm: 235*da58b97aSjoerg case X86::ADD64rr: 236*da58b97aSjoerg case X86::ADD64rr_REV: 237*da58b97aSjoerg case X86::ADD8i8: 238*da58b97aSjoerg case X86::ADD8ri: 239*da58b97aSjoerg case X86::ADD8ri8: 240*da58b97aSjoerg case X86::ADD8rm: 241*da58b97aSjoerg case X86::ADD8rr: 242*da58b97aSjoerg case X86::ADD8rr_REV: 243*da58b97aSjoerg // SUB 244*da58b97aSjoerg case X86::SUB16i16: 245*da58b97aSjoerg case X86::SUB16ri: 246*da58b97aSjoerg case X86::SUB16ri8: 247*da58b97aSjoerg case X86::SUB16rm: 248*da58b97aSjoerg case X86::SUB16rr: 249*da58b97aSjoerg case X86::SUB16rr_REV: 250*da58b97aSjoerg case X86::SUB32i32: 251*da58b97aSjoerg case X86::SUB32ri: 252*da58b97aSjoerg case X86::SUB32ri8: 253*da58b97aSjoerg case X86::SUB32rm: 254*da58b97aSjoerg case X86::SUB32rr: 255*da58b97aSjoerg case X86::SUB32rr_REV: 256*da58b97aSjoerg case X86::SUB64i32: 257*da58b97aSjoerg case X86::SUB64ri32: 258*da58b97aSjoerg case X86::SUB64ri8: 259*da58b97aSjoerg case X86::SUB64rm: 260*da58b97aSjoerg case X86::SUB64rr: 261*da58b97aSjoerg case X86::SUB64rr_REV: 262*da58b97aSjoerg case X86::SUB8i8: 263*da58b97aSjoerg case X86::SUB8ri: 264*da58b97aSjoerg case X86::SUB8ri8: 265*da58b97aSjoerg case X86::SUB8rm: 266*da58b97aSjoerg case X86::SUB8rr: 267*da58b97aSjoerg case X86::SUB8rr_REV: 268*da58b97aSjoerg return FirstMacroFusionInstKind::AddSub; 269*da58b97aSjoerg // INC 270*da58b97aSjoerg case X86::INC16r: 271*da58b97aSjoerg case X86::INC16r_alt: 272*da58b97aSjoerg case X86::INC32r: 273*da58b97aSjoerg case X86::INC32r_alt: 274*da58b97aSjoerg case X86::INC64r: 275*da58b97aSjoerg case X86::INC8r: 276*da58b97aSjoerg // DEC 277*da58b97aSjoerg case X86::DEC16r: 278*da58b97aSjoerg case X86::DEC16r_alt: 279*da58b97aSjoerg case X86::DEC32r: 280*da58b97aSjoerg case X86::DEC32r_alt: 281*da58b97aSjoerg case X86::DEC64r: 282*da58b97aSjoerg case X86::DEC8r: 283*da58b97aSjoerg return FirstMacroFusionInstKind::IncDec; 284*da58b97aSjoerg } 285*da58b97aSjoerg } 286*da58b97aSjoerg 287*da58b97aSjoerg /// \returns the type of the second instruction in macro-fusion. 288*da58b97aSjoerg inline SecondMacroFusionInstKind classifySecondCondCodeInMacroFusion(X86::CondCode CC)289*da58b97aSjoerg classifySecondCondCodeInMacroFusion(X86::CondCode CC) { 290*da58b97aSjoerg if (CC == X86::COND_INVALID) 291*da58b97aSjoerg return SecondMacroFusionInstKind::Invalid; 292*da58b97aSjoerg 293*da58b97aSjoerg switch (CC) { 294*da58b97aSjoerg default: 295*da58b97aSjoerg return SecondMacroFusionInstKind::Invalid; 296*da58b97aSjoerg // JE,JZ 297*da58b97aSjoerg case X86::COND_E: 298*da58b97aSjoerg // JNE,JNZ 299*da58b97aSjoerg case X86::COND_NE: 300*da58b97aSjoerg // JL,JNGE 301*da58b97aSjoerg case X86::COND_L: 302*da58b97aSjoerg // JLE,JNG 303*da58b97aSjoerg case X86::COND_LE: 304*da58b97aSjoerg // JG,JNLE 305*da58b97aSjoerg case X86::COND_G: 306*da58b97aSjoerg // JGE,JNL 307*da58b97aSjoerg case X86::COND_GE: 308*da58b97aSjoerg return SecondMacroFusionInstKind::ELG; 309*da58b97aSjoerg // JB,JC 310*da58b97aSjoerg case X86::COND_B: 311*da58b97aSjoerg // JNA,JBE 312*da58b97aSjoerg case X86::COND_BE: 313*da58b97aSjoerg // JA,JNBE 314*da58b97aSjoerg case X86::COND_A: 315*da58b97aSjoerg // JAE,JNC,JNB 316*da58b97aSjoerg case X86::COND_AE: 317*da58b97aSjoerg return SecondMacroFusionInstKind::AB; 318*da58b97aSjoerg // JS 319*da58b97aSjoerg case X86::COND_S: 320*da58b97aSjoerg // JNS 321*da58b97aSjoerg case X86::COND_NS: 322*da58b97aSjoerg // JP,JPE 323*da58b97aSjoerg case X86::COND_P: 324*da58b97aSjoerg // JNP,JPO 325*da58b97aSjoerg case X86::COND_NP: 326*da58b97aSjoerg // JO 327*da58b97aSjoerg case X86::COND_O: 328*da58b97aSjoerg // JNO 329*da58b97aSjoerg case X86::COND_NO: 330*da58b97aSjoerg return SecondMacroFusionInstKind::SPO; 331*da58b97aSjoerg } 332*da58b97aSjoerg } 333*da58b97aSjoerg 334*da58b97aSjoerg /// \param FirstKind kind of the first instruction in macro fusion. 335*da58b97aSjoerg /// \param SecondKind kind of the second instruction in macro fusion. 336*da58b97aSjoerg /// 337*da58b97aSjoerg /// \returns true if the two instruction can be macro fused. isMacroFused(FirstMacroFusionInstKind FirstKind,SecondMacroFusionInstKind SecondKind)338*da58b97aSjoerg inline bool isMacroFused(FirstMacroFusionInstKind FirstKind, 339*da58b97aSjoerg SecondMacroFusionInstKind SecondKind) { 340*da58b97aSjoerg switch (FirstKind) { 341*da58b97aSjoerg case X86::FirstMacroFusionInstKind::Test: 342*da58b97aSjoerg case X86::FirstMacroFusionInstKind::And: 343*da58b97aSjoerg return true; 344*da58b97aSjoerg case X86::FirstMacroFusionInstKind::Cmp: 345*da58b97aSjoerg case X86::FirstMacroFusionInstKind::AddSub: 346*da58b97aSjoerg return SecondKind == X86::SecondMacroFusionInstKind::AB || 347*da58b97aSjoerg SecondKind == X86::SecondMacroFusionInstKind::ELG; 348*da58b97aSjoerg case X86::FirstMacroFusionInstKind::IncDec: 349*da58b97aSjoerg return SecondKind == X86::SecondMacroFusionInstKind::ELG; 350*da58b97aSjoerg case X86::FirstMacroFusionInstKind::Invalid: 351*da58b97aSjoerg return false; 352*da58b97aSjoerg } 353*da58b97aSjoerg llvm_unreachable("unknown fusion type"); 354*da58b97aSjoerg } 355*da58b97aSjoerg 356*da58b97aSjoerg /// Defines the possible values of the branch boundary alignment mask. 357*da58b97aSjoerg enum AlignBranchBoundaryKind : uint8_t { 358*da58b97aSjoerg AlignBranchNone = 0, 359*da58b97aSjoerg AlignBranchFused = 1U << 0, 360*da58b97aSjoerg AlignBranchJcc = 1U << 1, 361*da58b97aSjoerg AlignBranchJmp = 1U << 2, 362*da58b97aSjoerg AlignBranchCall = 1U << 3, 363*da58b97aSjoerg AlignBranchRet = 1U << 4, 364*da58b97aSjoerg AlignBranchIndirect = 1U << 5 365*da58b97aSjoerg }; 366*da58b97aSjoerg 367*da58b97aSjoerg /// Defines the encoding values for segment override prefix. 368*da58b97aSjoerg enum EncodingOfSegmentOverridePrefix : uint8_t { 369*da58b97aSjoerg CS_Encoding = 0x2E, 370*da58b97aSjoerg DS_Encoding = 0x3E, 371*da58b97aSjoerg ES_Encoding = 0x26, 372*da58b97aSjoerg FS_Encoding = 0x64, 373*da58b97aSjoerg GS_Encoding = 0x65, 374*da58b97aSjoerg SS_Encoding = 0x36 375*da58b97aSjoerg }; 376*da58b97aSjoerg 377*da58b97aSjoerg /// Given a segment register, return the encoding of the segment override 378*da58b97aSjoerg /// prefix for it. 379*da58b97aSjoerg inline EncodingOfSegmentOverridePrefix getSegmentOverridePrefixForReg(unsigned Reg)380*da58b97aSjoerg getSegmentOverridePrefixForReg(unsigned Reg) { 381*da58b97aSjoerg switch (Reg) { 382*da58b97aSjoerg default: 383*da58b97aSjoerg llvm_unreachable("Unknown segment register!"); 384*da58b97aSjoerg case X86::CS: 385*da58b97aSjoerg return CS_Encoding; 386*da58b97aSjoerg case X86::DS: 387*da58b97aSjoerg return DS_Encoding; 388*da58b97aSjoerg case X86::ES: 389*da58b97aSjoerg return ES_Encoding; 390*da58b97aSjoerg case X86::FS: 391*da58b97aSjoerg return FS_Encoding; 392*da58b97aSjoerg case X86::GS: 393*da58b97aSjoerg return GS_Encoding; 394*da58b97aSjoerg case X86::SS: 395*da58b97aSjoerg return SS_Encoding; 396*da58b97aSjoerg } 397*da58b97aSjoerg } 398*da58b97aSjoerg 39906f32e7eSjoerg } // end namespace X86; 40006f32e7eSjoerg 40106f32e7eSjoerg /// X86II - This namespace holds all of the target specific flags that 40206f32e7eSjoerg /// instruction info tracks. 40306f32e7eSjoerg /// 40406f32e7eSjoerg namespace X86II { 40506f32e7eSjoerg /// Target Operand Flag enum. 40606f32e7eSjoerg enum TOF { 40706f32e7eSjoerg //===------------------------------------------------------------------===// 40806f32e7eSjoerg // X86 Specific MachineOperand flags. 40906f32e7eSjoerg 41006f32e7eSjoerg MO_NO_FLAG, 41106f32e7eSjoerg 41206f32e7eSjoerg /// MO_GOT_ABSOLUTE_ADDRESS - On a symbol operand, this represents a 41306f32e7eSjoerg /// relocation of: 41406f32e7eSjoerg /// SYMBOL_LABEL + [. - PICBASELABEL] 41506f32e7eSjoerg MO_GOT_ABSOLUTE_ADDRESS, 41606f32e7eSjoerg 41706f32e7eSjoerg /// MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the 41806f32e7eSjoerg /// immediate should get the value of the symbol minus the PIC base label: 41906f32e7eSjoerg /// SYMBOL_LABEL - PICBASELABEL 42006f32e7eSjoerg MO_PIC_BASE_OFFSET, 42106f32e7eSjoerg 42206f32e7eSjoerg /// MO_GOT - On a symbol operand this indicates that the immediate is the 42306f32e7eSjoerg /// offset to the GOT entry for the symbol name from the base of the GOT. 42406f32e7eSjoerg /// 42506f32e7eSjoerg /// See the X86-64 ELF ABI supplement for more details. 42606f32e7eSjoerg /// SYMBOL_LABEL @GOT 42706f32e7eSjoerg MO_GOT, 42806f32e7eSjoerg 42906f32e7eSjoerg /// MO_GOTOFF - On a symbol operand this indicates that the immediate is 43006f32e7eSjoerg /// the offset to the location of the symbol name from the base of the GOT. 43106f32e7eSjoerg /// 43206f32e7eSjoerg /// See the X86-64 ELF ABI supplement for more details. 43306f32e7eSjoerg /// SYMBOL_LABEL @GOTOFF 43406f32e7eSjoerg MO_GOTOFF, 43506f32e7eSjoerg 43606f32e7eSjoerg /// MO_GOTPCREL - On a symbol operand this indicates that the immediate is 43706f32e7eSjoerg /// offset to the GOT entry for the symbol name from the current code 43806f32e7eSjoerg /// location. 43906f32e7eSjoerg /// 44006f32e7eSjoerg /// See the X86-64 ELF ABI supplement for more details. 44106f32e7eSjoerg /// SYMBOL_LABEL @GOTPCREL 44206f32e7eSjoerg MO_GOTPCREL, 44306f32e7eSjoerg 44406f32e7eSjoerg /// MO_PLT - On a symbol operand this indicates that the immediate is 44506f32e7eSjoerg /// offset to the PLT entry of symbol name from the current code location. 44606f32e7eSjoerg /// 44706f32e7eSjoerg /// See the X86-64 ELF ABI supplement for more details. 44806f32e7eSjoerg /// SYMBOL_LABEL @PLT 44906f32e7eSjoerg MO_PLT, 45006f32e7eSjoerg 45106f32e7eSjoerg /// MO_TLSGD - On a symbol operand this indicates that the immediate is 45206f32e7eSjoerg /// the offset of the GOT entry with the TLS index structure that contains 45306f32e7eSjoerg /// the module number and variable offset for the symbol. Used in the 45406f32e7eSjoerg /// general dynamic TLS access model. 45506f32e7eSjoerg /// 45606f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 45706f32e7eSjoerg /// SYMBOL_LABEL @TLSGD 45806f32e7eSjoerg MO_TLSGD, 45906f32e7eSjoerg 46006f32e7eSjoerg /// MO_TLSLD - On a symbol operand this indicates that the immediate is 46106f32e7eSjoerg /// the offset of the GOT entry with the TLS index for the module that 46206f32e7eSjoerg /// contains the symbol. When this index is passed to a call to 46306f32e7eSjoerg /// __tls_get_addr, the function will return the base address of the TLS 46406f32e7eSjoerg /// block for the symbol. Used in the x86-64 local dynamic TLS access model. 46506f32e7eSjoerg /// 46606f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 46706f32e7eSjoerg /// SYMBOL_LABEL @TLSLD 46806f32e7eSjoerg MO_TLSLD, 46906f32e7eSjoerg 47006f32e7eSjoerg /// MO_TLSLDM - On a symbol operand this indicates that the immediate is 47106f32e7eSjoerg /// the offset of the GOT entry with the TLS index for the module that 47206f32e7eSjoerg /// contains the symbol. When this index is passed to a call to 47306f32e7eSjoerg /// ___tls_get_addr, the function will return the base address of the TLS 47406f32e7eSjoerg /// block for the symbol. Used in the IA32 local dynamic TLS access model. 47506f32e7eSjoerg /// 47606f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 47706f32e7eSjoerg /// SYMBOL_LABEL @TLSLDM 47806f32e7eSjoerg MO_TLSLDM, 47906f32e7eSjoerg 48006f32e7eSjoerg /// MO_GOTTPOFF - On a symbol operand this indicates that the immediate is 48106f32e7eSjoerg /// the offset of the GOT entry with the thread-pointer offset for the 48206f32e7eSjoerg /// symbol. Used in the x86-64 initial exec TLS access model. 48306f32e7eSjoerg /// 48406f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 48506f32e7eSjoerg /// SYMBOL_LABEL @GOTTPOFF 48606f32e7eSjoerg MO_GOTTPOFF, 48706f32e7eSjoerg 48806f32e7eSjoerg /// MO_INDNTPOFF - On a symbol operand this indicates that the immediate is 48906f32e7eSjoerg /// the absolute address of the GOT entry with the negative thread-pointer 49006f32e7eSjoerg /// offset for the symbol. Used in the non-PIC IA32 initial exec TLS access 49106f32e7eSjoerg /// model. 49206f32e7eSjoerg /// 49306f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 49406f32e7eSjoerg /// SYMBOL_LABEL @INDNTPOFF 49506f32e7eSjoerg MO_INDNTPOFF, 49606f32e7eSjoerg 49706f32e7eSjoerg /// MO_TPOFF - On a symbol operand this indicates that the immediate is 49806f32e7eSjoerg /// the thread-pointer offset for the symbol. Used in the x86-64 local 49906f32e7eSjoerg /// exec TLS access model. 50006f32e7eSjoerg /// 50106f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 50206f32e7eSjoerg /// SYMBOL_LABEL @TPOFF 50306f32e7eSjoerg MO_TPOFF, 50406f32e7eSjoerg 50506f32e7eSjoerg /// MO_DTPOFF - On a symbol operand this indicates that the immediate is 50606f32e7eSjoerg /// the offset of the GOT entry with the TLS offset of the symbol. Used 50706f32e7eSjoerg /// in the local dynamic TLS access model. 50806f32e7eSjoerg /// 50906f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 51006f32e7eSjoerg /// SYMBOL_LABEL @DTPOFF 51106f32e7eSjoerg MO_DTPOFF, 51206f32e7eSjoerg 51306f32e7eSjoerg /// MO_NTPOFF - On a symbol operand this indicates that the immediate is 51406f32e7eSjoerg /// the negative thread-pointer offset for the symbol. Used in the IA32 51506f32e7eSjoerg /// local exec TLS access model. 51606f32e7eSjoerg /// 51706f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 51806f32e7eSjoerg /// SYMBOL_LABEL @NTPOFF 51906f32e7eSjoerg MO_NTPOFF, 52006f32e7eSjoerg 52106f32e7eSjoerg /// MO_GOTNTPOFF - On a symbol operand this indicates that the immediate is 52206f32e7eSjoerg /// the offset of the GOT entry with the negative thread-pointer offset for 52306f32e7eSjoerg /// the symbol. Used in the PIC IA32 initial exec TLS access model. 52406f32e7eSjoerg /// 52506f32e7eSjoerg /// See 'ELF Handling for Thread-Local Storage' for more details. 52606f32e7eSjoerg /// SYMBOL_LABEL @GOTNTPOFF 52706f32e7eSjoerg MO_GOTNTPOFF, 52806f32e7eSjoerg 52906f32e7eSjoerg /// MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the 53006f32e7eSjoerg /// reference is actually to the "__imp_FOO" symbol. This is used for 53106f32e7eSjoerg /// dllimport linkage on windows. 53206f32e7eSjoerg MO_DLLIMPORT, 53306f32e7eSjoerg 53406f32e7eSjoerg /// MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the 53506f32e7eSjoerg /// reference is actually to the "FOO$non_lazy_ptr" symbol, which is a 53606f32e7eSjoerg /// non-PIC-base-relative reference to a non-hidden dyld lazy pointer stub. 53706f32e7eSjoerg MO_DARWIN_NONLAZY, 53806f32e7eSjoerg 53906f32e7eSjoerg /// MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates 54006f32e7eSjoerg /// that the reference is actually to "FOO$non_lazy_ptr - PICBASE", which is 54106f32e7eSjoerg /// a PIC-base-relative reference to a non-hidden dyld lazy pointer stub. 54206f32e7eSjoerg MO_DARWIN_NONLAZY_PIC_BASE, 54306f32e7eSjoerg 54406f32e7eSjoerg /// MO_TLVP - On a symbol operand this indicates that the immediate is 54506f32e7eSjoerg /// some TLS offset. 54606f32e7eSjoerg /// 54706f32e7eSjoerg /// This is the TLS offset for the Darwin TLS mechanism. 54806f32e7eSjoerg MO_TLVP, 54906f32e7eSjoerg 55006f32e7eSjoerg /// MO_TLVP_PIC_BASE - On a symbol operand this indicates that the immediate 55106f32e7eSjoerg /// is some TLS offset from the picbase. 55206f32e7eSjoerg /// 55306f32e7eSjoerg /// This is the 32-bit TLS offset for Darwin TLS in PIC mode. 55406f32e7eSjoerg MO_TLVP_PIC_BASE, 55506f32e7eSjoerg 55606f32e7eSjoerg /// MO_SECREL - On a symbol operand this indicates that the immediate is 55706f32e7eSjoerg /// the offset from beginning of section. 55806f32e7eSjoerg /// 55906f32e7eSjoerg /// This is the TLS offset for the COFF/Windows TLS mechanism. 56006f32e7eSjoerg MO_SECREL, 56106f32e7eSjoerg 56206f32e7eSjoerg /// MO_ABS8 - On a symbol operand this indicates that the symbol is known 56306f32e7eSjoerg /// to be an absolute symbol in range [0,128), so we can use the @ABS8 56406f32e7eSjoerg /// symbol modifier. 56506f32e7eSjoerg MO_ABS8, 56606f32e7eSjoerg 56706f32e7eSjoerg /// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the 56806f32e7eSjoerg /// reference is actually to the ".refptr.FOO" symbol. This is used for 56906f32e7eSjoerg /// stub symbols on windows. 57006f32e7eSjoerg MO_COFFSTUB, 57106f32e7eSjoerg }; 57206f32e7eSjoerg 57306f32e7eSjoerg enum : uint64_t { 57406f32e7eSjoerg //===------------------------------------------------------------------===// 57506f32e7eSjoerg // Instruction encodings. These are the standard/most common forms for X86 57606f32e7eSjoerg // instructions. 57706f32e7eSjoerg // 57806f32e7eSjoerg 57906f32e7eSjoerg // PseudoFrm - This represents an instruction that is a pseudo instruction 58006f32e7eSjoerg // or one that has not been implemented yet. It is illegal to code generate 58106f32e7eSjoerg // it, but tolerated for intermediate implementation stages. 58206f32e7eSjoerg Pseudo = 0, 58306f32e7eSjoerg 58406f32e7eSjoerg /// Raw - This form is for instructions that don't have any operands, so 58506f32e7eSjoerg /// they are just a fixed opcode value, like 'leave'. 58606f32e7eSjoerg RawFrm = 1, 58706f32e7eSjoerg 58806f32e7eSjoerg /// AddRegFrm - This form is used for instructions like 'push r32' that have 58906f32e7eSjoerg /// their one register operand added to their opcode. 59006f32e7eSjoerg AddRegFrm = 2, 59106f32e7eSjoerg 59206f32e7eSjoerg /// RawFrmMemOffs - This form is for instructions that store an absolute 59306f32e7eSjoerg /// memory offset as an immediate with a possible segment override. 59406f32e7eSjoerg RawFrmMemOffs = 3, 59506f32e7eSjoerg 59606f32e7eSjoerg /// RawFrmSrc - This form is for instructions that use the source index 59706f32e7eSjoerg /// register SI/ESI/RSI with a possible segment override. 59806f32e7eSjoerg RawFrmSrc = 4, 59906f32e7eSjoerg 60006f32e7eSjoerg /// RawFrmDst - This form is for instructions that use the destination index 60106f32e7eSjoerg /// register DI/EDI/RDI. 60206f32e7eSjoerg RawFrmDst = 5, 60306f32e7eSjoerg 60406f32e7eSjoerg /// RawFrmDstSrc - This form is for instructions that use the source index 60506f32e7eSjoerg /// register SI/ESI/RSI with a possible segment override, and also the 60606f32e7eSjoerg /// destination index register DI/EDI/RDI. 60706f32e7eSjoerg RawFrmDstSrc = 6, 60806f32e7eSjoerg 60906f32e7eSjoerg /// RawFrmImm8 - This is used for the ENTER instruction, which has two 61006f32e7eSjoerg /// immediates, the first of which is a 16-bit immediate (specified by 61106f32e7eSjoerg /// the imm encoding) and the second is a 8-bit fixed value. 61206f32e7eSjoerg RawFrmImm8 = 7, 61306f32e7eSjoerg 61406f32e7eSjoerg /// RawFrmImm16 - This is used for CALL FAR instructions, which have two 61506f32e7eSjoerg /// immediates, the first of which is a 16 or 32-bit immediate (specified by 61606f32e7eSjoerg /// the imm encoding) and the second is a 16-bit fixed value. In the AMD 61706f32e7eSjoerg /// manual, this operand is described as pntr16:32 and pntr16:16 61806f32e7eSjoerg RawFrmImm16 = 8, 61906f32e7eSjoerg 62006f32e7eSjoerg /// AddCCFrm - This form is used for Jcc that encode the condition code 62106f32e7eSjoerg /// in the lower 4 bits of the opcode. 62206f32e7eSjoerg AddCCFrm = 9, 62306f32e7eSjoerg 624*da58b97aSjoerg /// PrefixByte - This form is used for instructions that represent a prefix 625*da58b97aSjoerg /// byte like data16 or rep. 626*da58b97aSjoerg PrefixByte = 10, 627*da58b97aSjoerg 62806f32e7eSjoerg /// MRM[0-7][rm] - These forms are used to represent instructions that use 62906f32e7eSjoerg /// a Mod/RM byte, and use the middle field to hold extended opcode 63006f32e7eSjoerg /// information. In the intel manual these are represented as /0, /1, ... 63106f32e7eSjoerg /// 63206f32e7eSjoerg 633*da58b97aSjoerg // Instructions operate on a register Reg/Opcode operand not the r/m field. 634*da58b97aSjoerg MRMr0 = 21, 635*da58b97aSjoerg 636*da58b97aSjoerg /// MRMSrcMem - But force to use the SIB field. 637*da58b97aSjoerg MRMSrcMemFSIB = 22, 638*da58b97aSjoerg 639*da58b97aSjoerg /// MRMDestMem - But force to use the SIB field. 640*da58b97aSjoerg MRMDestMemFSIB = 23, 641*da58b97aSjoerg 64206f32e7eSjoerg /// MRMDestMem - This form is used for instructions that use the Mod/RM byte 64306f32e7eSjoerg /// to specify a destination, which in this case is memory. 64406f32e7eSjoerg /// 645*da58b97aSjoerg MRMDestMem = 24, 64606f32e7eSjoerg 64706f32e7eSjoerg /// MRMSrcMem - This form is used for instructions that use the Mod/RM byte 64806f32e7eSjoerg /// to specify a source, which in this case is memory. 64906f32e7eSjoerg /// 650*da58b97aSjoerg MRMSrcMem = 25, 65106f32e7eSjoerg 65206f32e7eSjoerg /// MRMSrcMem4VOp3 - This form is used for instructions that encode 65306f32e7eSjoerg /// operand 3 with VEX.VVVV and load from memory. 65406f32e7eSjoerg /// 655*da58b97aSjoerg MRMSrcMem4VOp3 = 26, 65606f32e7eSjoerg 65706f32e7eSjoerg /// MRMSrcMemOp4 - This form is used for instructions that use the Mod/RM 65806f32e7eSjoerg /// byte to specify the fourth source, which in this case is memory. 65906f32e7eSjoerg /// 660*da58b97aSjoerg MRMSrcMemOp4 = 27, 66106f32e7eSjoerg 66206f32e7eSjoerg /// MRMSrcMemCC - This form is used for instructions that use the Mod/RM 66306f32e7eSjoerg /// byte to specify the operands and also encodes a condition code. 66406f32e7eSjoerg /// 665*da58b97aSjoerg MRMSrcMemCC = 28, 66606f32e7eSjoerg 66706f32e7eSjoerg /// MRMXm - This form is used for instructions that use the Mod/RM byte 66806f32e7eSjoerg /// to specify a memory source, but doesn't use the middle field. And has 66906f32e7eSjoerg /// a condition code. 67006f32e7eSjoerg /// 671*da58b97aSjoerg MRMXmCC = 30, 67206f32e7eSjoerg 67306f32e7eSjoerg /// MRMXm - This form is used for instructions that use the Mod/RM byte 67406f32e7eSjoerg /// to specify a memory source, but doesn't use the middle field. 67506f32e7eSjoerg /// 676*da58b97aSjoerg MRMXm = 31, 67706f32e7eSjoerg 67806f32e7eSjoerg // Next, instructions that operate on a memory r/m operand... 679*da58b97aSjoerg MRM0m = 32, MRM1m = 33, MRM2m = 34, MRM3m = 35, // Format /0 /1 /2 /3 680*da58b97aSjoerg MRM4m = 36, MRM5m = 37, MRM6m = 38, MRM7m = 39, // Format /4 /5 /6 /7 68106f32e7eSjoerg 68206f32e7eSjoerg /// MRMDestReg - This form is used for instructions that use the Mod/RM byte 68306f32e7eSjoerg /// to specify a destination, which in this case is a register. 68406f32e7eSjoerg /// 685*da58b97aSjoerg MRMDestReg = 40, 68606f32e7eSjoerg 68706f32e7eSjoerg /// MRMSrcReg - This form is used for instructions that use the Mod/RM byte 68806f32e7eSjoerg /// to specify a source, which in this case is a register. 68906f32e7eSjoerg /// 690*da58b97aSjoerg MRMSrcReg = 41, 69106f32e7eSjoerg 69206f32e7eSjoerg /// MRMSrcReg4VOp3 - This form is used for instructions that encode 69306f32e7eSjoerg /// operand 3 with VEX.VVVV and do not load from memory. 69406f32e7eSjoerg /// 695*da58b97aSjoerg MRMSrcReg4VOp3 = 42, 69606f32e7eSjoerg 69706f32e7eSjoerg /// MRMSrcRegOp4 - This form is used for instructions that use the Mod/RM 69806f32e7eSjoerg /// byte to specify the fourth source, which in this case is a register. 69906f32e7eSjoerg /// 700*da58b97aSjoerg MRMSrcRegOp4 = 43, 70106f32e7eSjoerg 70206f32e7eSjoerg /// MRMSrcRegCC - This form is used for instructions that use the Mod/RM 70306f32e7eSjoerg /// byte to specify the operands and also encodes a condition code 70406f32e7eSjoerg /// 705*da58b97aSjoerg MRMSrcRegCC = 44, 70606f32e7eSjoerg 70706f32e7eSjoerg /// MRMXCCr - This form is used for instructions that use the Mod/RM byte 70806f32e7eSjoerg /// to specify a register source, but doesn't use the middle field. And has 70906f32e7eSjoerg /// a condition code. 71006f32e7eSjoerg /// 711*da58b97aSjoerg MRMXrCC = 46, 71206f32e7eSjoerg 71306f32e7eSjoerg /// MRMXr - This form is used for instructions that use the Mod/RM byte 71406f32e7eSjoerg /// to specify a register source, but doesn't use the middle field. 71506f32e7eSjoerg /// 716*da58b97aSjoerg MRMXr = 47, 71706f32e7eSjoerg 71806f32e7eSjoerg // Instructions that operate on a register r/m operand... 719*da58b97aSjoerg MRM0r = 48, MRM1r = 49, MRM2r = 50, MRM3r = 51, // Format /0 /1 /2 /3 720*da58b97aSjoerg MRM4r = 52, MRM5r = 53, MRM6r = 54, MRM7r = 55, // Format /4 /5 /6 /7 721*da58b97aSjoerg 722*da58b97aSjoerg // Instructions that operate that have mod=11 and an opcode but ignore r/m. 723*da58b97aSjoerg MRM0X = 56, MRM1X = 57, MRM2X = 58, MRM3X = 59, // Format /0 /1 /2 /3 724*da58b97aSjoerg MRM4X = 60, MRM5X = 61, MRM6X = 62, MRM7X = 63, // Format /4 /5 /6 /7 72506f32e7eSjoerg 72606f32e7eSjoerg /// MRM_XX - A mod/rm byte of exactly 0xXX. 72706f32e7eSjoerg MRM_C0 = 64, MRM_C1 = 65, MRM_C2 = 66, MRM_C3 = 67, 72806f32e7eSjoerg MRM_C4 = 68, MRM_C5 = 69, MRM_C6 = 70, MRM_C7 = 71, 72906f32e7eSjoerg MRM_C8 = 72, MRM_C9 = 73, MRM_CA = 74, MRM_CB = 75, 73006f32e7eSjoerg MRM_CC = 76, MRM_CD = 77, MRM_CE = 78, MRM_CF = 79, 73106f32e7eSjoerg MRM_D0 = 80, MRM_D1 = 81, MRM_D2 = 82, MRM_D3 = 83, 73206f32e7eSjoerg MRM_D4 = 84, MRM_D5 = 85, MRM_D6 = 86, MRM_D7 = 87, 73306f32e7eSjoerg MRM_D8 = 88, MRM_D9 = 89, MRM_DA = 90, MRM_DB = 91, 73406f32e7eSjoerg MRM_DC = 92, MRM_DD = 93, MRM_DE = 94, MRM_DF = 95, 73506f32e7eSjoerg MRM_E0 = 96, MRM_E1 = 97, MRM_E2 = 98, MRM_E3 = 99, 73606f32e7eSjoerg MRM_E4 = 100, MRM_E5 = 101, MRM_E6 = 102, MRM_E7 = 103, 73706f32e7eSjoerg MRM_E8 = 104, MRM_E9 = 105, MRM_EA = 106, MRM_EB = 107, 73806f32e7eSjoerg MRM_EC = 108, MRM_ED = 109, MRM_EE = 110, MRM_EF = 111, 73906f32e7eSjoerg MRM_F0 = 112, MRM_F1 = 113, MRM_F2 = 114, MRM_F3 = 115, 74006f32e7eSjoerg MRM_F4 = 116, MRM_F5 = 117, MRM_F6 = 118, MRM_F7 = 119, 74106f32e7eSjoerg MRM_F8 = 120, MRM_F9 = 121, MRM_FA = 122, MRM_FB = 123, 74206f32e7eSjoerg MRM_FC = 124, MRM_FD = 125, MRM_FE = 126, MRM_FF = 127, 74306f32e7eSjoerg 74406f32e7eSjoerg FormMask = 127, 74506f32e7eSjoerg 74606f32e7eSjoerg //===------------------------------------------------------------------===// 74706f32e7eSjoerg // Actual flags... 74806f32e7eSjoerg 74906f32e7eSjoerg // OpSize - OpSizeFixed implies instruction never needs a 0x66 prefix. 75006f32e7eSjoerg // OpSize16 means this is a 16-bit instruction and needs 0x66 prefix in 75106f32e7eSjoerg // 32-bit mode. OpSize32 means this is a 32-bit instruction needs a 0x66 75206f32e7eSjoerg // prefix in 16-bit mode. 75306f32e7eSjoerg OpSizeShift = 7, 75406f32e7eSjoerg OpSizeMask = 0x3 << OpSizeShift, 75506f32e7eSjoerg 75606f32e7eSjoerg OpSizeFixed = 0 << OpSizeShift, 75706f32e7eSjoerg OpSize16 = 1 << OpSizeShift, 75806f32e7eSjoerg OpSize32 = 2 << OpSizeShift, 75906f32e7eSjoerg 76006f32e7eSjoerg // AsSize - AdSizeX implies this instruction determines its need of 0x67 76106f32e7eSjoerg // prefix from a normal ModRM memory operand. The other types indicate that 76206f32e7eSjoerg // an operand is encoded with a specific width and a prefix is needed if 76306f32e7eSjoerg // it differs from the current mode. 76406f32e7eSjoerg AdSizeShift = OpSizeShift + 2, 76506f32e7eSjoerg AdSizeMask = 0x3 << AdSizeShift, 76606f32e7eSjoerg 76706f32e7eSjoerg AdSizeX = 0 << AdSizeShift, 76806f32e7eSjoerg AdSize16 = 1 << AdSizeShift, 76906f32e7eSjoerg AdSize32 = 2 << AdSizeShift, 77006f32e7eSjoerg AdSize64 = 3 << AdSizeShift, 77106f32e7eSjoerg 77206f32e7eSjoerg //===------------------------------------------------------------------===// 77306f32e7eSjoerg // OpPrefix - There are several prefix bytes that are used as opcode 77406f32e7eSjoerg // extensions. These are 0x66, 0xF3, and 0xF2. If this field is 0 there is 77506f32e7eSjoerg // no prefix. 77606f32e7eSjoerg // 77706f32e7eSjoerg OpPrefixShift = AdSizeShift + 2, 77806f32e7eSjoerg OpPrefixMask = 0x3 << OpPrefixShift, 77906f32e7eSjoerg 78006f32e7eSjoerg // PD - Prefix code for packed double precision vector floating point 78106f32e7eSjoerg // operations performed in the SSE registers. 78206f32e7eSjoerg PD = 1 << OpPrefixShift, 78306f32e7eSjoerg 78406f32e7eSjoerg // XS, XD - These prefix codes are for single and double precision scalar 78506f32e7eSjoerg // floating point operations performed in the SSE registers. 78606f32e7eSjoerg XS = 2 << OpPrefixShift, XD = 3 << OpPrefixShift, 78706f32e7eSjoerg 78806f32e7eSjoerg //===------------------------------------------------------------------===// 78906f32e7eSjoerg // OpMap - This field determines which opcode map this instruction 79006f32e7eSjoerg // belongs to. i.e. one-byte, two-byte, 0x0f 0x38, 0x0f 0x3a, etc. 79106f32e7eSjoerg // 79206f32e7eSjoerg OpMapShift = OpPrefixShift + 2, 79306f32e7eSjoerg OpMapMask = 0x7 << OpMapShift, 79406f32e7eSjoerg 79506f32e7eSjoerg // OB - OneByte - Set if this instruction has a one byte opcode. 79606f32e7eSjoerg OB = 0 << OpMapShift, 79706f32e7eSjoerg 79806f32e7eSjoerg // TB - TwoByte - Set if this instruction has a two byte opcode, which 79906f32e7eSjoerg // starts with a 0x0F byte before the real opcode. 80006f32e7eSjoerg TB = 1 << OpMapShift, 80106f32e7eSjoerg 80206f32e7eSjoerg // T8, TA - Prefix after the 0x0F prefix. 80306f32e7eSjoerg T8 = 2 << OpMapShift, TA = 3 << OpMapShift, 80406f32e7eSjoerg 80506f32e7eSjoerg // XOP8 - Prefix to include use of imm byte. 80606f32e7eSjoerg XOP8 = 4 << OpMapShift, 80706f32e7eSjoerg 80806f32e7eSjoerg // XOP9 - Prefix to exclude use of imm byte. 80906f32e7eSjoerg XOP9 = 5 << OpMapShift, 81006f32e7eSjoerg 81106f32e7eSjoerg // XOPA - Prefix to encode 0xA in VEX.MMMM of XOP instructions. 81206f32e7eSjoerg XOPA = 6 << OpMapShift, 81306f32e7eSjoerg 81406f32e7eSjoerg /// ThreeDNow - This indicates that the instruction uses the 81506f32e7eSjoerg /// wacky 0x0F 0x0F prefix for 3DNow! instructions. The manual documents 81606f32e7eSjoerg /// this as having a 0x0F prefix with a 0x0F opcode, and each instruction 81706f32e7eSjoerg /// storing a classifier in the imm8 field. To simplify our implementation, 81806f32e7eSjoerg /// we handle this by storeing the classifier in the opcode field and using 81906f32e7eSjoerg /// this flag to indicate that the encoder should do the wacky 3DNow! thing. 82006f32e7eSjoerg ThreeDNow = 7 << OpMapShift, 82106f32e7eSjoerg 82206f32e7eSjoerg //===------------------------------------------------------------------===// 82306f32e7eSjoerg // REX_W - REX prefixes are instruction prefixes used in 64-bit mode. 82406f32e7eSjoerg // They are used to specify GPRs and SSE registers, 64-bit operand size, 82506f32e7eSjoerg // etc. We only cares about REX.W and REX.R bits and only the former is 82606f32e7eSjoerg // statically determined. 82706f32e7eSjoerg // 82806f32e7eSjoerg REXShift = OpMapShift + 3, 82906f32e7eSjoerg REX_W = 1 << REXShift, 83006f32e7eSjoerg 83106f32e7eSjoerg //===------------------------------------------------------------------===// 83206f32e7eSjoerg // This three-bit field describes the size of an immediate operand. Zero is 83306f32e7eSjoerg // unused so that we can tell if we forgot to set a value. 83406f32e7eSjoerg ImmShift = REXShift + 1, 83506f32e7eSjoerg ImmMask = 15 << ImmShift, 83606f32e7eSjoerg Imm8 = 1 << ImmShift, 83706f32e7eSjoerg Imm8PCRel = 2 << ImmShift, 83806f32e7eSjoerg Imm8Reg = 3 << ImmShift, 83906f32e7eSjoerg Imm16 = 4 << ImmShift, 84006f32e7eSjoerg Imm16PCRel = 5 << ImmShift, 84106f32e7eSjoerg Imm32 = 6 << ImmShift, 84206f32e7eSjoerg Imm32PCRel = 7 << ImmShift, 84306f32e7eSjoerg Imm32S = 8 << ImmShift, 84406f32e7eSjoerg Imm64 = 9 << ImmShift, 84506f32e7eSjoerg 84606f32e7eSjoerg //===------------------------------------------------------------------===// 84706f32e7eSjoerg // FP Instruction Classification... Zero is non-fp instruction. 84806f32e7eSjoerg 84906f32e7eSjoerg // FPTypeMask - Mask for all of the FP types... 85006f32e7eSjoerg FPTypeShift = ImmShift + 4, 85106f32e7eSjoerg FPTypeMask = 7 << FPTypeShift, 85206f32e7eSjoerg 85306f32e7eSjoerg // NotFP - The default, set for instructions that do not use FP registers. 85406f32e7eSjoerg NotFP = 0 << FPTypeShift, 85506f32e7eSjoerg 85606f32e7eSjoerg // ZeroArgFP - 0 arg FP instruction which implicitly pushes ST(0), f.e. fld0 85706f32e7eSjoerg ZeroArgFP = 1 << FPTypeShift, 85806f32e7eSjoerg 85906f32e7eSjoerg // OneArgFP - 1 arg FP instructions which implicitly read ST(0), such as fst 86006f32e7eSjoerg OneArgFP = 2 << FPTypeShift, 86106f32e7eSjoerg 86206f32e7eSjoerg // OneArgFPRW - 1 arg FP instruction which implicitly read ST(0) and write a 86306f32e7eSjoerg // result back to ST(0). For example, fcos, fsqrt, etc. 86406f32e7eSjoerg // 86506f32e7eSjoerg OneArgFPRW = 3 << FPTypeShift, 86606f32e7eSjoerg 86706f32e7eSjoerg // TwoArgFP - 2 arg FP instructions which implicitly read ST(0), and an 86806f32e7eSjoerg // explicit argument, storing the result to either ST(0) or the implicit 86906f32e7eSjoerg // argument. For example: fadd, fsub, fmul, etc... 87006f32e7eSjoerg TwoArgFP = 4 << FPTypeShift, 87106f32e7eSjoerg 87206f32e7eSjoerg // CompareFP - 2 arg FP instructions which implicitly read ST(0) and an 87306f32e7eSjoerg // explicit argument, but have no destination. Example: fucom, fucomi, ... 87406f32e7eSjoerg CompareFP = 5 << FPTypeShift, 87506f32e7eSjoerg 87606f32e7eSjoerg // CondMovFP - "2 operand" floating point conditional move instructions. 87706f32e7eSjoerg CondMovFP = 6 << FPTypeShift, 87806f32e7eSjoerg 87906f32e7eSjoerg // SpecialFP - Special instruction forms. Dispatch by opcode explicitly. 88006f32e7eSjoerg SpecialFP = 7 << FPTypeShift, 88106f32e7eSjoerg 88206f32e7eSjoerg // Lock prefix 88306f32e7eSjoerg LOCKShift = FPTypeShift + 3, 88406f32e7eSjoerg LOCK = 1 << LOCKShift, 88506f32e7eSjoerg 88606f32e7eSjoerg // REP prefix 88706f32e7eSjoerg REPShift = LOCKShift + 1, 88806f32e7eSjoerg REP = 1 << REPShift, 88906f32e7eSjoerg 89006f32e7eSjoerg // Execution domain for SSE instructions. 89106f32e7eSjoerg // 0 means normal, non-SSE instruction. 89206f32e7eSjoerg SSEDomainShift = REPShift + 1, 89306f32e7eSjoerg 89406f32e7eSjoerg // Encoding 89506f32e7eSjoerg EncodingShift = SSEDomainShift + 2, 89606f32e7eSjoerg EncodingMask = 0x3 << EncodingShift, 89706f32e7eSjoerg 89806f32e7eSjoerg // VEX - encoding using 0xC4/0xC5 89906f32e7eSjoerg VEX = 1 << EncodingShift, 90006f32e7eSjoerg 90106f32e7eSjoerg /// XOP - Opcode prefix used by XOP instructions. 90206f32e7eSjoerg XOP = 2 << EncodingShift, 90306f32e7eSjoerg 90406f32e7eSjoerg // VEX_EVEX - Specifies that this instruction use EVEX form which provides 90506f32e7eSjoerg // syntax support up to 32 512-bit register operands and up to 7 16-bit 90606f32e7eSjoerg // mask operands as well as source operand data swizzling/memory operand 90706f32e7eSjoerg // conversion, eviction hint, and rounding mode. 90806f32e7eSjoerg EVEX = 3 << EncodingShift, 90906f32e7eSjoerg 91006f32e7eSjoerg // Opcode 91106f32e7eSjoerg OpcodeShift = EncodingShift + 2, 91206f32e7eSjoerg 91306f32e7eSjoerg /// VEX_W - Has a opcode specific functionality, but is used in the same 91406f32e7eSjoerg /// way as REX_W is for regular SSE instructions. 91506f32e7eSjoerg VEX_WShift = OpcodeShift + 8, 91606f32e7eSjoerg VEX_W = 1ULL << VEX_WShift, 91706f32e7eSjoerg 91806f32e7eSjoerg /// VEX_4V - Used to specify an additional AVX/SSE register. Several 2 91906f32e7eSjoerg /// address instructions in SSE are represented as 3 address ones in AVX 92006f32e7eSjoerg /// and the additional register is encoded in VEX_VVVV prefix. 92106f32e7eSjoerg VEX_4VShift = VEX_WShift + 1, 92206f32e7eSjoerg VEX_4V = 1ULL << VEX_4VShift, 92306f32e7eSjoerg 92406f32e7eSjoerg /// VEX_L - Stands for a bit in the VEX opcode prefix meaning the current 92506f32e7eSjoerg /// instruction uses 256-bit wide registers. This is usually auto detected 92606f32e7eSjoerg /// if a VR256 register is used, but some AVX instructions also have this 92706f32e7eSjoerg /// field marked when using a f256 memory references. 92806f32e7eSjoerg VEX_LShift = VEX_4VShift + 1, 92906f32e7eSjoerg VEX_L = 1ULL << VEX_LShift, 93006f32e7eSjoerg 93106f32e7eSjoerg // EVEX_K - Set if this instruction requires masking 93206f32e7eSjoerg EVEX_KShift = VEX_LShift + 1, 93306f32e7eSjoerg EVEX_K = 1ULL << EVEX_KShift, 93406f32e7eSjoerg 93506f32e7eSjoerg // EVEX_Z - Set if this instruction has EVEX.Z field set. 93606f32e7eSjoerg EVEX_ZShift = EVEX_KShift + 1, 93706f32e7eSjoerg EVEX_Z = 1ULL << EVEX_ZShift, 93806f32e7eSjoerg 93906f32e7eSjoerg // EVEX_L2 - Set if this instruction has EVEX.L' field set. 94006f32e7eSjoerg EVEX_L2Shift = EVEX_ZShift + 1, 94106f32e7eSjoerg EVEX_L2 = 1ULL << EVEX_L2Shift, 94206f32e7eSjoerg 94306f32e7eSjoerg // EVEX_B - Set if this instruction has EVEX.B field set. 94406f32e7eSjoerg EVEX_BShift = EVEX_L2Shift + 1, 94506f32e7eSjoerg EVEX_B = 1ULL << EVEX_BShift, 94606f32e7eSjoerg 94706f32e7eSjoerg // The scaling factor for the AVX512's 8-bit compressed displacement. 94806f32e7eSjoerg CD8_Scale_Shift = EVEX_BShift + 1, 94906f32e7eSjoerg CD8_Scale_Mask = 127ULL << CD8_Scale_Shift, 95006f32e7eSjoerg 95106f32e7eSjoerg /// Explicitly specified rounding control 95206f32e7eSjoerg EVEX_RCShift = CD8_Scale_Shift + 7, 95306f32e7eSjoerg EVEX_RC = 1ULL << EVEX_RCShift, 95406f32e7eSjoerg 95506f32e7eSjoerg // NOTRACK prefix 95606f32e7eSjoerg NoTrackShift = EVEX_RCShift + 1, 957*da58b97aSjoerg NOTRACK = 1ULL << NoTrackShift, 958*da58b97aSjoerg 959*da58b97aSjoerg // Force VEX encoding 960*da58b97aSjoerg ExplicitVEXShift = NoTrackShift + 1, 961*da58b97aSjoerg ExplicitVEXPrefix = 1ULL << ExplicitVEXShift 96206f32e7eSjoerg }; 96306f32e7eSjoerg 964*da58b97aSjoerg /// \returns true if the instruction with given opcode is a prefix. isPrefix(uint64_t TSFlags)965*da58b97aSjoerg inline bool isPrefix(uint64_t TSFlags) { 966*da58b97aSjoerg return (TSFlags & X86II::FormMask) == PrefixByte; 967*da58b97aSjoerg } 968*da58b97aSjoerg 969*da58b97aSjoerg /// \returns true if the instruction with given opcode is a pseudo. isPseudo(uint64_t TSFlags)970*da58b97aSjoerg inline bool isPseudo(uint64_t TSFlags) { 971*da58b97aSjoerg return (TSFlags & X86II::FormMask) == Pseudo; 972*da58b97aSjoerg } 973*da58b97aSjoerg 974*da58b97aSjoerg /// \returns the "base" X86 opcode for the specified machine 975*da58b97aSjoerg /// instruction. getBaseOpcodeFor(uint64_t TSFlags)97606f32e7eSjoerg inline uint8_t getBaseOpcodeFor(uint64_t TSFlags) { 97706f32e7eSjoerg return TSFlags >> X86II::OpcodeShift; 97806f32e7eSjoerg } 97906f32e7eSjoerg hasImm(uint64_t TSFlags)98006f32e7eSjoerg inline bool hasImm(uint64_t TSFlags) { 98106f32e7eSjoerg return (TSFlags & X86II::ImmMask) != 0; 98206f32e7eSjoerg } 98306f32e7eSjoerg 984*da58b97aSjoerg /// Decode the "size of immediate" field from the TSFlags field of the 985*da58b97aSjoerg /// specified instruction. getSizeOfImm(uint64_t TSFlags)98606f32e7eSjoerg inline unsigned getSizeOfImm(uint64_t TSFlags) { 98706f32e7eSjoerg switch (TSFlags & X86II::ImmMask) { 98806f32e7eSjoerg default: llvm_unreachable("Unknown immediate size"); 98906f32e7eSjoerg case X86II::Imm8: 99006f32e7eSjoerg case X86II::Imm8PCRel: 99106f32e7eSjoerg case X86II::Imm8Reg: return 1; 99206f32e7eSjoerg case X86II::Imm16: 99306f32e7eSjoerg case X86II::Imm16PCRel: return 2; 99406f32e7eSjoerg case X86II::Imm32: 99506f32e7eSjoerg case X86II::Imm32S: 99606f32e7eSjoerg case X86II::Imm32PCRel: return 4; 99706f32e7eSjoerg case X86II::Imm64: return 8; 99806f32e7eSjoerg } 99906f32e7eSjoerg } 100006f32e7eSjoerg 1001*da58b97aSjoerg /// \returns true if the immediate of the specified instruction's TSFlags 1002*da58b97aSjoerg /// indicates that it is pc relative. isImmPCRel(uint64_t TSFlags)1003*da58b97aSjoerg inline bool isImmPCRel(uint64_t TSFlags) { 100406f32e7eSjoerg switch (TSFlags & X86II::ImmMask) { 100506f32e7eSjoerg default: llvm_unreachable("Unknown immediate size"); 100606f32e7eSjoerg case X86II::Imm8PCRel: 100706f32e7eSjoerg case X86II::Imm16PCRel: 100806f32e7eSjoerg case X86II::Imm32PCRel: 100906f32e7eSjoerg return true; 101006f32e7eSjoerg case X86II::Imm8: 101106f32e7eSjoerg case X86II::Imm8Reg: 101206f32e7eSjoerg case X86II::Imm16: 101306f32e7eSjoerg case X86II::Imm32: 101406f32e7eSjoerg case X86II::Imm32S: 101506f32e7eSjoerg case X86II::Imm64: 101606f32e7eSjoerg return false; 101706f32e7eSjoerg } 101806f32e7eSjoerg } 101906f32e7eSjoerg 1020*da58b97aSjoerg /// \returns true if the immediate of the specified instruction's 102106f32e7eSjoerg /// TSFlags indicates that it is signed. isImmSigned(uint64_t TSFlags)1022*da58b97aSjoerg inline bool isImmSigned(uint64_t TSFlags) { 102306f32e7eSjoerg switch (TSFlags & X86II::ImmMask) { 102406f32e7eSjoerg default: llvm_unreachable("Unknown immediate signedness"); 102506f32e7eSjoerg case X86II::Imm32S: 102606f32e7eSjoerg return true; 102706f32e7eSjoerg case X86II::Imm8: 102806f32e7eSjoerg case X86II::Imm8PCRel: 102906f32e7eSjoerg case X86II::Imm8Reg: 103006f32e7eSjoerg case X86II::Imm16: 103106f32e7eSjoerg case X86II::Imm16PCRel: 103206f32e7eSjoerg case X86II::Imm32: 103306f32e7eSjoerg case X86II::Imm32PCRel: 103406f32e7eSjoerg case X86II::Imm64: 103506f32e7eSjoerg return false; 103606f32e7eSjoerg } 103706f32e7eSjoerg } 103806f32e7eSjoerg 1039*da58b97aSjoerg /// Compute whether all of the def operands are repeated in the uses and 1040*da58b97aSjoerg /// therefore should be skipped. 104106f32e7eSjoerg /// This determines the start of the unique operand list. We need to determine 104206f32e7eSjoerg /// if all of the defs have a corresponding tied operand in the uses. 104306f32e7eSjoerg /// Unfortunately, the tied operand information is encoded in the uses not 104406f32e7eSjoerg /// the defs so we have to use some heuristics to find which operands to 104506f32e7eSjoerg /// query. getOperandBias(const MCInstrDesc & Desc)104606f32e7eSjoerg inline unsigned getOperandBias(const MCInstrDesc& Desc) { 104706f32e7eSjoerg unsigned NumDefs = Desc.getNumDefs(); 104806f32e7eSjoerg unsigned NumOps = Desc.getNumOperands(); 104906f32e7eSjoerg switch (NumDefs) { 105006f32e7eSjoerg default: llvm_unreachable("Unexpected number of defs"); 105106f32e7eSjoerg case 0: 105206f32e7eSjoerg return 0; 105306f32e7eSjoerg case 1: 105406f32e7eSjoerg // Common two addr case. 105506f32e7eSjoerg if (NumOps > 1 && Desc.getOperandConstraint(1, MCOI::TIED_TO) == 0) 105606f32e7eSjoerg return 1; 105706f32e7eSjoerg // Check for AVX-512 scatter which has a TIED_TO in the second to last 105806f32e7eSjoerg // operand. 105906f32e7eSjoerg if (NumOps == 8 && 106006f32e7eSjoerg Desc.getOperandConstraint(6, MCOI::TIED_TO) == 0) 106106f32e7eSjoerg return 1; 106206f32e7eSjoerg return 0; 106306f32e7eSjoerg case 2: 106406f32e7eSjoerg // XCHG/XADD have two destinations and two sources. 106506f32e7eSjoerg if (NumOps >= 4 && Desc.getOperandConstraint(2, MCOI::TIED_TO) == 0 && 106606f32e7eSjoerg Desc.getOperandConstraint(3, MCOI::TIED_TO) == 1) 106706f32e7eSjoerg return 2; 106806f32e7eSjoerg // Check for gather. AVX-512 has the second tied operand early. AVX2 106906f32e7eSjoerg // has it as the last op. 107006f32e7eSjoerg if (NumOps == 9 && Desc.getOperandConstraint(2, MCOI::TIED_TO) == 0 && 107106f32e7eSjoerg (Desc.getOperandConstraint(3, MCOI::TIED_TO) == 1 || 107206f32e7eSjoerg Desc.getOperandConstraint(8, MCOI::TIED_TO) == 1)) 107306f32e7eSjoerg return 2; 107406f32e7eSjoerg return 0; 107506f32e7eSjoerg } 107606f32e7eSjoerg } 107706f32e7eSjoerg 1078*da58b97aSjoerg /// The function returns the MCInst operand # for the first field of the 1079*da58b97aSjoerg /// memory operand. If the instruction doesn't have a 108006f32e7eSjoerg /// memory operand, this returns -1. 108106f32e7eSjoerg /// 108206f32e7eSjoerg /// Note that this ignores tied operands. If there is a tied register which 108306f32e7eSjoerg /// is duplicated in the MCInst (e.g. "EAX = addl EAX, [mem]") it is only 108406f32e7eSjoerg /// counted as one operand. 108506f32e7eSjoerg /// getMemoryOperandNo(uint64_t TSFlags)108606f32e7eSjoerg inline int getMemoryOperandNo(uint64_t TSFlags) { 108706f32e7eSjoerg bool HasVEX_4V = TSFlags & X86II::VEX_4V; 108806f32e7eSjoerg bool HasEVEX_K = TSFlags & X86II::EVEX_K; 108906f32e7eSjoerg 109006f32e7eSjoerg switch (TSFlags & X86II::FormMask) { 109106f32e7eSjoerg default: llvm_unreachable("Unknown FormMask value in getMemoryOperandNo!"); 109206f32e7eSjoerg case X86II::Pseudo: 109306f32e7eSjoerg case X86II::RawFrm: 109406f32e7eSjoerg case X86II::AddRegFrm: 109506f32e7eSjoerg case X86II::RawFrmImm8: 109606f32e7eSjoerg case X86II::RawFrmImm16: 109706f32e7eSjoerg case X86II::RawFrmMemOffs: 109806f32e7eSjoerg case X86II::RawFrmSrc: 109906f32e7eSjoerg case X86II::RawFrmDst: 110006f32e7eSjoerg case X86II::RawFrmDstSrc: 110106f32e7eSjoerg case X86II::AddCCFrm: 1102*da58b97aSjoerg case X86II::PrefixByte: 110306f32e7eSjoerg return -1; 110406f32e7eSjoerg case X86II::MRMDestMem: 1105*da58b97aSjoerg case X86II::MRMDestMemFSIB: 110606f32e7eSjoerg return 0; 110706f32e7eSjoerg case X86II::MRMSrcMem: 1108*da58b97aSjoerg case X86II::MRMSrcMemFSIB: 110906f32e7eSjoerg // Start from 1, skip any registers encoded in VEX_VVVV or I8IMM, or a 111006f32e7eSjoerg // mask register. 111106f32e7eSjoerg return 1 + HasVEX_4V + HasEVEX_K; 111206f32e7eSjoerg case X86II::MRMSrcMem4VOp3: 111306f32e7eSjoerg // Skip registers encoded in reg. 111406f32e7eSjoerg return 1 + HasEVEX_K; 111506f32e7eSjoerg case X86II::MRMSrcMemOp4: 111606f32e7eSjoerg // Skip registers encoded in reg, VEX_VVVV, and I8IMM. 111706f32e7eSjoerg return 3; 111806f32e7eSjoerg case X86II::MRMSrcMemCC: 111906f32e7eSjoerg // Start from 1, skip any registers encoded in VEX_VVVV or I8IMM, or a 112006f32e7eSjoerg // mask register. 112106f32e7eSjoerg return 1; 112206f32e7eSjoerg case X86II::MRMDestReg: 112306f32e7eSjoerg case X86II::MRMSrcReg: 112406f32e7eSjoerg case X86II::MRMSrcReg4VOp3: 112506f32e7eSjoerg case X86II::MRMSrcRegOp4: 112606f32e7eSjoerg case X86II::MRMSrcRegCC: 112706f32e7eSjoerg case X86II::MRMXrCC: 1128*da58b97aSjoerg case X86II::MRMr0: 112906f32e7eSjoerg case X86II::MRMXr: 113006f32e7eSjoerg case X86II::MRM0r: case X86II::MRM1r: 113106f32e7eSjoerg case X86II::MRM2r: case X86II::MRM3r: 113206f32e7eSjoerg case X86II::MRM4r: case X86II::MRM5r: 113306f32e7eSjoerg case X86II::MRM6r: case X86II::MRM7r: 113406f32e7eSjoerg return -1; 1135*da58b97aSjoerg case X86II::MRM0X: case X86II::MRM1X: 1136*da58b97aSjoerg case X86II::MRM2X: case X86II::MRM3X: 1137*da58b97aSjoerg case X86II::MRM4X: case X86II::MRM5X: 1138*da58b97aSjoerg case X86II::MRM6X: case X86II::MRM7X: 1139*da58b97aSjoerg return -1; 114006f32e7eSjoerg case X86II::MRMXmCC: 114106f32e7eSjoerg case X86II::MRMXm: 114206f32e7eSjoerg case X86II::MRM0m: case X86II::MRM1m: 114306f32e7eSjoerg case X86II::MRM2m: case X86II::MRM3m: 114406f32e7eSjoerg case X86II::MRM4m: case X86II::MRM5m: 114506f32e7eSjoerg case X86II::MRM6m: case X86II::MRM7m: 114606f32e7eSjoerg // Start from 0, skip registers encoded in VEX_VVVV or a mask register. 114706f32e7eSjoerg return 0 + HasVEX_4V + HasEVEX_K; 114806f32e7eSjoerg case X86II::MRM_C0: case X86II::MRM_C1: case X86II::MRM_C2: 114906f32e7eSjoerg case X86II::MRM_C3: case X86II::MRM_C4: case X86II::MRM_C5: 115006f32e7eSjoerg case X86II::MRM_C6: case X86II::MRM_C7: case X86II::MRM_C8: 115106f32e7eSjoerg case X86II::MRM_C9: case X86II::MRM_CA: case X86II::MRM_CB: 115206f32e7eSjoerg case X86II::MRM_CC: case X86II::MRM_CD: case X86II::MRM_CE: 115306f32e7eSjoerg case X86II::MRM_CF: case X86II::MRM_D0: case X86II::MRM_D1: 115406f32e7eSjoerg case X86II::MRM_D2: case X86II::MRM_D3: case X86II::MRM_D4: 115506f32e7eSjoerg case X86II::MRM_D5: case X86II::MRM_D6: case X86II::MRM_D7: 115606f32e7eSjoerg case X86II::MRM_D8: case X86II::MRM_D9: case X86II::MRM_DA: 115706f32e7eSjoerg case X86II::MRM_DB: case X86II::MRM_DC: case X86II::MRM_DD: 115806f32e7eSjoerg case X86II::MRM_DE: case X86II::MRM_DF: case X86II::MRM_E0: 115906f32e7eSjoerg case X86II::MRM_E1: case X86II::MRM_E2: case X86II::MRM_E3: 116006f32e7eSjoerg case X86II::MRM_E4: case X86II::MRM_E5: case X86II::MRM_E6: 116106f32e7eSjoerg case X86II::MRM_E7: case X86II::MRM_E8: case X86II::MRM_E9: 116206f32e7eSjoerg case X86II::MRM_EA: case X86II::MRM_EB: case X86II::MRM_EC: 116306f32e7eSjoerg case X86II::MRM_ED: case X86II::MRM_EE: case X86II::MRM_EF: 116406f32e7eSjoerg case X86II::MRM_F0: case X86II::MRM_F1: case X86II::MRM_F2: 116506f32e7eSjoerg case X86II::MRM_F3: case X86II::MRM_F4: case X86II::MRM_F5: 116606f32e7eSjoerg case X86II::MRM_F6: case X86II::MRM_F7: case X86II::MRM_F8: 116706f32e7eSjoerg case X86II::MRM_F9: case X86II::MRM_FA: case X86II::MRM_FB: 116806f32e7eSjoerg case X86II::MRM_FC: case X86II::MRM_FD: case X86II::MRM_FE: 116906f32e7eSjoerg case X86II::MRM_FF: 117006f32e7eSjoerg return -1; 117106f32e7eSjoerg } 117206f32e7eSjoerg } 117306f32e7eSjoerg 1174*da58b97aSjoerg /// \returns true if the MachineOperand is a x86-64 extended (r8 or 1175*da58b97aSjoerg /// higher) register, e.g. r8, xmm8, xmm13, etc. isX86_64ExtendedReg(unsigned RegNo)117606f32e7eSjoerg inline bool isX86_64ExtendedReg(unsigned RegNo) { 117706f32e7eSjoerg if ((RegNo >= X86::XMM8 && RegNo <= X86::XMM31) || 117806f32e7eSjoerg (RegNo >= X86::YMM8 && RegNo <= X86::YMM31) || 117906f32e7eSjoerg (RegNo >= X86::ZMM8 && RegNo <= X86::ZMM31)) 118006f32e7eSjoerg return true; 118106f32e7eSjoerg 118206f32e7eSjoerg switch (RegNo) { 118306f32e7eSjoerg default: break; 118406f32e7eSjoerg case X86::R8: case X86::R9: case X86::R10: case X86::R11: 118506f32e7eSjoerg case X86::R12: case X86::R13: case X86::R14: case X86::R15: 118606f32e7eSjoerg case X86::R8D: case X86::R9D: case X86::R10D: case X86::R11D: 118706f32e7eSjoerg case X86::R12D: case X86::R13D: case X86::R14D: case X86::R15D: 118806f32e7eSjoerg case X86::R8W: case X86::R9W: case X86::R10W: case X86::R11W: 118906f32e7eSjoerg case X86::R12W: case X86::R13W: case X86::R14W: case X86::R15W: 119006f32e7eSjoerg case X86::R8B: case X86::R9B: case X86::R10B: case X86::R11B: 119106f32e7eSjoerg case X86::R12B: case X86::R13B: case X86::R14B: case X86::R15B: 119206f32e7eSjoerg case X86::CR8: case X86::CR9: case X86::CR10: case X86::CR11: 119306f32e7eSjoerg case X86::CR12: case X86::CR13: case X86::CR14: case X86::CR15: 119406f32e7eSjoerg case X86::DR8: case X86::DR9: case X86::DR10: case X86::DR11: 119506f32e7eSjoerg case X86::DR12: case X86::DR13: case X86::DR14: case X86::DR15: 119606f32e7eSjoerg return true; 119706f32e7eSjoerg } 119806f32e7eSjoerg return false; 119906f32e7eSjoerg } 120006f32e7eSjoerg 1201*da58b97aSjoerg /// \returns true if the MemoryOperand is a 32 extended (zmm16 or higher) 1202*da58b97aSjoerg /// registers, e.g. zmm21, etc. is32ExtendedReg(unsigned RegNo)120306f32e7eSjoerg static inline bool is32ExtendedReg(unsigned RegNo) { 120406f32e7eSjoerg return ((RegNo >= X86::XMM16 && RegNo <= X86::XMM31) || 120506f32e7eSjoerg (RegNo >= X86::YMM16 && RegNo <= X86::YMM31) || 120606f32e7eSjoerg (RegNo >= X86::ZMM16 && RegNo <= X86::ZMM31)); 120706f32e7eSjoerg } 120806f32e7eSjoerg 120906f32e7eSjoerg isX86_64NonExtLowByteReg(unsigned reg)121006f32e7eSjoerg inline bool isX86_64NonExtLowByteReg(unsigned reg) { 121106f32e7eSjoerg return (reg == X86::SPL || reg == X86::BPL || 121206f32e7eSjoerg reg == X86::SIL || reg == X86::DIL); 121306f32e7eSjoerg } 121406f32e7eSjoerg 1215*da58b97aSjoerg /// \returns true if this is a masked instruction. isKMasked(uint64_t TSFlags)121606f32e7eSjoerg inline bool isKMasked(uint64_t TSFlags) { 121706f32e7eSjoerg return (TSFlags & X86II::EVEX_K) != 0; 121806f32e7eSjoerg } 121906f32e7eSjoerg 1220*da58b97aSjoerg /// \returns true if this is a merge masked instruction. isKMergeMasked(uint64_t TSFlags)122106f32e7eSjoerg inline bool isKMergeMasked(uint64_t TSFlags) { 122206f32e7eSjoerg return isKMasked(TSFlags) && (TSFlags & X86II::EVEX_Z) == 0; 122306f32e7eSjoerg } 122406f32e7eSjoerg } 122506f32e7eSjoerg 122606f32e7eSjoerg } // end namespace llvm; 122706f32e7eSjoerg 122806f32e7eSjoerg #endif 1229