xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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