1 //===-- X86InstrInfo.td - Main X86 Instruction Definition --*- tablegen -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file describes the X86 instruction set, defining the instructions, and
10 // properties of the instructions which are needed for code generation, machine
11 // code emission, and analysis.
13 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
16 // X86 specific DAG Nodes.
19 def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisSameAs<1, 2>]>;
21 def SDTX86Cmps : SDTypeProfile<1, 3, [SDTCisFP<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
22 //def SDTX86Cmpss : SDTypeProfile<1, 3, [SDTCisVT<0, f32>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
24 def SDTX86Cmov : SDTypeProfile<1, 4,
25 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
26 SDTCisVT<3, i8>, SDTCisVT<4, i32>]>;
28 // Unary and binary operator instructions that set EFLAGS as a side-effect.
29 def SDTUnaryArithWithFlags : SDTypeProfile<2, 1,
31 SDTCisInt<0>, SDTCisVT<1, i32>]>;
33 def SDTBinaryArithWithFlags : SDTypeProfile<2, 2,
36 SDTCisInt<0>, SDTCisVT<1, i32>]>;
38 // SDTBinaryArithWithFlagsInOut - RES1, EFLAGS = op LHS, RHS, EFLAGS
39 def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
45 // RES1, RES2, FLAGS = op LHS, RHS
46 def SDT2ResultBinaryArithWithFlags : SDTypeProfile<3, 2,
50 SDTCisInt<0>, SDTCisVT<1, i32>]>;
51 def SDTX86BrCond : SDTypeProfile<0, 3,
52 [SDTCisVT<0, OtherVT>,
53 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
55 def SDTX86SetCC : SDTypeProfile<1, 2,
57 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
58 def SDTX86SetCC_C : SDTypeProfile<1, 2,
60 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
62 def SDTX86sahf : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i8>]>;
64 def SDTX86rdrand : SDTypeProfile<2, 0, [SDTCisInt<0>, SDTCisVT<1, i32>]>;
66 def SDTX86rdpkru : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
67 def SDTX86wrpkru : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
70 def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>,
72 def SDTX86caspair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
73 def SDTX86caspairSaveEbx8 : SDTypeProfile<1, 3,
74 [SDTCisVT<0, i32>, SDTCisPtrTy<1>,
75 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
76 def SDTX86caspairSaveRbx16 : SDTypeProfile<1, 3,
77 [SDTCisVT<0, i64>, SDTCisPtrTy<1>,
78 SDTCisVT<2, i64>, SDTCisVT<3, i64>]>;
80 def SDTLockBinaryArithWithFlags : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
84 def SDTLockUnaryArithWithFlags : SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
87 def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
89 def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
91 def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
94 def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
96 def SDT_X86NtBrind : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
98 def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
102 def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
108 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
110 def SDTX86Void : SDTypeProfile<0, 0, []>;
112 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
114 def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
116 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
118 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
120 def SDT_X86WIN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
122 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
124 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
126 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
128 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
130 def SDT_X86ENQCMD : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
131 SDTCisPtrTy<1>, SDTCisSameAs<1, 2>]>;
133 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
134 [SDNPHasChain,SDNPSideEffect]>;
135 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
139 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
140 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
141 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
142 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
144 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
145 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
147 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
148 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
150 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
151 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
153 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
155 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
156 [SDNPHasChain, SDNPSideEffect]>;
158 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
159 [SDNPHasChain, SDNPSideEffect]>;
161 def X86rdpkru : SDNode<"X86ISD::RDPKRU", SDTX86rdpkru,
162 [SDNPHasChain, SDNPSideEffect]>;
163 def X86wrpkru : SDNode<"X86ISD::WRPKRU", SDTX86wrpkru,
164 [SDNPHasChain, SDNPSideEffect]>;
166 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
167 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
168 SDNPMayLoad, SDNPMemOperand]>;
169 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
170 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
171 SDNPMayLoad, SDNPMemOperand]>;
172 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
173 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
174 SDNPMayLoad, SDNPMemOperand]>;
175 def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG",
176 SDTX86caspairSaveEbx8,
177 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
178 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
179 def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG",
180 SDTX86caspairSaveRbx16,
181 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
182 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
184 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
185 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
186 def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret,
187 [SDNPHasChain, SDNPOptInGlue]>;
189 def X86vastart_save_xmm_regs :
190 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
191 SDT_X86VASTART_SAVE_XMM_REGS,
192 [SDNPHasChain, SDNPVariadic]>;
194 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
195 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
197 def X86callseq_start :
198 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
199 [SDNPHasChain, SDNPOutGlue]>;
201 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
202 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
204 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
205 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
208 def X86NoTrackCall : SDNode<"X86ISD::NT_CALL", SDT_X86Call,
209 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
211 def X86NoTrackBrind : SDNode<"X86ISD::NT_BRIND", SDT_X86NtBrind,
214 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
215 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
216 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
217 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
220 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
221 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
223 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
224 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
227 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
228 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
230 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
231 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
233 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
236 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
237 SDTypeProfile<1, 1, [SDTCisInt<0>,
239 [SDNPHasChain, SDNPSideEffect]>;
240 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
241 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
242 [SDNPHasChain, SDNPSideEffect]>;
243 def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH",
244 SDTypeProfile<0, 0, []>,
245 [SDNPHasChain, SDNPSideEffect]>;
247 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
248 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
250 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
252 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
253 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
255 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
257 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
258 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
260 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
262 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
264 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
267 def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags,
268 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
270 def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags,
271 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
273 def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags,
274 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
276 def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags,
277 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
279 def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags,
280 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
283 def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
285 def X86bzhi : SDNode<"X86ISD::BZHI", SDTIntBinOp>;
287 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
289 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
290 [SDNPHasChain, SDNPOutGlue]>;
292 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
295 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
296 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
298 def X86lwpins : SDNode<"X86ISD::LWPINS",
299 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
300 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
301 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>;
303 def X86umwait : SDNode<"X86ISD::UMWAIT",
304 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
305 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
306 [SDNPHasChain, SDNPSideEffect]>;
308 def X86tpause : SDNode<"X86ISD::TPAUSE",
309 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
310 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
311 [SDNPHasChain, SDNPSideEffect]>;
313 def X86enqcmd : SDNode<"X86ISD::ENQCMD", SDT_X86ENQCMD,
314 [SDNPHasChain, SDNPSideEffect]>;
315 def X86enqcmds : SDNode<"X86ISD::ENQCMDS", SDT_X86ENQCMD,
316 [SDNPHasChain, SDNPSideEffect]>;
318 //===----------------------------------------------------------------------===//
319 // X86 Operand Definitions.
322 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
323 // the index operand of an address, to conform to x86 encoding restrictions.
324 def ptr_rc_nosp : PointerLikeRegClass<1>;
326 // *mem - Operand definitions for the funky X86 addressing mode operands.
328 def X86MemAsmOperand : AsmOperandClass {
331 let RenderMethod = "addMemOperands", SuperClasses = [X86MemAsmOperand] in {
332 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
333 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
334 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
335 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
336 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
337 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
338 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
339 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
340 // Gather mem operands
341 def X86Mem64_RC128Operand : AsmOperandClass { let Name = "Mem64_RC128"; }
342 def X86Mem128_RC128Operand : AsmOperandClass { let Name = "Mem128_RC128"; }
343 def X86Mem256_RC128Operand : AsmOperandClass { let Name = "Mem256_RC128"; }
344 def X86Mem128_RC256Operand : AsmOperandClass { let Name = "Mem128_RC256"; }
345 def X86Mem256_RC256Operand : AsmOperandClass { let Name = "Mem256_RC256"; }
347 def X86Mem64_RC128XOperand : AsmOperandClass { let Name = "Mem64_RC128X"; }
348 def X86Mem128_RC128XOperand : AsmOperandClass { let Name = "Mem128_RC128X"; }
349 def X86Mem256_RC128XOperand : AsmOperandClass { let Name = "Mem256_RC128X"; }
350 def X86Mem128_RC256XOperand : AsmOperandClass { let Name = "Mem128_RC256X"; }
351 def X86Mem256_RC256XOperand : AsmOperandClass { let Name = "Mem256_RC256X"; }
352 def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; }
353 def X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; }
354 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; }
357 def X86AbsMemAsmOperand : AsmOperandClass {
359 let SuperClasses = [X86MemAsmOperand];
362 class X86MemOperand<string printMethod,
363 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
364 let PrintMethod = printMethod;
365 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
366 let ParserMatchClass = parserMatchClass;
367 let OperandType = "OPERAND_MEMORY";
370 // Gather mem operands
371 class X86VMemOperand<RegisterClass RC, string printMethod,
372 AsmOperandClass parserMatchClass>
373 : X86MemOperand<printMethod, parserMatchClass> {
374 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
377 def anymem : X86MemOperand<"printanymem">;
379 // FIXME: Right now we allow any size during parsing, but we might want to
380 // restrict to only unsized memory.
381 def opaquemem : X86MemOperand<"printopaquemem">;
383 def i8mem : X86MemOperand<"printbytemem", X86Mem8AsmOperand>;
384 def i16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand>;
385 def i32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>;
386 def i64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;
387 def i128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>;
388 def i256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>;
389 def i512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>;
390 def f32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>;
391 def f64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;
392 def f80mem : X86MemOperand<"printtbytemem", X86Mem80AsmOperand>;
393 def f128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>;
394 def f256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>;
395 def f512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>;
397 // Gather mem operands
398 def vx64mem : X86VMemOperand<VR128, "printqwordmem", X86Mem64_RC128Operand>;
399 def vx128mem : X86VMemOperand<VR128, "printxmmwordmem", X86Mem128_RC128Operand>;
400 def vx256mem : X86VMemOperand<VR128, "printymmwordmem", X86Mem256_RC128Operand>;
401 def vy128mem : X86VMemOperand<VR256, "printxmmwordmem", X86Mem128_RC256Operand>;
402 def vy256mem : X86VMemOperand<VR256, "printymmwordmem", X86Mem256_RC256Operand>;
404 def vx64xmem : X86VMemOperand<VR128X, "printqwordmem", X86Mem64_RC128XOperand>;
405 def vx128xmem : X86VMemOperand<VR128X, "printxmmwordmem", X86Mem128_RC128XOperand>;
406 def vx256xmem : X86VMemOperand<VR128X, "printymmwordmem", X86Mem256_RC128XOperand>;
407 def vy128xmem : X86VMemOperand<VR256X, "printxmmwordmem", X86Mem128_RC256XOperand>;
408 def vy256xmem : X86VMemOperand<VR256X, "printymmwordmem", X86Mem256_RC256XOperand>;
409 def vy512xmem : X86VMemOperand<VR256X, "printzmmwordmem", X86Mem512_RC256XOperand>;
410 def vz256mem : X86VMemOperand<VR512, "printymmwordmem", X86Mem256_RC512Operand>;
411 def vz512mem : X86VMemOperand<VR512, "printzmmwordmem", X86Mem512_RC512Operand>;
413 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
414 // of a plain GPR, so that it doesn't potentially require a REX prefix.
415 def ptr_rc_norex : PointerLikeRegClass<2>;
416 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
418 def i8mem_NOREX : Operand<iPTR> {
419 let PrintMethod = "printbytemem";
420 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
422 let ParserMatchClass = X86Mem8AsmOperand;
423 let OperandType = "OPERAND_MEMORY";
426 // GPRs available for tailcall.
427 // It represents GR32_TC, GR64_TC or GR64_TCW64.
428 def ptr_rc_tailcall : PointerLikeRegClass<4>;
430 // Special i32mem for addresses of load folding tail calls. These are not
431 // allowed to use callee-saved registers since they must be scheduled
432 // after callee-saved register are popped.
433 def i32mem_TC : Operand<i32> {
434 let PrintMethod = "printdwordmem";
435 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
436 i32imm, SEGMENT_REG);
437 let ParserMatchClass = X86Mem32AsmOperand;
438 let OperandType = "OPERAND_MEMORY";
441 // Special i64mem for addresses of load folding tail calls. These are not
442 // allowed to use callee-saved registers since they must be scheduled
443 // after callee-saved register are popped.
444 def i64mem_TC : Operand<i64> {
445 let PrintMethod = "printqwordmem";
446 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
447 ptr_rc_tailcall, i32imm, SEGMENT_REG);
448 let ParserMatchClass = X86Mem64AsmOperand;
449 let OperandType = "OPERAND_MEMORY";
452 let OperandType = "OPERAND_PCREL",
453 ParserMatchClass = X86AbsMemAsmOperand,
454 PrintMethod = "printPCRelImm" in {
455 def i32imm_pcrel : Operand<i32>;
456 def i16imm_pcrel : Operand<i16>;
458 // Branch targets have OtherVT type and print as pc-relative values.
459 def brtarget : Operand<OtherVT>;
460 def brtarget8 : Operand<OtherVT>;
464 // Special parser to detect 16-bit mode to select 16-bit displacement.
465 def X86AbsMem16AsmOperand : AsmOperandClass {
466 let Name = "AbsMem16";
467 let RenderMethod = "addAbsMemOperands";
468 let SuperClasses = [X86AbsMemAsmOperand];
471 // Branch targets have OtherVT type and print as pc-relative values.
472 let OperandType = "OPERAND_PCREL",
473 PrintMethod = "printPCRelImm" in {
474 let ParserMatchClass = X86AbsMem16AsmOperand in
475 def brtarget16 : Operand<OtherVT>;
476 let ParserMatchClass = X86AbsMemAsmOperand in
477 def brtarget32 : Operand<OtherVT>;
480 let RenderMethod = "addSrcIdxOperands" in {
481 def X86SrcIdx8Operand : AsmOperandClass {
482 let Name = "SrcIdx8";
483 let SuperClasses = [X86Mem8AsmOperand];
485 def X86SrcIdx16Operand : AsmOperandClass {
486 let Name = "SrcIdx16";
487 let SuperClasses = [X86Mem16AsmOperand];
489 def X86SrcIdx32Operand : AsmOperandClass {
490 let Name = "SrcIdx32";
491 let SuperClasses = [X86Mem32AsmOperand];
493 def X86SrcIdx64Operand : AsmOperandClass {
494 let Name = "SrcIdx64";
495 let SuperClasses = [X86Mem64AsmOperand];
497 } // RenderMethod = "addSrcIdxOperands"
499 let RenderMethod = "addDstIdxOperands" in {
500 def X86DstIdx8Operand : AsmOperandClass {
501 let Name = "DstIdx8";
502 let SuperClasses = [X86Mem8AsmOperand];
504 def X86DstIdx16Operand : AsmOperandClass {
505 let Name = "DstIdx16";
506 let SuperClasses = [X86Mem16AsmOperand];
508 def X86DstIdx32Operand : AsmOperandClass {
509 let Name = "DstIdx32";
510 let SuperClasses = [X86Mem32AsmOperand];
512 def X86DstIdx64Operand : AsmOperandClass {
513 let Name = "DstIdx64";
514 let SuperClasses = [X86Mem64AsmOperand];
516 } // RenderMethod = "addDstIdxOperands"
518 let RenderMethod = "addMemOffsOperands" in {
519 def X86MemOffs16_8AsmOperand : AsmOperandClass {
520 let Name = "MemOffs16_8";
521 let SuperClasses = [X86Mem8AsmOperand];
523 def X86MemOffs16_16AsmOperand : AsmOperandClass {
524 let Name = "MemOffs16_16";
525 let SuperClasses = [X86Mem16AsmOperand];
527 def X86MemOffs16_32AsmOperand : AsmOperandClass {
528 let Name = "MemOffs16_32";
529 let SuperClasses = [X86Mem32AsmOperand];
531 def X86MemOffs32_8AsmOperand : AsmOperandClass {
532 let Name = "MemOffs32_8";
533 let SuperClasses = [X86Mem8AsmOperand];
535 def X86MemOffs32_16AsmOperand : AsmOperandClass {
536 let Name = "MemOffs32_16";
537 let SuperClasses = [X86Mem16AsmOperand];
539 def X86MemOffs32_32AsmOperand : AsmOperandClass {
540 let Name = "MemOffs32_32";
541 let SuperClasses = [X86Mem32AsmOperand];
543 def X86MemOffs32_64AsmOperand : AsmOperandClass {
544 let Name = "MemOffs32_64";
545 let SuperClasses = [X86Mem64AsmOperand];
547 def X86MemOffs64_8AsmOperand : AsmOperandClass {
548 let Name = "MemOffs64_8";
549 let SuperClasses = [X86Mem8AsmOperand];
551 def X86MemOffs64_16AsmOperand : AsmOperandClass {
552 let Name = "MemOffs64_16";
553 let SuperClasses = [X86Mem16AsmOperand];
555 def X86MemOffs64_32AsmOperand : AsmOperandClass {
556 let Name = "MemOffs64_32";
557 let SuperClasses = [X86Mem32AsmOperand];
559 def X86MemOffs64_64AsmOperand : AsmOperandClass {
560 let Name = "MemOffs64_64";
561 let SuperClasses = [X86Mem64AsmOperand];
563 } // RenderMethod = "addMemOffsOperands"
565 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
566 : X86MemOperand<printMethod, parserMatchClass> {
567 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
570 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
571 : X86MemOperand<printMethod, parserMatchClass> {
572 let MIOperandInfo = (ops ptr_rc);
575 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
576 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
577 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
578 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
579 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
580 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
581 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
582 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
584 class X86MemOffsOperand<Operand immOperand, string printMethod,
585 AsmOperandClass parserMatchClass>
586 : X86MemOperand<printMethod, parserMatchClass> {
587 let MIOperandInfo = (ops immOperand, SEGMENT_REG);
590 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
591 X86MemOffs16_8AsmOperand>;
592 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
593 X86MemOffs16_16AsmOperand>;
594 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
595 X86MemOffs16_32AsmOperand>;
596 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
597 X86MemOffs32_8AsmOperand>;
598 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
599 X86MemOffs32_16AsmOperand>;
600 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
601 X86MemOffs32_32AsmOperand>;
602 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
603 X86MemOffs32_64AsmOperand>;
604 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
605 X86MemOffs64_8AsmOperand>;
606 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
607 X86MemOffs64_16AsmOperand>;
608 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
609 X86MemOffs64_32AsmOperand>;
610 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
611 X86MemOffs64_64AsmOperand>;
613 def ccode : Operand<i8> {
614 let PrintMethod = "printCondCode";
615 let OperandNamespace = "X86";
616 let OperandType = "OPERAND_COND_CODE";
619 class ImmSExtAsmOperandClass : AsmOperandClass {
620 let SuperClasses = [ImmAsmOperand];
621 let RenderMethod = "addImmOperands";
624 def X86GR32orGR64AsmOperand : AsmOperandClass {
625 let Name = "GR32orGR64";
628 def GR32orGR64 : RegisterOperand<GR32> {
629 let ParserMatchClass = X86GR32orGR64AsmOperand;
631 def AVX512RCOperand : AsmOperandClass {
632 let Name = "AVX512RC";
634 def AVX512RC : Operand<i32> {
635 let PrintMethod = "printRoundingControl";
636 let OperandNamespace = "X86";
637 let OperandType = "OPERAND_ROUNDING_CONTROL";
638 let ParserMatchClass = AVX512RCOperand;
641 // Sign-extended immediate classes. We don't need to define the full lattice
642 // here because there is no instruction with an ambiguity between ImmSExti64i32
645 // The strange ranges come from the fact that the assembler always works with
646 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
647 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
650 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
651 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
652 let Name = "ImmSExti64i32";
655 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
656 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
657 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
658 let Name = "ImmSExti16i8";
659 let SuperClasses = [ImmSExti64i32AsmOperand];
662 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
663 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
664 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
665 let Name = "ImmSExti32i8";
669 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
670 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
671 let Name = "ImmSExti64i8";
672 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
673 ImmSExti64i32AsmOperand];
676 // Unsigned immediate used by SSE/AVX instructions
678 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
679 def ImmUnsignedi8AsmOperand : AsmOperandClass {
680 let Name = "ImmUnsignedi8";
681 let RenderMethod = "addImmOperands";
684 // A couple of more descriptive operand definitions.
685 // 16-bits but only 8 bits are significant.
686 def i16i8imm : Operand<i16> {
687 let ParserMatchClass = ImmSExti16i8AsmOperand;
688 let OperandType = "OPERAND_IMMEDIATE";
690 // 32-bits but only 8 bits are significant.
691 def i32i8imm : Operand<i32> {
692 let ParserMatchClass = ImmSExti32i8AsmOperand;
693 let OperandType = "OPERAND_IMMEDIATE";
696 // 64-bits but only 32 bits are significant.
697 def i64i32imm : Operand<i64> {
698 let ParserMatchClass = ImmSExti64i32AsmOperand;
699 let OperandType = "OPERAND_IMMEDIATE";
702 // 64-bits but only 8 bits are significant.
703 def i64i8imm : Operand<i64> {
704 let ParserMatchClass = ImmSExti64i8AsmOperand;
705 let OperandType = "OPERAND_IMMEDIATE";
708 // Unsigned 8-bit immediate used by SSE/AVX instructions.
709 def u8imm : Operand<i8> {
710 let PrintMethod = "printU8Imm";
711 let ParserMatchClass = ImmUnsignedi8AsmOperand;
712 let OperandType = "OPERAND_IMMEDIATE";
715 // 16-bit immediate but only 8-bits are significant and they are unsigned.
716 // Used by BT instructions.
717 def i16u8imm : Operand<i16> {
718 let PrintMethod = "printU8Imm";
719 let ParserMatchClass = ImmUnsignedi8AsmOperand;
720 let OperandType = "OPERAND_IMMEDIATE";
723 // 32-bit immediate but only 8-bits are significant and they are unsigned.
724 // Used by some SSE/AVX instructions that use intrinsics.
725 def i32u8imm : Operand<i32> {
726 let PrintMethod = "printU8Imm";
727 let ParserMatchClass = ImmUnsignedi8AsmOperand;
728 let OperandType = "OPERAND_IMMEDIATE";
731 // 64-bit immediate but only 8-bits are significant and they are unsigned.
732 // Used by BT instructions.
733 def i64u8imm : Operand<i64> {
734 let PrintMethod = "printU8Imm";
735 let ParserMatchClass = ImmUnsignedi8AsmOperand;
736 let OperandType = "OPERAND_IMMEDIATE";
739 // 64-bits but only 32 bits are significant, and those bits are treated as being
741 def i64i32imm_pcrel : Operand<i64> {
742 let PrintMethod = "printPCRelImm";
743 let ParserMatchClass = X86AbsMemAsmOperand;
744 let OperandType = "OPERAND_PCREL";
747 def lea64_32mem : Operand<i32> {
748 let PrintMethod = "printanymem";
749 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
750 let ParserMatchClass = X86MemAsmOperand;
753 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
754 def lea64mem : Operand<i64> {
755 let PrintMethod = "printanymem";
756 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
757 let ParserMatchClass = X86MemAsmOperand;
760 let RenderMethod = "addMaskPairOperands" in {
761 def VK1PairAsmOperand : AsmOperandClass { let Name = "VK1Pair"; }
762 def VK2PairAsmOperand : AsmOperandClass { let Name = "VK2Pair"; }
763 def VK4PairAsmOperand : AsmOperandClass { let Name = "VK4Pair"; }
764 def VK8PairAsmOperand : AsmOperandClass { let Name = "VK8Pair"; }
765 def VK16PairAsmOperand : AsmOperandClass { let Name = "VK16Pair"; }
768 def VK1Pair : RegisterOperand<VK1PAIR, "printVKPair"> {
769 let ParserMatchClass = VK1PairAsmOperand;
772 def VK2Pair : RegisterOperand<VK2PAIR, "printVKPair"> {
773 let ParserMatchClass = VK2PairAsmOperand;
776 def VK4Pair : RegisterOperand<VK4PAIR, "printVKPair"> {
777 let ParserMatchClass = VK4PairAsmOperand;
780 def VK8Pair : RegisterOperand<VK8PAIR, "printVKPair"> {
781 let ParserMatchClass = VK8PairAsmOperand;
784 def VK16Pair : RegisterOperand<VK16PAIR, "printVKPair"> {
785 let ParserMatchClass = VK16PairAsmOperand;
788 //===----------------------------------------------------------------------===//
789 // X86 Complex Pattern Definitions.
792 // Define X86-specific addressing mode.
793 def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
794 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
795 [add, sub, mul, X86mul_imm, shl, or, frameindex],
797 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
798 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
799 [add, sub, mul, X86mul_imm, shl, or,
800 frameindex, X86WrapperRIP],
803 def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
804 [tglobaltlsaddr], []>;
806 def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
807 [tglobaltlsaddr], []>;
809 def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr",
810 [add, sub, mul, X86mul_imm, shl, or, frameindex,
813 def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
814 [tglobaltlsaddr], []>;
816 def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
817 [tglobaltlsaddr], []>;
819 def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
821 // A relocatable immediate is either an immediate operand or an operand that can
822 // be relocated by the linker to an immediate, such as a regular symbol in
824 def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", [imm, X86Wrapper], [],
827 //===----------------------------------------------------------------------===//
828 // X86 Instruction Predicate Definitions.
829 def TruePredicate : Predicate<"true">;
831 def HasCMov : Predicate<"Subtarget->hasCMov()">;
832 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
834 def HasMMX : Predicate<"Subtarget->hasMMX()">;
835 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
836 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
837 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
838 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
839 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
840 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
841 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
842 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
843 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
844 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
845 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
846 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
847 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
848 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
849 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
850 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
851 def NoAVX : Predicate<"!Subtarget->hasAVX()">;
852 def HasAVX : Predicate<"Subtarget->hasAVX()">;
853 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
854 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
855 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">;
856 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
857 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
858 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
859 def HasCDI : Predicate<"Subtarget->hasCDI()">;
860 def HasVPOPCNTDQ : Predicate<"Subtarget->hasVPOPCNTDQ()">;
861 def HasPFI : Predicate<"Subtarget->hasPFI()">;
862 def HasERI : Predicate<"Subtarget->hasERI()">;
863 def HasDQI : Predicate<"Subtarget->hasDQI()">;
864 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
865 def HasBWI : Predicate<"Subtarget->hasBWI()">;
866 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
867 def HasVLX : Predicate<"Subtarget->hasVLX()">;
868 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
869 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
870 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
871 def PKU : Predicate<"Subtarget->hasPKU()">;
872 def HasVNNI : Predicate<"Subtarget->hasVNNI()">;
873 def HasVP2INTERSECT : Predicate<"Subtarget->hasVP2INTERSECT()">;
874 def HasBF16 : Predicate<"Subtarget->hasBF16()">;
876 def HasBITALG : Predicate<"Subtarget->hasBITALG()">;
877 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
878 def HasAES : Predicate<"Subtarget->hasAES()">;
879 def HasVAES : Predicate<"Subtarget->hasVAES()">;
880 def NoVLX_Or_NoVAES : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVAES()">;
881 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
882 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
883 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
884 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
885 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
886 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
887 def NoVLX_Or_NoVPCLMULQDQ :
888 Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVPCLMULQDQ()">;
889 def HasVPCLMULQDQ : Predicate<"Subtarget->hasVPCLMULQDQ()">;
890 def HasGFNI : Predicate<"Subtarget->hasGFNI()">;
891 def HasFMA : Predicate<"Subtarget->hasFMA()">;
892 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
893 def NoFMA4 : Predicate<"!Subtarget->hasFMA4()">;
894 def HasXOP : Predicate<"Subtarget->hasXOP()">;
895 def HasTBM : Predicate<"Subtarget->hasTBM()">;
896 def NoTBM : Predicate<"!Subtarget->hasTBM()">;
897 def HasLWP : Predicate<"Subtarget->hasLWP()">;
898 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
899 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
900 def HasF16C : Predicate<"Subtarget->hasF16C()">;
901 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
902 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
903 def HasBMI : Predicate<"Subtarget->hasBMI()">;
904 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
905 def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">;
906 def HasVBMI : Predicate<"Subtarget->hasVBMI()">;
907 def HasVBMI2 : Predicate<"Subtarget->hasVBMI2()">;
908 def HasIFMA : Predicate<"Subtarget->hasIFMA()">;
909 def HasRTM : Predicate<"Subtarget->hasRTM()">;
910 def HasADX : Predicate<"Subtarget->hasADX()">;
911 def HasSHA : Predicate<"Subtarget->hasSHA()">;
912 def HasSGX : Predicate<"Subtarget->hasSGX()">;
913 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
914 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
915 def HasSSEPrefetch : Predicate<"Subtarget->hasSSEPrefetch()">;
916 def NoSSEPrefetch : Predicate<"!Subtarget->hasSSEPrefetch()">;
917 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
918 def HasPREFETCHWT1 : Predicate<"Subtarget->hasPREFETCHWT1()">;
919 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
920 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
921 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
922 def HasCLDEMOTE : Predicate<"Subtarget->hasCLDEMOTE()">;
923 def HasMOVDIRI : Predicate<"Subtarget->hasMOVDIRI()">;
924 def HasMOVDIR64B : Predicate<"Subtarget->hasMOVDIR64B()">;
925 def HasPTWRITE : Predicate<"Subtarget->hasPTWRITE()">;
926 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
927 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
928 def HasMPX : Predicate<"Subtarget->hasMPX()">;
929 def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">;
930 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
931 def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
932 def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">;
933 def HasRDPID : Predicate<"Subtarget->hasRDPID()">;
934 def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">;
935 def HasINVPCID : Predicate<"Subtarget->hasINVPCID()">;
936 def HasCmpxchg8b : Predicate<"Subtarget->hasCmpxchg8b()">;
937 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
938 def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">;
939 def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">;
940 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
941 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
942 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
943 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
944 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
945 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
946 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
947 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
948 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
949 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
950 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
951 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
952 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
953 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
954 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
955 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
956 let RecomputePerFunction = 1;
958 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
959 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
960 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
961 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
962 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
963 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
964 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
965 "TM.getCodeModel() == CodeModel::Kernel">;
966 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
968 // We could compute these on a per-module basis but doing so requires accessing
969 // the Function object through the <Target>Subtarget and objections were raised
970 // to that (see post-commit review comments for r301750).
971 let RecomputePerFunction = 1 in {
972 def OptForSize : Predicate<"MF->getFunction().hasOptSize()">;
973 def OptForMinSize : Predicate<"MF->getFunction().hasMinSize()">;
974 def OptForSpeed : Predicate<"!MF->getFunction().hasOptSize()">;
975 def UseIncDec : Predicate<"!Subtarget->slowIncDec() || "
976 "MF->getFunction().hasOptSize()">;
977 def NoSSE41_Or_OptForSize : Predicate<"MF->getFunction().hasOptSize() || "
978 "!Subtarget->hasSSE41()">;
981 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
982 def FavorMemIndirectCall : Predicate<"!Subtarget->slowTwoMemOps()">;
983 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
984 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
985 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
986 def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
987 def HasMFence : Predicate<"Subtarget->hasMFence()">;
988 def UseRetpolineIndirectCalls : Predicate<"Subtarget->useRetpolineIndirectCalls()">;
989 def NotUseRetpolineIndirectCalls : Predicate<"!Subtarget->useRetpolineIndirectCalls()">;
991 //===----------------------------------------------------------------------===//
992 // X86 Instruction Format Definitions.
995 include "X86InstrFormats.td"
997 //===----------------------------------------------------------------------===//
998 // Pattern fragments.
1001 // X86 specific condition code. These correspond to CondCode in
1002 // X86InstrInfo.h. They must be kept in synch.
1003 def X86_COND_O : PatLeaf<(i8 0)>;
1004 def X86_COND_NO : PatLeaf<(i8 1)>;
1005 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
1006 def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC
1007 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
1008 def X86_COND_NE : PatLeaf<(i8 5)>; // alt. COND_NZ
1009 def X86_COND_BE : PatLeaf<(i8 6)>; // alt. COND_NA
1010 def X86_COND_A : PatLeaf<(i8 7)>; // alt. COND_NBE
1011 def X86_COND_S : PatLeaf<(i8 8)>;
1012 def X86_COND_NS : PatLeaf<(i8 9)>;
1013 def X86_COND_P : PatLeaf<(i8 10)>; // alt. COND_PE
1014 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
1015 def X86_COND_L : PatLeaf<(i8 12)>; // alt. COND_NGE
1016 def X86_COND_GE : PatLeaf<(i8 13)>; // alt. COND_NL
1017 def X86_COND_LE : PatLeaf<(i8 14)>; // alt. COND_NG
1018 def X86_COND_G : PatLeaf<(i8 15)>; // alt. COND_NLE
1020 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
1021 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
1022 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
1023 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
1025 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
1026 // relocImm-based matchers, but then FastISel would be unable to use them.
1027 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
1028 return isSExtRelocImm<8>(N);
1030 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
1031 return isSExtRelocImm<32>(N);
1034 // If we have multiple users of an immediate, it's much smaller to reuse
1035 // the register, rather than encode the immediate in every instruction.
1036 // This has the risk of increasing register pressure from stretched live
1037 // ranges, however, the immediates should be trivial to rematerialize by
1038 // the RA in the event of high register pressure.
1039 // TODO : This is currently enabled for stores and binary ops. There are more
1040 // cases for which this can be enabled, though this catches the bulk of the
1042 // TODO2 : This should really also be enabled under O2, but there's currently
1043 // an issue with RA where we don't pull the constants into their users
1044 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
1046 // TODO3 : This is currently limited to single basic blocks (DAG creation
1047 // pulls block immediates to the top and merges them if necessary).
1048 // Eventually, it would be nice to allow ConstantHoisting to merge constants
1049 // globally for potentially added savings.
1051 def relocImm8_su : PatLeaf<(i8 relocImm), [{
1052 return !shouldAvoidImmediateInstFormsForSize(N);
1054 def relocImm16_su : PatLeaf<(i16 relocImm), [{
1055 return !shouldAvoidImmediateInstFormsForSize(N);
1057 def relocImm32_su : PatLeaf<(i32 relocImm), [{
1058 return !shouldAvoidImmediateInstFormsForSize(N);
1061 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
1062 return !shouldAvoidImmediateInstFormsForSize(N);
1064 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
1065 return !shouldAvoidImmediateInstFormsForSize(N);
1067 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
1068 return !shouldAvoidImmediateInstFormsForSize(N);
1071 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
1072 return !shouldAvoidImmediateInstFormsForSize(N);
1074 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
1075 return !shouldAvoidImmediateInstFormsForSize(N);
1078 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1080 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1082 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1083 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1086 // Helper fragments for loads.
1088 // It's safe to fold a zextload/extload from i1 as a regular i8 load. The
1089 // upper bits are guaranteed to be zero and we were going to emit a MOV8rm
1090 // which might get folded during peephole anyway.
1091 def loadi8 : PatFrag<(ops node:$ptr), (i8 (unindexedload node:$ptr)), [{
1092 LoadSDNode *LD = cast<LoadSDNode>(N);
1093 ISD::LoadExtType ExtType = LD->getExtensionType();
1094 return ExtType == ISD::NON_EXTLOAD || ExtType == ISD::EXTLOAD ||
1095 ExtType == ISD::ZEXTLOAD;
1098 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1099 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1100 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1101 LoadSDNode *LD = cast<LoadSDNode>(N);
1102 ISD::LoadExtType ExtType = LD->getExtensionType();
1103 if (ExtType == ISD::NON_EXTLOAD)
1105 if (ExtType == ISD::EXTLOAD)
1106 return LD->getAlignment() >= 2 && !LD->isVolatile();
1110 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1111 LoadSDNode *LD = cast<LoadSDNode>(N);
1112 ISD::LoadExtType ExtType = LD->getExtensionType();
1113 if (ExtType == ISD::NON_EXTLOAD)
1115 if (ExtType == ISD::EXTLOAD)
1116 return LD->getAlignment() >= 4 && !LD->isVolatile();
1120 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1121 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1122 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1123 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1124 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1125 def alignedloadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{
1126 LoadSDNode *Ld = cast<LoadSDNode>(N);
1127 return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
1129 def memopf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{
1130 LoadSDNode *Ld = cast<LoadSDNode>(N);
1131 return Subtarget->hasSSEUnalignedMem() ||
1132 Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
1135 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1136 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1137 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1138 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1139 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1140 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1142 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1143 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1144 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1145 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1146 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1147 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1148 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1149 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1150 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1151 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1153 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1154 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1155 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1156 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1157 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1158 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1159 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1160 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1161 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1163 // We can treat an i8/i16 extending load to i64 as a 32 bit load if its known
1164 // to be 4 byte aligned or better.
1165 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (unindexedload node:$ptr)), [{
1166 LoadSDNode *LD = cast<LoadSDNode>(N);
1167 ISD::LoadExtType ExtType = LD->getExtensionType();
1168 if (ExtType != ISD::EXTLOAD)
1170 if (LD->getMemoryVT() == MVT::i32)
1173 return LD->getAlignment() >= 4 && !LD->isVolatile();
1177 // An 'and' node with a single use.
1178 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1179 return N->hasOneUse();
1181 // An 'srl' node with a single use.
1182 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1183 return N->hasOneUse();
1185 // An 'trunc' node with a single use.
1186 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1187 return N->hasOneUse();
1190 //===----------------------------------------------------------------------===//
1191 // Instruction list.
1195 let hasSideEffects = 0, SchedRW = [WriteNop] in {
1196 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
1197 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1198 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable;
1199 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1200 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable;
1201 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
1202 "nop{q}\t$zero", []>, TB, NotMemoryFoldable,
1203 Requires<[In64BitMode]>;
1204 // Also allow register so we can assemble/disassemble
1205 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
1206 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable;
1207 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
1208 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable;
1209 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
1210 "nop{q}\t$zero", []>, TB, NotMemoryFoldable,
1211 Requires<[In64BitMode]>;
1215 // Constructing a stack frame.
1216 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1217 "enter\t$len, $lvl", []>, Sched<[WriteMicrocoded]>;
1219 let SchedRW = [WriteALU] in {
1220 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1221 def LEAVE : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
1222 Requires<[Not64BitMode]>;
1224 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1225 def LEAVE64 : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
1226 Requires<[In64BitMode]>;
1229 //===----------------------------------------------------------------------===//
1230 // Miscellaneous Instructions.
1233 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
1234 SchedRW = [WriteSystem] in
1235 def Int_eh_sjlj_setup_dispatch
1236 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1238 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1239 let mayLoad = 1, SchedRW = [WriteLoad] in {
1240 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
1242 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
1243 OpSize32, Requires<[Not64BitMode]>;
1244 // Long form for the disassembler.
1245 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1246 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
1247 OpSize16, NotMemoryFoldable;
1248 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
1249 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable;
1250 } // isCodeGenOnly = 1, ForceDisassemble = 1
1251 } // mayLoad, SchedRW
1252 let mayStore = 1, mayLoad = 1, SchedRW = [WriteCopy] in {
1253 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", []>,
1255 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", []>,
1256 OpSize32, Requires<[Not64BitMode]>;
1257 } // mayStore, mayLoad, SchedRW
1259 let mayStore = 1, SchedRW = [WriteStore] in {
1260 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
1262 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
1263 OpSize32, Requires<[Not64BitMode]>;
1264 // Long form for the disassembler.
1265 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1266 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
1267 OpSize16, NotMemoryFoldable;
1268 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
1269 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable;
1270 } // isCodeGenOnly = 1, ForceDisassemble = 1
1272 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1273 "push{w}\t$imm", []>, OpSize16;
1274 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1275 "push{w}\t$imm", []>, OpSize16;
1277 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1278 "push{l}\t$imm", []>, OpSize32,
1279 Requires<[Not64BitMode]>;
1280 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1281 "push{l}\t$imm", []>, OpSize32,
1282 Requires<[Not64BitMode]>;
1283 } // mayStore, SchedRW
1285 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
1286 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src", []>,
1288 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src", []>,
1289 OpSize32, Requires<[Not64BitMode]>;
1290 } // mayLoad, mayStore, SchedRW
1294 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1295 SchedRW = [WriteRMW], Defs = [ESP] in {
1297 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1298 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1299 Requires<[Not64BitMode]>;
1302 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1303 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1304 Requires<[In64BitMode]>;
1307 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1308 SchedRW = [WriteRMW] in {
1309 let Defs = [ESP, EFLAGS, DF], Uses = [ESP] in
1310 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1311 [(int_x86_flags_write_u32 GR32:$src)]>,
1312 Requires<[Not64BitMode]>;
1314 let Defs = [RSP, EFLAGS, DF], Uses = [RSP] in
1315 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1316 [(int_x86_flags_write_u64 GR64:$src)]>,
1317 Requires<[In64BitMode]>;
1320 let Defs = [ESP, EFLAGS, DF], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1321 SchedRW = [WriteLoad] in {
1322 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize16;
1323 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>, OpSize32,
1324 Requires<[Not64BitMode]>;
1327 let Defs = [ESP], Uses = [ESP, EFLAGS, DF], mayStore = 1, hasSideEffects=0,
1328 SchedRW = [WriteStore] in {
1329 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize16;
1330 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>, OpSize32,
1331 Requires<[Not64BitMode]>;
1334 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1335 let mayLoad = 1, SchedRW = [WriteLoad] in {
1336 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
1337 OpSize32, Requires<[In64BitMode]>;
1338 // Long form for the disassembler.
1339 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1340 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
1341 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable;
1342 } // isCodeGenOnly = 1, ForceDisassemble = 1
1343 } // mayLoad, SchedRW
1344 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in
1345 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>,
1346 OpSize32, Requires<[In64BitMode]>;
1347 let mayStore = 1, SchedRW = [WriteStore] in {
1348 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
1349 OpSize32, Requires<[In64BitMode]>;
1350 // Long form for the disassembler.
1351 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1352 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
1353 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable;
1354 } // isCodeGenOnly = 1, ForceDisassemble = 1
1355 } // mayStore, SchedRW
1356 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
1357 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>,
1358 OpSize32, Requires<[In64BitMode]>;
1359 } // mayLoad, mayStore, SchedRW
1362 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1363 SchedRW = [WriteStore] in {
1364 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1365 "push{q}\t$imm", []>, OpSize32,
1366 Requires<[In64BitMode]>;
1367 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1368 "push{q}\t$imm", []>, OpSize32,
1369 Requires<[In64BitMode]>;
1372 let Defs = [RSP, EFLAGS, DF], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1373 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", []>,
1374 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1375 let Defs = [RSP], Uses = [RSP, EFLAGS, DF], mayStore = 1, hasSideEffects=0 in
1376 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>,
1377 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1379 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1380 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1381 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", []>,
1382 OpSize32, Requires<[Not64BitMode]>;
1383 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", []>,
1384 OpSize16, Requires<[Not64BitMode]>;
1386 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1387 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1388 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", []>,
1389 OpSize32, Requires<[Not64BitMode]>;
1390 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", []>,
1391 OpSize16, Requires<[Not64BitMode]>;
1394 let Constraints = "$src = $dst", SchedRW = [WriteBSWAP32] in {
1395 // This instruction is a consequence of BSWAP32r observing operand size. The
1396 // encoding is valid, but the behavior is undefined.
1397 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
1398 def BSWAP16r_BAD : I<0xC8, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
1399 "bswap{w}\t$dst", []>, OpSize16, TB;
1400 // GR32 = bswap GR32
1401 def BSWAP32r : I<0xC8, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
1403 [(set GR32:$dst, (bswap GR32:$src))]>, OpSize32, TB;
1405 let SchedRW = [WriteBSWAP64] in
1406 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1408 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
1409 } // Constraints = "$src = $dst", SchedRW
1411 // Bit scan instructions.
1412 let Defs = [EFLAGS] in {
1413 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1414 "bsf{w}\t{$src, $dst|$dst, $src}",
1415 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))]>,
1416 PS, OpSize16, Sched<[WriteBSF]>;
1417 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1418 "bsf{w}\t{$src, $dst|$dst, $src}",
1419 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))]>,
1420 PS, OpSize16, Sched<[WriteBSFLd]>;
1421 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1422 "bsf{l}\t{$src, $dst|$dst, $src}",
1423 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))]>,
1424 PS, OpSize32, Sched<[WriteBSF]>;
1425 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1426 "bsf{l}\t{$src, $dst|$dst, $src}",
1427 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))]>,
1428 PS, OpSize32, Sched<[WriteBSFLd]>;
1429 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1430 "bsf{q}\t{$src, $dst|$dst, $src}",
1431 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>,
1432 PS, Sched<[WriteBSF]>;
1433 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1434 "bsf{q}\t{$src, $dst|$dst, $src}",
1435 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>,
1436 PS, Sched<[WriteBSFLd]>;
1438 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1439 "bsr{w}\t{$src, $dst|$dst, $src}",
1440 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))]>,
1441 PS, OpSize16, Sched<[WriteBSR]>;
1442 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1443 "bsr{w}\t{$src, $dst|$dst, $src}",
1444 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))]>,
1445 PS, OpSize16, Sched<[WriteBSRLd]>;
1446 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1447 "bsr{l}\t{$src, $dst|$dst, $src}",
1448 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))]>,
1449 PS, OpSize32, Sched<[WriteBSR]>;
1450 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1451 "bsr{l}\t{$src, $dst|$dst, $src}",
1452 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))]>,
1453 PS, OpSize32, Sched<[WriteBSRLd]>;
1454 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1455 "bsr{q}\t{$src, $dst|$dst, $src}",
1456 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>,
1457 PS, Sched<[WriteBSR]>;
1458 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1459 "bsr{q}\t{$src, $dst|$dst, $src}",
1460 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>,
1461 PS, Sched<[WriteBSRLd]>;
1462 } // Defs = [EFLAGS]
1464 let SchedRW = [WriteMicrocoded] in {
1465 let Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in {
1466 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1467 "movsb\t{$src, $dst|$dst, $src}", []>;
1468 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1469 "movsw\t{$src, $dst|$dst, $src}", []>, OpSize16;
1470 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1471 "movs{l|d}\t{$src, $dst|$dst, $src}", []>, OpSize32;
1472 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1473 "movsq\t{$src, $dst|$dst, $src}", []>,
1474 Requires<[In64BitMode]>;
1477 let Defs = [EDI], Uses = [AL,EDI,DF] in
1478 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1479 "stosb\t{%al, $dst|$dst, al}", []>;
1480 let Defs = [EDI], Uses = [AX,EDI,DF] in
1481 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1482 "stosw\t{%ax, $dst|$dst, ax}", []>, OpSize16;
1483 let Defs = [EDI], Uses = [EAX,EDI,DF] in
1484 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1485 "stos{l|d}\t{%eax, $dst|$dst, eax}", []>, OpSize32;
1486 let Defs = [RDI], Uses = [RAX,RDI,DF] in
1487 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1488 "stosq\t{%rax, $dst|$dst, rax}", []>,
1489 Requires<[In64BitMode]>;
1491 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in
1492 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1493 "scasb\t{$dst, %al|al, $dst}", []>;
1494 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in
1495 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1496 "scasw\t{$dst, %ax|ax, $dst}", []>, OpSize16;
1497 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in
1498 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1499 "scas{l|d}\t{$dst, %eax|eax, $dst}", []>, OpSize32;
1500 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in
1501 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1502 "scasq\t{$dst, %rax|rax, $dst}", []>,
1503 Requires<[In64BitMode]>;
1505 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in {
1506 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1507 "cmpsb\t{$dst, $src|$src, $dst}", []>;
1508 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1509 "cmpsw\t{$dst, $src|$src, $dst}", []>, OpSize16;
1510 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1511 "cmps{l|d}\t{$dst, $src|$src, $dst}", []>, OpSize32;
1512 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1513 "cmpsq\t{$dst, $src|$src, $dst}", []>,
1514 Requires<[In64BitMode]>;
1518 //===----------------------------------------------------------------------===//
1519 // Move Instructions.
1521 let SchedRW = [WriteMove] in {
1522 let hasSideEffects = 0, isMoveReg = 1 in {
1523 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1524 "mov{b}\t{$src, $dst|$dst, $src}", []>;
1525 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1526 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
1527 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1528 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
1529 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1530 "mov{q}\t{$src, $dst|$dst, $src}", []>;
1533 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
1534 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1535 "mov{b}\t{$src, $dst|$dst, $src}",
1536 [(set GR8:$dst, imm:$src)]>;
1537 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1538 "mov{w}\t{$src, $dst|$dst, $src}",
1539 [(set GR16:$dst, imm:$src)]>, OpSize16;
1540 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1541 "mov{l}\t{$src, $dst|$dst, $src}",
1542 [(set GR32:$dst, relocImm:$src)]>, OpSize32;
1543 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1544 "mov{q}\t{$src, $dst|$dst, $src}",
1545 [(set GR64:$dst, i64immSExt32:$src)]>;
1547 let isReMaterializable = 1, isMoveImm = 1 in {
1548 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1549 "movabs{q}\t{$src, $dst|$dst, $src}",
1550 [(set GR64:$dst, relocImm:$src)]>;
1553 // Longer forms that use a ModR/M byte. Needed for disassembler
1554 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1555 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1556 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1557 FoldGenData<"MOV8ri">;
1558 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1559 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16,
1560 FoldGenData<"MOV16ri">;
1561 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1562 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32,
1563 FoldGenData<"MOV32ri">;
1567 let SchedRW = [WriteStore] in {
1568 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1569 "mov{b}\t{$src, $dst|$dst, $src}",
1570 [(store (i8 relocImm8_su:$src), addr:$dst)]>;
1571 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1572 "mov{w}\t{$src, $dst|$dst, $src}",
1573 [(store (i16 relocImm16_su:$src), addr:$dst)]>, OpSize16;
1574 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1575 "mov{l}\t{$src, $dst|$dst, $src}",
1576 [(store (i32 relocImm32_su:$src), addr:$dst)]>, OpSize32;
1577 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1578 "mov{q}\t{$src, $dst|$dst, $src}",
1579 [(store i64relocImmSExt32_su:$src, addr:$dst)]>,
1580 Requires<[In64BitMode]>;
1583 let hasSideEffects = 0 in {
1585 /// Memory offset versions of moves. The immediate is an address mode sized
1586 /// offset from the segment base.
1587 let SchedRW = [WriteALU] in {
1588 let mayLoad = 1 in {
1590 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1591 "mov{b}\t{$src, %al|al, $src}", []>,
1594 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1595 "mov{w}\t{$src, %ax|ax, $src}", []>,
1598 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1599 "mov{l}\t{$src, %eax|eax, $src}", []>,
1602 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1603 "mov{q}\t{$src, %rax|rax, $src}", []>,
1607 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1608 "mov{b}\t{$src, %al|al, $src}", []>, AdSize16;
1610 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1611 "mov{w}\t{$src, %ax|ax, $src}", []>,
1614 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1615 "mov{l}\t{$src, %eax|eax, $src}", []>,
1618 let mayStore = 1 in {
1620 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1621 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize32;
1623 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1624 "mov{w}\t{%ax, $dst|$dst, ax}", []>,
1627 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1628 "mov{l}\t{%eax, $dst|$dst, eax}", []>,
1631 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1632 "mov{q}\t{%rax, $dst|$dst, rax}", []>,
1636 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1637 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize16;
1639 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1640 "mov{w}\t{%ax, $dst|$dst, ax}", []>,
1643 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1644 "mov{l}\t{%eax, $dst|$dst, eax}", []>,
1648 // These forms all have full 64-bit absolute addresses in their instructions
1649 // and use the movabs mnemonic to indicate this specific form.
1650 let mayLoad = 1 in {
1652 def MOV8ao64 : Ii64<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1653 "movabs{b}\t{$src, %al|al, $src}", []>,
1656 def MOV16ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1657 "movabs{w}\t{$src, %ax|ax, $src}", []>,
1660 def MOV32ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1661 "movabs{l}\t{$src, %eax|eax, $src}", []>,
1664 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1665 "movabs{q}\t{$src, %rax|rax, $src}", []>,
1669 let mayStore = 1 in {
1671 def MOV8o64a : Ii64<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1672 "movabs{b}\t{%al, $dst|$dst, al}", []>,
1675 def MOV16o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1676 "movabs{w}\t{%ax, $dst|$dst, ax}", []>,
1679 def MOV32o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1680 "movabs{l}\t{%eax, $dst|$dst, eax}", []>,
1683 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1684 "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
1688 } // hasSideEffects = 0
1690 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1691 SchedRW = [WriteMove], isMoveReg = 1 in {
1692 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1693 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1694 FoldGenData<"MOV8rr">;
1695 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1696 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16,
1697 FoldGenData<"MOV16rr">;
1698 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1699 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32,
1700 FoldGenData<"MOV32rr">;
1701 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1702 "mov{q}\t{$src, $dst|$dst, $src}", []>,
1703 FoldGenData<"MOV64rr">;
1706 // Reversed version with ".s" suffix for GAS compatibility.
1707 def : InstAlias<"mov{b}.s\t{$src, $dst|$dst, $src}",
1708 (MOV8rr_REV GR8:$dst, GR8:$src), 0>;
1709 def : InstAlias<"mov{w}.s\t{$src, $dst|$dst, $src}",
1710 (MOV16rr_REV GR16:$dst, GR16:$src), 0>;
1711 def : InstAlias<"mov{l}.s\t{$src, $dst|$dst, $src}",
1712 (MOV32rr_REV GR32:$dst, GR32:$src), 0>;
1713 def : InstAlias<"mov{q}.s\t{$src, $dst|$dst, $src}",
1714 (MOV64rr_REV GR64:$dst, GR64:$src), 0>;
1715 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1716 (MOV8rr_REV GR8:$dst, GR8:$src), 0, "att">;
1717 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1718 (MOV16rr_REV GR16:$dst, GR16:$src), 0, "att">;
1719 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1720 (MOV32rr_REV GR32:$dst, GR32:$src), 0, "att">;
1721 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1722 (MOV64rr_REV GR64:$dst, GR64:$src), 0, "att">;
1724 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1725 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1726 "mov{b}\t{$src, $dst|$dst, $src}",
1727 [(set GR8:$dst, (loadi8 addr:$src))]>;
1728 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1729 "mov{w}\t{$src, $dst|$dst, $src}",
1730 [(set GR16:$dst, (loadi16 addr:$src))]>, OpSize16;
1731 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1732 "mov{l}\t{$src, $dst|$dst, $src}",
1733 [(set GR32:$dst, (loadi32 addr:$src))]>, OpSize32;
1734 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1735 "mov{q}\t{$src, $dst|$dst, $src}",
1736 [(set GR64:$dst, (load addr:$src))]>;
1739 let SchedRW = [WriteStore] in {
1740 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1741 "mov{b}\t{$src, $dst|$dst, $src}",
1742 [(store GR8:$src, addr:$dst)]>;
1743 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1744 "mov{w}\t{$src, $dst|$dst, $src}",
1745 [(store GR16:$src, addr:$dst)]>, OpSize16;
1746 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1747 "mov{l}\t{$src, $dst|$dst, $src}",
1748 [(store GR32:$src, addr:$dst)]>, OpSize32;
1749 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1750 "mov{q}\t{$src, $dst|$dst, $src}",
1751 [(store GR64:$src, addr:$dst)]>;
1754 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1755 // that they can be used for copying and storing h registers, which can't be
1756 // encoded when a REX prefix is present.
1757 let isCodeGenOnly = 1 in {
1758 let hasSideEffects = 0, isMoveReg = 1 in
1759 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1760 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1761 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1763 let mayStore = 1, hasSideEffects = 0 in
1764 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1765 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1766 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1767 Sched<[WriteStore]>;
1768 let mayLoad = 1, hasSideEffects = 0,
1769 canFoldAsLoad = 1, isReMaterializable = 1 in
1770 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1771 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1772 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1777 // Condition code ops, incl. set if equal/not equal/...
1778 let SchedRW = [WriteLAHFSAHF] in {
1779 let Defs = [EFLAGS], Uses = [AH] in
1780 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1781 [(set EFLAGS, (X86sahf AH))]>,
1782 Requires<[HasLAHFSAHF]>;
1783 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1784 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>, // AH = flags
1785 Requires<[HasLAHFSAHF]>;
1788 //===----------------------------------------------------------------------===//
1789 // Bit tests instructions: BT, BTS, BTR, BTC.
1791 let Defs = [EFLAGS] in {
1792 let SchedRW = [WriteBitTest] in {
1793 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1794 "bt{w}\t{$src2, $src1|$src1, $src2}",
1795 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>,
1796 OpSize16, TB, NotMemoryFoldable;
1797 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1798 "bt{l}\t{$src2, $src1|$src1, $src2}",
1799 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>,
1800 OpSize32, TB, NotMemoryFoldable;
1801 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1802 "bt{q}\t{$src2, $src1|$src1, $src2}",
1803 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB,
1807 // Unlike with the register+register form, the memory+register form of the
1808 // bt instruction does not ignore the high bits of the index. From ISel's
1809 // perspective, this is pretty bizarre. Make these instructions disassembly
1810 // only for now. These instructions are also slow on modern CPUs so that's
1811 // another reason to avoid generating them.
1813 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in {
1814 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1815 "bt{w}\t{$src2, $src1|$src1, $src2}",
1816 []>, OpSize16, TB, NotMemoryFoldable;
1817 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1818 "bt{l}\t{$src2, $src1|$src1, $src2}",
1819 []>, OpSize32, TB, NotMemoryFoldable;
1820 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1821 "bt{q}\t{$src2, $src1|$src1, $src2}",
1822 []>, TB, NotMemoryFoldable;
1825 let SchedRW = [WriteBitTest] in {
1826 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2),
1827 "bt{w}\t{$src2, $src1|$src1, $src2}",
1828 [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>,
1830 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2),
1831 "bt{l}\t{$src2, $src1|$src1, $src2}",
1832 [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>,
1834 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2),
1835 "bt{q}\t{$src2, $src1|$src1, $src2}",
1836 [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB;
1839 // Note that these instructions aren't slow because that only applies when the
1840 // other operand is in a register. When it's an immediate, bt is still fast.
1841 let SchedRW = [WriteBitTestImmLd] in {
1842 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1843 "bt{w}\t{$src2, $src1|$src1, $src2}",
1844 [(set EFLAGS, (X86bt (loadi16 addr:$src1),
1847 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1848 "bt{l}\t{$src2, $src1|$src1, $src2}",
1849 [(set EFLAGS, (X86bt (loadi32 addr:$src1),
1852 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1853 "bt{q}\t{$src2, $src1|$src1, $src2}",
1854 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1856 Requires<[In64BitMode]>;
1859 let hasSideEffects = 0 in {
1860 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1861 def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1862 "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
1863 OpSize16, TB, NotMemoryFoldable;
1864 def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1865 "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
1866 OpSize32, TB, NotMemoryFoldable;
1867 def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1868 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1872 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1873 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1874 "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
1875 OpSize16, TB, NotMemoryFoldable;
1876 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1877 "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
1878 OpSize32, TB, NotMemoryFoldable;
1879 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1880 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1884 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1885 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1886 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1887 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1888 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1889 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1890 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1893 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1894 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1895 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1896 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1897 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1898 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1899 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1900 Requires<[In64BitMode]>;
1903 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1904 def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1905 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1906 OpSize16, TB, NotMemoryFoldable;
1907 def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1908 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1909 OpSize32, TB, NotMemoryFoldable;
1910 def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1911 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1915 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1916 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1917 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1918 OpSize16, TB, NotMemoryFoldable;
1919 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1920 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1921 OpSize32, TB, NotMemoryFoldable;
1922 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1923 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1927 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1928 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1929 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1931 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1932 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1934 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1935 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1938 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1939 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1940 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1942 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1943 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1945 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1946 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1947 Requires<[In64BitMode]>;
1950 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1951 def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1952 "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
1953 OpSize16, TB, NotMemoryFoldable;
1954 def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1955 "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
1956 OpSize32, TB, NotMemoryFoldable;
1957 def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1958 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1962 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1963 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1964 "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
1965 OpSize16, TB, NotMemoryFoldable;
1966 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1967 "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
1968 OpSize32, TB, NotMemoryFoldable;
1969 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1970 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1974 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1975 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1976 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1977 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1978 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1979 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1980 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1983 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1984 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1985 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1986 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1987 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1988 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1989 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1990 Requires<[In64BitMode]>;
1992 } // hasSideEffects = 0
1993 } // Defs = [EFLAGS]
1996 //===----------------------------------------------------------------------===//
2000 // Atomic swap. These are just normal xchg instructions. But since a memory
2001 // operand is referenced, the atomicity is ensured.
2002 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag> {
2003 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
2004 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
2005 (ins GR8:$val, i8mem:$ptr),
2006 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
2009 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>;
2010 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
2011 (ins GR16:$val, i16mem:$ptr),
2012 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
2015 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>,
2017 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
2018 (ins GR32:$val, i32mem:$ptr),
2019 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
2022 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>,
2024 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
2025 (ins GR64:$val, i64mem:$ptr),
2026 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
2029 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>;
2033 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap">, NotMemoryFoldable;
2035 // Swap between registers.
2036 let SchedRW = [WriteXCHG] in {
2037 let Constraints = "$src1 = $dst1, $src2 = $dst2", hasSideEffects = 0 in {
2038 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst1, GR8:$dst2),
2039 (ins GR8:$src1, GR8:$src2),
2040 "xchg{b}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable;
2041 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst1, GR16:$dst2),
2042 (ins GR16:$src1, GR16:$src2),
2043 "xchg{w}\t{$src2, $src1|$src1, $src2}", []>,
2044 OpSize16, NotMemoryFoldable;
2045 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst1, GR32:$dst2),
2046 (ins GR32:$src1, GR32:$src2),
2047 "xchg{l}\t{$src2, $src1|$src1, $src2}", []>,
2048 OpSize32, NotMemoryFoldable;
2049 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst1, GR64:$dst2),
2050 (ins GR64:$src1 ,GR64:$src2),
2051 "xchg{q}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable;
2054 // Swap between EAX and other registers.
2055 let Constraints = "$src = $dst", hasSideEffects = 0 in {
2056 let Uses = [AX], Defs = [AX] in
2057 def XCHG16ar : I<0x90, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
2058 "xchg{w}\t{$src, %ax|ax, $src}", []>, OpSize16;
2059 let Uses = [EAX], Defs = [EAX] in
2060 def XCHG32ar : I<0x90, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
2061 "xchg{l}\t{$src, %eax|eax, $src}", []>, OpSize32;
2062 let Uses = [RAX], Defs = [RAX] in
2063 def XCHG64ar : RI<0x90, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
2064 "xchg{q}\t{$src, %rax|rax, $src}", []>;
2068 let hasSideEffects = 0, Constraints = "$src1 = $dst1, $src2 = $dst2",
2069 Defs = [EFLAGS], SchedRW = [WriteXCHG] in {
2070 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst1, GR8:$dst2),
2071 (ins GR8:$src1, GR8:$src2),
2072 "xadd{b}\t{$src2, $src1|$src1, $src2}", []>, TB;
2073 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst1, GR16:$dst2),
2074 (ins GR16:$src1, GR16:$src2),
2075 "xadd{w}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize16;
2076 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst1, GR32:$dst2),
2077 (ins GR32:$src1, GR32:$src2),
2078 "xadd{l}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize32;
2079 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst1, GR64:$dst2),
2080 (ins GR64:$src1, GR64:$src2),
2081 "xadd{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
2084 let mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$val = $dst",
2085 Defs = [EFLAGS], SchedRW = [WriteALULd, WriteRMW] in {
2086 def XADD8rm : I<0xC0, MRMSrcMem, (outs GR8:$dst),
2087 (ins GR8:$val, i8mem:$ptr),
2088 "xadd{b}\t{$val, $ptr|$ptr, $val}", []>, TB;
2089 def XADD16rm : I<0xC1, MRMSrcMem, (outs GR16:$dst),
2090 (ins GR16:$val, i16mem:$ptr),
2091 "xadd{w}\t{$val, $ptr|$ptr, $val}", []>, TB,
2093 def XADD32rm : I<0xC1, MRMSrcMem, (outs GR32:$dst),
2094 (ins GR32:$val, i32mem:$ptr),
2095 "xadd{l}\t{$val, $ptr|$ptr, $val}", []>, TB,
2097 def XADD64rm : RI<0xC1, MRMSrcMem, (outs GR64:$dst),
2098 (ins GR64:$val, i64mem:$ptr),
2099 "xadd{q}\t{$val, $ptr|$ptr, $val}", []>, TB;
2103 let SchedRW = [WriteCMPXCHG], hasSideEffects = 0 in {
2104 let Defs = [AL, EFLAGS], Uses = [AL] in
2105 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
2106 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB,
2108 let Defs = [AX, EFLAGS], Uses = [AX] in
2109 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2110 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16,
2112 let Defs = [EAX, EFLAGS], Uses = [EAX] in
2113 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
2114 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32,
2116 let Defs = [RAX, EFLAGS], Uses = [RAX] in
2117 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
2118 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB,
2120 } // SchedRW, hasSideEffects
2122 let SchedRW = [WriteCMPXCHGRMW], mayLoad = 1, mayStore = 1,
2123 hasSideEffects = 0 in {
2124 let Defs = [AL, EFLAGS], Uses = [AL] in
2125 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
2126 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB,
2128 let Defs = [AX, EFLAGS], Uses = [AX] in
2129 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2130 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16,
2132 let Defs = [EAX, EFLAGS], Uses = [EAX] in
2133 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2134 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32,
2136 let Defs = [RAX, EFLAGS], Uses = [RAX] in
2137 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2138 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB,
2141 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
2142 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
2143 "cmpxchg8b\t$dst", []>, TB, Requires<[HasCmpxchg8b]>;
2145 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
2146 // NOTE: In64BitMode check needed for the AssemblerPredicate.
2147 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
2148 "cmpxchg16b\t$dst", []>,
2149 TB, Requires<[HasCmpxchg16b,In64BitMode]>;
2150 } // SchedRW, mayLoad, mayStore, hasSideEffects
2153 // Lock instruction prefix
2154 let SchedRW = [WriteMicrocoded] in
2155 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
2157 let SchedRW = [WriteNop] in {
2159 // Rex64 instruction prefix
2160 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
2161 Requires<[In64BitMode]>;
2163 // Data16 instruction prefix
2164 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
2167 // Repeat string operation instruction prefixes
2168 let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in {
2169 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2170 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2171 // Repeat while not equal (used with CMPS and SCAS)
2172 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2175 // String manipulation instructions
2176 let SchedRW = [WriteMicrocoded] in {
2177 let Defs = [AL,ESI], Uses = [ESI,DF] in
2178 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2179 "lodsb\t{$src, %al|al, $src}", []>;
2180 let Defs = [AX,ESI], Uses = [ESI,DF] in
2181 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2182 "lodsw\t{$src, %ax|ax, $src}", []>, OpSize16;
2183 let Defs = [EAX,ESI], Uses = [ESI,DF] in
2184 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2185 "lods{l|d}\t{$src, %eax|eax, $src}", []>, OpSize32;
2186 let Defs = [RAX,ESI], Uses = [ESI,DF] in
2187 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2188 "lodsq\t{$src, %rax|rax, $src}", []>,
2189 Requires<[In64BitMode]>;
2192 let SchedRW = [WriteSystem] in {
2193 let Defs = [ESI], Uses = [DX,ESI,DF] in {
2194 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2195 "outsb\t{$src, %dx|dx, $src}", []>;
2196 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2197 "outsw\t{$src, %dx|dx, $src}", []>, OpSize16;
2198 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2199 "outs{l|d}\t{$src, %dx|dx, $src}", []>, OpSize32;
2202 let Defs = [EDI], Uses = [DX,EDI,DF] in {
2203 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2204 "insb\t{%dx, $dst|$dst, dx}", []>;
2205 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2206 "insw\t{%dx, $dst|$dst, dx}", []>, OpSize16;
2207 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2208 "ins{l|d}\t{%dx, $dst|$dst, dx}", []>, OpSize32;
2212 // EFLAGS management instructions.
2213 let SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in {
2214 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", []>;
2215 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", []>;
2216 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", []>;
2219 // DF management instructions.
2220 let SchedRW = [WriteALU], Defs = [DF] in {
2221 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", []>;
2222 def STD : I<0xFD, RawFrm, (outs), (ins), "std", []>;
2225 // Table lookup instructions
2226 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2227 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", []>, Sched<[WriteLoad]>;
2229 let SchedRW = [WriteMicrocoded] in {
2230 // ASCII Adjust After Addition
2231 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2232 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", []>,
2233 Requires<[Not64BitMode]>;
2235 // ASCII Adjust AX Before Division
2236 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2237 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2238 "aad\t$src", []>, Requires<[Not64BitMode]>;
2240 // ASCII Adjust AX After Multiply
2241 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2242 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2243 "aam\t$src", []>, Requires<[Not64BitMode]>;
2245 // ASCII Adjust AL After Subtraction - sets
2246 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2247 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", []>,
2248 Requires<[Not64BitMode]>;
2250 // Decimal Adjust AL after Addition
2251 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2252 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", []>,
2253 Requires<[Not64BitMode]>;
2255 // Decimal Adjust AL after Subtraction
2256 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2257 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", []>,
2258 Requires<[Not64BitMode]>;
2261 let SchedRW = [WriteSystem] in {
2262 // Check Array Index Against Bounds
2263 // Note: "bound" does not have reversed operands in at&t syntax.
2264 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2265 "bound\t$dst, $src", []>, OpSize16,
2266 Requires<[Not64BitMode]>;
2267 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2268 "bound\t$dst, $src", []>, OpSize32,
2269 Requires<[Not64BitMode]>;
2271 // Adjust RPL Field of Segment Selector
2272 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2273 "arpl\t{$src, $dst|$dst, $src}", []>,
2274 Requires<[Not64BitMode]>, NotMemoryFoldable;
2276 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2277 "arpl\t{$src, $dst|$dst, $src}", []>,
2278 Requires<[Not64BitMode]>, NotMemoryFoldable;
2281 //===----------------------------------------------------------------------===//
2282 // MOVBE Instructions
2284 let Predicates = [HasMOVBE] in {
2285 let SchedRW = [WriteALULd] in {
2286 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2287 "movbe{w}\t{$src, $dst|$dst, $src}",
2288 [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>,
2290 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2291 "movbe{l}\t{$src, $dst|$dst, $src}",
2292 [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>,
2294 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2295 "movbe{q}\t{$src, $dst|$dst, $src}",
2296 [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>,
2299 let SchedRW = [WriteStore] in {
2300 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2301 "movbe{w}\t{$src, $dst|$dst, $src}",
2302 [(store (bswap GR16:$src), addr:$dst)]>,
2304 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2305 "movbe{l}\t{$src, $dst|$dst, $src}",
2306 [(store (bswap GR32:$src), addr:$dst)]>,
2308 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2309 "movbe{q}\t{$src, $dst|$dst, $src}",
2310 [(store (bswap GR64:$src), addr:$dst)]>,
2315 //===----------------------------------------------------------------------===//
2316 // RDRAND Instruction
2318 let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2319 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2320 "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>,
2322 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2323 "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>,
2325 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2326 "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>,
2330 //===----------------------------------------------------------------------===//
2331 // RDSEED Instruction
2333 let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2334 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst",
2335 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, PS;
2336 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst",
2337 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, PS;
2338 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst",
2339 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, PS;
2342 //===----------------------------------------------------------------------===//
2343 // LZCNT Instruction
2345 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2346 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2347 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2348 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>,
2349 XS, OpSize16, Sched<[WriteLZCNT]>;
2350 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2351 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2352 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2353 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteLZCNTLd]>;
2355 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2356 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2357 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>,
2358 XS, OpSize32, Sched<[WriteLZCNT]>;
2359 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2360 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2361 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2362 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteLZCNTLd]>;
2364 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2365 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2366 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2367 XS, Sched<[WriteLZCNT]>;
2368 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2369 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2370 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2371 (implicit EFLAGS)]>, XS, Sched<[WriteLZCNTLd]>;
2374 //===----------------------------------------------------------------------===//
2377 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2378 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2379 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2380 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>,
2381 XS, OpSize16, Sched<[WriteTZCNT]>;
2382 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2383 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2384 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2385 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteTZCNTLd]>;
2387 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2388 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2389 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>,
2390 XS, OpSize32, Sched<[WriteTZCNT]>;
2391 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2392 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2393 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2394 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteTZCNTLd]>;
2396 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2397 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2398 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2399 XS, Sched<[WriteTZCNT]>;
2400 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2401 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2402 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2403 (implicit EFLAGS)]>, XS, Sched<[WriteTZCNTLd]>;
2406 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2407 RegisterClass RC, X86MemOperand x86memop> {
2408 let hasSideEffects = 0 in {
2409 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2410 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
2411 T8PS, VEX_4V, Sched<[WriteBLS]>;
2413 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2414 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
2415 T8PS, VEX_4V, Sched<[WriteBLS.Folded]>;
2419 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2420 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2421 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2422 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2423 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2424 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2425 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2428 //===----------------------------------------------------------------------===//
2429 // Pattern fragments to auto generate BMI instructions.
2430 //===----------------------------------------------------------------------===//
2432 def or_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2433 (X86or_flag node:$lhs, node:$rhs), [{
2434 return hasNoCarryFlagUses(SDValue(N, 1));
2437 def xor_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2438 (X86xor_flag node:$lhs, node:$rhs), [{
2439 return hasNoCarryFlagUses(SDValue(N, 1));
2442 def and_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2443 (X86and_flag node:$lhs, node:$rhs), [{
2444 return hasNoCarryFlagUses(SDValue(N, 1));
2447 let Predicates = [HasBMI] in {
2448 // FIXME: patterns for the load versions are not implemented
2449 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2450 (BLSR32rr GR32:$src)>;
2451 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2452 (BLSR64rr GR64:$src)>;
2454 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2455 (BLSMSK32rr GR32:$src)>;
2456 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2457 (BLSMSK64rr GR64:$src)>;
2459 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2460 (BLSI32rr GR32:$src)>;
2461 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2462 (BLSI64rr GR64:$src)>;
2464 // Versions to match flag producing ops.
2465 def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, -1)),
2466 (BLSR32rr GR32:$src)>;
2467 def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, -1)),
2468 (BLSR64rr GR64:$src)>;
2470 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, -1)),
2471 (BLSMSK32rr GR32:$src)>;
2472 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, -1)),
2473 (BLSMSK64rr GR64:$src)>;
2475 def : Pat<(and_flag_nocf GR32:$src, (ineg GR32:$src)),
2476 (BLSI32rr GR32:$src)>;
2477 def : Pat<(and_flag_nocf GR64:$src, (ineg GR64:$src)),
2478 (BLSI64rr GR64:$src)>;
2481 multiclass bmi_bextr<bits<8> opc, string mnemonic, RegisterClass RC,
2482 X86MemOperand x86memop, SDNode OpNode,
2483 PatFrag ld_frag, X86FoldableSchedWrite Sched> {
2484 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2485 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2486 [(set RC:$dst, (OpNode RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2487 T8PS, VEX, Sched<[Sched]>;
2488 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2489 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2490 [(set RC:$dst, (OpNode (ld_frag addr:$src1), RC:$src2)),
2491 (implicit EFLAGS)]>, T8PS, VEX,
2492 Sched<[Sched.Folded,
2494 ReadDefault, ReadDefault, ReadDefault, ReadDefault,
2497 Sched.ReadAfterFold]>;
2500 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2501 defm BEXTR32 : bmi_bextr<0xF7, "bextr{l}", GR32, i32mem,
2502 X86bextr, loadi32, WriteBEXTR>;
2503 defm BEXTR64 : bmi_bextr<0xF7, "bextr{q}", GR64, i64mem,
2504 X86bextr, loadi64, WriteBEXTR>, VEX_W;
2507 multiclass bmi_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2508 X86MemOperand x86memop, Intrinsic Int,
2509 PatFrag ld_frag, X86FoldableSchedWrite Sched> {
2510 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2511 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2512 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2513 T8PS, VEX, Sched<[Sched]>;
2514 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2515 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2516 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2517 (implicit EFLAGS)]>, T8PS, VEX,
2518 Sched<[Sched.Folded,
2520 ReadDefault, ReadDefault, ReadDefault, ReadDefault,
2523 Sched.ReadAfterFold]>;
2526 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2527 defm BZHI32 : bmi_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2528 X86bzhi, loadi32, WriteBZHI>;
2529 defm BZHI64 : bmi_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2530 X86bzhi, loadi64, WriteBZHI>, VEX_W;
2533 def CountTrailingOnes : SDNodeXForm<imm, [{
2534 // Count the trailing ones in the immediate.
2535 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2538 def BEXTRMaskXForm : SDNodeXForm<imm, [{
2539 unsigned Length = countTrailingOnes(N->getZExtValue());
2540 return getI32Imm(Length << 8, SDLoc(N));
2543 def AndMask64 : ImmLeaf<i64, [{
2544 return isMask_64(Imm) && !isUInt<32>(Imm);
2547 // Use BEXTR for 64-bit 'and' with large immediate 'mask'.
2548 let Predicates = [HasBMI, NoBMI2, NoTBM] in {
2549 def : Pat<(and GR64:$src, AndMask64:$mask),
2550 (BEXTR64rr GR64:$src,
2551 (SUBREG_TO_REG (i64 0),
2552 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2553 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2554 (BEXTR64rm addr:$src,
2555 (SUBREG_TO_REG (i64 0),
2556 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2559 // Use BZHI for 64-bit 'and' with large immediate 'mask'.
2560 let Predicates = [HasBMI2, NoTBM] in {
2561 def : Pat<(and GR64:$src, AndMask64:$mask),
2562 (BZHI64rr GR64:$src,
2563 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2564 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2565 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2566 (BZHI64rm addr:$src,
2567 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2568 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2571 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2572 X86MemOperand x86memop, Intrinsic Int,
2574 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2575 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2576 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2577 VEX_4V, Sched<[WriteALU]>;
2578 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2579 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2580 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>,
2581 VEX_4V, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>;
2584 let Predicates = [HasBMI2] in {
2585 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2586 int_x86_bmi_pdep_32, loadi32>, T8XD;
2587 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2588 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2589 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2590 int_x86_bmi_pext_32, loadi32>, T8XS;
2591 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2592 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2595 //===----------------------------------------------------------------------===//
2598 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2600 multiclass tbm_ternary_imm<bits<8> opc, RegisterClass RC, string OpcodeStr,
2601 X86MemOperand x86memop, PatFrag ld_frag,
2602 SDNode OpNode, Operand immtype,
2603 SDPatternOperator immoperator,
2604 X86FoldableSchedWrite Sched> {
2605 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2606 !strconcat(OpcodeStr,
2607 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2608 [(set RC:$dst, (OpNode RC:$src1, immoperator:$cntl))]>,
2609 XOP, XOPA, Sched<[Sched]>;
2610 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2611 (ins x86memop:$src1, immtype:$cntl),
2612 !strconcat(OpcodeStr,
2613 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2614 [(set RC:$dst, (OpNode (ld_frag addr:$src1), immoperator:$cntl))]>,
2615 XOP, XOPA, Sched<[Sched.Folded]>;
2618 defm BEXTRI32 : tbm_ternary_imm<0x10, GR32, "bextr{l}", i32mem, loadi32,
2619 X86bextr, i32imm, imm, WriteBEXTR>;
2620 let ImmT = Imm32S in
2621 defm BEXTRI64 : tbm_ternary_imm<0x10, GR64, "bextr{q}", i64mem, loadi64,
2622 X86bextr, i64i32imm,
2623 i64immSExt32, WriteBEXTR>, VEX_W;
2625 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2626 RegisterClass RC, string OpcodeStr,
2627 X86MemOperand x86memop, X86FoldableSchedWrite Sched> {
2628 let hasSideEffects = 0 in {
2629 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2630 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>,
2631 XOP_4V, XOP9, Sched<[Sched]>;
2633 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2634 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>,
2635 XOP_4V, XOP9, Sched<[Sched.Folded]>;
2639 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2640 X86FoldableSchedWrite Sched,
2641 Format FormReg, Format FormMem> {
2642 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr#"{l}",
2644 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr#"{q}",
2645 i64mem, Sched>, VEX_W;
2648 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", WriteALU, MRM1r, MRM1m>;
2649 defm BLCI : tbm_binary_intr<0x02, "blci", WriteALU, MRM6r, MRM6m>;
2650 defm BLCIC : tbm_binary_intr<0x01, "blcic", WriteALU, MRM5r, MRM5m>;
2651 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", WriteALU, MRM1r, MRM1m>;
2652 defm BLCS : tbm_binary_intr<0x01, "blcs", WriteALU, MRM3r, MRM3m>;
2653 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", WriteALU, MRM2r, MRM2m>;
2654 defm BLSIC : tbm_binary_intr<0x01, "blsic", WriteALU, MRM6r, MRM6m>;
2655 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", WriteALU, MRM7r, MRM7m>;
2656 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", WriteALU, MRM4r, MRM4m>;
2659 // Use BEXTRI for 64-bit 'and' with large immediate 'mask'.
2660 let Predicates = [HasTBM] in {
2661 def : Pat<(and GR64:$src, AndMask64:$mask),
2662 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>;
2664 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2665 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>;
2668 //===----------------------------------------------------------------------===//
2669 // Lightweight Profiling Instructions
2671 let Predicates = [HasLWP], SchedRW = [WriteSystem] in {
2673 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2674 [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9;
2675 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2676 [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9;
2678 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2679 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, VEX_W;
2680 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2681 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, VEX_W;
2683 multiclass lwpins_intr<RegisterClass RC> {
2684 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2685 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2686 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, imm:$cntl))]>,
2689 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2690 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2691 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), imm:$cntl))]>,
2695 let Defs = [EFLAGS] in {
2696 defm LWPINS32 : lwpins_intr<GR32>;
2697 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2700 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2701 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2702 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2703 [(Int RC:$src0, GR32:$src1, imm:$cntl)]>, XOP_4V, XOPA;
2705 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2706 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2707 [(Int RC:$src0, (loadi32 addr:$src1), imm:$cntl)]>,
2711 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2712 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2714 } // HasLWP, SchedRW
2716 //===----------------------------------------------------------------------===//
2717 // MONITORX/MWAITX Instructions
2719 let SchedRW = [ WriteSystem ] in {
2720 let Uses = [ EAX, ECX, EDX ] in
2721 def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
2722 TB, Requires<[ HasMWAITX, Not64BitMode ]>;
2723 let Uses = [ RAX, ECX, EDX ] in
2724 def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
2725 TB, Requires<[ HasMWAITX, In64BitMode ]>;
2727 let Uses = [ ECX, EAX, EBX ] in {
2728 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2729 [(int_x86_mwaitx ECX, EAX, EBX)]>,
2730 TB, Requires<[ HasMWAITX ]>;
2734 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2735 Requires<[ Not64BitMode ]>;
2736 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2737 Requires<[ In64BitMode ]>;
2739 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORX32rrr)>,
2740 Requires<[ Not64BitMode ]>;
2741 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORX64rrr)>,
2742 Requires<[ In64BitMode ]>;
2744 //===----------------------------------------------------------------------===//
2745 // WAITPKG Instructions
2747 let SchedRW = [WriteSystem] in {
2748 def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src),
2749 "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>,
2750 XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>;
2751 def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src),
2752 "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>,
2753 XS, AdSize32, Requires<[HasWAITPKG]>;
2754 def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src),
2755 "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>,
2756 XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>;
2757 let Uses = [EAX, EDX], Defs = [EFLAGS] in {
2758 def UMWAIT : I<0xAE, MRM6r,
2759 (outs), (ins GR32orGR64:$src), "umwait\t$src",
2760 [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>,
2761 XD, Requires<[HasWAITPKG]>;
2762 def TPAUSE : I<0xAE, MRM6r,
2763 (outs), (ins GR32orGR64:$src), "tpause\t$src",
2764 [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>,
2765 PD, Requires<[HasWAITPKG]>, NotMemoryFoldable;
2769 //===----------------------------------------------------------------------===//
2770 // MOVDIRI - Move doubleword/quadword as direct store
2772 let SchedRW = [WriteStore] in {
2773 def MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2774 "movdiri\t{$src, $dst|$dst, $src}",
2775 [(int_x86_directstore32 addr:$dst, GR32:$src)]>,
2776 T8, Requires<[HasMOVDIRI]>;
2777 def MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2778 "movdiri\t{$src, $dst|$dst, $src}",
2779 [(int_x86_directstore64 addr:$dst, GR64:$src)]>,
2780 T8, Requires<[In64BitMode, HasMOVDIRI]>;
2783 //===----------------------------------------------------------------------===//
2784 // MOVDIR64B - Move 64 bytes as direct store
2786 let SchedRW = [WriteStore] in {
2787 def MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2788 "movdir64b\t{$src, $dst|$dst, $src}", []>,
2789 T8PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>;
2790 def MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2791 "movdir64b\t{$src, $dst|$dst, $src}",
2792 [(int_x86_movdir64b GR32:$dst, addr:$src)]>,
2793 T8PD, AdSize32, Requires<[HasMOVDIR64B]>;
2794 def MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2795 "movdir64b\t{$src, $dst|$dst, $src}",
2796 [(int_x86_movdir64b GR64:$dst, addr:$src)]>,
2797 T8PD, AdSize64, Requires<[HasMOVDIR64B, In64BitMode]>;
2800 //===----------------------------------------------------------------------===//
2801 // ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity
2803 let SchedRW = [WriteStore], Defs = [EFLAGS] in {
2804 def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2805 "enqcmd\t{$src, $dst|$dst, $src}",
2806 [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>,
2807 T8XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
2808 def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2809 "enqcmd\t{$src, $dst|$dst, $src}",
2810 [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>,
2811 T8XD, AdSize32, Requires<[HasENQCMD]>;
2812 def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2813 "enqcmd\t{$src, $dst|$dst, $src}",
2814 [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>,
2815 T8XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
2817 def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2818 "enqcmds\t{$src, $dst|$dst, $src}",
2819 [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>,
2820 T8XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
2821 def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2822 "enqcmds\t{$src, $dst|$dst, $src}",
2823 [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>,
2824 T8XS, AdSize32, Requires<[HasENQCMD]>;
2825 def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2826 "enqcmds\t{$src, $dst|$dst, $src}",
2827 [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>,
2828 T8XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
2831 //===----------------------------------------------------------------------===//
2832 // CLZERO Instruction
2834 let SchedRW = [WriteSystem] in {
2836 def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
2837 TB, Requires<[HasCLZERO, Not64BitMode]>;
2839 def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
2840 TB, Requires<[HasCLZERO, In64BitMode]>;
2843 def : InstAlias<"clzero\t{%eax|eax}", (CLZERO32r)>, Requires<[Not64BitMode]>;
2844 def : InstAlias<"clzero\t{%rax|rax}", (CLZERO64r)>, Requires<[In64BitMode]>;
2846 //===----------------------------------------------------------------------===//
2847 // Pattern fragments to auto generate TBM instructions.
2848 //===----------------------------------------------------------------------===//
2850 let Predicates = [HasTBM] in {
2851 // FIXME: patterns for the load versions are not implemented
2852 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2853 (BLCFILL32rr GR32:$src)>;
2854 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2855 (BLCFILL64rr GR64:$src)>;
2857 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2858 (BLCI32rr GR32:$src)>;
2859 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2860 (BLCI64rr GR64:$src)>;
2862 // Extra patterns because opt can optimize the above patterns to this.
2863 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2864 (BLCI32rr GR32:$src)>;
2865 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2866 (BLCI64rr GR64:$src)>;
2868 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2869 (BLCIC32rr GR32:$src)>;
2870 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2871 (BLCIC64rr GR64:$src)>;
2873 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2874 (BLCMSK32rr GR32:$src)>;
2875 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2876 (BLCMSK64rr GR64:$src)>;
2878 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2879 (BLCS32rr GR32:$src)>;
2880 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2881 (BLCS64rr GR64:$src)>;
2883 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2884 (BLSFILL32rr GR32:$src)>;
2885 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2886 (BLSFILL64rr GR64:$src)>;
2888 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2889 (BLSIC32rr GR32:$src)>;
2890 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2891 (BLSIC64rr GR64:$src)>;
2893 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2894 (T1MSKC32rr GR32:$src)>;
2895 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2896 (T1MSKC64rr GR64:$src)>;
2898 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2899 (TZMSK32rr GR32:$src)>;
2900 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2901 (TZMSK64rr GR64:$src)>;
2903 // Patterns to match flag producing ops.
2904 def : Pat<(or_flag_nocf GR32:$src, (not (add GR32:$src, 1))),
2905 (BLCI32rr GR32:$src)>;
2906 def : Pat<(or_flag_nocf GR64:$src, (not (add GR64:$src, 1))),
2907 (BLCI64rr GR64:$src)>;
2909 // Extra patterns because opt can optimize the above patterns to this.
2910 def : Pat<(or_flag_nocf GR32:$src, (sub -2, GR32:$src)),
2911 (BLCI32rr GR32:$src)>;
2912 def : Pat<(or_flag_nocf GR64:$src, (sub -2, GR64:$src)),
2913 (BLCI64rr GR64:$src)>;
2915 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, 1)),
2916 (BLCIC32rr GR32:$src)>;
2917 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, 1)),
2918 (BLCIC64rr GR64:$src)>;
2920 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, 1)),
2921 (BLCMSK32rr GR32:$src)>;
2922 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, 1)),
2923 (BLCMSK64rr GR64:$src)>;
2925 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, 1)),
2926 (BLCS32rr GR32:$src)>;
2927 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, 1)),
2928 (BLCS64rr GR64:$src)>;
2930 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, -1)),
2931 (BLSFILL32rr GR32:$src)>;
2932 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, -1)),
2933 (BLSFILL64rr GR64:$src)>;
2935 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, -1)),
2936 (BLSIC32rr GR32:$src)>;
2937 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, -1)),
2938 (BLSIC64rr GR64:$src)>;
2940 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, 1)),
2941 (T1MSKC32rr GR32:$src)>;
2942 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, 1)),
2943 (T1MSKC64rr GR64:$src)>;
2945 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, -1)),
2946 (TZMSK32rr GR32:$src)>;
2947 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, -1)),
2948 (TZMSK64rr GR64:$src)>;
2951 //===----------------------------------------------------------------------===//
2952 // Memory Instructions
2955 let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
2956 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2957 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
2959 let Predicates = [HasCLWB], SchedRW = [WriteLoad] in
2960 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
2961 [(int_x86_clwb addr:$src)]>, PD, NotMemoryFoldable;
2963 let Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in
2964 def CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src",
2965 [(int_x86_cldemote addr:$src)]>, TB;
2967 //===----------------------------------------------------------------------===//
2969 //===----------------------------------------------------------------------===//
2971 include "X86InstrArithmetic.td"
2972 include "X86InstrCMovSetCC.td"
2973 include "X86InstrExtension.td"
2974 include "X86InstrControl.td"
2975 include "X86InstrShiftRotate.td"
2977 // X87 Floating Point Stack.
2978 include "X86InstrFPStack.td"
2980 // SIMD support (SSE, MMX and AVX)
2981 include "X86InstrFragmentsSIMD.td"
2983 // FMA - Fused Multiply-Add support (requires FMA)
2984 include "X86InstrFMA.td"
2987 include "X86InstrXOP.td"
2989 // SSE, MMX and 3DNow! vector support.
2990 include "X86InstrSSE.td"
2991 include "X86InstrAVX512.td"
2992 include "X86InstrMMX.td"
2993 include "X86Instr3DNow.td"
2996 include "X86InstrMPX.td"
2998 include "X86InstrVMX.td"
2999 include "X86InstrSVM.td"
3001 include "X86InstrTSX.td"
3002 include "X86InstrSGX.td"
3004 // System instructions.
3005 include "X86InstrSystem.td"
3007 // Compiler Pseudo Instructions and Pat Patterns
3008 include "X86InstrCompiler.td"
3009 include "X86InstrVecCompiler.td"
3011 //===----------------------------------------------------------------------===//
3012 // Assembler Mnemonic Aliases
3013 //===----------------------------------------------------------------------===//
3015 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
3016 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
3017 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
3019 def : MnemonicAlias<"cbw", "cbtw", "att">;
3020 def : MnemonicAlias<"cwde", "cwtl", "att">;
3021 def : MnemonicAlias<"cwd", "cwtd", "att">;
3022 def : MnemonicAlias<"cdq", "cltd", "att">;
3023 def : MnemonicAlias<"cdqe", "cltq", "att">;
3024 def : MnemonicAlias<"cqo", "cqto", "att">;
3026 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
3027 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
3028 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
3030 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
3031 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
3033 def : MnemonicAlias<"loopz", "loope">;
3034 def : MnemonicAlias<"loopnz", "loopne">;
3036 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
3037 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
3038 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
3039 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
3040 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
3041 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
3042 def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>;
3043 def : MnemonicAlias<"popfd", "popfl", "att">;
3044 def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In32BitMode]>;
3045 def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In64BitMode]>;
3047 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
3048 // all modes. However: "push (addr)" and "push $42" should default to
3049 // pushl/pushq depending on the current mode. Similar for "pop %bx"
3050 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
3051 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
3052 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
3053 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
3054 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
3055 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
3056 def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>;
3057 def : MnemonicAlias<"pushfd", "pushfl", "att">;
3058 def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In32BitMode]>;
3059 def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In64BitMode]>;
3061 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
3062 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
3063 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
3064 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
3065 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
3066 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
3068 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
3069 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
3070 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
3071 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
3073 def : MnemonicAlias<"repe", "rep">;
3074 def : MnemonicAlias<"repz", "rep">;
3075 def : MnemonicAlias<"repnz", "repne">;
3077 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
3078 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
3079 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
3081 // Apply 'ret' behavior to 'retn'
3082 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
3083 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
3084 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
3085 def : MnemonicAlias<"retn", "ret", "intel">;
3087 def : MnemonicAlias<"sal", "shl", "intel">;
3088 def : MnemonicAlias<"salb", "shlb", "att">;
3089 def : MnemonicAlias<"salw", "shlw", "att">;
3090 def : MnemonicAlias<"sall", "shll", "att">;
3091 def : MnemonicAlias<"salq", "shlq", "att">;
3093 def : MnemonicAlias<"smovb", "movsb", "att">;
3094 def : MnemonicAlias<"smovw", "movsw", "att">;
3095 def : MnemonicAlias<"smovl", "movsl", "att">;
3096 def : MnemonicAlias<"smovq", "movsq", "att">;
3098 def : MnemonicAlias<"ud2a", "ud2", "att">;
3099 def : MnemonicAlias<"verrw", "verr", "att">;
3101 // MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release'
3102 def : MnemonicAlias<"acquire", "xacquire", "intel">;
3103 def : MnemonicAlias<"release", "xrelease", "intel">;
3105 // System instruction aliases.
3106 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
3107 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
3108 def : MnemonicAlias<"sysret", "sysretl", "att">;
3109 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
3111 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
3112 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
3113 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
3114 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
3115 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
3116 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
3117 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
3118 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
3119 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
3120 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
3121 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
3122 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
3123 def : MnemonicAlias<"lgdt", "lgdtw", "intel">, Requires<[In16BitMode]>;
3124 def : MnemonicAlias<"lgdt", "lgdtd", "intel">, Requires<[In32BitMode]>;
3125 def : MnemonicAlias<"lidt", "lidtw", "intel">, Requires<[In16BitMode]>;
3126 def : MnemonicAlias<"lidt", "lidtd", "intel">, Requires<[In32BitMode]>;
3127 def : MnemonicAlias<"sgdt", "sgdtw", "intel">, Requires<[In16BitMode]>;
3128 def : MnemonicAlias<"sgdt", "sgdtd", "intel">, Requires<[In32BitMode]>;
3129 def : MnemonicAlias<"sidt", "sidtw", "intel">, Requires<[In16BitMode]>;
3130 def : MnemonicAlias<"sidt", "sidtd", "intel">, Requires<[In32BitMode]>;
3133 // Floating point stack aliases.
3134 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
3135 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
3136 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
3137 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
3138 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
3139 def : MnemonicAlias<"fcomip", "fcompi">;
3140 def : MnemonicAlias<"fildq", "fildll", "att">;
3141 def : MnemonicAlias<"fistpq", "fistpll", "att">;
3142 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
3143 def : MnemonicAlias<"fldcww", "fldcw", "att">;
3144 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
3145 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
3146 def : MnemonicAlias<"fucomip", "fucompi">;
3147 def : MnemonicAlias<"fwait", "wait">;
3149 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
3150 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
3151 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
3152 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
3153 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
3154 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
3155 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
3156 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
3158 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
3160 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
3161 !strconcat(Prefix, NewCond, Suffix), VariantName>;
3163 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
3164 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
3165 /// example "setz" -> "sete".
3166 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
3168 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
3169 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
3170 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
3171 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
3172 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
3173 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
3174 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
3175 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
3176 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
3177 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
3179 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
3180 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
3181 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
3182 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
3185 // Aliases for set<CC>
3186 defm : IntegerCondCodeMnemonicAlias<"set", "">;
3187 // Aliases for j<CC>
3188 defm : IntegerCondCodeMnemonicAlias<"j", "">;
3189 // Aliases for cmov<CC>{w,l,q}
3190 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
3191 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
3192 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
3193 // No size suffix for intel-style asm.
3194 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
3197 //===----------------------------------------------------------------------===//
3198 // Assembler Instruction Aliases
3199 //===----------------------------------------------------------------------===//
3201 // aad/aam default to base 10 if no operand is specified.
3202 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
3203 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
3205 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
3206 // Likewise for btc/btr/bts.
3207 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
3208 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0, "att">;
3209 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
3210 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0, "att">;
3211 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
3212 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0, "att">;
3213 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
3214 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0, "att">;
3217 def : InstAlias<"clr{b}\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
3218 def : InstAlias<"clr{w}\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
3219 def : InstAlias<"clr{l}\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
3220 def : InstAlias<"clr{q}\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
3222 // lods aliases. Accept the destination being omitted because it's implicit
3223 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3224 // in the destination.
3225 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
3226 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
3227 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
3228 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3229 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
3230 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
3231 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
3232 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3233 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0, "intel">;
3234 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0, "intel">;
3235 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0, "intel">;
3236 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3239 // stos aliases. Accept the source being omitted because it's implicit in
3240 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
3242 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
3243 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
3244 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
3245 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3246 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
3247 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
3248 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
3249 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3250 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0, "intel">;
3251 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0, "intel">;
3252 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0, "intel">;
3253 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>;
3256 // scas aliases. Accept the destination being omitted because it's implicit
3257 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3258 // in the destination.
3259 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
3260 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
3261 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
3262 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3263 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
3264 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
3265 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
3266 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3267 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0, "intel">;
3268 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0, "intel">;
3269 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0, "intel">;
3270 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>;
3272 // cmps aliases. Mnemonic suffix being omitted because it's implicit
3273 // in the destination.
3274 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0, "intel">;
3275 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0, "intel">;
3276 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0, "intel">;
3277 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3279 // movs aliases. Mnemonic suffix being omitted because it's implicit
3280 // in the destination.
3281 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0, "intel">;
3282 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0, "intel">;
3283 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0, "intel">;
3284 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3286 // div and idiv aliases for explicit A register.
3287 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
3288 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
3289 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
3290 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
3291 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
3292 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
3293 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
3294 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
3295 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
3296 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
3297 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
3298 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
3299 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
3300 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
3301 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
3302 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
3306 // Various unary fpstack operations default to operating on ST1.
3307 // For example, "fxch" -> "fxch %st(1)"
3308 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
3309 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
3310 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
3311 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
3312 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
3313 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
3314 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
3315 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
3316 def : InstAlias<"fxch", (XCH_F ST1), 0>;
3317 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
3318 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
3319 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
3320 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
3321 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
3322 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
3323 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
3324 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
3326 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
3327 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
3328 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
3330 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
3331 def : InstAlias<!strconcat(Mnemonic, "\t$op"),
3332 (Inst RSTi:$op), EmitAlias>;
3333 def : InstAlias<!strconcat(Mnemonic, "\t{%st, %st|st, st}"),
3334 (Inst ST0), EmitAlias>;
3337 defm : FpUnaryAlias<"fadd", ADD_FST0r, 0>;
3338 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
3339 defm : FpUnaryAlias<"fsub", SUB_FST0r, 0>;
3340 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0, 0>;
3341 defm : FpUnaryAlias<"fsubr", SUBR_FST0r, 0>;
3342 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0, 0>;
3343 defm : FpUnaryAlias<"fmul", MUL_FST0r, 0>;
3344 defm : FpUnaryAlias<"fmulp", MUL_FPrST0, 0>;
3345 defm : FpUnaryAlias<"fdiv", DIV_FST0r, 0>;
3346 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0, 0>;
3347 defm : FpUnaryAlias<"fdivr", DIVR_FST0r, 0>;
3348 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0, 0>;
3349 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
3350 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
3351 defm : FpUnaryAlias<"fcompi", COM_FIPr, 0>;
3352 defm : FpUnaryAlias<"fucompi", UCOM_FIPr, 0>;
3355 // Handle "f{mulp,addp} $op, %st(0)" the same as "f{mulp,addp} $op", since they
3356 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3357 // solely because gas supports it.
3358 def : InstAlias<"faddp\t{$op, %st|st, $op}", (ADD_FPrST0 RSTi:$op), 0>;
3359 def : InstAlias<"fmulp\t{$op, %st|st, $op}", (MUL_FPrST0 RSTi:$op), 0>;
3360 def : InstAlias<"fsub{|r}p\t{$op, %st|st, $op}", (SUBR_FPrST0 RSTi:$op), 0>;
3361 def : InstAlias<"fsub{r|}p\t{$op, %st|st, $op}", (SUB_FPrST0 RSTi:$op), 0>;
3362 def : InstAlias<"fdiv{|r}p\t{$op, %st|st, $op}", (DIVR_FPrST0 RSTi:$op), 0>;
3363 def : InstAlias<"fdiv{r|}p\t{$op, %st|st, $op}", (DIV_FPrST0 RSTi:$op), 0>;
3365 def : InstAlias<"fnstsw" , (FNSTSW16r), 0>;
3367 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3368 // this is compatible with what GAS does.
3369 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3370 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3371 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>;
3372 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>;
3373 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3374 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3375 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaquemem:$dst), 0>, Requires<[In16BitMode]>;
3376 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaquemem:$dst), 0>, Requires<[In16BitMode]>;
3378 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0, "att">, Requires<[In64BitMode]>;
3379 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0, "att">, Requires<[In32BitMode]>;
3380 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0, "att">, Requires<[In16BitMode]>;
3383 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3384 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3385 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3386 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3387 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3388 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3389 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3391 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3392 // in the destination.
3393 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0, "intel">;
3394 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0, "intel">;
3395 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0, "intel">;
3397 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3399 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0, "intel">;
3400 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0, "intel">;
3401 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0, "intel">;
3403 // inb %dx -> inb %al, %dx
3404 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3405 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3406 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3407 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3408 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3409 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3412 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3413 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3414 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3415 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3416 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3417 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3418 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3419 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3420 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3422 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3423 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3425 // Match 'movd GR64, MMX' as an alias for movq to be compatible with gas,
3426 // which supports this due to an old AMD documentation bug when 64-bit mode was
3428 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
3429 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3430 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
3431 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3434 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0, "att">;
3435 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0, "att">;
3436 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0, "att">;
3437 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0, "att">;
3438 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0, "att">;
3439 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0, "att">;
3440 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0, "att">;
3443 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0, "att">;
3444 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0, "att">;
3445 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0, "att">;
3446 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0, "att">;
3447 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0, "att">;
3448 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0, "att">;
3449 // Note: No GR32->GR64 movzx form.
3451 // outb %dx -> outb %al, %dx
3452 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3453 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3454 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3455 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3456 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3457 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3459 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3460 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3461 // errors, since its encoding is the most compact.
3462 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3464 // shld/shrd op,op -> shld op, op, CL
3465 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3466 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3467 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3468 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3469 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3470 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3472 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3473 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3474 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3475 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3476 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3477 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3479 /* FIXME: This is disabled because the asm matcher is currently incapable of
3480 * matching a fixed immediate like $1.
3481 // "shl X, $1" is an alias for "shl X".
3482 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3483 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3484 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3485 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3486 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3487 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3488 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3489 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3490 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3491 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3492 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3493 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3494 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3495 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3496 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3497 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3498 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3501 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3502 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3503 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3504 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3507 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3508 def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}",
3509 (TEST8mr i8mem :$mem, GR8 :$val), 0>;
3510 def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}",
3511 (TEST16mr i16mem:$mem, GR16:$val), 0>;
3512 def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}",
3513 (TEST32mr i32mem:$mem, GR32:$val), 0>;
3514 def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}",
3515 (TEST64mr i64mem:$mem, GR64:$val), 0>;
3517 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3518 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3519 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3520 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3521 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3522 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3523 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3524 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3525 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3527 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3528 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3529 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}", (XCHG32ar GR32:$src), 0>;
3530 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3532 // In 64-bit mode, xchg %eax, %eax can't be encoded with the 0x90 opcode we
3533 // would get by default because it's defined as NOP. But xchg %eax, %eax implies
3534 // implicit zeroing of the upper 32 bits. So alias to the longer encoding.
3535 def : InstAlias<"xchg{l}\t{%eax, %eax|eax, eax}",
3536 (XCHG32rr EAX, EAX), 0>, Requires<[In64BitMode]>;
3538 // xchg %rax, %rax is a nop in x86-64 and can be encoded as such. Without this
3539 // we emit an unneeded REX.w prefix.
3540 def : InstAlias<"xchg{q}\t{%rax, %rax|rax, rax}", (NOOP), 0>;
3542 // These aliases exist to get the parser to prioritize matching 8-bit
3543 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3544 // explicitly mentioning the A register here, these entries will be ordered
3545 // first due to the more explicit immediate type.
3546 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3547 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3548 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3549 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3550 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3551 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3552 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3553 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3555 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3556 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3557 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3558 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3559 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3560 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3561 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3562 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3564 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3565 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3566 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3567 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3568 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3569 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3570 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3571 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;