10b57cec5SDimitry Andric //===-- X86BaseInfo.h - Top level definitions for X86 -------- --*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains small standalone helper functions and enum definitions for 100b57cec5SDimitry Andric // the X86 target useful for the compiler back-end and the MC libraries. 110b57cec5SDimitry Andric // As such, it deliberately does not include references to LLVM core 120b57cec5SDimitry Andric // code gen types, passes, etc.. 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_X86_MCTARGETDESC_X86BASEINFO_H 170b57cec5SDimitry Andric #define LLVM_LIB_TARGET_X86_MCTARGETDESC_X86BASEINFO_H 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric #include "X86MCTargetDesc.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 210b57cec5SDimitry Andric #include "llvm/Support/DataTypes.h" 220b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace llvm { 250b57cec5SDimitry Andric namespace X86 { 260b57cec5SDimitry Andric // Enums for memory operand decoding. Each memory operand is represented with 275f757f3fSDimitry Andric // a 5 operand sequence in the form: [Base, Scale, Index, Disp, Segment] 280b57cec5SDimitry Andric enum { 290b57cec5SDimitry Andric AddrBaseReg = 0, 300b57cec5SDimitry Andric AddrScaleAmt = 1, 310b57cec5SDimitry Andric AddrIndexReg = 2, 320b57cec5SDimitry Andric AddrDisp = 3, 335f757f3fSDimitry Andric // The operand # of the segment in the memory operand. 340b57cec5SDimitry Andric AddrSegmentReg = 4, 355f757f3fSDimitry Andric // Total number of operands in a memory reference. 360b57cec5SDimitry Andric AddrNumOperands = 5 370b57cec5SDimitry Andric }; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric /// AVX512 static rounding constants. These need to match the values in 400b57cec5SDimitry Andric /// avx512fintrin.h. 410b57cec5SDimitry Andric enum STATIC_ROUNDING { 420b57cec5SDimitry Andric TO_NEAREST_INT = 0, 430b57cec5SDimitry Andric TO_NEG_INF = 1, 440b57cec5SDimitry Andric TO_POS_INF = 2, 450b57cec5SDimitry Andric TO_ZERO = 3, 460b57cec5SDimitry Andric CUR_DIRECTION = 4, 470b57cec5SDimitry Andric NO_EXC = 8 480b57cec5SDimitry Andric }; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric /// The constants to describe instr prefixes if there are 510b57cec5SDimitry Andric enum IPREFIXES { 520b57cec5SDimitry Andric IP_NO_PREFIX = 0, 53e8d8bef9SDimitry Andric IP_HAS_OP_SIZE = 1U << 0, 54e8d8bef9SDimitry Andric IP_HAS_AD_SIZE = 1U << 1, 55e8d8bef9SDimitry Andric IP_HAS_REPEAT_NE = 1U << 2, 56e8d8bef9SDimitry Andric IP_HAS_REPEAT = 1U << 3, 57e8d8bef9SDimitry Andric IP_HAS_LOCK = 1U << 4, 58e8d8bef9SDimitry Andric IP_HAS_NOTRACK = 1U << 5, 59*0fca6ea1SDimitry Andric IP_USE_REX = 1U << 6, 60*0fca6ea1SDimitry Andric IP_USE_REX2 = 1U << 7, 61*0fca6ea1SDimitry Andric IP_USE_VEX = 1U << 8, 62*0fca6ea1SDimitry Andric IP_USE_VEX2 = 1U << 9, 63*0fca6ea1SDimitry Andric IP_USE_VEX3 = 1U << 10, 64*0fca6ea1SDimitry Andric IP_USE_EVEX = 1U << 11, 65*0fca6ea1SDimitry Andric IP_USE_DISP8 = 1U << 12, 66*0fca6ea1SDimitry Andric IP_USE_DISP32 = 1U << 13, 670b57cec5SDimitry Andric }; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric enum OperandType : unsigned { 705f757f3fSDimitry Andric // AVX512 embedded rounding control. This should only have values 0-3. 710b57cec5SDimitry Andric OPERAND_ROUNDING_CONTROL = MCOI::OPERAND_FIRST_TARGET, 720b57cec5SDimitry Andric OPERAND_COND_CODE, 730b57cec5SDimitry Andric }; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric // X86 specific condition code. These correspond to X86_*_COND in 760b57cec5SDimitry Andric // X86InstrInfo.td. They must be kept in synch. 770b57cec5SDimitry Andric enum CondCode { 780b57cec5SDimitry Andric COND_O = 0, 790b57cec5SDimitry Andric COND_NO = 1, 800b57cec5SDimitry Andric COND_B = 2, 810b57cec5SDimitry Andric COND_AE = 3, 820b57cec5SDimitry Andric COND_E = 4, 830b57cec5SDimitry Andric COND_NE = 5, 840b57cec5SDimitry Andric COND_BE = 6, 850b57cec5SDimitry Andric COND_A = 7, 860b57cec5SDimitry Andric COND_S = 8, 870b57cec5SDimitry Andric COND_NS = 9, 880b57cec5SDimitry Andric COND_P = 10, 890b57cec5SDimitry Andric COND_NP = 11, 900b57cec5SDimitry Andric COND_L = 12, 910b57cec5SDimitry Andric COND_GE = 13, 920b57cec5SDimitry Andric COND_LE = 14, 930b57cec5SDimitry Andric COND_G = 15, 940b57cec5SDimitry Andric LAST_VALID_COND = COND_G, 955ffd83dbSDimitry Andric // Artificial condition codes. These are used by analyzeBranch 960b57cec5SDimitry Andric // to indicate a block terminated with two conditional branches that together 970b57cec5SDimitry Andric // form a compound condition. They occur in code using FCMP_OEQ or FCMP_UNE, 980b57cec5SDimitry Andric // which can't be represented on x86 with a single condition. These 990b57cec5SDimitry Andric // are never used in MachineInstrs and are inverses of one another. 1000b57cec5SDimitry Andric COND_NE_OR_P, 1010b57cec5SDimitry Andric COND_E_AND_NP, 1020b57cec5SDimitry Andric COND_INVALID 1030b57cec5SDimitry Andric }; 104480093f4SDimitry Andric 105480093f4SDimitry Andric // The classification for the first instruction in macro fusion. 106fe6060f1SDimitry Andric // FIXME: Zen 3 support branch fusion for OR/XOR. 1075f757f3fSDimitry Andric enum class FirstMacroFusionInstKind { 1085f757f3fSDimitry Andric Test, // TEST 1095f757f3fSDimitry Andric Cmp, // CMP 1105f757f3fSDimitry Andric And, // AND 1115f757f3fSDimitry Andric AddSub, // ADD, SUB 1125f757f3fSDimitry Andric IncDec, // INC, DEC 1135f757f3fSDimitry Andric Invalid // Not valid as a first macro fusion instruction 114480093f4SDimitry Andric }; 115480093f4SDimitry Andric 116480093f4SDimitry Andric enum class SecondMacroFusionInstKind { 1175f757f3fSDimitry Andric AB, // JA, JB and variants 1185f757f3fSDimitry Andric ELG, // JE, JL, JG and variants 1195f757f3fSDimitry Andric SPO, // JS, JP, JO and variants 1205f757f3fSDimitry Andric Invalid, // Not a fusible jump. 121480093f4SDimitry Andric }; 122480093f4SDimitry Andric 123480093f4SDimitry Andric /// \returns the type of the first instruction in macro-fusion. 1245f757f3fSDimitry Andric // FIXME: Zen 3 support branch fusion for OR/XOR. 125480093f4SDimitry Andric inline FirstMacroFusionInstKind 126480093f4SDimitry Andric classifyFirstOpcodeInMacroFusion(unsigned Opcode) { 127480093f4SDimitry Andric switch (Opcode) { 128480093f4SDimitry Andric default: 129480093f4SDimitry Andric return FirstMacroFusionInstKind::Invalid; 130480093f4SDimitry Andric // TEST 131480093f4SDimitry Andric case X86::TEST16i16: 132480093f4SDimitry Andric case X86::TEST16mr: 133480093f4SDimitry Andric case X86::TEST16ri: 134480093f4SDimitry Andric case X86::TEST16rr: 135480093f4SDimitry Andric case X86::TEST32i32: 136480093f4SDimitry Andric case X86::TEST32mr: 137480093f4SDimitry Andric case X86::TEST32ri: 138480093f4SDimitry Andric case X86::TEST32rr: 139480093f4SDimitry Andric case X86::TEST64i32: 140480093f4SDimitry Andric case X86::TEST64mr: 141480093f4SDimitry Andric case X86::TEST64ri32: 142480093f4SDimitry Andric case X86::TEST64rr: 143480093f4SDimitry Andric case X86::TEST8i8: 144480093f4SDimitry Andric case X86::TEST8mr: 145480093f4SDimitry Andric case X86::TEST8ri: 146480093f4SDimitry Andric case X86::TEST8rr: 147480093f4SDimitry Andric return FirstMacroFusionInstKind::Test; 148480093f4SDimitry Andric case X86::AND16i16: 149480093f4SDimitry Andric case X86::AND16ri: 150480093f4SDimitry Andric case X86::AND16ri8: 151480093f4SDimitry Andric case X86::AND16rm: 152480093f4SDimitry Andric case X86::AND16rr: 153480093f4SDimitry Andric case X86::AND32i32: 154480093f4SDimitry Andric case X86::AND32ri: 155480093f4SDimitry Andric case X86::AND32ri8: 156480093f4SDimitry Andric case X86::AND32rm: 157480093f4SDimitry Andric case X86::AND32rr: 158480093f4SDimitry Andric case X86::AND64i32: 159480093f4SDimitry Andric case X86::AND64ri32: 160480093f4SDimitry Andric case X86::AND64ri8: 161480093f4SDimitry Andric case X86::AND64rm: 162480093f4SDimitry Andric case X86::AND64rr: 163480093f4SDimitry Andric case X86::AND8i8: 164480093f4SDimitry Andric case X86::AND8ri: 165480093f4SDimitry Andric case X86::AND8ri8: 166480093f4SDimitry Andric case X86::AND8rm: 167480093f4SDimitry Andric case X86::AND8rr: 168480093f4SDimitry Andric return FirstMacroFusionInstKind::And; 169480093f4SDimitry Andric // CMP 170480093f4SDimitry Andric case X86::CMP16i16: 171480093f4SDimitry Andric case X86::CMP16mr: 172480093f4SDimitry Andric case X86::CMP16ri: 173480093f4SDimitry Andric case X86::CMP16ri8: 174480093f4SDimitry Andric case X86::CMP16rm: 175480093f4SDimitry Andric case X86::CMP16rr: 176480093f4SDimitry Andric case X86::CMP32i32: 177480093f4SDimitry Andric case X86::CMP32mr: 178480093f4SDimitry Andric case X86::CMP32ri: 179480093f4SDimitry Andric case X86::CMP32ri8: 180480093f4SDimitry Andric case X86::CMP32rm: 181480093f4SDimitry Andric case X86::CMP32rr: 182480093f4SDimitry Andric case X86::CMP64i32: 183480093f4SDimitry Andric case X86::CMP64mr: 184480093f4SDimitry Andric case X86::CMP64ri32: 185480093f4SDimitry Andric case X86::CMP64ri8: 186480093f4SDimitry Andric case X86::CMP64rm: 187480093f4SDimitry Andric case X86::CMP64rr: 188480093f4SDimitry Andric case X86::CMP8i8: 189480093f4SDimitry Andric case X86::CMP8mr: 190480093f4SDimitry Andric case X86::CMP8ri: 191480093f4SDimitry Andric case X86::CMP8ri8: 192480093f4SDimitry Andric case X86::CMP8rm: 193480093f4SDimitry Andric case X86::CMP8rr: 194480093f4SDimitry Andric return FirstMacroFusionInstKind::Cmp; 195480093f4SDimitry Andric // ADD 196480093f4SDimitry Andric case X86::ADD16i16: 197480093f4SDimitry Andric case X86::ADD16ri: 198480093f4SDimitry Andric case X86::ADD16ri8: 199480093f4SDimitry Andric case X86::ADD16rm: 200480093f4SDimitry Andric case X86::ADD16rr: 201480093f4SDimitry Andric case X86::ADD32i32: 202480093f4SDimitry Andric case X86::ADD32ri: 203480093f4SDimitry Andric case X86::ADD32ri8: 204480093f4SDimitry Andric case X86::ADD32rm: 205480093f4SDimitry Andric case X86::ADD32rr: 206480093f4SDimitry Andric case X86::ADD64i32: 207480093f4SDimitry Andric case X86::ADD64ri32: 208480093f4SDimitry Andric case X86::ADD64ri8: 209480093f4SDimitry Andric case X86::ADD64rm: 210480093f4SDimitry Andric case X86::ADD64rr: 211480093f4SDimitry Andric case X86::ADD8i8: 212480093f4SDimitry Andric case X86::ADD8ri: 213480093f4SDimitry Andric case X86::ADD8ri8: 214480093f4SDimitry Andric case X86::ADD8rm: 215480093f4SDimitry Andric case X86::ADD8rr: 216480093f4SDimitry Andric // SUB 217480093f4SDimitry Andric case X86::SUB16i16: 218480093f4SDimitry Andric case X86::SUB16ri: 219480093f4SDimitry Andric case X86::SUB16ri8: 220480093f4SDimitry Andric case X86::SUB16rm: 221480093f4SDimitry Andric case X86::SUB16rr: 222480093f4SDimitry Andric case X86::SUB32i32: 223480093f4SDimitry Andric case X86::SUB32ri: 224480093f4SDimitry Andric case X86::SUB32ri8: 225480093f4SDimitry Andric case X86::SUB32rm: 226480093f4SDimitry Andric case X86::SUB32rr: 227480093f4SDimitry Andric case X86::SUB64i32: 228480093f4SDimitry Andric case X86::SUB64ri32: 229480093f4SDimitry Andric case X86::SUB64ri8: 230480093f4SDimitry Andric case X86::SUB64rm: 231480093f4SDimitry Andric case X86::SUB64rr: 232480093f4SDimitry Andric case X86::SUB8i8: 233480093f4SDimitry Andric case X86::SUB8ri: 234480093f4SDimitry Andric case X86::SUB8ri8: 235480093f4SDimitry Andric case X86::SUB8rm: 236480093f4SDimitry Andric case X86::SUB8rr: 237480093f4SDimitry Andric return FirstMacroFusionInstKind::AddSub; 238480093f4SDimitry Andric // INC 239480093f4SDimitry Andric case X86::INC16r: 240480093f4SDimitry Andric case X86::INC16r_alt: 241480093f4SDimitry Andric case X86::INC32r: 242480093f4SDimitry Andric case X86::INC32r_alt: 243480093f4SDimitry Andric case X86::INC64r: 244480093f4SDimitry Andric case X86::INC8r: 245480093f4SDimitry Andric // DEC 246480093f4SDimitry Andric case X86::DEC16r: 247480093f4SDimitry Andric case X86::DEC16r_alt: 248480093f4SDimitry Andric case X86::DEC32r: 249480093f4SDimitry Andric case X86::DEC32r_alt: 250480093f4SDimitry Andric case X86::DEC64r: 251480093f4SDimitry Andric case X86::DEC8r: 252480093f4SDimitry Andric return FirstMacroFusionInstKind::IncDec; 253480093f4SDimitry Andric } 254480093f4SDimitry Andric } 255480093f4SDimitry Andric 256480093f4SDimitry Andric /// \returns the type of the second instruction in macro-fusion. 257480093f4SDimitry Andric inline SecondMacroFusionInstKind 258480093f4SDimitry Andric classifySecondCondCodeInMacroFusion(X86::CondCode CC) { 259480093f4SDimitry Andric if (CC == X86::COND_INVALID) 260480093f4SDimitry Andric return SecondMacroFusionInstKind::Invalid; 261480093f4SDimitry Andric switch (CC) { 262480093f4SDimitry Andric default: 263480093f4SDimitry Andric return SecondMacroFusionInstKind::Invalid; 2645f757f3fSDimitry Andric case X86::COND_E: // JE,JZ 2655f757f3fSDimitry Andric case X86::COND_NE: // JNE,JNZ 2665f757f3fSDimitry Andric case X86::COND_L: // JL,JNGE 2675f757f3fSDimitry Andric case X86::COND_LE: // JLE,JNG 2685f757f3fSDimitry Andric case X86::COND_G: // JG,JNLE 2695f757f3fSDimitry Andric case X86::COND_GE: // JGE,JNL 270480093f4SDimitry Andric return SecondMacroFusionInstKind::ELG; 2715f757f3fSDimitry Andric case X86::COND_B: // JB,JC 2725f757f3fSDimitry Andric case X86::COND_BE: // JNA,JBE 2735f757f3fSDimitry Andric case X86::COND_A: // JA,JNBE 2745f757f3fSDimitry Andric case X86::COND_AE: // JAE,JNC,JNB 275480093f4SDimitry Andric return SecondMacroFusionInstKind::AB; 2765f757f3fSDimitry Andric case X86::COND_S: // JS 2775f757f3fSDimitry Andric case X86::COND_NS: // JNS 2785f757f3fSDimitry Andric case X86::COND_P: // JP,JPE 2795f757f3fSDimitry Andric case X86::COND_NP: // JNP,JPO 2805f757f3fSDimitry Andric case X86::COND_O: // JO 2815f757f3fSDimitry Andric case X86::COND_NO: // JNO 282480093f4SDimitry Andric return SecondMacroFusionInstKind::SPO; 283480093f4SDimitry Andric } 284480093f4SDimitry Andric } 285480093f4SDimitry Andric 286480093f4SDimitry Andric /// \param FirstKind kind of the first instruction in macro fusion. 287480093f4SDimitry Andric /// \param SecondKind kind of the second instruction in macro fusion. 288480093f4SDimitry Andric /// 289480093f4SDimitry Andric /// \returns true if the two instruction can be macro fused. 290480093f4SDimitry Andric inline bool isMacroFused(FirstMacroFusionInstKind FirstKind, 291480093f4SDimitry Andric SecondMacroFusionInstKind SecondKind) { 292480093f4SDimitry Andric switch (FirstKind) { 293480093f4SDimitry Andric case X86::FirstMacroFusionInstKind::Test: 294480093f4SDimitry Andric case X86::FirstMacroFusionInstKind::And: 295480093f4SDimitry Andric return true; 296480093f4SDimitry Andric case X86::FirstMacroFusionInstKind::Cmp: 297480093f4SDimitry Andric case X86::FirstMacroFusionInstKind::AddSub: 298480093f4SDimitry Andric return SecondKind == X86::SecondMacroFusionInstKind::AB || 299480093f4SDimitry Andric SecondKind == X86::SecondMacroFusionInstKind::ELG; 300480093f4SDimitry Andric case X86::FirstMacroFusionInstKind::IncDec: 301480093f4SDimitry Andric return SecondKind == X86::SecondMacroFusionInstKind::ELG; 302480093f4SDimitry Andric case X86::FirstMacroFusionInstKind::Invalid: 303480093f4SDimitry Andric return false; 304480093f4SDimitry Andric } 305480093f4SDimitry Andric llvm_unreachable("unknown fusion type"); 306480093f4SDimitry Andric } 307480093f4SDimitry Andric 308480093f4SDimitry Andric /// Defines the possible values of the branch boundary alignment mask. 309480093f4SDimitry Andric enum AlignBranchBoundaryKind : uint8_t { 310480093f4SDimitry Andric AlignBranchNone = 0, 311480093f4SDimitry Andric AlignBranchFused = 1U << 0, 312480093f4SDimitry Andric AlignBranchJcc = 1U << 1, 313480093f4SDimitry Andric AlignBranchJmp = 1U << 2, 314480093f4SDimitry Andric AlignBranchCall = 1U << 3, 315480093f4SDimitry Andric AlignBranchRet = 1U << 4, 316480093f4SDimitry Andric AlignBranchIndirect = 1U << 5 317480093f4SDimitry Andric }; 3185ffd83dbSDimitry Andric 3195ffd83dbSDimitry Andric /// Defines the encoding values for segment override prefix. 3205ffd83dbSDimitry Andric enum EncodingOfSegmentOverridePrefix : uint8_t { 3215ffd83dbSDimitry Andric CS_Encoding = 0x2E, 3225ffd83dbSDimitry Andric DS_Encoding = 0x3E, 3235ffd83dbSDimitry Andric ES_Encoding = 0x26, 3245ffd83dbSDimitry Andric FS_Encoding = 0x64, 3255ffd83dbSDimitry Andric GS_Encoding = 0x65, 3265ffd83dbSDimitry Andric SS_Encoding = 0x36 3275ffd83dbSDimitry Andric }; 3285ffd83dbSDimitry Andric 3295ffd83dbSDimitry Andric /// Given a segment register, return the encoding of the segment override 3305ffd83dbSDimitry Andric /// prefix for it. 3315ffd83dbSDimitry Andric inline EncodingOfSegmentOverridePrefix 3325ffd83dbSDimitry Andric getSegmentOverridePrefixForReg(unsigned Reg) { 3335ffd83dbSDimitry Andric switch (Reg) { 3345ffd83dbSDimitry Andric default: 3355ffd83dbSDimitry Andric llvm_unreachable("Unknown segment register!"); 3365ffd83dbSDimitry Andric case X86::CS: 3375ffd83dbSDimitry Andric return CS_Encoding; 3385ffd83dbSDimitry Andric case X86::DS: 3395ffd83dbSDimitry Andric return DS_Encoding; 3405ffd83dbSDimitry Andric case X86::ES: 3415ffd83dbSDimitry Andric return ES_Encoding; 3425ffd83dbSDimitry Andric case X86::FS: 3435ffd83dbSDimitry Andric return FS_Encoding; 3445ffd83dbSDimitry Andric case X86::GS: 3455ffd83dbSDimitry Andric return GS_Encoding; 3465ffd83dbSDimitry Andric case X86::SS: 3475ffd83dbSDimitry Andric return SS_Encoding; 3485ffd83dbSDimitry Andric } 3495ffd83dbSDimitry Andric } 3505ffd83dbSDimitry Andric 3515f757f3fSDimitry Andric } // namespace X86 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric /// X86II - This namespace holds all of the target specific flags that 3540b57cec5SDimitry Andric /// instruction info tracks. 3550b57cec5SDimitry Andric /// 3560b57cec5SDimitry Andric namespace X86II { 3570b57cec5SDimitry Andric /// Target Operand Flag enum. 3580b57cec5SDimitry Andric enum TOF { 3590b57cec5SDimitry Andric //===------------------------------------------------------------------===// 3600b57cec5SDimitry Andric // X86 Specific MachineOperand flags. 3615f757f3fSDimitry Andric // 3625f757f3fSDimitry Andric /// MO_NO_FLAG - No flag for the operand 3630b57cec5SDimitry Andric MO_NO_FLAG, 3640b57cec5SDimitry Andric /// MO_GOT_ABSOLUTE_ADDRESS - On a symbol operand, this represents a 3650b57cec5SDimitry Andric /// relocation of: 3660b57cec5SDimitry Andric /// SYMBOL_LABEL + [. - PICBASELABEL] 3670b57cec5SDimitry Andric MO_GOT_ABSOLUTE_ADDRESS, 3680b57cec5SDimitry Andric /// MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the 3690b57cec5SDimitry Andric /// immediate should get the value of the symbol minus the PIC base label: 3700b57cec5SDimitry Andric /// SYMBOL_LABEL - PICBASELABEL 3710b57cec5SDimitry Andric MO_PIC_BASE_OFFSET, 3720b57cec5SDimitry Andric /// MO_GOT - On a symbol operand this indicates that the immediate is the 3730b57cec5SDimitry Andric /// offset to the GOT entry for the symbol name from the base of the GOT. 3740b57cec5SDimitry Andric /// See the X86-64 ELF ABI supplement for more details. 3750b57cec5SDimitry Andric /// SYMBOL_LABEL @GOT 3760b57cec5SDimitry Andric MO_GOT, 3770b57cec5SDimitry Andric /// MO_GOTOFF - On a symbol operand this indicates that the immediate is 3780b57cec5SDimitry Andric /// the offset to the location of the symbol name from the base of the GOT. 3790b57cec5SDimitry Andric /// See the X86-64 ELF ABI supplement for more details. 3800b57cec5SDimitry Andric /// SYMBOL_LABEL @GOTOFF 3810b57cec5SDimitry Andric MO_GOTOFF, 3820b57cec5SDimitry Andric /// MO_GOTPCREL - On a symbol operand this indicates that the immediate is 3830b57cec5SDimitry Andric /// offset to the GOT entry for the symbol name from the current code 3840b57cec5SDimitry Andric /// location. 3850b57cec5SDimitry Andric /// See the X86-64 ELF ABI supplement for more details. 3860b57cec5SDimitry Andric /// SYMBOL_LABEL @GOTPCREL 3870b57cec5SDimitry Andric MO_GOTPCREL, 388349cc55cSDimitry Andric /// MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL 389349cc55cSDimitry Andric /// relocations are guaranteed to be emitted by the integrated assembler 390349cc55cSDimitry Andric /// instead of the relaxable R_X86_64[_REX]_GOTPCRELX relocations. 391349cc55cSDimitry Andric MO_GOTPCREL_NORELAX, 3920b57cec5SDimitry Andric /// MO_PLT - On a symbol operand this indicates that the immediate is 3930b57cec5SDimitry Andric /// offset to the PLT entry of symbol name from the current code location. 3940b57cec5SDimitry Andric /// See the X86-64 ELF ABI supplement for more details. 3950b57cec5SDimitry Andric /// SYMBOL_LABEL @PLT 3960b57cec5SDimitry Andric MO_PLT, 3970b57cec5SDimitry Andric /// MO_TLSGD - On a symbol operand this indicates that the immediate is 3980b57cec5SDimitry Andric /// the offset of the GOT entry with the TLS index structure that contains 3990b57cec5SDimitry Andric /// the module number and variable offset for the symbol. Used in the 4000b57cec5SDimitry Andric /// general dynamic TLS access model. 4010b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4020b57cec5SDimitry Andric /// SYMBOL_LABEL @TLSGD 4030b57cec5SDimitry Andric MO_TLSGD, 4040b57cec5SDimitry Andric /// MO_TLSLD - On a symbol operand this indicates that the immediate is 4050b57cec5SDimitry Andric /// the offset of the GOT entry with the TLS index for the module that 4060b57cec5SDimitry Andric /// contains the symbol. When this index is passed to a call to 4070b57cec5SDimitry Andric /// __tls_get_addr, the function will return the base address of the TLS 4080b57cec5SDimitry Andric /// block for the symbol. Used in the x86-64 local dynamic TLS access model. 4090b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4100b57cec5SDimitry Andric /// SYMBOL_LABEL @TLSLD 4110b57cec5SDimitry Andric MO_TLSLD, 4120b57cec5SDimitry Andric /// MO_TLSLDM - On a symbol operand this indicates that the immediate is 4130b57cec5SDimitry Andric /// the offset of the GOT entry with the TLS index for the module that 4140b57cec5SDimitry Andric /// contains the symbol. When this index is passed to a call to 4150b57cec5SDimitry Andric /// ___tls_get_addr, the function will return the base address of the TLS 4160b57cec5SDimitry Andric /// block for the symbol. Used in the IA32 local dynamic TLS access model. 4170b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4180b57cec5SDimitry Andric /// SYMBOL_LABEL @TLSLDM 4190b57cec5SDimitry Andric MO_TLSLDM, 4200b57cec5SDimitry Andric /// MO_GOTTPOFF - On a symbol operand this indicates that the immediate is 4210b57cec5SDimitry Andric /// the offset of the GOT entry with the thread-pointer offset for the 4220b57cec5SDimitry Andric /// symbol. Used in the x86-64 initial exec TLS access model. 4230b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4240b57cec5SDimitry Andric /// SYMBOL_LABEL @GOTTPOFF 4250b57cec5SDimitry Andric MO_GOTTPOFF, 4260b57cec5SDimitry Andric /// MO_INDNTPOFF - On a symbol operand this indicates that the immediate is 4270b57cec5SDimitry Andric /// the absolute address of the GOT entry with the negative thread-pointer 4280b57cec5SDimitry Andric /// offset for the symbol. Used in the non-PIC IA32 initial exec TLS access 4290b57cec5SDimitry Andric /// model. 4300b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4310b57cec5SDimitry Andric /// SYMBOL_LABEL @INDNTPOFF 4320b57cec5SDimitry Andric MO_INDNTPOFF, 4330b57cec5SDimitry Andric /// MO_TPOFF - On a symbol operand this indicates that the immediate is 4340b57cec5SDimitry Andric /// the thread-pointer offset for the symbol. Used in the x86-64 local 4350b57cec5SDimitry Andric /// exec TLS access model. 4360b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4370b57cec5SDimitry Andric /// SYMBOL_LABEL @TPOFF 4380b57cec5SDimitry Andric MO_TPOFF, 4390b57cec5SDimitry Andric /// MO_DTPOFF - On a symbol operand this indicates that the immediate is 4400b57cec5SDimitry Andric /// the offset of the GOT entry with the TLS offset of the symbol. Used 4410b57cec5SDimitry Andric /// in the local dynamic TLS access model. 4420b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4430b57cec5SDimitry Andric /// SYMBOL_LABEL @DTPOFF 4440b57cec5SDimitry Andric MO_DTPOFF, 4450b57cec5SDimitry Andric /// MO_NTPOFF - On a symbol operand this indicates that the immediate is 4460b57cec5SDimitry Andric /// the negative thread-pointer offset for the symbol. Used in the IA32 4470b57cec5SDimitry Andric /// local exec TLS access model. 4480b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4490b57cec5SDimitry Andric /// SYMBOL_LABEL @NTPOFF 4500b57cec5SDimitry Andric MO_NTPOFF, 4510b57cec5SDimitry Andric /// MO_GOTNTPOFF - On a symbol operand this indicates that the immediate is 4520b57cec5SDimitry Andric /// the offset of the GOT entry with the negative thread-pointer offset for 4530b57cec5SDimitry Andric /// the symbol. Used in the PIC IA32 initial exec TLS access model. 4540b57cec5SDimitry Andric /// See 'ELF Handling for Thread-Local Storage' for more details. 4550b57cec5SDimitry Andric /// SYMBOL_LABEL @GOTNTPOFF 4560b57cec5SDimitry Andric MO_GOTNTPOFF, 4570b57cec5SDimitry Andric /// MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the 4580b57cec5SDimitry Andric /// reference is actually to the "__imp_FOO" symbol. This is used for 4590b57cec5SDimitry Andric /// dllimport linkage on windows. 4600b57cec5SDimitry Andric MO_DLLIMPORT, 4610b57cec5SDimitry Andric /// MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the 4620b57cec5SDimitry Andric /// reference is actually to the "FOO$non_lazy_ptr" symbol, which is a 4630b57cec5SDimitry Andric /// non-PIC-base-relative reference to a non-hidden dyld lazy pointer stub. 4640b57cec5SDimitry Andric MO_DARWIN_NONLAZY, 4650b57cec5SDimitry Andric /// MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates 4660b57cec5SDimitry Andric /// that the reference is actually to "FOO$non_lazy_ptr - PICBASE", which is 4670b57cec5SDimitry Andric /// a PIC-base-relative reference to a non-hidden dyld lazy pointer stub. 4680b57cec5SDimitry Andric MO_DARWIN_NONLAZY_PIC_BASE, 4690b57cec5SDimitry Andric /// MO_TLVP - On a symbol operand this indicates that the immediate is 4700b57cec5SDimitry Andric /// some TLS offset. 4710b57cec5SDimitry Andric /// This is the TLS offset for the Darwin TLS mechanism. 4720b57cec5SDimitry Andric MO_TLVP, 4730b57cec5SDimitry Andric /// MO_TLVP_PIC_BASE - On a symbol operand this indicates that the immediate 4740b57cec5SDimitry Andric /// is some TLS offset from the picbase. 4750b57cec5SDimitry Andric /// This is the 32-bit TLS offset for Darwin TLS in PIC mode. 4760b57cec5SDimitry Andric MO_TLVP_PIC_BASE, 4770b57cec5SDimitry Andric /// MO_SECREL - On a symbol operand this indicates that the immediate is 4780b57cec5SDimitry Andric /// the offset from beginning of section. 4790b57cec5SDimitry Andric /// This is the TLS offset for the COFF/Windows TLS mechanism. 4800b57cec5SDimitry Andric MO_SECREL, 4810b57cec5SDimitry Andric /// MO_ABS8 - On a symbol operand this indicates that the symbol is known 4820b57cec5SDimitry Andric /// to be an absolute symbol in range [0,128), so we can use the @ABS8 4830b57cec5SDimitry Andric /// symbol modifier. 4840b57cec5SDimitry Andric MO_ABS8, 4850b57cec5SDimitry Andric /// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the 4860b57cec5SDimitry Andric /// reference is actually to the ".refptr.FOO" symbol. This is used for 4870b57cec5SDimitry Andric /// stub symbols on windows. 4880b57cec5SDimitry Andric MO_COFFSTUB, 4890b57cec5SDimitry Andric }; 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric enum : uint64_t { 4920b57cec5SDimitry Andric //===------------------------------------------------------------------===// 4930b57cec5SDimitry Andric // Instruction encodings. These are the standard/most common forms for X86 4940b57cec5SDimitry Andric // instructions. 4950b57cec5SDimitry Andric // 4965f757f3fSDimitry Andric /// PseudoFrm - This represents an instruction that is a pseudo instruction 4975f757f3fSDimitry Andric /// or one that has not been implemented yet. It is illegal to code generate 4985f757f3fSDimitry Andric /// it, but tolerated for intermediate implementation stages. 4990b57cec5SDimitry Andric Pseudo = 0, 5000b57cec5SDimitry Andric /// Raw - This form is for instructions that don't have any operands, so 5010b57cec5SDimitry Andric /// they are just a fixed opcode value, like 'leave'. 5020b57cec5SDimitry Andric RawFrm = 1, 5030b57cec5SDimitry Andric /// AddRegFrm - This form is used for instructions like 'push r32' that have 5040b57cec5SDimitry Andric /// their one register operand added to their opcode. 5050b57cec5SDimitry Andric AddRegFrm = 2, 5060b57cec5SDimitry Andric /// RawFrmMemOffs - This form is for instructions that store an absolute 5070b57cec5SDimitry Andric /// memory offset as an immediate with a possible segment override. 5080b57cec5SDimitry Andric RawFrmMemOffs = 3, 5090b57cec5SDimitry Andric /// RawFrmSrc - This form is for instructions that use the source index 5100b57cec5SDimitry Andric /// register SI/ESI/RSI with a possible segment override. 5110b57cec5SDimitry Andric RawFrmSrc = 4, 5120b57cec5SDimitry Andric /// RawFrmDst - This form is for instructions that use the destination index 5130b57cec5SDimitry Andric /// register DI/EDI/RDI. 5140b57cec5SDimitry Andric RawFrmDst = 5, 5150b57cec5SDimitry Andric /// RawFrmDstSrc - This form is for instructions that use the source index 5160b57cec5SDimitry Andric /// register SI/ESI/RSI with a possible segment override, and also the 5170b57cec5SDimitry Andric /// destination index register DI/EDI/RDI. 5180b57cec5SDimitry Andric RawFrmDstSrc = 6, 5190b57cec5SDimitry Andric /// RawFrmImm8 - This is used for the ENTER instruction, which has two 5200b57cec5SDimitry Andric /// immediates, the first of which is a 16-bit immediate (specified by 5210b57cec5SDimitry Andric /// the imm encoding) and the second is a 8-bit fixed value. 5220b57cec5SDimitry Andric RawFrmImm8 = 7, 5230b57cec5SDimitry Andric /// RawFrmImm16 - This is used for CALL FAR instructions, which have two 5240b57cec5SDimitry Andric /// immediates, the first of which is a 16 or 32-bit immediate (specified by 5250b57cec5SDimitry Andric /// the imm encoding) and the second is a 16-bit fixed value. In the AMD 5260b57cec5SDimitry Andric /// manual, this operand is described as pntr16:32 and pntr16:16 5270b57cec5SDimitry Andric RawFrmImm16 = 8, 5280b57cec5SDimitry Andric /// AddCCFrm - This form is used for Jcc that encode the condition code 5290b57cec5SDimitry Andric /// in the lower 4 bits of the opcode. 5300b57cec5SDimitry Andric AddCCFrm = 9, 5315ffd83dbSDimitry Andric /// PrefixByte - This form is used for instructions that represent a prefix 5325ffd83dbSDimitry Andric /// byte like data16 or rep. 5335ffd83dbSDimitry Andric PrefixByte = 10, 534*0fca6ea1SDimitry Andric /// MRMDestRegCC - This form is used for the cfcmov instructions, which use 535*0fca6ea1SDimitry Andric /// the Mod/RM byte to specify the operands reg(r/m) and reg(reg) and also 536*0fca6ea1SDimitry Andric /// encodes a condition code. 537*0fca6ea1SDimitry Andric MRMDestRegCC = 18, 538*0fca6ea1SDimitry Andric /// MRMDestMemCC - This form is used for the cfcmov instructions, which use 539*0fca6ea1SDimitry Andric /// the Mod/RM byte to specify the operands mem(r/m) and reg(reg) and also 540*0fca6ea1SDimitry Andric /// encodes a condition code. 541*0fca6ea1SDimitry Andric MRMDestMemCC = 19, 542bdd1243dSDimitry Andric /// MRMDestMem4VOp3CC - This form is used for instructions that use the Mod/RM 543bdd1243dSDimitry Andric /// byte to specify a destination which in this case is memory and operand 3 544bdd1243dSDimitry Andric /// with VEX.VVVV, and also encodes a condition code. 545bdd1243dSDimitry Andric MRMDestMem4VOp3CC = 20, 5465f757f3fSDimitry Andric /// Instructions operate on a register Reg/Opcode operand not the r/m field. 5475ffd83dbSDimitry Andric MRMr0 = 21, 5485ffd83dbSDimitry Andric /// MRMSrcMem - But force to use the SIB field. 5495ffd83dbSDimitry Andric MRMSrcMemFSIB = 22, 5505ffd83dbSDimitry Andric /// MRMDestMem - But force to use the SIB field. 5515ffd83dbSDimitry Andric MRMDestMemFSIB = 23, 5520b57cec5SDimitry Andric /// MRMDestMem - This form is used for instructions that use the Mod/RM byte 5530b57cec5SDimitry Andric /// to specify a destination, which in this case is memory. 5545ffd83dbSDimitry Andric MRMDestMem = 24, 5550b57cec5SDimitry Andric /// MRMSrcMem - This form is used for instructions that use the Mod/RM byte 5560b57cec5SDimitry Andric /// to specify a source, which in this case is memory. 5575ffd83dbSDimitry Andric MRMSrcMem = 25, 5580b57cec5SDimitry Andric /// MRMSrcMem4VOp3 - This form is used for instructions that encode 5590b57cec5SDimitry Andric /// operand 3 with VEX.VVVV and load from memory. 5605ffd83dbSDimitry Andric MRMSrcMem4VOp3 = 26, 5610b57cec5SDimitry Andric /// MRMSrcMemOp4 - This form is used for instructions that use the Mod/RM 5620b57cec5SDimitry Andric /// byte to specify the fourth source, which in this case is memory. 5635ffd83dbSDimitry Andric MRMSrcMemOp4 = 27, 5640b57cec5SDimitry Andric /// MRMSrcMemCC - This form is used for instructions that use the Mod/RM 5650b57cec5SDimitry Andric /// byte to specify the operands and also encodes a condition code. 5665ffd83dbSDimitry Andric MRMSrcMemCC = 28, 5670b57cec5SDimitry Andric /// MRMXm - This form is used for instructions that use the Mod/RM byte 5680b57cec5SDimitry Andric /// to specify a memory source, but doesn't use the middle field. And has 5690b57cec5SDimitry Andric /// a condition code. 5705ffd83dbSDimitry Andric MRMXmCC = 30, 5710b57cec5SDimitry Andric /// MRMXm - This form is used for instructions that use the Mod/RM byte 5720b57cec5SDimitry Andric /// to specify a memory source, but doesn't use the middle field. 5735ffd83dbSDimitry Andric MRMXm = 31, 5745f757f3fSDimitry Andric /// MRM0m-MRM7m - Instructions that operate on a memory r/m operand and use 5755f757f3fSDimitry Andric /// reg field to hold extended opcode, which is represented as /0, /1, ... 5765f757f3fSDimitry Andric MRM0m = 32, // Format /0 5775f757f3fSDimitry Andric MRM1m = 33, // Format /1 5785f757f3fSDimitry Andric MRM2m = 34, // Format /2 5795f757f3fSDimitry Andric MRM3m = 35, // Format /3 5805f757f3fSDimitry Andric MRM4m = 36, // Format /4 5815f757f3fSDimitry Andric MRM5m = 37, // Format /5 5825f757f3fSDimitry Andric MRM6m = 38, // Format /6 5835f757f3fSDimitry Andric MRM7m = 39, // Format /7 5840b57cec5SDimitry Andric /// MRMDestReg - This form is used for instructions that use the Mod/RM byte 5850b57cec5SDimitry Andric /// to specify a destination, which in this case is a register. 5865ffd83dbSDimitry Andric MRMDestReg = 40, 5870b57cec5SDimitry Andric /// MRMSrcReg - This form is used for instructions that use the Mod/RM byte 5880b57cec5SDimitry Andric /// to specify a source, which in this case is a register. 5895ffd83dbSDimitry Andric MRMSrcReg = 41, 5900b57cec5SDimitry Andric /// MRMSrcReg4VOp3 - This form is used for instructions that encode 5910b57cec5SDimitry Andric /// operand 3 with VEX.VVVV and do not load from memory. 5925ffd83dbSDimitry Andric MRMSrcReg4VOp3 = 42, 5930b57cec5SDimitry Andric /// MRMSrcRegOp4 - This form is used for instructions that use the Mod/RM 5940b57cec5SDimitry Andric /// byte to specify the fourth source, which in this case is a register. 5955ffd83dbSDimitry Andric MRMSrcRegOp4 = 43, 5960b57cec5SDimitry Andric /// MRMSrcRegCC - This form is used for instructions that use the Mod/RM 5970b57cec5SDimitry Andric /// byte to specify the operands and also encodes a condition code 5985ffd83dbSDimitry Andric MRMSrcRegCC = 44, 5990b57cec5SDimitry Andric /// MRMXCCr - This form is used for instructions that use the Mod/RM byte 6000b57cec5SDimitry Andric /// to specify a register source, but doesn't use the middle field. And has 6010b57cec5SDimitry Andric /// a condition code. 6025ffd83dbSDimitry Andric MRMXrCC = 46, 6030b57cec5SDimitry Andric /// MRMXr - This form is used for instructions that use the Mod/RM byte 6040b57cec5SDimitry Andric /// to specify a register source, but doesn't use the middle field. 6055ffd83dbSDimitry Andric MRMXr = 47, 6065f757f3fSDimitry Andric /// MRM0r-MRM7r - Instructions that operate on a register r/m operand and use 6075f757f3fSDimitry Andric /// reg field to hold extended opcode, which is represented as /0, /1, ... 6085f757f3fSDimitry Andric MRM0r = 48, // Format /0 6095f757f3fSDimitry Andric MRM1r = 49, // Format /1 6105f757f3fSDimitry Andric MRM2r = 50, // Format /2 6115f757f3fSDimitry Andric MRM3r = 51, // Format /3 6125f757f3fSDimitry Andric MRM4r = 52, // Format /4 6135f757f3fSDimitry Andric MRM5r = 53, // Format /5 6145f757f3fSDimitry Andric MRM6r = 54, // Format /6 6155f757f3fSDimitry Andric MRM7r = 55, // Format /7 6165f757f3fSDimitry Andric /// MRM0X-MRM7X - Instructions that operate that have mod=11 and an opcode but 6175f757f3fSDimitry Andric /// ignore r/m. 6185f757f3fSDimitry Andric MRM0X = 56, // Format /0 6195f757f3fSDimitry Andric MRM1X = 57, // Format /1 6205f757f3fSDimitry Andric MRM2X = 58, // Format /2 6215f757f3fSDimitry Andric MRM3X = 59, // Format /3 6225f757f3fSDimitry Andric MRM4X = 60, // Format /4 6235f757f3fSDimitry Andric MRM5X = 61, // Format /5 6245f757f3fSDimitry Andric MRM6X = 62, // Format /6 6255f757f3fSDimitry Andric MRM7X = 63, // Format /7 6265f757f3fSDimitry Andric /// MRM_XX (XX: C0-FF)- A mod/rm byte of exactly 0xXX. 6275f757f3fSDimitry Andric MRM_C0 = 64, 6285f757f3fSDimitry Andric MRM_C1 = 65, 6295f757f3fSDimitry Andric MRM_C2 = 66, 6305f757f3fSDimitry Andric MRM_C3 = 67, 6315f757f3fSDimitry Andric MRM_C4 = 68, 6325f757f3fSDimitry Andric MRM_C5 = 69, 6335f757f3fSDimitry Andric MRM_C6 = 70, 6345f757f3fSDimitry Andric MRM_C7 = 71, 6355f757f3fSDimitry Andric MRM_C8 = 72, 6365f757f3fSDimitry Andric MRM_C9 = 73, 6375f757f3fSDimitry Andric MRM_CA = 74, 6385f757f3fSDimitry Andric MRM_CB = 75, 6395f757f3fSDimitry Andric MRM_CC = 76, 6405f757f3fSDimitry Andric MRM_CD = 77, 6415f757f3fSDimitry Andric MRM_CE = 78, 6425f757f3fSDimitry Andric MRM_CF = 79, 6435f757f3fSDimitry Andric MRM_D0 = 80, 6445f757f3fSDimitry Andric MRM_D1 = 81, 6455f757f3fSDimitry Andric MRM_D2 = 82, 6465f757f3fSDimitry Andric MRM_D3 = 83, 6475f757f3fSDimitry Andric MRM_D4 = 84, 6485f757f3fSDimitry Andric MRM_D5 = 85, 6495f757f3fSDimitry Andric MRM_D6 = 86, 6505f757f3fSDimitry Andric MRM_D7 = 87, 6515f757f3fSDimitry Andric MRM_D8 = 88, 6525f757f3fSDimitry Andric MRM_D9 = 89, 6535f757f3fSDimitry Andric MRM_DA = 90, 6545f757f3fSDimitry Andric MRM_DB = 91, 6555f757f3fSDimitry Andric MRM_DC = 92, 6565f757f3fSDimitry Andric MRM_DD = 93, 6575f757f3fSDimitry Andric MRM_DE = 94, 6585f757f3fSDimitry Andric MRM_DF = 95, 6595f757f3fSDimitry Andric MRM_E0 = 96, 6605f757f3fSDimitry Andric MRM_E1 = 97, 6615f757f3fSDimitry Andric MRM_E2 = 98, 6625f757f3fSDimitry Andric MRM_E3 = 99, 6635f757f3fSDimitry Andric MRM_E4 = 100, 6645f757f3fSDimitry Andric MRM_E5 = 101, 6655f757f3fSDimitry Andric MRM_E6 = 102, 6665f757f3fSDimitry Andric MRM_E7 = 103, 6675f757f3fSDimitry Andric MRM_E8 = 104, 6685f757f3fSDimitry Andric MRM_E9 = 105, 6695f757f3fSDimitry Andric MRM_EA = 106, 6705f757f3fSDimitry Andric MRM_EB = 107, 6715f757f3fSDimitry Andric MRM_EC = 108, 6725f757f3fSDimitry Andric MRM_ED = 109, 6735f757f3fSDimitry Andric MRM_EE = 110, 6745f757f3fSDimitry Andric MRM_EF = 111, 6755f757f3fSDimitry Andric MRM_F0 = 112, 6765f757f3fSDimitry Andric MRM_F1 = 113, 6775f757f3fSDimitry Andric MRM_F2 = 114, 6785f757f3fSDimitry Andric MRM_F3 = 115, 6795f757f3fSDimitry Andric MRM_F4 = 116, 6805f757f3fSDimitry Andric MRM_F5 = 117, 6815f757f3fSDimitry Andric MRM_F6 = 118, 6825f757f3fSDimitry Andric MRM_F7 = 119, 6835f757f3fSDimitry Andric MRM_F8 = 120, 6845f757f3fSDimitry Andric MRM_F9 = 121, 6855f757f3fSDimitry Andric MRM_FA = 122, 6865f757f3fSDimitry Andric MRM_FB = 123, 6875f757f3fSDimitry Andric MRM_FC = 124, 6885f757f3fSDimitry Andric MRM_FD = 125, 6895f757f3fSDimitry Andric MRM_FE = 126, 6905f757f3fSDimitry Andric MRM_FF = 127, 6910b57cec5SDimitry Andric FormMask = 127, 6920b57cec5SDimitry Andric //===------------------------------------------------------------------===// 6930b57cec5SDimitry Andric // Actual flags... 6945f757f3fSDimitry Andric /// OpSize - OpSizeFixed implies instruction never needs a 0x66 prefix. 6955f757f3fSDimitry Andric /// OpSize16 means this is a 16-bit instruction and needs 0x66 prefix in 6965f757f3fSDimitry Andric /// 32-bit mode. OpSize32 means this is a 32-bit instruction needs a 0x66 6975f757f3fSDimitry Andric /// prefix in 16-bit mode. 6980b57cec5SDimitry Andric OpSizeShift = 7, 6990b57cec5SDimitry Andric OpSizeMask = 0x3 << OpSizeShift, 7000b57cec5SDimitry Andric OpSizeFixed = 0 << OpSizeShift, 7010b57cec5SDimitry Andric OpSize16 = 1 << OpSizeShift, 7020b57cec5SDimitry Andric OpSize32 = 2 << OpSizeShift, 7035f757f3fSDimitry Andric /// AsSize - AdSizeX implies this instruction determines its need of 0x67 7045f757f3fSDimitry Andric /// prefix from a normal ModRM memory operand. The other types indicate that 7055f757f3fSDimitry Andric /// an operand is encoded with a specific width and a prefix is needed if 7065f757f3fSDimitry Andric /// it differs from the current mode. 7070b57cec5SDimitry Andric AdSizeShift = OpSizeShift + 2, 7080b57cec5SDimitry Andric AdSizeMask = 0x3 << AdSizeShift, 7090b57cec5SDimitry Andric AdSizeX = 0 << AdSizeShift, 7100b57cec5SDimitry Andric AdSize16 = 1 << AdSizeShift, 7110b57cec5SDimitry Andric AdSize32 = 2 << AdSizeShift, 7120b57cec5SDimitry Andric AdSize64 = 3 << AdSizeShift, 7130b57cec5SDimitry Andric //===------------------------------------------------------------------===// 7145f757f3fSDimitry Andric /// OpPrefix - There are several prefix bytes that are used as opcode 7155f757f3fSDimitry Andric /// extensions. These are 0x66, 0xF3, and 0xF2. If this field is 0 there is 7165f757f3fSDimitry Andric /// no prefix. 7170b57cec5SDimitry Andric OpPrefixShift = AdSizeShift + 2, 7180b57cec5SDimitry Andric OpPrefixMask = 0x3 << OpPrefixShift, 7195f757f3fSDimitry Andric /// PD - Prefix code for packed double precision vector floating point 7205f757f3fSDimitry Andric /// operations performed in the SSE registers. 7210b57cec5SDimitry Andric PD = 1 << OpPrefixShift, 7225f757f3fSDimitry Andric /// XS, XD - These prefix codes are for single and double precision scalar 7235f757f3fSDimitry Andric /// floating point operations performed in the SSE registers. 7245f757f3fSDimitry Andric XS = 2 << OpPrefixShift, 7255f757f3fSDimitry Andric XD = 3 << OpPrefixShift, 7260b57cec5SDimitry Andric //===------------------------------------------------------------------===// 7275f757f3fSDimitry Andric /// OpMap - This field determines which opcode map this instruction 7285f757f3fSDimitry Andric /// belongs to. i.e. one-byte, two-byte, 0x0f 0x38, 0x0f 0x3a, etc. 7290b57cec5SDimitry Andric OpMapShift = OpPrefixShift + 2, 730349cc55cSDimitry Andric OpMapMask = 0xF << OpMapShift, 7315f757f3fSDimitry Andric /// OB - OneByte - Set if this instruction has a one byte opcode. 7320b57cec5SDimitry Andric OB = 0 << OpMapShift, 7335f757f3fSDimitry Andric /// TB - TwoByte - Set if this instruction has a two byte opcode, which 7345f757f3fSDimitry Andric /// starts with a 0x0F byte before the real opcode. 7350b57cec5SDimitry Andric TB = 1 << OpMapShift, 7365f757f3fSDimitry Andric /// T8, TA - Prefix after the 0x0F prefix. 7375f757f3fSDimitry Andric T8 = 2 << OpMapShift, 7385f757f3fSDimitry Andric TA = 3 << OpMapShift, 7395f757f3fSDimitry Andric /// XOP8 - Prefix to include use of imm byte. 7400b57cec5SDimitry Andric XOP8 = 4 << OpMapShift, 7415f757f3fSDimitry Andric /// XOP9 - Prefix to exclude use of imm byte. 7420b57cec5SDimitry Andric XOP9 = 5 << OpMapShift, 7435f757f3fSDimitry Andric /// XOPA - Prefix to encode 0xA in VEX.MMMM of XOP instructions. 7440b57cec5SDimitry Andric XOPA = 6 << OpMapShift, 7450b57cec5SDimitry Andric /// ThreeDNow - This indicates that the instruction uses the 7460b57cec5SDimitry Andric /// wacky 0x0F 0x0F prefix for 3DNow! instructions. The manual documents 7470b57cec5SDimitry Andric /// this as having a 0x0F prefix with a 0x0F opcode, and each instruction 7480b57cec5SDimitry Andric /// storing a classifier in the imm8 field. To simplify our implementation, 7490b57cec5SDimitry Andric /// we handle this by storeing the classifier in the opcode field and using 7500b57cec5SDimitry Andric /// this flag to indicate that the encoder should do the wacky 3DNow! thing. 7510b57cec5SDimitry Andric ThreeDNow = 7 << OpMapShift, 7525f757f3fSDimitry Andric /// MAP4, MAP5, MAP6, MAP7 - Prefix after the 0x0F prefix. 7535f757f3fSDimitry Andric T_MAP4 = 8 << OpMapShift, 7545f757f3fSDimitry Andric T_MAP5 = 9 << OpMapShift, 7555f757f3fSDimitry Andric T_MAP6 = 10 << OpMapShift, 7565f757f3fSDimitry Andric T_MAP7 = 11 << OpMapShift, 7570b57cec5SDimitry Andric //===------------------------------------------------------------------===// 7585f757f3fSDimitry Andric /// REX_W - REX prefixes are instruction prefixes used in 64-bit mode. 7595f757f3fSDimitry Andric /// They are used to specify GPRs and SSE registers, 64-bit operand size, 7605f757f3fSDimitry Andric /// etc. We only cares about REX.W and REX.R bits and only the former is 7615f757f3fSDimitry Andric /// statically determined. 762349cc55cSDimitry Andric REXShift = OpMapShift + 4, 7630b57cec5SDimitry Andric REX_W = 1 << REXShift, 7640b57cec5SDimitry Andric //===------------------------------------------------------------------===// 7655f757f3fSDimitry Andric // This 4-bit field describes the size of an immediate operand. Zero is 7660b57cec5SDimitry Andric // unused so that we can tell if we forgot to set a value. 7670b57cec5SDimitry Andric ImmShift = REXShift + 1, 7680b57cec5SDimitry Andric Imm8 = 1 << ImmShift, 7690b57cec5SDimitry Andric Imm8PCRel = 2 << ImmShift, 7700b57cec5SDimitry Andric Imm8Reg = 3 << ImmShift, 7710b57cec5SDimitry Andric Imm16 = 4 << ImmShift, 7720b57cec5SDimitry Andric Imm16PCRel = 5 << ImmShift, 7730b57cec5SDimitry Andric Imm32 = 6 << ImmShift, 7740b57cec5SDimitry Andric Imm32PCRel = 7 << ImmShift, 7750b57cec5SDimitry Andric Imm32S = 8 << ImmShift, 7760b57cec5SDimitry Andric Imm64 = 9 << ImmShift, 7775f757f3fSDimitry Andric ImmMask = 15 << ImmShift, 7780b57cec5SDimitry Andric //===------------------------------------------------------------------===// 7795f757f3fSDimitry Andric /// FP Instruction Classification... Zero is non-fp instruction. 7805f757f3fSDimitry Andric /// FPTypeMask - Mask for all of the FP types... 7810b57cec5SDimitry Andric FPTypeShift = ImmShift + 4, 7820b57cec5SDimitry Andric FPTypeMask = 7 << FPTypeShift, 7835f757f3fSDimitry Andric /// NotFP - The default, set for instructions that do not use FP registers. 7840b57cec5SDimitry Andric NotFP = 0 << FPTypeShift, 7855f757f3fSDimitry Andric /// ZeroArgFP - 0 arg FP instruction which implicitly pushes ST(0), f.e. fld0 7860b57cec5SDimitry Andric ZeroArgFP = 1 << FPTypeShift, 7875f757f3fSDimitry Andric /// OneArgFP - 1 arg FP instructions which implicitly read ST(0), such as fst 7880b57cec5SDimitry Andric OneArgFP = 2 << FPTypeShift, 7895f757f3fSDimitry Andric /// OneArgFPRW - 1 arg FP instruction which implicitly read ST(0) and write a 7905f757f3fSDimitry Andric /// result back to ST(0). For example, fcos, fsqrt, etc. 7910b57cec5SDimitry Andric OneArgFPRW = 3 << FPTypeShift, 7925f757f3fSDimitry Andric /// TwoArgFP - 2 arg FP instructions which implicitly read ST(0), and an 7935f757f3fSDimitry Andric /// explicit argument, storing the result to either ST(0) or the implicit 7945f757f3fSDimitry Andric /// argument. For example: fadd, fsub, fmul, etc... 7950b57cec5SDimitry Andric TwoArgFP = 4 << FPTypeShift, 7965f757f3fSDimitry Andric /// CompareFP - 2 arg FP instructions which implicitly read ST(0) and an 7975f757f3fSDimitry Andric /// explicit argument, but have no destination. Example: fucom, fucomi, ... 7980b57cec5SDimitry Andric CompareFP = 5 << FPTypeShift, 7995f757f3fSDimitry Andric /// CondMovFP - "2 operand" floating point conditional move instructions. 8000b57cec5SDimitry Andric CondMovFP = 6 << FPTypeShift, 8015f757f3fSDimitry Andric /// SpecialFP - Special instruction forms. Dispatch by opcode explicitly. 8020b57cec5SDimitry Andric SpecialFP = 7 << FPTypeShift, 8035f757f3fSDimitry Andric /// Lock prefix 8040b57cec5SDimitry Andric LOCKShift = FPTypeShift + 3, 8050b57cec5SDimitry Andric LOCK = 1 << LOCKShift, 8065f757f3fSDimitry Andric /// REP prefix 8070b57cec5SDimitry Andric REPShift = LOCKShift + 1, 8080b57cec5SDimitry Andric REP = 1 << REPShift, 8095f757f3fSDimitry Andric /// Execution domain for SSE instructions. 8105f757f3fSDimitry Andric /// 0 means normal, non-SSE instruction. 8110b57cec5SDimitry Andric SSEDomainShift = REPShift + 1, 8125f757f3fSDimitry Andric /// Encoding 8130b57cec5SDimitry Andric EncodingShift = SSEDomainShift + 2, 8140b57cec5SDimitry Andric EncodingMask = 0x3 << EncodingShift, 8157a6dacacSDimitry Andric /// LEGACY - encoding using REX/REX2 or w/o opcode prefix. 8167a6dacacSDimitry Andric LEGACY = 0 << EncodingShift, 8175f757f3fSDimitry Andric /// VEX - encoding using 0xC4/0xC5 8180b57cec5SDimitry Andric VEX = 1 << EncodingShift, 8190b57cec5SDimitry Andric /// XOP - Opcode prefix used by XOP instructions. 8200b57cec5SDimitry Andric XOP = 2 << EncodingShift, 8215f757f3fSDimitry Andric /// EVEX - Specifies that this instruction use EVEX form which provides 8225f757f3fSDimitry Andric /// syntax support up to 32 512-bit register operands and up to 7 16-bit 8235f757f3fSDimitry Andric /// mask operands as well as source operand data swizzling/memory operand 8245f757f3fSDimitry Andric /// conversion, eviction hint, and rounding mode. 8250b57cec5SDimitry Andric EVEX = 3 << EncodingShift, 8265f757f3fSDimitry Andric /// Opcode 8270b57cec5SDimitry Andric OpcodeShift = EncodingShift + 2, 8280b57cec5SDimitry Andric /// VEX_4V - Used to specify an additional AVX/SSE register. Several 2 8290b57cec5SDimitry Andric /// address instructions in SSE are represented as 3 address ones in AVX 8300b57cec5SDimitry Andric /// and the additional register is encoded in VEX_VVVV prefix. 83106c3fb27SDimitry Andric VEX_4VShift = OpcodeShift + 8, 8320b57cec5SDimitry Andric VEX_4V = 1ULL << VEX_4VShift, 8330b57cec5SDimitry Andric /// VEX_L - Stands for a bit in the VEX opcode prefix meaning the current 8340b57cec5SDimitry Andric /// instruction uses 256-bit wide registers. This is usually auto detected 8350b57cec5SDimitry Andric /// if a VR256 register is used, but some AVX instructions also have this 8360b57cec5SDimitry Andric /// field marked when using a f256 memory references. 8370b57cec5SDimitry Andric VEX_LShift = VEX_4VShift + 1, 8380b57cec5SDimitry Andric VEX_L = 1ULL << VEX_LShift, 8395f757f3fSDimitry Andric /// EVEX_K - Set if this instruction requires masking 8400b57cec5SDimitry Andric EVEX_KShift = VEX_LShift + 1, 8410b57cec5SDimitry Andric EVEX_K = 1ULL << EVEX_KShift, 8425f757f3fSDimitry Andric /// EVEX_Z - Set if this instruction has EVEX.Z field set. 8430b57cec5SDimitry Andric EVEX_ZShift = EVEX_KShift + 1, 8440b57cec5SDimitry Andric EVEX_Z = 1ULL << EVEX_ZShift, 8455f757f3fSDimitry Andric /// EVEX_L2 - Set if this instruction has EVEX.L' field set. 8460b57cec5SDimitry Andric EVEX_L2Shift = EVEX_ZShift + 1, 8470b57cec5SDimitry Andric EVEX_L2 = 1ULL << EVEX_L2Shift, 8485f757f3fSDimitry Andric /// EVEX_B - Set if this instruction has EVEX.B field set. 8490b57cec5SDimitry Andric EVEX_BShift = EVEX_L2Shift + 1, 8500b57cec5SDimitry Andric EVEX_B = 1ULL << EVEX_BShift, 8515f757f3fSDimitry Andric /// The scaling factor for the AVX512's 8-bit compressed displacement. 8520b57cec5SDimitry Andric CD8_Scale_Shift = EVEX_BShift + 1, 85306c3fb27SDimitry Andric CD8_Scale_Mask = 7ULL << CD8_Scale_Shift, 8540b57cec5SDimitry Andric /// Explicitly specified rounding control 85506c3fb27SDimitry Andric EVEX_RCShift = CD8_Scale_Shift + 3, 8560b57cec5SDimitry Andric EVEX_RC = 1ULL << EVEX_RCShift, 8575f757f3fSDimitry Andric /// NOTRACK prefix 8580b57cec5SDimitry Andric NoTrackShift = EVEX_RCShift + 1, 859e8d8bef9SDimitry Andric NOTRACK = 1ULL << NoTrackShift, 8605f757f3fSDimitry Andric /// Force REX2/VEX/EVEX encoding 8615f757f3fSDimitry Andric ExplicitOpPrefixShift = NoTrackShift + 1, 8625f757f3fSDimitry Andric /// For instructions that require REX2 prefix even if EGPR is not used. 8635f757f3fSDimitry Andric ExplicitREX2Prefix = 1ULL << ExplicitOpPrefixShift, 8645f757f3fSDimitry Andric /// For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} 8655f757f3fSDimitry Andric /// is present. 8665f757f3fSDimitry Andric ExplicitVEXPrefix = 2ULL << ExplicitOpPrefixShift, 8675f757f3fSDimitry Andric /// For instructions that are promoted to EVEX space for EGPR. 8685f757f3fSDimitry Andric ExplicitEVEXPrefix = 3ULL << ExplicitOpPrefixShift, 869647cbc5dSDimitry Andric ExplicitOpPrefixMask = 3ULL << ExplicitOpPrefixShift, 870647cbc5dSDimitry Andric /// EVEX_NF - Set if this instruction has EVEX.NF field set. 871647cbc5dSDimitry Andric EVEX_NFShift = ExplicitOpPrefixShift + 2, 872*0fca6ea1SDimitry Andric EVEX_NF = 1ULL << EVEX_NFShift, 873*0fca6ea1SDimitry Andric // TwoConditionalOps - Set if this instruction has two conditional operands 874*0fca6ea1SDimitry Andric TwoConditionalOps_Shift = EVEX_NFShift + 1, 875*0fca6ea1SDimitry Andric TwoConditionalOps = 1ULL << TwoConditionalOps_Shift 8760b57cec5SDimitry Andric }; 8770b57cec5SDimitry Andric 8785ffd83dbSDimitry Andric /// \returns true if the instruction with given opcode is a prefix. 8795ffd83dbSDimitry Andric inline bool isPrefix(uint64_t TSFlags) { 8805ffd83dbSDimitry Andric return (TSFlags & X86II::FormMask) == PrefixByte; 8815ffd83dbSDimitry Andric } 8825ffd83dbSDimitry Andric 8835ffd83dbSDimitry Andric /// \returns true if the instruction with given opcode is a pseudo. 8845ffd83dbSDimitry Andric inline bool isPseudo(uint64_t TSFlags) { 8855ffd83dbSDimitry Andric return (TSFlags & X86II::FormMask) == Pseudo; 8865ffd83dbSDimitry Andric } 8875ffd83dbSDimitry Andric 888480093f4SDimitry Andric /// \returns the "base" X86 opcode for the specified machine 889480093f4SDimitry Andric /// instruction. 8900b57cec5SDimitry Andric inline uint8_t getBaseOpcodeFor(uint64_t TSFlags) { 8910b57cec5SDimitry Andric return TSFlags >> X86II::OpcodeShift; 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric 8945f757f3fSDimitry Andric inline bool hasImm(uint64_t TSFlags) { return (TSFlags & X86II::ImmMask) != 0; } 8950b57cec5SDimitry Andric 896480093f4SDimitry Andric /// Decode the "size of immediate" field from the TSFlags field of the 897480093f4SDimitry Andric /// specified instruction. 8980b57cec5SDimitry Andric inline unsigned getSizeOfImm(uint64_t TSFlags) { 8990b57cec5SDimitry Andric switch (TSFlags & X86II::ImmMask) { 9005f757f3fSDimitry Andric default: 9015f757f3fSDimitry Andric llvm_unreachable("Unknown immediate size"); 9020b57cec5SDimitry Andric case X86II::Imm8: 9030b57cec5SDimitry Andric case X86II::Imm8PCRel: 9045f757f3fSDimitry Andric case X86II::Imm8Reg: 9055f757f3fSDimitry Andric return 1; 9060b57cec5SDimitry Andric case X86II::Imm16: 9075f757f3fSDimitry Andric case X86II::Imm16PCRel: 9085f757f3fSDimitry Andric return 2; 9090b57cec5SDimitry Andric case X86II::Imm32: 9100b57cec5SDimitry Andric case X86II::Imm32S: 9115f757f3fSDimitry Andric case X86II::Imm32PCRel: 9125f757f3fSDimitry Andric return 4; 9135f757f3fSDimitry Andric case X86II::Imm64: 9145f757f3fSDimitry Andric return 8; 9150b57cec5SDimitry Andric } 9160b57cec5SDimitry Andric } 9170b57cec5SDimitry Andric 918480093f4SDimitry Andric /// \returns true if the immediate of the specified instruction's TSFlags 919480093f4SDimitry Andric /// indicates that it is pc relative. 920480093f4SDimitry Andric inline bool isImmPCRel(uint64_t TSFlags) { 9210b57cec5SDimitry Andric switch (TSFlags & X86II::ImmMask) { 9225f757f3fSDimitry Andric default: 9235f757f3fSDimitry Andric llvm_unreachable("Unknown immediate size"); 9240b57cec5SDimitry Andric case X86II::Imm8PCRel: 9250b57cec5SDimitry Andric case X86II::Imm16PCRel: 9260b57cec5SDimitry Andric case X86II::Imm32PCRel: 9270b57cec5SDimitry Andric return true; 9280b57cec5SDimitry Andric case X86II::Imm8: 9290b57cec5SDimitry Andric case X86II::Imm8Reg: 9300b57cec5SDimitry Andric case X86II::Imm16: 9310b57cec5SDimitry Andric case X86II::Imm32: 9320b57cec5SDimitry Andric case X86II::Imm32S: 9330b57cec5SDimitry Andric case X86II::Imm64: 9340b57cec5SDimitry Andric return false; 9350b57cec5SDimitry Andric } 9360b57cec5SDimitry Andric } 9370b57cec5SDimitry Andric 938480093f4SDimitry Andric /// \returns true if the immediate of the specified instruction's 9390b57cec5SDimitry Andric /// TSFlags indicates that it is signed. 940480093f4SDimitry Andric inline bool isImmSigned(uint64_t TSFlags) { 9410b57cec5SDimitry Andric switch (TSFlags & X86II::ImmMask) { 9425f757f3fSDimitry Andric default: 9435f757f3fSDimitry Andric llvm_unreachable("Unknown immediate signedness"); 9440b57cec5SDimitry Andric case X86II::Imm32S: 9450b57cec5SDimitry Andric return true; 9460b57cec5SDimitry Andric case X86II::Imm8: 9470b57cec5SDimitry Andric case X86II::Imm8PCRel: 9480b57cec5SDimitry Andric case X86II::Imm8Reg: 9490b57cec5SDimitry Andric case X86II::Imm16: 9500b57cec5SDimitry Andric case X86II::Imm16PCRel: 9510b57cec5SDimitry Andric case X86II::Imm32: 9520b57cec5SDimitry Andric case X86II::Imm32PCRel: 9530b57cec5SDimitry Andric case X86II::Imm64: 9540b57cec5SDimitry Andric return false; 9550b57cec5SDimitry Andric } 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric 958480093f4SDimitry Andric /// Compute whether all of the def operands are repeated in the uses and 959480093f4SDimitry Andric /// therefore should be skipped. 9600b57cec5SDimitry Andric /// This determines the start of the unique operand list. We need to determine 9610b57cec5SDimitry Andric /// if all of the defs have a corresponding tied operand in the uses. 9620b57cec5SDimitry Andric /// Unfortunately, the tied operand information is encoded in the uses not 9630b57cec5SDimitry Andric /// the defs so we have to use some heuristics to find which operands to 9640b57cec5SDimitry Andric /// query. 9650b57cec5SDimitry Andric inline unsigned getOperandBias(const MCInstrDesc &Desc) { 9660b57cec5SDimitry Andric unsigned NumDefs = Desc.getNumDefs(); 9670b57cec5SDimitry Andric unsigned NumOps = Desc.getNumOperands(); 9680b57cec5SDimitry Andric switch (NumDefs) { 9695f757f3fSDimitry Andric default: 9705f757f3fSDimitry Andric llvm_unreachable("Unexpected number of defs"); 9710b57cec5SDimitry Andric case 0: 9720b57cec5SDimitry Andric return 0; 9730b57cec5SDimitry Andric case 1: 9740b57cec5SDimitry Andric // Common two addr case. 9750b57cec5SDimitry Andric if (NumOps > 1 && Desc.getOperandConstraint(1, MCOI::TIED_TO) == 0) 9760b57cec5SDimitry Andric return 1; 9770b57cec5SDimitry Andric // Check for AVX-512 scatter which has a TIED_TO in the second to last 9780b57cec5SDimitry Andric // operand. 9795f757f3fSDimitry Andric if (NumOps == 8 && Desc.getOperandConstraint(6, MCOI::TIED_TO) == 0) 9800b57cec5SDimitry Andric return 1; 9810b57cec5SDimitry Andric return 0; 9820b57cec5SDimitry Andric case 2: 9830b57cec5SDimitry Andric // XCHG/XADD have two destinations and two sources. 9840b57cec5SDimitry Andric if (NumOps >= 4 && Desc.getOperandConstraint(2, MCOI::TIED_TO) == 0 && 9850b57cec5SDimitry Andric Desc.getOperandConstraint(3, MCOI::TIED_TO) == 1) 9860b57cec5SDimitry Andric return 2; 9870b57cec5SDimitry Andric // Check for gather. AVX-512 has the second tied operand early. AVX2 9880b57cec5SDimitry Andric // has it as the last op. 9890b57cec5SDimitry Andric if (NumOps == 9 && Desc.getOperandConstraint(2, MCOI::TIED_TO) == 0 && 9900b57cec5SDimitry Andric (Desc.getOperandConstraint(3, MCOI::TIED_TO) == 1 || 9910b57cec5SDimitry Andric Desc.getOperandConstraint(8, MCOI::TIED_TO) == 1)) 9920b57cec5SDimitry Andric return 2; 9930b57cec5SDimitry Andric return 0; 9940b57cec5SDimitry Andric } 9950b57cec5SDimitry Andric } 9960b57cec5SDimitry Andric 997647cbc5dSDimitry Andric /// \returns true if the instruction has a NDD (new data destination). 998647cbc5dSDimitry Andric inline bool hasNewDataDest(uint64_t TSFlags) { 999647cbc5dSDimitry Andric return (TSFlags & X86II::OpMapMask) == X86II::T_MAP4 && 1000647cbc5dSDimitry Andric (TSFlags & X86II::EVEX_B) && (TSFlags & X86II::VEX_4V); 1001647cbc5dSDimitry Andric } 1002647cbc5dSDimitry Andric 10035f757f3fSDimitry Andric /// \returns operand # for the first field of the memory operand or -1 if no 10045f757f3fSDimitry Andric /// memory operands. 10055f757f3fSDimitry Andric /// NOTE: This ignores tied operands. If there is a tied register which is 10065f757f3fSDimitry Andric /// duplicated in the MCInst (e.g. "EAX = addl EAX, [mem]") it is only counted 10075f757f3fSDimitry Andric /// as one operand. 10080b57cec5SDimitry Andric inline int getMemoryOperandNo(uint64_t TSFlags) { 10090b57cec5SDimitry Andric bool HasVEX_4V = TSFlags & X86II::VEX_4V; 10100b57cec5SDimitry Andric bool HasEVEX_K = TSFlags & X86II::EVEX_K; 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric switch (TSFlags & X86II::FormMask) { 10135f757f3fSDimitry Andric default: 10145f757f3fSDimitry Andric llvm_unreachable("Unknown FormMask value in getMemoryOperandNo!"); 10150b57cec5SDimitry Andric case X86II::Pseudo: 10160b57cec5SDimitry Andric case X86II::RawFrm: 10170b57cec5SDimitry Andric case X86II::AddRegFrm: 10180b57cec5SDimitry Andric case X86II::RawFrmImm8: 10190b57cec5SDimitry Andric case X86II::RawFrmImm16: 10200b57cec5SDimitry Andric case X86II::RawFrmMemOffs: 10210b57cec5SDimitry Andric case X86II::RawFrmSrc: 10220b57cec5SDimitry Andric case X86II::RawFrmDst: 10230b57cec5SDimitry Andric case X86II::RawFrmDstSrc: 10240b57cec5SDimitry Andric case X86II::AddCCFrm: 10255ffd83dbSDimitry Andric case X86II::PrefixByte: 10260b57cec5SDimitry Andric return -1; 10270b57cec5SDimitry Andric case X86II::MRMDestMem: 10285ffd83dbSDimitry Andric case X86II::MRMDestMemFSIB: 1029*0fca6ea1SDimitry Andric case X86II::MRMDestMemCC: 1030647cbc5dSDimitry Andric return hasNewDataDest(TSFlags); 10310b57cec5SDimitry Andric case X86II::MRMSrcMem: 10325ffd83dbSDimitry Andric case X86II::MRMSrcMemFSIB: 10330b57cec5SDimitry Andric // Start from 1, skip any registers encoded in VEX_VVVV or I8IMM, or a 10340b57cec5SDimitry Andric // mask register. 10350b57cec5SDimitry Andric return 1 + HasVEX_4V + HasEVEX_K; 10360b57cec5SDimitry Andric case X86II::MRMSrcMem4VOp3: 10370b57cec5SDimitry Andric // Skip registers encoded in reg. 10380b57cec5SDimitry Andric return 1 + HasEVEX_K; 10390b57cec5SDimitry Andric case X86II::MRMSrcMemOp4: 10400b57cec5SDimitry Andric // Skip registers encoded in reg, VEX_VVVV, and I8IMM. 10410b57cec5SDimitry Andric return 3; 10420b57cec5SDimitry Andric case X86II::MRMSrcMemCC: 1043*0fca6ea1SDimitry Andric return 1 + hasNewDataDest(TSFlags); 1044bdd1243dSDimitry Andric case X86II::MRMDestMem4VOp3CC: 10450b57cec5SDimitry Andric // Start from 1, skip any registers encoded in VEX_VVVV or I8IMM, or a 10460b57cec5SDimitry Andric // mask register. 10470b57cec5SDimitry Andric return 1; 10480b57cec5SDimitry Andric case X86II::MRMDestReg: 1049*0fca6ea1SDimitry Andric case X86II::MRMDestRegCC: 10500b57cec5SDimitry Andric case X86II::MRMSrcReg: 10510b57cec5SDimitry Andric case X86II::MRMSrcReg4VOp3: 10520b57cec5SDimitry Andric case X86II::MRMSrcRegOp4: 10530b57cec5SDimitry Andric case X86II::MRMSrcRegCC: 10540b57cec5SDimitry Andric case X86II::MRMXrCC: 10555ffd83dbSDimitry Andric case X86II::MRMr0: 10560b57cec5SDimitry Andric case X86II::MRMXr: 10575f757f3fSDimitry Andric case X86II::MRM0r: 10585f757f3fSDimitry Andric case X86II::MRM1r: 10595f757f3fSDimitry Andric case X86II::MRM2r: 10605f757f3fSDimitry Andric case X86II::MRM3r: 10615f757f3fSDimitry Andric case X86II::MRM4r: 10625f757f3fSDimitry Andric case X86II::MRM5r: 10635f757f3fSDimitry Andric case X86II::MRM6r: 10645f757f3fSDimitry Andric case X86II::MRM7r: 10650b57cec5SDimitry Andric return -1; 10665f757f3fSDimitry Andric case X86II::MRM0X: 10675f757f3fSDimitry Andric case X86II::MRM1X: 10685f757f3fSDimitry Andric case X86II::MRM2X: 10695f757f3fSDimitry Andric case X86II::MRM3X: 10705f757f3fSDimitry Andric case X86II::MRM4X: 10715f757f3fSDimitry Andric case X86II::MRM5X: 10725f757f3fSDimitry Andric case X86II::MRM6X: 10735f757f3fSDimitry Andric case X86II::MRM7X: 10745ffd83dbSDimitry Andric return -1; 10750b57cec5SDimitry Andric case X86II::MRMXmCC: 10760b57cec5SDimitry Andric case X86II::MRMXm: 10775f757f3fSDimitry Andric case X86II::MRM0m: 10785f757f3fSDimitry Andric case X86II::MRM1m: 10795f757f3fSDimitry Andric case X86II::MRM2m: 10805f757f3fSDimitry Andric case X86II::MRM3m: 10815f757f3fSDimitry Andric case X86II::MRM4m: 10825f757f3fSDimitry Andric case X86II::MRM5m: 10835f757f3fSDimitry Andric case X86II::MRM6m: 10845f757f3fSDimitry Andric case X86II::MRM7m: 10850b57cec5SDimitry Andric // Start from 0, skip registers encoded in VEX_VVVV or a mask register. 10860b57cec5SDimitry Andric return 0 + HasVEX_4V + HasEVEX_K; 10875f757f3fSDimitry Andric case X86II::MRM_C0: 10885f757f3fSDimitry Andric case X86II::MRM_C1: 10895f757f3fSDimitry Andric case X86II::MRM_C2: 10905f757f3fSDimitry Andric case X86II::MRM_C3: 10915f757f3fSDimitry Andric case X86II::MRM_C4: 10925f757f3fSDimitry Andric case X86II::MRM_C5: 10935f757f3fSDimitry Andric case X86II::MRM_C6: 10945f757f3fSDimitry Andric case X86II::MRM_C7: 10955f757f3fSDimitry Andric case X86II::MRM_C8: 10965f757f3fSDimitry Andric case X86II::MRM_C9: 10975f757f3fSDimitry Andric case X86II::MRM_CA: 10985f757f3fSDimitry Andric case X86II::MRM_CB: 10995f757f3fSDimitry Andric case X86II::MRM_CC: 11005f757f3fSDimitry Andric case X86II::MRM_CD: 11015f757f3fSDimitry Andric case X86II::MRM_CE: 11025f757f3fSDimitry Andric case X86II::MRM_CF: 11035f757f3fSDimitry Andric case X86II::MRM_D0: 11045f757f3fSDimitry Andric case X86II::MRM_D1: 11055f757f3fSDimitry Andric case X86II::MRM_D2: 11065f757f3fSDimitry Andric case X86II::MRM_D3: 11075f757f3fSDimitry Andric case X86II::MRM_D4: 11085f757f3fSDimitry Andric case X86II::MRM_D5: 11095f757f3fSDimitry Andric case X86II::MRM_D6: 11105f757f3fSDimitry Andric case X86II::MRM_D7: 11115f757f3fSDimitry Andric case X86II::MRM_D8: 11125f757f3fSDimitry Andric case X86II::MRM_D9: 11135f757f3fSDimitry Andric case X86II::MRM_DA: 11145f757f3fSDimitry Andric case X86II::MRM_DB: 11155f757f3fSDimitry Andric case X86II::MRM_DC: 11165f757f3fSDimitry Andric case X86II::MRM_DD: 11175f757f3fSDimitry Andric case X86II::MRM_DE: 11185f757f3fSDimitry Andric case X86II::MRM_DF: 11195f757f3fSDimitry Andric case X86II::MRM_E0: 11205f757f3fSDimitry Andric case X86II::MRM_E1: 11215f757f3fSDimitry Andric case X86II::MRM_E2: 11225f757f3fSDimitry Andric case X86II::MRM_E3: 11235f757f3fSDimitry Andric case X86II::MRM_E4: 11245f757f3fSDimitry Andric case X86II::MRM_E5: 11255f757f3fSDimitry Andric case X86II::MRM_E6: 11265f757f3fSDimitry Andric case X86II::MRM_E7: 11275f757f3fSDimitry Andric case X86II::MRM_E8: 11285f757f3fSDimitry Andric case X86II::MRM_E9: 11295f757f3fSDimitry Andric case X86II::MRM_EA: 11305f757f3fSDimitry Andric case X86II::MRM_EB: 11315f757f3fSDimitry Andric case X86II::MRM_EC: 11325f757f3fSDimitry Andric case X86II::MRM_ED: 11335f757f3fSDimitry Andric case X86II::MRM_EE: 11345f757f3fSDimitry Andric case X86II::MRM_EF: 11355f757f3fSDimitry Andric case X86II::MRM_F0: 11365f757f3fSDimitry Andric case X86II::MRM_F1: 11375f757f3fSDimitry Andric case X86II::MRM_F2: 11385f757f3fSDimitry Andric case X86II::MRM_F3: 11395f757f3fSDimitry Andric case X86II::MRM_F4: 11405f757f3fSDimitry Andric case X86II::MRM_F5: 11415f757f3fSDimitry Andric case X86II::MRM_F6: 11425f757f3fSDimitry Andric case X86II::MRM_F7: 11435f757f3fSDimitry Andric case X86II::MRM_F8: 11445f757f3fSDimitry Andric case X86II::MRM_F9: 11455f757f3fSDimitry Andric case X86II::MRM_FA: 11465f757f3fSDimitry Andric case X86II::MRM_FB: 11475f757f3fSDimitry Andric case X86II::MRM_FC: 11485f757f3fSDimitry Andric case X86II::MRM_FD: 11495f757f3fSDimitry Andric case X86II::MRM_FE: 11500b57cec5SDimitry Andric case X86II::MRM_FF: 11510b57cec5SDimitry Andric return -1; 11520b57cec5SDimitry Andric } 11530b57cec5SDimitry Andric } 11540b57cec5SDimitry Andric 11555f757f3fSDimitry Andric /// \returns true if the register is a XMM. 11565f757f3fSDimitry Andric inline bool isXMMReg(unsigned RegNo) { 1157*0fca6ea1SDimitry Andric static_assert(X86::XMM15 - X86::XMM0 == 15, 11585f757f3fSDimitry Andric "XMM0-15 registers are not continuous"); 1159*0fca6ea1SDimitry Andric static_assert(X86::XMM31 - X86::XMM16 == 15, 11605f757f3fSDimitry Andric "XMM16-31 registers are not continuous"); 11615f757f3fSDimitry Andric return (RegNo >= X86::XMM0 && RegNo <= X86::XMM15) || 11625f757f3fSDimitry Andric (RegNo >= X86::XMM16 && RegNo <= X86::XMM31); 11635f757f3fSDimitry Andric } 11645f757f3fSDimitry Andric 11655f757f3fSDimitry Andric /// \returns true if the register is a YMM. 11665f757f3fSDimitry Andric inline bool isYMMReg(unsigned RegNo) { 1167*0fca6ea1SDimitry Andric static_assert(X86::YMM15 - X86::YMM0 == 15, 11685f757f3fSDimitry Andric "YMM0-15 registers are not continuous"); 1169*0fca6ea1SDimitry Andric static_assert(X86::YMM31 - X86::YMM16 == 15, 11705f757f3fSDimitry Andric "YMM16-31 registers are not continuous"); 11715f757f3fSDimitry Andric return (RegNo >= X86::YMM0 && RegNo <= X86::YMM15) || 11725f757f3fSDimitry Andric (RegNo >= X86::YMM16 && RegNo <= X86::YMM31); 11735f757f3fSDimitry Andric } 11745f757f3fSDimitry Andric 11755f757f3fSDimitry Andric /// \returns true if the register is a ZMM. 11765f757f3fSDimitry Andric inline bool isZMMReg(unsigned RegNo) { 1177*0fca6ea1SDimitry Andric static_assert(X86::ZMM31 - X86::ZMM0 == 31, 1178*0fca6ea1SDimitry Andric "ZMM registers are not continuous"); 11795f757f3fSDimitry Andric return RegNo >= X86::ZMM0 && RegNo <= X86::ZMM31; 11805f757f3fSDimitry Andric } 11815f757f3fSDimitry Andric 11825f757f3fSDimitry Andric /// \returns true if \p RegNo is an apx extended register. 11835f757f3fSDimitry Andric inline bool isApxExtendedReg(unsigned RegNo) { 1184*0fca6ea1SDimitry Andric static_assert(X86::R31WH - X86::R16 == 95, "EGPRs are not continuous"); 11855f757f3fSDimitry Andric return RegNo >= X86::R16 && RegNo <= X86::R31WH; 11865f757f3fSDimitry Andric } 11875f757f3fSDimitry Andric 1188480093f4SDimitry Andric /// \returns true if the MachineOperand is a x86-64 extended (r8 or 1189480093f4SDimitry Andric /// higher) register, e.g. r8, xmm8, xmm13, etc. 11900b57cec5SDimitry Andric inline bool isX86_64ExtendedReg(unsigned RegNo) { 11915f757f3fSDimitry Andric if ((RegNo >= X86::XMM8 && RegNo <= X86::XMM15) || 11925f757f3fSDimitry Andric (RegNo >= X86::XMM16 && RegNo <= X86::XMM31) || 11935f757f3fSDimitry Andric (RegNo >= X86::YMM8 && RegNo <= X86::YMM15) || 11945f757f3fSDimitry Andric (RegNo >= X86::YMM16 && RegNo <= X86::YMM31) || 11950b57cec5SDimitry Andric (RegNo >= X86::ZMM8 && RegNo <= X86::ZMM31)) 11960b57cec5SDimitry Andric return true; 11970b57cec5SDimitry Andric 11985f757f3fSDimitry Andric if (isApxExtendedReg(RegNo)) 11995f757f3fSDimitry Andric return true; 12005f757f3fSDimitry Andric 12010b57cec5SDimitry Andric switch (RegNo) { 12025f757f3fSDimitry Andric default: 12035f757f3fSDimitry Andric break; 12045f757f3fSDimitry Andric case X86::R8: 12055f757f3fSDimitry Andric case X86::R9: 12065f757f3fSDimitry Andric case X86::R10: 12075f757f3fSDimitry Andric case X86::R11: 12085f757f3fSDimitry Andric case X86::R12: 12095f757f3fSDimitry Andric case X86::R13: 12105f757f3fSDimitry Andric case X86::R14: 12115f757f3fSDimitry Andric case X86::R15: 12125f757f3fSDimitry Andric case X86::R8D: 12135f757f3fSDimitry Andric case X86::R9D: 12145f757f3fSDimitry Andric case X86::R10D: 12155f757f3fSDimitry Andric case X86::R11D: 12165f757f3fSDimitry Andric case X86::R12D: 12175f757f3fSDimitry Andric case X86::R13D: 12185f757f3fSDimitry Andric case X86::R14D: 12195f757f3fSDimitry Andric case X86::R15D: 12205f757f3fSDimitry Andric case X86::R8W: 12215f757f3fSDimitry Andric case X86::R9W: 12225f757f3fSDimitry Andric case X86::R10W: 12235f757f3fSDimitry Andric case X86::R11W: 12245f757f3fSDimitry Andric case X86::R12W: 12255f757f3fSDimitry Andric case X86::R13W: 12265f757f3fSDimitry Andric case X86::R14W: 12275f757f3fSDimitry Andric case X86::R15W: 12285f757f3fSDimitry Andric case X86::R8B: 12295f757f3fSDimitry Andric case X86::R9B: 12305f757f3fSDimitry Andric case X86::R10B: 12315f757f3fSDimitry Andric case X86::R11B: 12325f757f3fSDimitry Andric case X86::R12B: 12335f757f3fSDimitry Andric case X86::R13B: 12345f757f3fSDimitry Andric case X86::R14B: 12355f757f3fSDimitry Andric case X86::R15B: 12365f757f3fSDimitry Andric case X86::CR8: 12375f757f3fSDimitry Andric case X86::CR9: 12385f757f3fSDimitry Andric case X86::CR10: 12395f757f3fSDimitry Andric case X86::CR11: 12405f757f3fSDimitry Andric case X86::CR12: 12415f757f3fSDimitry Andric case X86::CR13: 12425f757f3fSDimitry Andric case X86::CR14: 12435f757f3fSDimitry Andric case X86::CR15: 12445f757f3fSDimitry Andric case X86::DR8: 12455f757f3fSDimitry Andric case X86::DR9: 12465f757f3fSDimitry Andric case X86::DR10: 12475f757f3fSDimitry Andric case X86::DR11: 12485f757f3fSDimitry Andric case X86::DR12: 12495f757f3fSDimitry Andric case X86::DR13: 12505f757f3fSDimitry Andric case X86::DR14: 12515f757f3fSDimitry Andric case X86::DR15: 12520b57cec5SDimitry Andric return true; 12530b57cec5SDimitry Andric } 12540b57cec5SDimitry Andric return false; 12550b57cec5SDimitry Andric } 12560b57cec5SDimitry Andric 12575f757f3fSDimitry Andric inline bool canUseApxExtendedReg(const MCInstrDesc &Desc) { 12585f757f3fSDimitry Andric uint64_t TSFlags = Desc.TSFlags; 12595f757f3fSDimitry Andric uint64_t Encoding = TSFlags & EncodingMask; 12605f757f3fSDimitry Andric // EVEX can always use egpr. 12615f757f3fSDimitry Andric if (Encoding == X86II::EVEX) 12625f757f3fSDimitry Andric return true; 12635f757f3fSDimitry Andric 12647a6dacacSDimitry Andric unsigned Opcode = Desc.Opcode; 12657a6dacacSDimitry Andric // MOV32r0 is always expanded to XOR32rr 12667a6dacacSDimitry Andric if (Opcode == X86::MOV32r0) 12677a6dacacSDimitry Andric return true; 12685f757f3fSDimitry Andric // To be conservative, egpr is not used for all pseudo instructions 12695f757f3fSDimitry Andric // because we are not sure what instruction it will become. 12705f757f3fSDimitry Andric // FIXME: Could we improve it in X86ExpandPseudo? 12715f757f3fSDimitry Andric if (isPseudo(TSFlags)) 12725f757f3fSDimitry Andric return false; 12735f757f3fSDimitry Andric 12745f757f3fSDimitry Andric // MAP OB/TB in legacy encoding space can always use egpr except 12755f757f3fSDimitry Andric // XSAVE*/XRSTOR*. 12765f757f3fSDimitry Andric switch (Opcode) { 12775f757f3fSDimitry Andric default: 12785f757f3fSDimitry Andric break; 12795f757f3fSDimitry Andric case X86::XSAVE: 12805f757f3fSDimitry Andric case X86::XSAVE64: 12815f757f3fSDimitry Andric case X86::XSAVEOPT: 12825f757f3fSDimitry Andric case X86::XSAVEOPT64: 12835f757f3fSDimitry Andric case X86::XSAVEC: 12845f757f3fSDimitry Andric case X86::XSAVEC64: 12855f757f3fSDimitry Andric case X86::XSAVES: 12865f757f3fSDimitry Andric case X86::XSAVES64: 12875f757f3fSDimitry Andric case X86::XRSTOR: 12885f757f3fSDimitry Andric case X86::XRSTOR64: 12895f757f3fSDimitry Andric case X86::XRSTORS: 12905f757f3fSDimitry Andric case X86::XRSTORS64: 12915f757f3fSDimitry Andric return false; 12925f757f3fSDimitry Andric } 12935f757f3fSDimitry Andric uint64_t OpMap = TSFlags & X86II::OpMapMask; 12945f757f3fSDimitry Andric return !Encoding && (OpMap == X86II::OB || OpMap == X86II::TB); 12955f757f3fSDimitry Andric } 12965f757f3fSDimitry Andric 1297480093f4SDimitry Andric /// \returns true if the MemoryOperand is a 32 extended (zmm16 or higher) 1298480093f4SDimitry Andric /// registers, e.g. zmm21, etc. 12990b57cec5SDimitry Andric static inline bool is32ExtendedReg(unsigned RegNo) { 13000b57cec5SDimitry Andric return ((RegNo >= X86::XMM16 && RegNo <= X86::XMM31) || 13010b57cec5SDimitry Andric (RegNo >= X86::YMM16 && RegNo <= X86::YMM31) || 13020b57cec5SDimitry Andric (RegNo >= X86::ZMM16 && RegNo <= X86::ZMM31)); 13030b57cec5SDimitry Andric } 13040b57cec5SDimitry Andric 13050b57cec5SDimitry Andric inline bool isX86_64NonExtLowByteReg(unsigned reg) { 13065f757f3fSDimitry Andric return (reg == X86::SPL || reg == X86::BPL || reg == X86::SIL || 13075f757f3fSDimitry Andric reg == X86::DIL); 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric 1310480093f4SDimitry Andric /// \returns true if this is a masked instruction. 13110b57cec5SDimitry Andric inline bool isKMasked(uint64_t TSFlags) { 13120b57cec5SDimitry Andric return (TSFlags & X86II::EVEX_K) != 0; 13130b57cec5SDimitry Andric } 13140b57cec5SDimitry Andric 1315480093f4SDimitry Andric /// \returns true if this is a merge masked instruction. 13160b57cec5SDimitry Andric inline bool isKMergeMasked(uint64_t TSFlags) { 13170b57cec5SDimitry Andric return isKMasked(TSFlags) && (TSFlags & X86II::EVEX_Z) == 0; 13180b57cec5SDimitry Andric } 1319*0fca6ea1SDimitry Andric 1320*0fca6ea1SDimitry Andric /// \returns true if the intruction needs a SIB. 1321*0fca6ea1SDimitry Andric inline bool needSIB(unsigned BaseReg, unsigned IndexReg, bool In64BitMode) { 1322*0fca6ea1SDimitry Andric // The SIB byte must be used if there is an index register. 1323*0fca6ea1SDimitry Andric if (IndexReg) 1324*0fca6ea1SDimitry Andric return true; 1325*0fca6ea1SDimitry Andric 1326*0fca6ea1SDimitry Andric // The SIB byte must be used if the base is ESP/RSP/R12/R20/R28, all of 1327*0fca6ea1SDimitry Andric // which encode to an R/M value of 4, which indicates that a SIB byte is 1328*0fca6ea1SDimitry Andric // present. 1329*0fca6ea1SDimitry Andric switch (BaseReg) { 1330*0fca6ea1SDimitry Andric default: 1331*0fca6ea1SDimitry Andric // If there is no base register and we're in 64-bit mode, we need a SIB 1332*0fca6ea1SDimitry Andric // byte to emit an addr that is just 'disp32' (the non-RIP relative form). 1333*0fca6ea1SDimitry Andric return In64BitMode && !BaseReg; 1334*0fca6ea1SDimitry Andric case X86::ESP: 1335*0fca6ea1SDimitry Andric case X86::RSP: 1336*0fca6ea1SDimitry Andric case X86::R12: 1337*0fca6ea1SDimitry Andric case X86::R12D: 1338*0fca6ea1SDimitry Andric case X86::R20: 1339*0fca6ea1SDimitry Andric case X86::R20D: 1340*0fca6ea1SDimitry Andric case X86::R28: 1341*0fca6ea1SDimitry Andric case X86::R28D: 1342*0fca6ea1SDimitry Andric return true; 1343*0fca6ea1SDimitry Andric } 1344*0fca6ea1SDimitry Andric } 1345*0fca6ea1SDimitry Andric 13465f757f3fSDimitry Andric } // namespace X86II 13475f757f3fSDimitry Andric } // namespace llvm 13480b57cec5SDimitry Andric #endif 1349